base += BAST_IDE_CS;
        aux  += BAST_IDE_CS;
 
-       for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
-               hw.io_ports[i] = (unsigned long)base;
+       for (i = 0; i <= 7; i++) {
+               hw.io_ports_array[i] = (unsigned long)base;
                base += 0x20;
        }
 
-       hw.io_ports[IDE_CONTROL_OFFSET] = aux + (6 * 0x20);
+       hw.io_ports.ctl_addr = aux + (6 * 0x20);
        hw.irq = irq;
 
        hwif = ide_find_port();
 
                 */
                default_hwif_mmiops(hwif);
 
-               for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
-                       hwif->io_ports[i] = port;
+               for (i = 0; i <= 7; i++) {
+                       hwif->io_ports_array[i] = port;
                        port += 1 << info->stepping;
                }
-               hwif->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)base + info->ctrloffset;
+               hwif->io_ports.ctl_addr =
+                       (unsigned long)base + info->ctrloffset;
                hwif->irq     = ec->irq;
                hwif->chipset = ide_acorn;
                hwif->gendev.parent = &ec->dev;
 
                                          const struct ide_port_info *d)
 {
        unsigned long base =
-               hwif->io_ports[IDE_DATA_OFFSET] - IDE_PALM_ATA_PRI_REG_OFFSET;
+               hwif->io_ports.data_addr - IDE_PALM_ATA_PRI_REG_OFFSET;
 
        printk(KERN_INFO "    %s: MMIO-DMA\n", hwif->name);
 
 
        pribase = mem->start + IDE_PALM_ATA_PRI_REG_OFFSET;
        for (i = 0; i < IDE_NR_PORTS - 2; i++)
-               hw.io_ports[i] = pribase + i;
-       hw.io_ports[IDE_CONTROL_OFFSET] = mem->start +
+               hw.io_ports_array[i] = pribase + i;
+       hw.io_ports.ctl_addr = mem->start +
                        IDE_PALM_ATA_PRI_CTL_OFFSET;
        hw.irq = irq->start;
        hw.chipset = ide_palm3710;
 
        unsigned long port = (unsigned long)base;
        int i;
 
-       for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
-               hw->io_ports[i] = port;
+       for (i = 0; i <= 7; i++) {
+               hw->io_ports_array[i] = port;
                port += sz;
        }
-       hw->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
+       hw->io_ports.ctl_addr = (unsigned long)ctrl;
        hw->irq = irq;
 }
 
 
 int
 cris_ide_ack_intr(ide_hwif_t* hwif)
 {
-       reg_ata_rw_ctrl2 ctrl2 = REG_TYPE_CONV(reg_ata_rw_ctrl2,
-                                int, hwif->io_ports[0]);
+       reg_ata_rw_ctrl2 ctrl2 = REG_TYPE_CONV(reg_ata_rw_ctrl2, int,
+                                              hwif->io_ports.data_addr);
        REG_WR_INT(ata, regi_ata, rw_ack_intr, 1 << ctrl2.sel);
        return 1;
 }
        ide_hwif_t *hwif = drive->hwif;
 
        reg_ata_rw_ctrl2 ctrl2 = REG_TYPE_CONV(reg_ata_rw_ctrl2, int,
-                                              hwif->io_ports[IDE_DATA_OFFSET]);
+                                              hwif->io_ports.data_addr);
        reg_ata_rw_trf_cnt trf_cnt = {0};
 
        mycontext.saved_data = (dma_descr_data*)virt_to_phys(d);
        int intr = REG_RD_INT(ata, regi_ata, r_intr);
 
        reg_ata_rw_ctrl2 ctrl2 = REG_TYPE_CONV(reg_ata_rw_ctrl2, int,
-                                              hwif->io_ports[IDE_DATA_OFFSET]);
+                                              hwif->io_ports.data_addr);
 
        return intr & (1 << ctrl2.sel) ? 1 : 0;
 }
        *R_ATA_CTRL_DATA =
                cmd |
                IO_FIELD(R_ATA_CTRL_DATA, data,
-                        drive->hwif->io_ports[IDE_DATA_OFFSET]) |
+                        drive->hwif->io_ports.data_addr) |
                IO_STATE(R_ATA_CTRL_DATA, src_dst,  dma)  |
                IO_STATE(R_ATA_CTRL_DATA, multi,    on)   |
                IO_STATE(R_ATA_CTRL_DATA, dma_size, word);
 {
        int intr = *R_IRQ_MASK0_RD;
        int bus = IO_EXTRACT(R_ATA_CTRL_DATA, sel,
-                            drive->hwif->io_ports[IDE_DATA_OFFSET]);
+                            drive->hwif->io_ports.data_addr);
 
        return intr & (1 << (bus + IO_BITNR(R_IRQ_MASK0_RD, ata_irq0))) ? 1 : 0;
 }
                 * call will also timeout on busy, but as long as the
                 * write is still performed, everything will be fine.
                 */
-               if (cris_ide_get_reg(reg) == IDE_STATUS_OFFSET)
+               if (cris_ide_get_reg(reg) == 7)
                        return BUSY_STAT;
                else
                        /* For other rare cases we assume 0 is good enough.  */
        memset(hw, 0, sizeof(*hw));
 
        for (i = 0; i <= 7; i++)
-               hw->io_ports[i] = base + cris_ide_reg_addr(i, 0, 1);
+               hw->io_ports_array[i] = base + cris_ide_reg_addr(i, 0, 1);
 
        /*
         * the IDE control register is at ATA address 6,
         * with CS1 active instead of CS0
         */
-       hw->io_ports[IDE_CONTROL_OFFSET] = base + cris_ide_reg_addr(6, 1, 0);
+       hw->io_ports.ctl_addr = base + cris_ide_reg_addr(6, 1, 0);
 
        hw->irq = ide_default_irq(0);
        hw->ack_intr = cris_ide_ack_intr;
 
        int i;
 
        memset(hw, 0, sizeof(hw_regs_t));
-       for (i = 0; i <= IDE_STATUS_OFFSET; i++)
-               hw->io_ports[i] = CONFIG_H8300_IDE_BASE + H8300_IDE_GAP*i;
-       hw->io_ports[IDE_CONTROL_OFFSET] = CONFIG_H8300_IDE_ALT;
+       for (i = 0; i <= 7; i++)
+               hw->io_ports_array[i] = CONFIG_H8300_IDE_BASE + H8300_IDE_GAP*i;
+       hw->io_ports.ctl_addr = CONFIG_H8300_IDE_ALT;
        hw->irq = EXT_IRQ0 + CONFIG_H8300_IDE_IRQ;
        hw->chipset = ide_generic;
 }
 
                /* packet command */
                spin_lock_irqsave(&ide_lock, flags);
                hwif->OUTBSYNC(drive, WIN_PACKETCMD,
-                              hwif->io_ports[IDE_COMMAND_OFFSET]);
+                              hwif->io_ports.command_addr);
                ndelay(400);
                spin_unlock_irqrestore(&ide_lock, flags);
 
        }
 
        /* ok we fall to pio :/ */
-       ireason = hwif->INB(hwif->io_ports[IDE_IREASON_OFFSET]) & 0x3;
-       lowcyl  = hwif->INB(hwif->io_ports[IDE_BCOUNTL_OFFSET]);
-       highcyl = hwif->INB(hwif->io_ports[IDE_BCOUNTH_OFFSET]);
+       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);
 
 
        }
 
        /* Get the number of bytes to transfer */
-       bcount = (hwif->INB(hwif->io_ports[IDE_BCOUNTH_OFFSET]) << 8) |
-                 hwif->INB(hwif->io_ports[IDE_BCOUNTL_OFFSET]);
+       bcount = (hwif->INB(hwif->io_ports.lbah_addr) << 8) |
+                 hwif->INB(hwif->io_ports.lbam_addr);
        /* on this interrupt */
-       ireason = hwif->INB(hwif->io_ports[IDE_IREASON_OFFSET]);
+       ireason = hwif->INB(hwif->io_ports.nsect_addr);
 
        if (ireason & CD) {
                printk(KERN_ERR "ide-floppy: CoD != 0 in %s\n", __func__);
                                "initiated yet DRQ isn't asserted\n");
                return startstop;
        }
-       ireason = hwif->INB(hwif->io_ports[IDE_IREASON_OFFSET]);
+       ireason = hwif->INB(hwif->io_ports.nsect_addr);
        if ((ireason & CD) == 0 || (ireason & IO)) {
                printk(KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while "
                                "issuing a packet command\n");
                                "initiated yet DRQ isn't asserted\n");
                return startstop;
        }
-       ireason = hwif->INB(hwif->io_ports[IDE_IREASON_OFFSET]);
+       ireason = hwif->INB(hwif->io_ports.nsect_addr);
        if ((ireason & CD) == 0 || (ireason & IO)) {
                printk(KERN_ERR "ide-floppy: (IO,CoD) != (0,1) "
                                "while issuing a packet command\n");
                return ide_started;
        } else {
                /* Issue the packet command */
-               hwif->OUTB(WIN_PACKETCMD, hwif->io_ports[IDE_COMMAND_OFFSET]);
+               hwif->OUTB(WIN_PACKETCMD, hwif->io_ports.command_addr);
                return (*pkt_xfer_routine) (drive);
        }
 }
 
 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;
        struct ide_taskfile *tf = &task->tf;
 
        if (task->tf_flags & IDE_TFLAG_IN_DATA) {
-               u16 data = hwif->INW(hwif->io_ports[IDE_DATA_OFFSET]);
+               u16 data = hwif->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 */
-       hwif->OUTB(drive->ctl & ~0x80, hwif->io_ports[IDE_CONTROL_OFFSET]);
+       hwif->OUTB(drive->ctl & ~0x80, io_ports->ctl_addr);
 
        if (task->tf_flags & IDE_TFLAG_IN_NSECT)
-               tf->nsect  = hwif->INB(hwif->io_ports[IDE_NSECTOR_OFFSET]);
+               tf->nsect  = hwif->INB(io_ports->nsect_addr);
        if (task->tf_flags & IDE_TFLAG_IN_LBAL)
-               tf->lbal   = hwif->INB(hwif->io_ports[IDE_SECTOR_OFFSET]);
+               tf->lbal   = hwif->INB(io_ports->lbal_addr);
        if (task->tf_flags & IDE_TFLAG_IN_LBAM)
-               tf->lbam   = hwif->INB(hwif->io_ports[IDE_LCYL_OFFSET]);
+               tf->lbam   = hwif->INB(io_ports->lbam_addr);
        if (task->tf_flags & IDE_TFLAG_IN_LBAH)
-               tf->lbah   = hwif->INB(hwif->io_ports[IDE_HCYL_OFFSET]);
+               tf->lbah   = hwif->INB(io_ports->lbah_addr);
        if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
-               tf->device = hwif->INB(hwif->io_ports[IDE_SELECT_OFFSET]);
+               tf->device = hwif->INB(io_ports->device_addr);
 
        if (task->tf_flags & IDE_TFLAG_LBA48) {
-               hwif->OUTB(drive->ctl | 0x80,
-                          hwif->io_ports[IDE_CONTROL_OFFSET]);
+               hwif->OUTB(drive->ctl | 0x80, io_ports->ctl_addr);
 
                if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
-                       tf->hob_feature =
-                               hwif->INB(hwif->io_ports[IDE_FEATURE_OFFSET]);
+                       tf->hob_feature = hwif->INB(io_ports->feature_addr);
                if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
-                       tf->hob_nsect   =
-                               hwif->INB(hwif->io_ports[IDE_NSECTOR_OFFSET]);
+                       tf->hob_nsect   = hwif->INB(io_ports->nsect_addr);
                if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
-                       tf->hob_lbal    =
-                               hwif->INB(hwif->io_ports[IDE_SECTOR_OFFSET]);
+                       tf->hob_lbal    = hwif->INB(io_ports->lbal_addr);
                if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
-                       tf->hob_lbam    =
-                               hwif->INB(hwif->io_ports[IDE_LCYL_OFFSET]);
+                       tf->hob_lbam    = hwif->INB(io_ports->lbam_addr);
                if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
-                       tf->hob_lbah    =
-                               hwif->INB(hwif->io_ports[IDE_HCYL_OFFSET]);
+                       tf->hob_lbah    = hwif->INB(io_ports->lbah_addr);
        }
 }
 
                if (err == ABRT_ERR) {
                        if (drive->select.b.lba &&
                            /* some newer drives don't support WIN_SPECIFY */
-                           hwif->INB(hwif->io_ports[IDE_COMMAND_OFFSET]) ==
+                           hwif->INB(hwif->io_ports.command_addr) ==
                                WIN_SPECIFY)
                                return ide_stopped;
                } else if ((err & BAD_CRC) == BAD_CRC) {
 
        if (ide_read_status(drive) & (BUSY_STAT | DRQ_STAT))
                /* force an abort */
-               hwif->OUTB(WIN_IDLEIMMEDIATE,
-                          hwif->io_ports[IDE_COMMAND_OFFSET]);
+               hwif->OUTB(WIN_IDLEIMMEDIATE, hwif->io_ports.command_addr);
 
        if (rq->errors >= ERROR_MAX) {
                ide_kill_rq(drive, rq);
         */
        do {
                if (hwif->irq == irq) {
-                       stat = hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]);
+                       stat = hwif->INB(hwif->io_ports.status_addr);
                        if (!OK_STAT(stat, READY_STAT, BAD_STAT)) {
                                /* Try to not flood the console with msgs */
                                static unsigned long last_msgtime, count;
                         * Whack the status register, just in case
                         * we have a leftover pending IRQ.
                         */
-                       (void) hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]);
+                       (void) hwif->INB(hwif->io_ports.status_addr);
 #endif /* CONFIG_BLK_DEV_IDEPCI */
                }
                spin_unlock_irqrestore(&ide_lock, flags);
 
        if (port_ops && port_ops->selectproc)
                port_ops->selectproc(drive);
 
-       hwif->OUTB(drive->select.all, hwif->io_ports[IDE_SELECT_OFFSET]);
+       hwif->OUTB(drive->select.all, hwif->io_ports.device_addr);
 }
 
 void SELECT_MASK (ide_drive_t *drive, int mask)
  */
 static void ata_input_data(ide_drive_t *drive, void *buffer, u32 wcount)
 {
-       ide_hwif_t *hwif        = HWIF(drive);
-       u8 io_32bit             = drive->io_32bit;
+       ide_hwif_t *hwif = drive->hwif;
+       struct ide_io_ports *io_ports = &hwif->io_ports;
+       u8 io_32bit = drive->io_32bit;
 
        if (io_32bit) {
                if (io_32bit & 2) {
                        unsigned long flags;
 
                        local_irq_save(flags);
-                       ata_vlb_sync(drive, hwif->io_ports[IDE_NSECTOR_OFFSET]);
-                       hwif->INSL(hwif->io_ports[IDE_DATA_OFFSET], buffer,
-                                  wcount);
+                       ata_vlb_sync(drive, io_ports->nsect_addr);
+                       hwif->INSL(io_ports->data_addr, buffer, wcount);
                        local_irq_restore(flags);
                } else
-                       hwif->INSL(hwif->io_ports[IDE_DATA_OFFSET], buffer,
-                                  wcount);
+                       hwif->INSL(io_ports->data_addr, buffer, wcount);
        } else
-               hwif->INSW(hwif->io_ports[IDE_DATA_OFFSET], buffer,
-                          wcount << 1);
+               hwif->INSW(io_ports->data_addr, buffer, wcount << 1);
 }
 
 /*
  */
 static void ata_output_data(ide_drive_t *drive, void *buffer, u32 wcount)
 {
-       ide_hwif_t *hwif        = HWIF(drive);
-       u8 io_32bit             = drive->io_32bit;
+       ide_hwif_t *hwif = drive->hwif;
+       struct ide_io_ports *io_ports = &hwif->io_ports;
+       u8 io_32bit = drive->io_32bit;
 
        if (io_32bit) {
                if (io_32bit & 2) {
                        unsigned long flags;
 
                        local_irq_save(flags);
-                       ata_vlb_sync(drive, hwif->io_ports[IDE_NSECTOR_OFFSET]);
-                       hwif->OUTSL(hwif->io_ports[IDE_DATA_OFFSET], buffer,
-                                   wcount);
+                       ata_vlb_sync(drive, io_ports->nsect_addr);
+                       hwif->OUTSL(io_ports->data_addr, buffer, wcount);
                        local_irq_restore(flags);
                } else
-                       hwif->OUTSL(hwif->io_ports[IDE_DATA_OFFSET], buffer,
-                                   wcount);
+                       hwif->OUTSL(io_ports->data_addr, buffer, wcount);
        } else
-               hwif->OUTSW(hwif->io_ports[IDE_DATA_OFFSET], buffer,
-                           wcount << 1);
+               hwif->OUTSW(io_ports->data_addr, buffer, wcount << 1);
 }
 
 /*
 #if defined(CONFIG_ATARI) || defined(CONFIG_Q40)
        if (MACH_IS_ATARI || MACH_IS_Q40) {
                /* Atari has a byte-swapped IDE interface */
-               insw_swapw(hwif->io_ports[IDE_DATA_OFFSET], buffer,
-                          bytecount / 2);
+               insw_swapw(hwif->io_ports.data_addr, buffer, bytecount / 2);
                return;
        }
 #endif /* CONFIG_ATARI || CONFIG_Q40 */
        hwif->ata_input_data(drive, buffer, bytecount / 4);
        if ((bytecount & 0x03) >= 2)
-               hwif->INSW(hwif->io_ports[IDE_DATA_OFFSET],
+               hwif->INSW(hwif->io_ports.data_addr,
                           (u8 *)buffer + (bytecount & ~0x03), 1);
 }
 
 #if defined(CONFIG_ATARI) || defined(CONFIG_Q40)
        if (MACH_IS_ATARI || MACH_IS_Q40) {
                /* Atari has a byte-swapped IDE interface */
-               outsw_swapw(hwif->io_ports[IDE_DATA_OFFSET], buffer,
-                           bytecount / 2);
+               outsw_swapw(hwif->io_ports.data_addr, buffer, bytecount / 2);
                return;
        }
 #endif /* CONFIG_ATARI || CONFIG_Q40 */
        hwif->ata_output_data(drive, buffer, bytecount / 4);
        if ((bytecount & 0x03) >= 2)
-               hwif->OUTSW(hwif->io_ports[IDE_DATA_OFFSET],
+               hwif->OUTSW(hwif->io_ports.data_addr,
                            (u8 *)buffer + (bytecount & ~0x03), 1);
 }
 
         * an interrupt with another pci card/device.  We make no assumptions
         * about possible isa-pnp and pci-pnp issues yet.
         */
-       if (hwif->io_ports[IDE_CONTROL_OFFSET])
+       if (hwif->io_ports.ctl_addr)
                stat = ide_read_altstatus(drive);
        else
                /* Note: this may clear a pending IRQ!! */
        SELECT_MASK(drive, 1);
        ide_set_irq(drive, 1);
        msleep(50);
-       hwif->OUTB(WIN_IDENTIFY, hwif->io_ports[IDE_COMMAND_OFFSET]);
+       hwif->OUTB(WIN_IDENTIFY, hwif->io_ports.command_addr);
        timeout = jiffies + WAIT_WORSTCASE;
        do {
                if (time_after(jiffies, timeout)) {
 int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
 {
        ide_hwif_t *hwif = drive->hwif;
+       struct ide_io_ports *io_ports = &hwif->io_ports;
        int error = 0;
        u8 stat;
 
        SELECT_MASK(drive, 0);
        udelay(1);
        ide_set_irq(drive, 0);
-       hwif->OUTB(speed, hwif->io_ports[IDE_NSECTOR_OFFSET]);
-       hwif->OUTB(SETFEATURES_XFER, hwif->io_ports[IDE_FEATURE_OFFSET]);
-       hwif->OUTBSYNC(drive, WIN_SETFEATURES,
-                      hwif->io_ports[IDE_COMMAND_OFFSET]);
+       hwif->OUTB(speed, io_ports->nsect_addr);
+       hwif->OUTB(SETFEATURES_XFER, io_ports->feature_addr);
+       hwif->OUTBSYNC(drive, WIN_SETFEATURES, io_ports->command_addr);
        if (drive->quirk_list == 2)
                ide_set_irq(drive, 1);
 
 
        spin_lock_irqsave(&ide_lock, flags);
        __ide_set_handler(drive, handler, timeout, expiry);
-       hwif->OUTBSYNC(drive, cmd, hwif->io_ports[IDE_COMMAND_OFFSET]);
+       hwif->OUTBSYNC(drive, cmd, hwif->io_ports.command_addr);
        /*
         * Drive takes 400nS to respond, we must avoid the IRQ being
         * serviced before that.
        unsigned long flags;
        ide_hwif_t *hwif;
        ide_hwgroup_t *hwgroup;
+       struct ide_io_ports *io_ports;
        const struct ide_port_ops *port_ops;
        u8 ctl;
 
        hwif = HWIF(drive);
        hwgroup = HWGROUP(drive);
 
+       io_ports = &hwif->io_ports;
+
        /* We must not reset with running handlers */
        BUG_ON(hwgroup->handler != NULL);
 
                pre_reset(drive);
                SELECT_DRIVE(drive);
                udelay (20);
-               hwif->OUTBSYNC(drive, WIN_SRST,
-                              hwif->io_ports[IDE_COMMAND_OFFSET]);
+               hwif->OUTBSYNC(drive, WIN_SRST, io_ports->command_addr);
                ndelay(400);
                hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
                hwgroup->polling = 1;
        for (unit = 0; unit < MAX_DRIVES; ++unit)
                pre_reset(&hwif->drives[unit]);
 
-       if (hwif->io_ports[IDE_CONTROL_OFFSET] == 0) {
+       if (io_ports->ctl_addr == 0) {
                spin_unlock_irqrestore(&ide_lock, flags);
                return ide_stopped;
        }
         * recover from reset very quickly, saving us the first 50ms wait time.
         */
        /* set SRST and nIEN */
-       hwif->OUTBSYNC(drive, drive->ctl|6, hwif->io_ports[IDE_CONTROL_OFFSET]);
+       hwif->OUTBSYNC(drive, drive->ctl|6, io_ports->ctl_addr);
        /* more than enough time */
        udelay(10);
        if (drive->quirk_list == 2)
                ctl = drive->ctl;       /* clear SRST and nIEN */
        else
                ctl = drive->ctl | 2;   /* clear SRST, leave nIEN */
-       hwif->OUTBSYNC(drive, ctl, hwif->io_ports[IDE_CONTROL_OFFSET]);
+       hwif->OUTBSYNC(drive, ctl, io_ports->ctl_addr);
        /* more than enough time */
        udelay(10);
        hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
                 * about locking issues (2.5 work ?).
                 */
                mdelay(1);
-               stat = hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]);
+               stat = hwif->INB(hwif->io_ports.status_addr);
                if ((stat & BUSY_STAT) == 0)
                        return 0;
                /*
 
 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;
        int use_altstatus = 0, rc;
        unsigned long timeout;
        u8 s = 0, a = 0;
        /* take a deep breath */
        msleep(50);
 
-       if (hwif->io_ports[IDE_CONTROL_OFFSET]) {
+       if (io_ports->ctl_addr) {
                a = ide_read_altstatus(drive);
                s = ide_read_status(drive);
                if ((a ^ s) & ~INDEX_STAT)
         */
        if ((cmd == WIN_PIDENTIFY))
                /* disable dma & overlap */
-               hwif->OUTB(0, hwif->io_ports[IDE_FEATURE_OFFSET]);
+               hwif->OUTB(0, io_ports->feature_addr);
 
        /* ask drive for ID */
-       hwif->OUTB(cmd, hwif->io_ports[IDE_COMMAND_OFFSET]);
+       hwif->OUTB(cmd, io_ports->command_addr);
 
        timeout = ((cmd == WIN_IDENTIFY) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2;
        timeout += jiffies;
         * interrupts during the identify-phase that
         * the irq handler isn't expecting.
         */
-       if (hwif->io_ports[IDE_CONTROL_OFFSET]) {
+       if (hwif->io_ports.ctl_addr) {
                if (!hwif->irq) {
                        autoprobe = 1;
                        cookie = probe_irq_on();
 
        do {
                msleep(50);
-               stat = hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]);
+               stat = hwif->INB(hwif->io_ports.status_addr);
                if ((stat & BUSY_STAT) == 0)
                        return 0;
        } while (time_before(jiffies, timeout));
 static int do_probe (ide_drive_t *drive, u8 cmd)
 {
        ide_hwif_t *hwif = HWIF(drive);
+       struct ide_io_ports *io_ports = &hwif->io_ports;
        int rc;
        u8 stat;
 
        msleep(50);
        SELECT_DRIVE(drive);
        msleep(50);
-       if (hwif->INB(hwif->io_ports[IDE_SELECT_OFFSET]) != drive->select.all &&
+       if (hwif->INB(io_ports->device_addr) != drive->select.all &&
            !drive->present) {
                if (drive->select.b.unit != 0) {
                        /* exit with drive0 selected */
                        printk(KERN_ERR "%s: no response (status = 0x%02x), "
                                        "resetting drive\n", drive->name, stat);
                        msleep(50);
-                       hwif->OUTB(drive->select.all,
-                                  hwif->io_ports[IDE_SELECT_OFFSET]);
+                       hwif->OUTB(drive->select.all, io_ports->device_addr);
                        msleep(50);
-                       hwif->OUTB(WIN_SRST,
-                                  hwif->io_ports[IDE_COMMAND_OFFSET]);
+                       hwif->OUTB(WIN_SRST, io_ports->command_addr);
                        (void)ide_busy_sleep(hwif);
                        rc = try_to_identify(drive, cmd);
                }
        printk("%s: enabling %s -- ", hwif->name, drive->id->model);
        SELECT_DRIVE(drive);
        msleep(50);
-       hwif->OUTB(EXABYTE_ENABLE_NEST, hwif->io_ports[IDE_COMMAND_OFFSET]);
+       hwif->OUTB(EXABYTE_ENABLE_NEST, hwif->io_ports.command_addr);
 
        if (ide_busy_sleep(hwif)) {
                printk(KERN_CONT "failed (timeout)\n");
  */
 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;
                if (IDE_CHIPSET_IS_PCI(hwif->chipset))
                        sa = IRQF_SHARED;
 
-               if (hwif->io_ports[IDE_CONTROL_OFFSET])
+               if (io_ports->ctl_addr)
                        /* clear nIEN */
-                       hwif->OUTB(0x08, hwif->io_ports[IDE_CONTROL_OFFSET]);
+                       hwif->OUTB(0x08, io_ports->ctl_addr);
 
                if (request_irq(hwif->irq,&ide_intr,sa,hwif->name,hwgroup))
                        goto out_unlink;
 
 #if !defined(__mc68000__)
        printk("%s at 0x%03lx-0x%03lx,0x%03lx on irq %d", hwif->name,
-               hwif->io_ports[IDE_DATA_OFFSET],
-               hwif->io_ports[IDE_DATA_OFFSET]+7,
-               hwif->io_ports[IDE_CONTROL_OFFSET], hwif->irq);
+               io_ports->data_addr, io_ports->status_addr,
+               io_ports->ctl_addr, hwif->irq);
 #else
        printk("%s at 0x%08lx on irq %d", hwif->name,
-               hwif->io_ports[IDE_DATA_OFFSET], hwif->irq);
+               io_ports->data_addr, hwif->irq);
 #endif /* __mc68000__ */
        if (match)
                printk(" (%sed with %s)",
        int old_irq;
 
        if (!hwif->irq) {
-               if (!(hwif->irq = ide_default_irq(hwif->io_ports[IDE_DATA_OFFSET])))
-               {
+               hwif->irq = ide_default_irq(hwif->io_ports.data_addr);
+               if (!hwif->irq) {
                        printk("%s: DISABLED, NO IRQ\n", hwif->name);
                        return 0;
                }
         *      It failed to initialise. Find the default IRQ for 
         *      this port and try that.
         */
-       if (!(hwif->irq = ide_default_irq(hwif->io_ports[IDE_DATA_OFFSET]))) {
+       hwif->irq = ide_default_irq(hwif->io_ports.data_addr);
+       if (!hwif->irq) {
                printk("%s: Disabled unable to get IRQ %d.\n",
                        hwif->name, old_irq);
                goto out;
 
                return ide_do_reset(drive);
        }
        /* Get the number of bytes to transfer on this interrupt. */
-       bcount = (hwif->INB(hwif->io_ports[IDE_BCOUNTH_OFFSET]) << 8) |
-                 hwif->INB(hwif->io_ports[IDE_BCOUNTL_OFFSET]);
+       bcount = (hwif->INB(hwif->io_ports.lbah_addr) << 8) |
+                 hwif->INB(hwif->io_ports.lbam_addr);
 
-       ireason = hwif->INB(hwif->io_ports[IDE_IREASON_OFFSET]);
+       ireason = hwif->INB(hwif->io_ports.nsect_addr);
 
        if (ireason & CD) {
                printk(KERN_ERR "ide-tape: CoD != 0 in %s\n", __func__);
                                "yet DRQ isn't asserted\n");
                return startstop;
        }
-       ireason = hwif->INB(hwif->io_ports[IDE_IREASON_OFFSET]);
+       ireason = hwif->INB(hwif->io_ports.nsect_addr);
        while (retries-- && ((ireason & CD) == 0 || (ireason & IO))) {
                printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while issuing "
                                "a packet command, retrying\n");
                udelay(100);
-               ireason = hwif->INB(hwif->io_ports[IDE_IREASON_OFFSET]);
+               ireason = hwif->INB(hwif->io_ports.nsect_addr);
                if (retries == 0) {
                        printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while "
                                        "issuing a packet command, ignoring\n");
                                    IDETAPE_WAIT_CMD, NULL);
                return ide_started;
        } else {
-               hwif->OUTB(WIN_PACKETCMD, hwif->io_ports[IDE_COMMAND_OFFSET]);
+               hwif->OUTB(WIN_PACKETCMD, hwif->io_ports.command_addr);
                return idetape_transfer_pc(drive);
        }
 }
 
 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;
        struct ide_taskfile *tf = &task->tf;
        u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
 
                SELECT_MASK(drive, 0);
 
        if (task->tf_flags & IDE_TFLAG_OUT_DATA)
-               hwif->OUTW((tf->hob_data << 8) | tf->data,
-                          hwif->io_ports[IDE_DATA_OFFSET]);
+               hwif->OUTW((tf->hob_data << 8) | tf->data, io_ports->data_addr);
 
        if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
-               hwif->OUTB(tf->hob_feature, hwif->io_ports[IDE_FEATURE_OFFSET]);
+               hwif->OUTB(tf->hob_feature, io_ports->feature_addr);
        if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
-               hwif->OUTB(tf->hob_nsect, hwif->io_ports[IDE_NSECTOR_OFFSET]);
+               hwif->OUTB(tf->hob_nsect, io_ports->nsect_addr);
        if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
-               hwif->OUTB(tf->hob_lbal, hwif->io_ports[IDE_SECTOR_OFFSET]);
+               hwif->OUTB(tf->hob_lbal, io_ports->lbal_addr);
        if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
-               hwif->OUTB(tf->hob_lbam, hwif->io_ports[IDE_LCYL_OFFSET]);
+               hwif->OUTB(tf->hob_lbam, io_ports->lbam_addr);
        if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
-               hwif->OUTB(tf->hob_lbah, hwif->io_ports[IDE_HCYL_OFFSET]);
+               hwif->OUTB(tf->hob_lbah, io_ports->lbah_addr);
 
        if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
-               hwif->OUTB(tf->feature, hwif->io_ports[IDE_FEATURE_OFFSET]);
+               hwif->OUTB(tf->feature, io_ports->feature_addr);
        if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
-               hwif->OUTB(tf->nsect, hwif->io_ports[IDE_NSECTOR_OFFSET]);
+               hwif->OUTB(tf->nsect, io_ports->nsect_addr);
        if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
-               hwif->OUTB(tf->lbal, hwif->io_ports[IDE_SECTOR_OFFSET]);
+               hwif->OUTB(tf->lbal, io_ports->lbal_addr);
        if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
-               hwif->OUTB(tf->lbam, hwif->io_ports[IDE_LCYL_OFFSET]);
+               hwif->OUTB(tf->lbam, io_ports->lbam_addr);
        if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
-               hwif->OUTB(tf->lbah, hwif->io_ports[IDE_HCYL_OFFSET]);
+               hwif->OUTB(tf->lbah, io_ports->lbah_addr);
 
        if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
                hwif->OUTB((tf->device & HIHI) | drive->select.all,
-                          hwif->io_ports[IDE_SELECT_OFFSET]);
+                          io_ports->device_addr);
 }
 
 int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf)
        switch (task->data_phase) {
        case TASKFILE_MULTI_OUT:
        case TASKFILE_OUT:
-               hwif->OUTBSYNC(drive, tf->command,
-                              hwif->io_ports[IDE_COMMAND_OFFSET]);
+               hwif->OUTBSYNC(drive, tf->command, hwif->io_ports.command_addr);
                ndelay(400);    /* FIXME */
                return pre_task_out_intr(drive, task->rq);
        case TASKFILE_MULTI_IN:
 
 
 void ide_init_port_hw(ide_hwif_t *hwif, hw_regs_t *hw)
 {
-       memcpy(hwif->io_ports, hw->io_ports, sizeof(hwif->io_ports));
+       memcpy(&hwif->io_ports, &hw->io_ports, sizeof(hwif->io_ports));
        hwif->irq = hw->irq;
        hwif->chipset = hw->chipset;
        hwif->gendev.parent = hw->dev;
 
 {
     unsigned char ch;
 
-    ch = z_readb(hwif->io_ports[IDE_IRQ_OFFSET]);
+    ch = z_readb(hwif->io_ports.irq_addr);
     if (!(ch & 0x80))
            return 0;
     return 1;
 {
     unsigned char ch;
 
-    ch = z_readb(hwif->io_ports[IDE_IRQ_OFFSET]);
+    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[IDE_IRQ_OFFSET]); 
+    z_writeb(0, hwif->io_ports.irq_addr);
     if (!(ch & 0x80))
            return 0;
     return 1;
 
        memset(hw, 0, sizeof(*hw));
 
-       hw->io_ports[IDE_DATA_OFFSET] = base;
+       hw->io_ports.data_addr = base;
 
        for (i = 1; i < 8; i++)
-               hw->io_ports[i] = base + 2 + i * 4;
+               hw->io_ports_array[i] = base + 2 + i * 4;
 
-       hw->io_ports[IDE_CONTROL_OFFSET] = ctl;
-       hw->io_ports[IDE_IRQ_OFFSET] = irq_port;
+       hw->io_ports.ctl_addr = ctl;
+       hw->io_ports.irq_addr = irq_port;
 
        hw->irq = IRQ_AMIGA_PORTS;
        hw->ack_intr = ack_intr;
 
 
        memset(hw, 0, sizeof(*hw));
 
-       hw->io_ports[IDE_DATA_OFFSET] = ATA_HD_BASE;
+       hw->io_ports.data_addr = ATA_HD_BASE;
 
        for (i = 1; i < 8; i++)
-               hw->io_ports[i] = ATA_HD_BASE + 1 + i * 4;
+               hw->io_ports_array[i] = ATA_HD_BASE + 1 + i * 4;
 
-       hw->io_ports[IDE_CONTROL_OFFSET] = ATA_HD_BASE + ATA_HD_CONTROL;
+       hw->io_ports.ctl_addr = ATA_HD_BASE + ATA_HD_CONTROL;
 
        hw->irq = IRQ_MFP_IDE;
        hw->ack_intr = NULL;
 
 {
     unsigned char ch;
 
-    ch = z_readb(hwif->io_ports[IDE_IRQ_OFFSET]);
+    ch = z_readb(hwif->io_ports.irq_addr);
     if (!(ch & GAYLE_IRQ_IDE))
        return 0;
     return 1;
 {
     unsigned char ch;
 
-    ch = z_readb(hwif->io_ports[IDE_IRQ_OFFSET]);
+    ch = z_readb(hwif->io_ports.irq_addr);
     if (!(ch & GAYLE_IRQ_IDE))
        return 0;
-    (void)z_readb(hwif->io_ports[IDE_STATUS_OFFSET]);
-    z_writeb(0x7c, hwif->io_ports[IDE_IRQ_OFFSET]);
+    (void)z_readb(hwif->io_ports.status_addr);
+    z_writeb(0x7c, hwif->io_ports.irq_addr);
     return 1;
 }
 
 
        memset(hw, 0, sizeof(*hw));
 
-       hw->io_ports[IDE_DATA_OFFSET] = base;
+       hw->io_ports.data_addr = base;
 
        for (i = 1; i < 8; i++)
-               hw->io_ports[i] = base + 2 + i * 4;
+               hw->io_ports_array[i] = base + 2 + i * 4;
 
-       hw->io_ports[IDE_CONTROL_OFFSET] = ctl;
-       hw->io_ports[IDE_IRQ_OFFSET] = irq_port;
+       hw->io_ports.ctl_addr = ctl;
+       hw->io_ports.irq_addr = irq_port;
 
        hw->irq = IRQ_AMIGA_PORTS;
        hw->ack_intr = ack_intr;
 
                /*
                 * Set timing for this drive:
                 */
-               outb(timing, hwif->io_ports[IDE_SELECT_OFFSET]);
-               (void)inb(hwif->io_ports[IDE_STATUS_OFFSET]);
+               outb(timing, hwif->io_ports.device_addr);
+               (void)inb(hwif->io_ports.status_addr);
 #ifdef DEBUG
                printk("ht6560b: %s: select=%#x timing=%#x\n",
                        drive->name, select, timing);
 
 
     ide_release(link);
 
-    release_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1);
-    release_region(hwif->io_ports[IDE_DATA_OFFSET], 8);
+    release_region(hwif->io_ports.ctl_addr, 1);
+    release_region(hwif->io_ports.data_addr, 8);
 
     kfree(info);
 } /* ide_detach */
 
        unsigned long port = (unsigned long)base;
        int i;
 
-       hw->io_ports[IDE_DATA_OFFSET] = port;
+       hw->io_ports.data_addr = port;
 
        port += (1 << pdata->ioport_shift);
-       for (i = IDE_ERROR_OFFSET; i <= IDE_STATUS_OFFSET;
+       for (i = 1; i <= 7;
             i++, port += (1 << pdata->ioport_shift))
-               hw->io_ports[i] = port;
+               hw->io_ports_array[i] = port;
 
-       hw->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
+       hw->io_ports.ctl_addr = (unsigned long)ctrl;
 
        hw->irq = irq;
 
 
        memset(hw, 0, sizeof(*hw));
 
        for (i = 0; i < 8; i++)
-               hw->io_ports[i] = base + i * 4;
+               hw->io_ports_array[i] = base + i * 4;
 
-       hw->io_ports[IDE_CONTROL_OFFSET] = base + IDE_CONTROL;
+       hw->io_ports.ctl_addr = base + IDE_CONTROL;
 
        hw->irq = irq;
        hw->ack_intr = ack_intr;
 
        for (i = 0; i < IDE_NR_PORTS; i++) {
                /* BIG FAT WARNING: 
                   assumption: only DATA port is ever used in 16 bit mode */
-               if ( i==0 )
-                       hw->io_ports[i] = Q40_ISA_IO_W(base + offsets[i]);
+               if (i == 0)
+                       hw->io_ports_array[i] = Q40_ISA_IO_W(base + offsets[i]);
                else
-                       hw->io_ports[i] = Q40_ISA_IO_B(base + offsets[i]);
+                       hw->io_ports_array[i] = Q40_ISA_IO_B(base + offsets[i]);
        }
 
        hw->irq = irq;
 
 static void auide_setup_ports(hw_regs_t *hw, _auide_hwif *ahwif)
 {
        int i;
-       unsigned long *ata_regs = hw->io_ports;
+       unsigned long *ata_regs = hw->io_ports_array;
 
        /* FIXME? */
-       for (i = 0; i < IDE_CONTROL_OFFSET; i++) {
+       for (i = 0; i < 8; i++)
                *ata_regs++ = ahwif->regbase + (i << AU1XXX_ATA_REG_OFFSET);
-       }
 
        /* set the Alternative Status register */
        *ata_regs = ahwif->regbase + (14 << AU1XXX_ATA_REG_OFFSET);
 
 
        hwif->chipset = ide_generic;
 
-       for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
-               hwif->io_ports[i] =
+       for (i = 0; i <= 7; i++)
+               hwif->io_ports_array[i] =
                                (unsigned long)(base + ((0x1f0 + i) << 5));
-       hwif->io_ports[IDE_CONTROL_OFFSET] =
+       hwif->io_ports.ctl_addr =
                                (unsigned long)(base + (0x3f6 << 5));
        hwif->irq = K_INT_GB_IDE;
 
 
 
        spin_lock_irqsave(&cmd640_lock, flags);
 
-       outb_p(0x0a, 0x170 + IDE_SELECT_OFFSET);        /* select drive0 */
+       outb_p(0x0a, 0x176);    /* select drive0 */
        udelay(100);
-       if ((inb_p(0x170 + IDE_SELECT_OFFSET) & 0x1f) != 0x0a) {
-               outb_p(0x1a, 0x170 + IDE_SELECT_OFFSET); /* select drive1 */
+       if ((inb_p(0x176) & 0x1f) != 0x0a) {
+               outb_p(0x1a, 0x176); /* select drive1 */
                udelay(100);
-               if ((inb_p(0x170 + IDE_SELECT_OFFSET) & 0x1f) != 0x1a) {
+               if ((inb_p(0x176) & 0x1f) != 0x1a) {
                        spin_unlock_irqrestore(&cmd640_lock, flags);
                        return 0; /* nothing responded */
                }
 
                }
        } else
                outb(mask ? (drive->ctl | 2) : (drive->ctl & ~2),
-                    hwif->io_ports[IDE_CONTROL_OFFSET]);
+                    hwif->io_ports.ctl_addr);
 }
 
 /*
 
        base = pci_resource_start(pdev, port * 2) & ~3;
        dmabase = pci_resource_start(pdev, 4) & ~3;
 
-       superio_ide_status[port] = base + IDE_STATUS_OFFSET;
-       superio_ide_select[port] = base + IDE_SELECT_OFFSET;
+       superio_ide_status[port] = base + 7;
+       superio_ide_select[port] = base + 6;
        superio_ide_dma_status[port] = dmabase + (!port ? 2 : 0xa);
 
        /* Clear error/interrupt, enable dma */
                 *      SELECT_DRIVE() properly during first ide_probe_port().
                 */
                timeout = 10000;
-               outb(12, hwif->io_ports[IDE_CONTROL_OFFSET]);
+               outb(12, hwif->io_ports.ctl_addr);
                udelay(10);
-               outb(8, hwif->io_ports[IDE_CONTROL_OFFSET]);
+               outb(8, hwif->io_ports.ctl_addr);
                do {
                        udelay(50);
-                       stat = hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]);
+                       stat = hwif->INB(hwif->io_ports.status_addr);
                        if (stat == 0xff)
                                break;
                } while ((stat & BUSY_STAT) && --timeout);
        }
 
        if (!using_inta)
-               hwif->irq = ide_default_irq(hwif->io_ports[IDE_DATA_OFFSET]);
+               hwif->irq = ide_default_irq(hwif->io_ports.data_addr);
        else if (!hwif->irq && hwif->mate && hwif->mate->irq)
                hwif->irq = hwif->mate->irq;    /* share IRQ with mate */
 
 
 
        spin_lock_irqsave(&opti621_lock, flags);
 
-       reg_base = hwif->io_ports[IDE_DATA_OFFSET];
+       reg_base = hwif->io_ports.data_addr;
 
        /* allow Register-B */
        outb(0xc0, reg_base + CNTRL_REG);
 
 
        /* errata A308 workaround: Step5 (check data loss) */
        /* We don't check non ide_disk because it is limited to UDMA4 */
-       if (!(in_be32((void __iomem *)hwif->io_ports[IDE_ALTSTATUS_OFFSET])
+       if (!(in_be32((void __iomem *)hwif->io_ports.ctl_addr)
              & ERR_STAT) &&
            drive->media == ide_disk && drive->current_speed > XFER_UDMA_4) {
                reg = in_be32((void __iomem *)intsts_port);
        u32 int_stat = in_be32((void __iomem *)hwif->dma_base + 0x014);
 
        /* SCC errata A252,A308 workaround: Step4 */
-       if ((in_be32((void __iomem *)hwif->io_ports[IDE_ALTSTATUS_OFFSET])
+       if ((in_be32((void __iomem *)hwif->io_ports.ctl_addr)
             & ERR_STAT) &&
            (int_stat & INTSTS_INTRQ))
                return 1;
        }
 
        memset(&hw, 0, sizeof(hw));
-       for (i = IDE_DATA_OFFSET; i <= IDE_CONTROL_OFFSET; i++)
-               hw.io_ports[i] = ports->dma + 0x20 + i * 4;
+       for (i = 0; i <= 8; i++)
+               hw.io_ports_array[i] = ports->dma + 0x20 + i * 4;
        hw.irq = dev->irq;
        hw.dev = &dev->dev;
        hw.chipset = ide_pci;
 
        int i;
 
        /* Registers are word (32 bit) aligned */
-       for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
-               hw->io_ports[i] = reg + i * 4;
+       for (i = 0; i <= 7; i++)
+               hw->io_ports_array[i] = reg + i * 4;
 
        if (ctrl_port)
-               hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
+               hw->io_ports.ctl_addr = ctrl_port;
 
        if (irq_port)
-               hw->io_ports[IDE_IRQ_OFFSET] = irq_port;
+               hw->io_ports.irq_addr = irq_port;
 }
 
 static void
 sgiioc4_maskproc(ide_drive_t * drive, int mask)
 {
        writeb(mask ? (drive->ctl | 2) : (drive->ctl & ~2),
-              (void __iomem *)drive->hwif->io_ports[IDE_CONTROL_OFFSET]);
+              (void __iomem *)drive->hwif->io_ports.ctl_addr);
 }
 
 static int
 sgiioc4_checkirq(ide_hwif_t * hwif)
 {
        unsigned long intr_addr =
-               hwif->io_ports[IDE_IRQ_OFFSET] + IOC4_INTR_REG * 4;
+               hwif->io_ports.irq_addr + IOC4_INTR_REG * 4;
 
        if ((u8)readl((void __iomem *)intr_addr) & 0x03)
                return 1;
 {
        u32 intr_reg;
        ide_hwif_t *hwif = HWIF(drive);
-       unsigned long other_ir =
-           hwif->io_ports[IDE_IRQ_OFFSET] + (IOC4_INTR_REG << 2);
+       struct ide_io_ports *io_ports = &hwif->io_ports;
+       unsigned long other_ir = io_ports->irq_addr + (IOC4_INTR_REG << 2);
 
        /* Code to check for PCI error conditions */
        intr_reg = readl((void __iomem *)other_ir);
                 * a "clear" status if it got cleared.  If not, then spin
                 * for a bit trying to clear it.
                 */
-               u8 stat = sgiioc4_INB(hwif->io_ports[IDE_STATUS_OFFSET]);
+               u8 stat = sgiioc4_INB(io_ports->status_addr);
                int count = 0;
-               stat = sgiioc4_INB(hwif->io_ports[IDE_STATUS_OFFSET]);
+               stat = sgiioc4_INB(io_ports->status_addr);
                while ((stat & 0x80) && (count++ < 100)) {
                        udelay(1);
-                       stat = sgiioc4_INB(hwif->io_ports[IDE_STATUS_OFFSET]);
+                       stat = sgiioc4_INB(io_ports->status_addr);
                }
 
                if (intr_reg & 0x02) {
                            pci_stat_cmd_reg;
 
                        pci_err_addr_low =
-                               readl((void __iomem *)hwif->io_ports[IDE_IRQ_OFFSET]);
+                               readl((void __iomem *)io_ports->irq_addr);
                        pci_err_addr_high =
-                               readl((void __iomem *)(hwif->io_ports[IDE_IRQ_OFFSET] + 4));
+                               readl((void __iomem *)(io_ports->irq_addr + 4));
                        pci_read_config_dword(dev, PCI_COMMAND,
                                              &pci_stat_cmd_reg);
                        printk(KERN_ERR
 
        struct pci_dev *dev     = to_pci_dev(hwif->dev);
        void *addr              = pci_get_drvdata(dev);
        u8 ch                   = hwif->channel;
-       hw_regs_t               hw;
        unsigned long           base;
 
+       struct ide_io_ports *io_ports = &hwif->io_ports;
+
        /*
         *      Fill in the basic HWIF bits
         */
         *      based I/O
         */
 
-       memset(&hw, 0, sizeof(hw_regs_t));
+       memset(io_ports, 0, sizeof(*io_ports));
 
        base = (unsigned long)addr;
        if (ch)
         *      so we can't currently use it sanely since we want to
         *      use LBA48 mode.
         */     
-       hw.io_ports[IDE_DATA_OFFSET]    = base;
-       hw.io_ports[IDE_ERROR_OFFSET]   = base + 1;
-       hw.io_ports[IDE_NSECTOR_OFFSET] = base + 2;
-       hw.io_ports[IDE_SECTOR_OFFSET]  = base + 3;
-       hw.io_ports[IDE_LCYL_OFFSET]    = base + 4;
-       hw.io_ports[IDE_HCYL_OFFSET]    = base + 5;
-       hw.io_ports[IDE_SELECT_OFFSET]  = base + 6;
-       hw.io_ports[IDE_STATUS_OFFSET]  = base + 7;
-       hw.io_ports[IDE_CONTROL_OFFSET] = base + 10;
-
-       hw.io_ports[IDE_IRQ_OFFSET]     = 0;
+       io_ports->data_addr     = base;
+       io_ports->error_addr    = base + 1;
+       io_ports->nsect_addr    = base + 2;
+       io_ports->lbal_addr     = base + 3;
+       io_ports->lbam_addr     = base + 4;
+       io_ports->lbah_addr     = base + 5;
+       io_ports->device_addr   = base + 6;
+       io_ports->status_addr   = base + 7;
+       io_ports->ctl_addr      = base + 10;
 
        if (pdev_is_sata(dev)) {
                base = (unsigned long)addr;
                hwif->sata_scr[SATA_CONTROL_OFFSET]     = base + 0x100;
        }
 
-       memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports));
-
        hwif->irq = dev->irq;
 
        hwif->dma_base = (unsigned long)addr + (ch ? 0x08 : 0x00);
 
                if (old != compat && old_mask == 0xff) {
                        /* leave lower 10 bits untouched */
                        compat += (next_offset += 0x400);
-                       hwif->io_ports[IDE_CONTROL_OFFSET] = compat + 2;
+                       hwif->io_ports.ctl_addr = compat + 2;
                        outw(compat | 1, hwif->config_data);
                        new = inw(hwif->config_data);
                        printk(KERN_INFO "%s: control basereg workaround: "
 
 #if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_IDE_8xx_DIRECT)
 static int __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port)
 {
-       unsigned long *p = hw->io_ports;
+       unsigned long *p = hw->io_ports_array;
        int i;
 
        typedef struct {
 #if defined(CONFIG_IDE_EXT_DIRECT)
 static int __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port)
 {
-       unsigned long *p = hw->io_ports;
+       unsigned long *p = hw->io_ports_array;
        int i;
 
        u32 ide_phy_base;
 
 #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
 
 #define PMAC_IDE_REG(x) \
-       ((void __iomem *)((drive)->hwif->io_ports[IDE_DATA_OFFSET] + (x)))
+       ((void __iomem *)((drive)->hwif->io_ports.data_addr + (x)))
 
 /*
  * Apply the timings of the proper unit (master/slave) to the shared
        int i;
 
        for (i = 0; i < 8; ++i)
-               hw->io_ports[i] = base + i * 0x10;
-       hw->io_ports[8] = base + 0x160;
+               hw->io_ports_array[i] = base + i * 0x10;
+
+       hw->io_ports.ctl_addr = base + 0x160;
 }
 
 /*
 
 
        if (ide_read_status(drive) & (BUSY_STAT | DRQ_STAT))
                /* force an abort */
-               hwif->OUTB(WIN_IDLEIMMEDIATE,
-                          hwif->io_ports[IDE_COMMAND_OFFSET]);
+               hwif->OUTB(WIN_IDLEIMMEDIATE, hwif->io_ports.command_addr);
 
        rq->errors++;
 
                idescsi_end_request (drive, 1, 0);
                return ide_stopped;
        }
-       bcount = (hwif->INB(hwif->io_ports[IDE_BCOUNTH_OFFSET]) << 8) |
-                 hwif->INB(hwif->io_ports[IDE_BCOUNTL_OFFSET]);
-       ireason = hwif->INB(hwif->io_ports[IDE_IREASON_OFFSET]);
+       bcount = (hwif->INB(hwif->io_ports.lbah_addr) << 8) |
+                 hwif->INB(hwif->io_ports.lbam_addr);
+       ireason = hwif->INB(hwif->io_ports.nsect_addr);
 
        if (ireason & CD) {
                printk(KERN_ERR "ide-scsi: CoD != 0 in idescsi_pc_intr\n");
                        "initiated yet DRQ isn't asserted\n");
                return startstop;
        }
-       ireason = hwif->INB(hwif->io_ports[IDE_IREASON_OFFSET]);
+       ireason = hwif->INB(hwif->io_ports.nsect_addr);
        if ((ireason & CD) == 0 || (ireason & IO)) {
                printk(KERN_ERR "ide-scsi: (IO,CoD) != (0,1) while "
                                "issuing a packet command\n");
                return ide_started;
        } else {
                /* Issue the packet command */
-               hwif->OUTB(WIN_PACKETCMD, hwif->io_ports[IDE_COMMAND_OFFSET]);
+               hwif->OUTB(WIN_PACKETCMD, hwif->io_ports.command_addr);
                return idescsi_transfer_pc(drive);
        }
 }
 
 
        memset(hw, 0, sizeof(*hw));
 
-       for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
-               hw->io_ports[i] = reg;
+       for (i = 0; i <= 7; i++) {
+               hw->io_ports_array[i] = reg;
                reg += regincr;
        }
 
-       hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
+       hw->io_ports.ctl_addr = ctrl_port;
 
        if (irq)
                *irq = 0;
 
        int i;
 
        /* fill in ports for ATA addresses 0 to 7 */
-
-       for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
-               hw->io_ports[i] = data_port |
+       for (i = 0; i <= 7; i++) {
+               hw->io_ports_array[i] = data_port |
                        IO_FIELD(R_ATA_CTRL_DATA, addr, i) |
                        IO_STATE(R_ATA_CTRL_DATA, cs0, active);
        }
 
        /* the IDE control register is at ATA address 6, with CS1 active instead of CS0 */
-
-       hw->io_ports[IDE_CONTROL_OFFSET] = data_port |
+       hw->io_ports.ctl_addr = data_port |
                        IO_FIELD(R_ATA_CTRL_DATA, addr, 6) |
                        IO_STATE(R_ATA_CTRL_DATA, cs1, active);
 
        /* whats this for ? */
-
-       hw->io_ports[IDE_IRQ_OFFSET] = 0;
+       hw->io_ports.irq_addr = 0;
 }
 
 static inline void ide_init_default_hwifs(void)
 
  */
 #define IDE_NR_PORTS           (10)
 
-#define IDE_DATA_OFFSET                (0)
-#define IDE_ERROR_OFFSET       (1)
-#define IDE_NSECTOR_OFFSET     (2)
-#define IDE_SECTOR_OFFSET      (3)
-#define IDE_LCYL_OFFSET                (4)
-#define IDE_HCYL_OFFSET                (5)
-#define IDE_SELECT_OFFSET      (6)
-#define IDE_STATUS_OFFSET      (7)
-#define IDE_CONTROL_OFFSET     (8)
-#define IDE_IRQ_OFFSET         (9)
-
-#define IDE_FEATURE_OFFSET     IDE_ERROR_OFFSET
-#define IDE_COMMAND_OFFSET     IDE_STATUS_OFFSET
-#define IDE_ALTSTATUS_OFFSET   IDE_CONTROL_OFFSET
-#define IDE_IREASON_OFFSET     IDE_NSECTOR_OFFSET
-#define IDE_BCOUNTL_OFFSET     IDE_LCYL_OFFSET
-#define IDE_BCOUNTH_OFFSET     IDE_HCYL_OFFSET
+struct ide_io_ports {
+       unsigned long   data_addr;
+
+       union {
+               unsigned long error_addr;       /*   read:  error */
+               unsigned long feature_addr;     /*  write: feature */
+       };
+
+       unsigned long   nsect_addr;
+       unsigned long   lbal_addr;
+       unsigned long   lbam_addr;
+       unsigned long   lbah_addr;
+
+       unsigned long   device_addr;
+
+       union {
+               unsigned long status_addr;      /*  read: status  */
+               unsigned long command_addr;     /* write: command */
+       };
+
+       unsigned long   ctl_addr;
+
+       unsigned long   irq_addr;
+};
 
 #define OK_STAT(stat,good,bad) (((stat)&((good)|(bad)))==(good))
 #define BAD_R_STAT             (BUSY_STAT   | ERR_STAT)
  * Structure to hold all information about the location of this port
  */
 typedef struct hw_regs_s {
-       unsigned long   io_ports[IDE_NR_PORTS]; /* task file registers */
+       union {
+               struct ide_io_ports     io_ports;
+               unsigned long           io_ports_array[IDE_NR_PORTS];
+       };
+
        int             irq;                    /* our irq number */
        ide_ack_intr_t  *ack_intr;              /* acknowledge interrupt */
        hwif_chipset_t  chipset;
 {
        unsigned int i;
 
-       for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
-               hw->io_ports[i] = io_addr++;
+       for (i = 0; i <= 7; i++)
+               hw->io_ports_array[i] = io_addr++;
 
-       hw->io_ports[IDE_CONTROL_OFFSET] = ctl_addr;
+       hw->io_ports.ctl_addr = ctl_addr;
 }
 
 #include <asm/ide.h>
 
        char name[6];                   /* name of interface, eg. "ide0" */
 
-               /* task file registers for pata and sata */
-       unsigned long   io_ports[IDE_NR_PORTS];
+       struct ide_io_ports     io_ports;
+
        unsigned long   sata_scr[SATA_NR_PORTS];
 
        ide_drive_t     drives[MAX_DRIVES];     /* drive info */
 {
        ide_hwif_t *hwif = drive->hwif;
 
-       hwif->OUTB(drive->ctl | (on ? 0 : 2),
-                  hwif->io_ports[IDE_CONTROL_OFFSET]);
+       hwif->OUTB(drive->ctl | (on ? 0 : 2), hwif->io_ports.ctl_addr);
 }
 
 static inline u8 ide_read_status(ide_drive_t *drive)
 {
        ide_hwif_t *hwif = drive->hwif;
 
-       return hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]);
+       return hwif->INB(hwif->io_ports.status_addr);
 }
 
 static inline u8 ide_read_altstatus(ide_drive_t *drive)
 {
        ide_hwif_t *hwif = drive->hwif;
 
-       return hwif->INB(hwif->io_ports[IDE_CONTROL_OFFSET]);
+       return hwif->INB(hwif->io_ports.ctl_addr);
 }
 
 static inline u8 ide_read_error(ide_drive_t *drive)
 {
        ide_hwif_t *hwif = drive->hwif;
 
-       return hwif->INB(hwif->io_ports[IDE_ERROR_OFFSET]);
+       return hwif->INB(hwif->io_ports.error_addr);
 }
 
 /*
 
        /* FIXME: use ->atapi_input_bytes */
        while (bcount--)
-               (void)hwif->INB(hwif->io_ports[IDE_DATA_OFFSET]);
+               (void)hwif->INB(hwif->io_ports.data_addr);
 }
 
 static inline void ide_atapi_write_zeros(ide_drive_t *drive, unsigned bcount)
 
        /* FIXME: use ->atapi_output_bytes */
        while (bcount--)
-               hwif->OUTB(0, hwif->io_ports[IDE_DATA_OFFSET]);
+               hwif->OUTB(0, hwif->io_ports.data_addr);
 }
 
 #endif /* _IDE_H */