All new accounts created on Gitlab now require administrator approval. If you invite any collaborators, please let Flux staff know so they can approve the accounts.

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: default avatarBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
parent d6276b5f
......@@ -382,7 +382,7 @@ static void icside_dma_timeout(ide_drive_t *drive)
if (icside_dma_test_irq(drive))
return;
ide_dump_status(drive, "DMA timeout", hwif->read_status(hwif));
ide_dump_status(drive, "DMA timeout", hwif->tp_ops->read_status(hwif));
icside_dma_end(drive);
}
......
......@@ -155,6 +155,21 @@ static void h8300_output_data(ide_drive_t *drive, struct request *rq,
mm_outsw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2);
}
static const struct ide_tp_ops h8300_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
.read_sff_dma_status = ide_read_sff_dma_status,
.set_irq = ide_set_irq,
.tf_load = h8300_tf_load,
.tf_read = h8300_tf_read,
.input_data = h8300_input_data,
.output_data = h8300_output_data,
};
#define H8300_IDE_GAP (2)
static inline void hw_setup(hw_regs_t *hw)
......@@ -169,16 +184,8 @@ static inline void hw_setup(hw_regs_t *hw)
hw->chipset = ide_generic;
}
static inline void hwif_setup(ide_hwif_t *hwif)
{
hwif->tf_load = h8300_tf_load;
hwif->tf_read = h8300_tf_read;
hwif->input_data = h8300_input_data;
hwif->output_data = h8300_output_data;
}
static const struct ide_port_info h8300_port_info = {
.tp_ops = &h8300_tp_ops,
.host_flags = IDE_HFLAG_NO_IO_32BIT | IDE_HFLAG_NO_DMA,
};
......@@ -205,7 +212,6 @@ static int __init h8300_ide_init(void)
return -ENOENT;
index = hwif->index;
hwif_setup(hwif);
idx[0] = index;
......
......@@ -22,6 +22,7 @@ ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc,
void (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned, int))
{
ide_hwif_t *hwif = drive->hwif;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
xfer_func_t *xferfunc;
unsigned int temp;
u16 bcount;
......@@ -35,7 +36,7 @@ ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc,
}
/* Clear the interrupt */
stat = hwif->read_status(hwif);
stat = tp_ops->read_status(hwif);
if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
if (hwif->dma_ops->dma_end(drive) ||
......@@ -140,7 +141,7 @@ cmd_finished:
if (pc->sg)
io_buffers(drive, pc, temp, 0);
else
hwif->input_data(drive, NULL,
tp_ops->input_data(drive, NULL,
pc->cur_pos, temp);
printk(KERN_ERR "%s: transferred %d of "
"%d bytes\n",
......@@ -157,9 +158,9 @@ cmd_finished:
debug_log("The device wants to send us more data than "
"expected - allowing transfer\n");
}
xferfunc = hwif->input_data;
xferfunc = tp_ops->input_data;
} else
xferfunc = hwif->output_data;
xferfunc = tp_ops->output_data;
if ((drive->media == ide_floppy && !scsi && !pc->buf) ||
(drive->media == ide_tape && !scsi && pc->bh) ||
......@@ -188,7 +189,7 @@ static u8 ide_read_ireason(ide_drive_t *drive)
memset(&task, 0, sizeof(task));
task.tf_flags = IDE_TFLAG_IN_NSECT;
drive->hwif->tf_read(drive, &task);
drive->hwif->tp_ops->tf_read(drive, &task);
return task.tf.nsect & 3;
}
......@@ -249,7 +250,7 @@ ide_startstop_t ide_transfer_pc(ide_drive_t *drive, struct ide_atapi_pc *pc,
/* Send the actual packet */
if ((pc->flags & PC_FLAG_ZIP_DRIVE) == 0)
hwif->output_data(drive, NULL, pc->c, 12);
hwif->tp_ops->output_data(drive, NULL, pc->c, 12);
return ide_started;
}
......
......@@ -285,7 +285,7 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
int stat, err, sense_key;
/* check for errors */
stat = hwif->read_status(hwif);
stat = hwif->tp_ops->read_status(hwif);
if (stat_ret)
*stat_ret = stat;
......@@ -590,7 +590,7 @@ static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive,
cmd_len = ATAPI_MIN_CDB_BYTES;
/* send the command to the device */
hwif->output_data(drive, NULL, rq->cmd, cmd_len);
hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len);
/* start the DMA if need be */
if (info->dma)
......@@ -627,7 +627,7 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq,
* Some drives (ASUS) seem to tell us that status info is
* available. Just get it and ignore.
*/
(void)hwif->read_status(hwif);
(void)hwif->tp_ops->read_status(hwif);
return 0;
} else {
/* drive wants a command packet, or invalid ireason... */
......@@ -990,10 +990,10 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
if (ireason == 0) {
write = 1;
xferfunc = hwif->output_data;
xferfunc = hwif->tp_ops->output_data;
} else {
write = 0;
xferfunc = hwif->input_data;
xferfunc = hwif->tp_ops->input_data;
}
/* transfer data */
......@@ -1200,7 +1200,7 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
if (info->cd_flags & IDE_CD_FLAG_SEEKING) {
ide_hwif_t *hwif = drive->hwif;
unsigned long elapsed = jiffies - info->start_seek;
int stat = hwif->read_status(hwif);
int stat = hwif->tp_ops->read_status(hwif);
if ((stat & SEEK_STAT) != SEEK_STAT) {
if (elapsed < IDECD_SEEK_TIMEOUT) {
......
......@@ -104,7 +104,7 @@ ide_startstop_t ide_dma_intr (ide_drive_t *drive)
u8 stat = 0, dma_stat = 0;
dma_stat = hwif->dma_ops->dma_end(drive);
stat = hwif->read_status(hwif);
stat = hwif->tp_ops->read_status(hwif);
if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
if (!dma_stat) {
......@@ -335,7 +335,7 @@ static int config_drive_for_dma (ide_drive_t *drive)
static int dma_timer_expiry (ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
u8 dma_stat = hwif->read_sff_dma_status(hwif);
u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif);
printk(KERN_WARNING "%s: dma_timer_expiry: dma status == 0x%02x\n",
drive->name, dma_stat);
......@@ -370,7 +370,7 @@ void ide_dma_host_set(ide_drive_t *drive, int on)
{
ide_hwif_t *hwif = HWIF(drive);
u8 unit = (drive->select.b.unit & 0x01);
u8 dma_stat = hwif->read_sff_dma_status(hwif);
u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif);
if (on)
dma_stat |= (1 << (5 + unit));
......@@ -482,7 +482,7 @@ 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->read_sff_dma_status(hwif);
dma_stat = hwif->tp_ops->read_sff_dma_status(hwif);
/* clear INTR & ERROR flags */
if (mmio)
......@@ -551,7 +551,7 @@ int __ide_dma_end (ide_drive_t *drive)
}
/* get DMA status */
dma_stat = hwif->read_sff_dma_status(hwif);
dma_stat = hwif->tp_ops->read_sff_dma_status(hwif);
if (mmio)
/* clear the INTR & ERROR bits */
......@@ -574,7 +574,7 @@ EXPORT_SYMBOL(__ide_dma_end);
int ide_dma_test_irq(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
u8 dma_stat = hwif->read_sff_dma_status(hwif);
u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif);
/* return 1 if INTR asserted */
if ((dma_stat & 4) == 4)
......
......@@ -247,9 +247,9 @@ static void ide_floppy_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
data = bvec_kmap_irq(bvec, &flags);
if (direction)
hwif->output_data(drive, NULL, data, count);
hwif->tp_ops->output_data(drive, NULL, data, count);
else
hwif->input_data(drive, NULL, data, count);
hwif->tp_ops->input_data(drive, NULL, data, count);
bvec_kunmap_irq(data, &flags);
bcount -= count;
......@@ -402,7 +402,7 @@ static int idefloppy_transfer_pc(ide_drive_t *drive)
idefloppy_floppy_t *floppy = drive->driver_data;
/* Send the actual packet */
drive->hwif->output_data(drive, NULL, floppy->pc->c, 12);
drive->hwif->tp_ops->output_data(drive, NULL, floppy->pc->c, 12);
/* Timeout for the packet command */
return IDEFLOPPY_WAIT_CMD;
......@@ -954,7 +954,7 @@ static int idefloppy_get_format_progress(ide_drive_t *drive, int __user *arg)
u8 stat;
local_irq_save(flags);
stat = hwif->read_status(hwif);
stat = hwif->tp_ops->read_status(hwif);
local_irq_restore(flags);
progress_indication = ((stat & SEEK_STAT) == 0) ? 0 : 0x10000;
......
......@@ -330,7 +330,7 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
tf->error = err;
tf->status = stat;
drive->hwif->tf_read(drive, task);
drive->hwif->tp_ops->tf_read(drive, task);
if (task->tf_flags & IDE_TFLAG_DYN)
kfree(task);
......@@ -381,7 +381,7 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8
if (err == ABRT_ERR) {
if (drive->select.b.lba &&
/* some newer drives don't support WIN_SPECIFY */
hwif->read_status(hwif) == WIN_SPECIFY)
hwif->tp_ops->read_status(hwif) == WIN_SPECIFY)
return ide_stopped;
} else if ((err & BAD_CRC) == BAD_CRC) {
/* UDMA crc error, just retry the operation */
......@@ -407,7 +407,7 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8
return ide_stopped;
}
if (hwif->read_status(hwif) & (BUSY_STAT | DRQ_STAT))
if (hwif->tp_ops->read_status(hwif) & (BUSY_STAT | DRQ_STAT))
rq->errors |= ERROR_RESET;
if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
......@@ -434,9 +434,9 @@ static ide_startstop_t ide_atapi_error(ide_drive_t *drive, struct request *rq, u
/* add decoding error stuff */
}
if (hwif->read_status(hwif) & (BUSY_STAT | DRQ_STAT))
if (hwif->tp_ops->read_status(hwif) & (BUSY_STAT | DRQ_STAT))
/* force an abort */
hwif->exec_command(hwif, WIN_IDLEIMMEDIATE);
hwif->tp_ops->exec_command(hwif, WIN_IDLEIMMEDIATE);
if (rq->errors >= ERROR_MAX) {
ide_kill_rq(drive, rq);
......@@ -710,7 +710,7 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
#ifdef DEBUG
printk("%s: DRIVE_CMD (null)\n", drive->name);
#endif
ide_end_drive_cmd(drive, hwif->read_status(hwif),
ide_end_drive_cmd(drive, hwif->tp_ops->read_status(hwif),
ide_read_error(drive));
return ide_stopped;
......@@ -755,7 +755,7 @@ static void ide_check_pm_state(ide_drive_t *drive, struct request *rq)
if (rc)
printk(KERN_WARNING "%s: bus not ready on wakeup\n", drive->name);
SELECT_DRIVE(drive);
hwif->set_irq(hwif, 1);
hwif->tp_ops->set_irq(hwif, 1);
rc = ide_wait_not_busy(hwif, 100000);
if (rc)
printk(KERN_WARNING "%s: drive not ready on wakeup\n", drive->name);
......@@ -1042,7 +1042,7 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)
* quirk_list may not like intr setups/cleanups
*/
if (drive->quirk_list != 1)
hwif->set_irq(hwif, 0);
hwif->tp_ops->set_irq(hwif, 0);
}
hwgroup->hwif = hwif;
hwgroup->drive = drive;
......@@ -1142,7 +1142,7 @@ static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
printk(KERN_WARNING "%s: DMA timeout error\n", drive->name);
(void)hwif->dma_ops->dma_end(drive);
ret = ide_error(drive, "dma timeout error",
hwif->read_status(hwif));
hwif->tp_ops->read_status(hwif));
} else {
printk(KERN_WARNING "%s: DMA timeout retry\n", drive->name);
hwif->dma_ops->dma_timeout(drive);
......@@ -1267,7 +1267,7 @@ void ide_timer_expiry (unsigned long data)
} else
startstop =
ide_error(drive, "irq timeout",
hwif->read_status(hwif));
hwif->tp_ops->read_status(hwif));
}
drive->service_time = jiffies - drive->service_start;
spin_lock_irq(&ide_lock);
......@@ -1323,7 +1323,7 @@ static void unexpected_intr (int irq, ide_hwgroup_t *hwgroup)
*/
do {
if (hwif->irq == irq) {
stat = hwif->read_status(hwif);
stat = hwif->tp_ops->read_status(hwif);
if (!OK_STAT(stat, READY_STAT, BAD_STAT)) {
/* Try to not flood the console with msgs */
......@@ -1414,7 +1414,7 @@ irqreturn_t ide_intr (int irq, void *dev_id)
* Whack the status register, just in case
* we have a leftover pending IRQ.
*/
(void)hwif->read_status(hwif);
(void)hwif->tp_ops->read_status(hwif);
#endif /* CONFIG_BLK_DEV_IDEPCI */
}
spin_unlock_irqrestore(&ide_lock, flags);
......@@ -1531,9 +1531,9 @@ void ide_pktcmd_tf_load(ide_drive_t *drive, u32 tf_flags, u16 bcount, u8 dma)
task.tf.lbah = (bcount >> 8) & 0xff;
ide_tf_dump(drive->name, &task.tf);
hwif->set_irq(hwif, 1);
hwif->tp_ops->set_irq(hwif, 1);
SELECT_MASK(drive, 0);
hwif->tf_load(drive, &task);
hwif->tp_ops->tf_load(drive, &task);
}
EXPORT_SYMBOL_GPL(ide_pktcmd_tf_load);
......@@ -1545,9 +1545,9 @@ void ide_pad_transfer(ide_drive_t *drive, int write, int len)
while (len > 0) {
if (write)
hwif->output_data(drive, NULL, buf, min(4, len));
hwif->tp_ops->output_data(drive, NULL, buf, min(4, len));
else
hwif->input_data(drive, NULL, buf, min(4, len));
hwif->tp_ops->input_data(drive, NULL, buf, min(4, len));
len -= 4;
}
}
......
......@@ -68,7 +68,7 @@ void SELECT_DRIVE (ide_drive_t *drive)
memset(&task, 0, sizeof(task));
task.tf_flags = IDE_TFLAG_OUT_DEVICE;
drive->hwif->tf_load(drive, &task);
drive->hwif->tp_ops->tf_load(drive, &task);
}
void SELECT_MASK(ide_drive_t *drive, int mask)
......@@ -79,39 +79,43 @@ void SELECT_MASK(ide_drive_t *drive, int mask)
port_ops->maskproc(drive, mask);
}
static void ide_exec_command(ide_hwif_t *hwif, u8 cmd)
void ide_exec_command(ide_hwif_t *hwif, u8 cmd)
{
if (hwif->host_flags & IDE_HFLAG_MMIO)
writeb(cmd, (void __iomem *)hwif->io_ports.command_addr);
else
outb(cmd, hwif->io_ports.command_addr);
}
EXPORT_SYMBOL_GPL(ide_exec_command);
static u8 ide_read_status(ide_hwif_t *hwif)
u8 ide_read_status(ide_hwif_t *hwif)
{
if (hwif->host_flags & IDE_HFLAG_MMIO)
return readb((void __iomem *)hwif->io_ports.status_addr);
else
return inb(hwif->io_ports.status_addr);
}
EXPORT_SYMBOL_GPL(ide_read_status);
static u8 ide_read_altstatus(ide_hwif_t *hwif)
u8 ide_read_altstatus(ide_hwif_t *hwif)
{
if (hwif->host_flags & IDE_HFLAG_MMIO)
return readb((void __iomem *)hwif->io_ports.ctl_addr);
else
return inb(hwif->io_ports.ctl_addr);
}
EXPORT_SYMBOL_GPL(ide_read_altstatus);
static u8 ide_read_sff_dma_status(ide_hwif_t *hwif)
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);
static void ide_set_irq(ide_hwif_t *hwif, int on)
void ide_set_irq(ide_hwif_t *hwif, int on)
{
u8 ctl = ATA_DEVCTL_OBS;
......@@ -127,8 +131,9 @@ static void ide_set_irq(ide_hwif_t *hwif, int on)
else
outb(ctl, hwif->io_ports.ctl_addr);
}
EXPORT_SYMBOL_GPL(ide_set_irq);
static void ide_tf_load(ide_drive_t *drive, ide_task_t *task)
void ide_tf_load(ide_drive_t *drive, ide_task_t *task)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
......@@ -180,8 +185,9 @@ static void ide_tf_load(ide_drive_t *drive, ide_task_t *task)
tf_outb((tf->device & HIHI) | drive->select.all,
io_ports->device_addr);
}
EXPORT_SYMBOL_GPL(ide_tf_load);
static void ide_tf_read(ide_drive_t *drive, ide_task_t *task)
void ide_tf_read(ide_drive_t *drive, ide_task_t *task)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
......@@ -241,6 +247,7 @@ static void ide_tf_read(ide_drive_t *drive, ide_task_t *task)
tf->hob_lbah = tf_inb(io_ports->lbah_addr);
}
}
EXPORT_SYMBOL_GPL(ide_tf_read);
/*
* Some localbus EIDE interfaces require a special access sequence
......@@ -263,8 +270,8 @@ static void ata_vlb_sync(unsigned long port)
* so if an odd len is specified, be sure that there's at least one
* extra byte allocated for the buffer.
*/
static void ata_input_data(ide_drive_t *drive, struct request *rq,
void *buf, unsigned int len)
void ide_input_data(ide_drive_t *drive, struct request *rq, void *buf,
unsigned int len)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
......@@ -304,12 +311,13 @@ static void ata_input_data(ide_drive_t *drive, struct request *rq,
insw(data_addr, buf, len / 2);
}
}
EXPORT_SYMBOL_GPL(ide_input_data);
/*
* This is used for most PIO data transfers *to* the IDE interface
*/
static void ata_output_data(ide_drive_t *drive, struct request *rq,
void *buf, unsigned int len)
void ide_output_data(ide_drive_t *drive, struct request *rq, void *buf,
unsigned int len)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
......@@ -347,22 +355,7 @@ static void ata_output_data(ide_drive_t *drive, struct request *rq,
outsw(data_addr, buf, len / 2);
}
}
void default_hwif_transport(ide_hwif_t *hwif)
{
hwif->exec_command = ide_exec_command;
hwif->read_status = ide_read_status;
hwif->read_altstatus = ide_read_altstatus;
hwif->read_sff_dma_status = ide_read_sff_dma_status;
hwif->set_irq = ide_set_irq;
hwif->tf_load = ide_tf_load;
hwif->tf_read = ide_tf_read;
hwif->input_data = ata_input_data;
hwif->output_data = ata_output_data;
}
EXPORT_SYMBOL_GPL(ide_output_data);
u8 ide_read_error(ide_drive_t *drive)
{
......@@ -371,7 +364,7 @@ u8 ide_read_error(ide_drive_t *drive)
memset(&task, 0, sizeof(task));
task.tf_flags = IDE_TFLAG_IN_FEATURE;
drive->hwif->tf_read(drive, &task);
drive->hwif->tp_ops->tf_read(drive, &task);
return task.tf.error;
}
......@@ -385,13 +378,28 @@ void ide_read_bcount_and_ireason(ide_drive_t *drive, u16 *bcount, u8 *ireason)
task.tf_flags = IDE_TFLAG_IN_LBAH | IDE_TFLAG_IN_LBAM |
IDE_TFLAG_IN_NSECT;
drive->hwif->tf_read(drive, &task);
drive->hwif->tp_ops->tf_read(drive, &task);
*bcount = (task.tf.lbah << 8) | task.tf.lbam;
*ireason = task.tf.nsect & 3;
}
EXPORT_SYMBOL_GPL(ide_read_bcount_and_ireason);
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,
.tf_load = ide_tf_load,
.tf_read = ide_tf_read,
.input_data = ide_input_data,
.output_data = ide_output_data,
};
void ide_fix_driveid (struct hd_driveid *id)
{
#ifndef __LITTLE_ENDIAN
......@@ -545,10 +553,10 @@ int drive_is_ready (ide_drive_t *drive)
* about possible isa-pnp and pci-pnp issues yet.
*/
if (hwif->io_ports.ctl_addr)
stat = hwif->read_altstatus(hwif);
stat = hwif->tp_ops->read_altstatus(hwif);
else
/* Note: this may clear a pending IRQ!! */
stat = hwif->read_status(hwif);
stat = hwif->tp_ops->read_status(hwif);
if (stat & BUSY_STAT)
/* drive busy: definitely not interrupting */
......@@ -574,24 +582,25 @@ EXPORT_SYMBOL(drive_is_ready);
static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout, u8 *rstat)
{
ide_hwif_t *hwif = drive->hwif;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
unsigned long flags;
int i;
u8 stat;
udelay(1); /* spec allows drive 400ns to assert "BUSY" */
stat = hwif->read_status(hwif);
stat = tp_ops->read_status(hwif);
if (stat & BUSY_STAT) {
local_irq_set(flags);
timeout += jiffies;
while ((stat = hwif->read_status(hwif)) & BUSY_STAT) {
while ((stat = tp_ops->read_status(hwif)) & BUSY_STAT) {
if (time_after(jiffies, timeout)) {
/*
* One last read after the timeout in case
* heavy interrupt load made us not make any
* progress during the timeout..
*/
stat = hwif->read_status(hwif);
stat = tp_ops->read_status(hwif);
if (!(stat & BUSY_STAT))
break;
......@@ -611,7 +620,7 @@ static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long ti
*/
for (i = 0; i < 10; i++) {
udelay(1);
stat = hwif->read_status(hwif);
stat = tp_ops->read_status(hwif);
if (OK_STAT(stat, good, bad)) {
*rstat = stat;
......@@ -737,6 +746,7 @@ no_80w:
int ide_driveid_update(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
struct hd_driveid *id;
unsigned long timeout, flags;
u8 stat;
......@@ -747,9 +757,9 @@ int ide_driveid_update(ide_drive_t *drive)
*/
SELECT_MASK(drive, 1);
hwif->set_irq(hwif, 0);
tp_ops->set_irq(hwif, 0);
msleep(50);
hwif->exec_command(hwif, WIN_IDENTIFY);
tp_ops->exec_command(hwif, WIN_IDENTIFY);
timeout = jiffies + WAIT_WORSTCASE;
do {
if (time_after(jiffies, timeout)) {
......@@ -758,11 +768,11 @@ int ide_driveid_update(ide_drive_t *drive)
}
msleep(50); /* give drive a breather */
stat = hwif->read_altstatus(hwif);
stat = tp_ops->read_altstatus(hwif);
} while (stat & BUSY_STAT);
msleep(50); /* wait for IRQ and DRQ_STAT */
stat = hwif->read_status(hwif);
stat = tp_ops->read_status(hwif);
if (!OK_STAT(stat, DRQ_STAT, BAD_R_STAT)) {
SELECT_MASK(drive, 0);
......@@ -776,8 +786,8 @@ int ide_driveid_update(ide_drive_t *drive)
local_irq_restore(flags);
return 0;
}
hwif->input_data(drive, NULL, id, SECTOR_SIZE);
(void)hwif->read_status(hwif); /* clear drive IRQ */
tp_ops->input_data(drive, NULL, id, SECTOR_SIZE);
(void)tp_ops->read_status(hwif); /* clear drive IRQ */
local_irq_enable();
local_irq_restore(flags);
ide_fix_driveid(id);
......@@ -798,6 +808,7 @@ int ide_driveid_update(ide_drive_t *drive)
int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
{
ide_hwif_t *hwif = drive->hwif;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
int error = 0;
u8 stat;
ide_task_t task;
......@@ -833,19 +844,19 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
SELECT_DRIVE(drive);
SELECT_MASK(drive, 0);
udelay(1);
hwif->set_irq(hwif, 0);
tp_ops->set_irq(hwif, 0);