ide_dma_off(drive);
                return ide_do_reset(drive);
        }
-       /* Get the number of bytes to transfer on this interrupt. */
-       bcount = (hwif->INB(hwif->io_ports.lbah_addr) << 8) |
-                 hwif->INB(hwif->io_ports.lbam_addr);
 
-       ireason = hwif->INB(hwif->io_ports.nsect_addr);
+       /* Get the number of bytes to transfer on this interrupt. */
+       ide_read_bcount_and_ireason(drive, &bcount, &ireason);
 
        if (ireason & CD) {
                printk(KERN_ERR "%s: CoD != 0 in %s\n", drive->name, __func__);
 
        struct request *rq = HWGROUP(drive)->rq;
        xfer_func_t *xferfunc;
        ide_expiry_t *expiry = NULL;
-       int dma_error = 0, dma, stat, ireason, len, thislen, uptodate = 0;
+       int dma_error = 0, dma, stat, thislen, uptodate = 0;
        int write = (rq_data_dir(rq) == WRITE) ? 1 : 0;
        unsigned int timeout;
-       u8 lowcyl, highcyl;
+       u16 len;
+       u8 ireason;
 
        /* check for errors */
        dma = info->dma;
                goto end_request;
        }
 
-       /* ok we fall to pio :/ */
-       ireason = hwif->INB(hwif->io_ports.nsect_addr) & 0x3;
-       lowcyl  = hwif->INB(hwif->io_ports.lbam_addr);
-       highcyl = hwif->INB(hwif->io_ports.lbah_addr);
-
-       len = lowcyl + (256 * highcyl);
+       ide_read_bcount_and_ireason(drive, &len, &ireason);
 
        thislen = blk_fs_request(rq) ? len : rq->data_len;
        if (thislen > len)
 
 }
 EXPORT_SYMBOL_GPL(ide_read_error);
 
+void ide_read_bcount_and_ireason(ide_drive_t *drive, u16 *bcount, u8 *ireason)
+{
+       ide_task_t task;
+
+       memset(&task, 0, sizeof(task));
+       task.tf_flags = IDE_TFLAG_IN_LBAH | IDE_TFLAG_IN_LBAM |
+                       IDE_TFLAG_IN_NSECT;
+
+       drive->hwif->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);
+
 void ide_fix_driveid (struct hd_driveid *id)
 {
 #ifndef __LITTLE_ENDIAN
 
 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 *);
 
 extern int drive_is_ready(ide_drive_t *);