summaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-probe.c
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-07-23 19:55:56 +0200
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-07-23 19:55:56 +0200
commit374e042c3e767ac2e5a40b78529220e0b3de793c (patch)
tree433d258f6da9783f0cb34234af9c359353f531fe /drivers/ide/ide-probe.c
parentd6276b5f5cc7508124de291f3ed59c6945c17ae7 (diff)
downloadlinux-374e042c3e767ac2e5a40b78529220e0b3de793c.tar.bz2
ide: add struct ide_tp_ops (take 2)
* Add struct ide_tp_ops for transport methods. * Add 'const struct ide_tp_ops *tp_ops' to struct ide_port_info and ide_hwif_t. * Set the default hwif->tp_ops in ide_init_port_data(). * Set host driver specific hwif->tp_ops in ide_init_port(). * Export ide_exec_command(), ide_read_status(), ide_read_altstatus(), ide_read_sff_dma_status(), ide_set_irq(), ide_tf_{load,read}() and ata_{in,out}put_data(). * Convert host drivers and core code to use struct ide_tp_ops. * Remove no longer needed default_hwif_transport(). * Cleanup ide_hwif_t from methods that are now in struct ide_tp_ops. While at it: * Use struct ide_port_info in falconide.c and q40ide.c. * Rename ata_{in,out}put_data() to ide_{in,out}put_data(). v2: * Fix missing convertion in ns87415.c. There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide/ide-probe.c')
-rw-r--r--drivers/ide/ide-probe.c53
1 files changed, 30 insertions, 23 deletions
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 3cc8ade2cc4f..c588066295db 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -126,7 +126,7 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd)
id = drive->id;
/* read 512 bytes of id info */
- hwif->input_data(drive, NULL, id, SECTOR_SIZE);
+ hwif->tp_ops->input_data(drive, NULL, id, SECTOR_SIZE);
drive->id_read = 1;
local_irq_enable();
@@ -267,6 +267,7 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
{
ide_hwif_t *hwif = HWIF(drive);
struct ide_io_ports *io_ports = &hwif->io_ports;
+ const struct ide_tp_ops *tp_ops = hwif->tp_ops;
int use_altstatus = 0, rc;
unsigned long timeout;
u8 s = 0, a = 0;
@@ -275,8 +276,8 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
msleep(50);
if (io_ports->ctl_addr) {
- a = hwif->read_altstatus(hwif);
- s = hwif->read_status(hwif);
+ a = tp_ops->read_altstatus(hwif);
+ s = tp_ops->read_status(hwif);
if ((a ^ s) & ~INDEX_STAT)
/* ancient Seagate drives, broken interfaces */
printk(KERN_INFO "%s: probing with STATUS(0x%02x) "
@@ -297,11 +298,11 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
/* disable DMA & overlap */
task.tf_flags = IDE_TFLAG_OUT_FEATURE;
- drive->hwif->tf_load(drive, &task);
+ tp_ops->tf_load(drive, &task);
}
/* ask drive for ID */
- hwif->exec_command(hwif, cmd);
+ tp_ops->exec_command(hwif, cmd);
timeout = ((cmd == WIN_IDENTIFY) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2;
timeout += jiffies;
@@ -312,13 +313,13 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
}
/* give drive a breather */
msleep(50);
- s = use_altstatus ? hwif->read_altstatus(hwif)
- : hwif->read_status(hwif);
+ s = use_altstatus ? tp_ops->read_altstatus(hwif)
+ : tp_ops->read_status(hwif);
} while (s & BUSY_STAT);
/* wait for IRQ and DRQ_STAT */
msleep(50);
- s = hwif->read_status(hwif);
+ s = tp_ops->read_status(hwif);
if (OK_STAT(s, DRQ_STAT, BAD_R_STAT)) {
unsigned long flags;
@@ -330,7 +331,7 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
/* drive responded with ID */
rc = 0;
/* clear drive IRQ */
- (void)hwif->read_status(hwif);
+ (void)tp_ops->read_status(hwif);
local_irq_restore(flags);
} else {
/* drive refused ID */
@@ -352,6 +353,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);
+ const struct ide_tp_ops *tp_ops = hwif->tp_ops;
int retval;
int autoprobe = 0;
unsigned long cookie = 0;
@@ -367,7 +369,7 @@ static int try_to_identify (ide_drive_t *drive, u8 cmd)
autoprobe = 1;
cookie = probe_irq_on();
}
- hwif->set_irq(hwif, autoprobe);
+ tp_ops->set_irq(hwif, autoprobe);
}
retval = actual_try_to_identify(drive, cmd);
@@ -375,9 +377,9 @@ static int try_to_identify (ide_drive_t *drive, u8 cmd)
if (autoprobe) {
int irq;
- hwif->set_irq(hwif, 0);
+ tp_ops->set_irq(hwif, 0);
/* clear drive IRQ */
- (void)hwif->read_status(hwif);
+ (void)tp_ops->read_status(hwif);
udelay(5);
irq = probe_irq_off(cookie);
if (!hwif->irq) {
@@ -402,7 +404,7 @@ static int ide_busy_sleep(ide_hwif_t *hwif)
do {
msleep(50);
- stat = hwif->read_status(hwif);
+ stat = hwif->tp_ops->read_status(hwif);
if ((stat & BUSY_STAT) == 0)
return 0;
} while (time_before(jiffies, timeout));
@@ -417,7 +419,7 @@ static u8 ide_read_device(ide_drive_t *drive)
memset(&task, 0, sizeof(task));
task.tf_flags = IDE_TFLAG_IN_DEVICE;
- drive->hwif->tf_read(drive, &task);
+ drive->hwif->tp_ops->tf_read(drive, &task);
return task.tf.device;
}
@@ -446,6 +448,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);
+ const struct ide_tp_ops *tp_ops = hwif->tp_ops;
int rc;
u8 stat;
@@ -478,7 +481,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
return 3;
}
- stat = hwif->read_status(hwif);
+ stat = tp_ops->read_status(hwif);
if (OK_STAT(stat, READY_STAT, BUSY_STAT) ||
drive->present || cmd == WIN_PIDENTIFY) {
@@ -488,7 +491,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
rc = try_to_identify(drive,cmd);
}
- stat = hwif->read_status(hwif);
+ stat = tp_ops->read_status(hwif);
if (stat == (BUSY_STAT | READY_STAT))
return 4;
@@ -499,13 +502,13 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
msleep(50);
SELECT_DRIVE(drive);
msleep(50);
- hwif->exec_command(hwif, WIN_SRST);
+ tp_ops->exec_command(hwif, WIN_SRST);
(void)ide_busy_sleep(hwif);
rc = try_to_identify(drive, cmd);
}
/* ensure drive IRQ is clear */
- stat = hwif->read_status(hwif);
+ stat = tp_ops->read_status(hwif);
if (rc == 1)
printk(KERN_ERR "%s: no response (status = 0x%02x)\n",
@@ -519,7 +522,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
SELECT_DRIVE(&hwif->drives[0]);
msleep(50);
/* ensure drive irq is clear */
- (void)hwif->read_status(hwif);
+ (void)tp_ops->read_status(hwif);
}
return rc;
}
@@ -530,12 +533,13 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
static void enable_nest (ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
+ const struct ide_tp_ops *tp_ops = hwif->tp_ops;
u8 stat;
printk("%s: enabling %s -- ", hwif->name, drive->id->model);
SELECT_DRIVE(drive);
msleep(50);
- hwif->exec_command(hwif, EXABYTE_ENABLE_NEST);
+ tp_ops->exec_command(hwif, EXABYTE_ENABLE_NEST);
if (ide_busy_sleep(hwif)) {
printk(KERN_CONT "failed (timeout)\n");
@@ -544,7 +548,7 @@ static void enable_nest (ide_drive_t *drive)
msleep(50);
- stat = hwif->read_status(hwif);
+ stat = tp_ops->read_status(hwif);
if (!OK_STAT(stat, 0, BAD_STAT))
printk(KERN_CONT "failed (status = 0x%02x)\n", stat);
@@ -726,7 +730,7 @@ static int ide_port_wait_ready(ide_hwif_t *hwif)
/* Ignore disks that we will not probe for later. */
if (!drive->noprobe || drive->present) {
SELECT_DRIVE(drive);
- hwif->set_irq(hwif, 1);
+ hwif->tp_ops->set_irq(hwif, 1);
mdelay(2);
rc = ide_wait_not_busy(hwif, 35000);
if (rc)
@@ -1083,7 +1087,7 @@ static int init_irq (ide_hwif_t *hwif)
sa = IRQF_SHARED;
if (io_ports->ctl_addr)
- hwif->set_irq(hwif, 1);
+ hwif->tp_ops->set_irq(hwif, 1);
if (request_irq(hwif->irq,&ide_intr,sa,hwif->name,hwgroup))
goto out_unlink;
@@ -1361,6 +1365,9 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
hwif->host_flags |= d->host_flags;
hwif->pio_mask = d->pio_mask;
+ if (d->tp_ops)
+ hwif->tp_ops = d->tp_ops;
+
/* ->set_pio_mode for DTC2278 is currently limited to port 0 */
if (hwif->chipset != ide_dtc2278 || hwif->channel == 0)
hwif->port_ops = d->port_ops;