X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fide%2Fide-iops.c;h=bfec5d066b2533183cb357cdcc9873b6a042f3fd;hb=8d9f9a76ea09911f4aaf0d9e852fd25335080f53;hp=c32e759df2089a5229f211154f0642da5e6e3fed;hpb=256ae6a720618cbbfacc5e62ea1fe7c129d1b644;p=linux-2.6 diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index c32e759df2..bfec5d066b 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -158,15 +158,21 @@ EXPORT_SYMBOL(default_hwif_mmiops); void SELECT_DRIVE (ide_drive_t *drive) { - if (HWIF(drive)->selectproc) - HWIF(drive)->selectproc(drive); - HWIF(drive)->OUTB(drive->select.all, IDE_SELECT_REG); + ide_hwif_t *hwif = drive->hwif; + const struct ide_port_ops *port_ops = hwif->port_ops; + + if (port_ops && port_ops->selectproc) + port_ops->selectproc(drive); + + hwif->OUTB(drive->select.all, hwif->io_ports[IDE_SELECT_OFFSET]); } void SELECT_MASK (ide_drive_t *drive, int mask) { - if (HWIF(drive)->maskproc) - HWIF(drive)->maskproc(drive, mask); + const struct ide_port_ops *port_ops = drive->hwif->port_ops; + + if (port_ops && port_ops->maskproc) + port_ops->maskproc(drive, mask); } /* @@ -194,15 +200,18 @@ static void ata_input_data(ide_drive_t *drive, void *buffer, u32 wcount) if (io_32bit) { if (io_32bit & 2) { unsigned long flags; + local_irq_save(flags); - ata_vlb_sync(drive, IDE_NSECTOR_REG); - hwif->INSL(IDE_DATA_REG, buffer, wcount); + ata_vlb_sync(drive, hwif->io_ports[IDE_NSECTOR_OFFSET]); + hwif->INSL(hwif->io_ports[IDE_DATA_OFFSET], buffer, + wcount); local_irq_restore(flags); } else - hwif->INSL(IDE_DATA_REG, buffer, wcount); - } else { - hwif->INSW(IDE_DATA_REG, buffer, wcount<<1); - } + hwif->INSL(hwif->io_ports[IDE_DATA_OFFSET], buffer, + wcount); + } else + hwif->INSW(hwif->io_ports[IDE_DATA_OFFSET], buffer, + wcount << 1); } /* @@ -216,15 +225,18 @@ static void ata_output_data(ide_drive_t *drive, void *buffer, u32 wcount) if (io_32bit) { if (io_32bit & 2) { unsigned long flags; + local_irq_save(flags); - ata_vlb_sync(drive, IDE_NSECTOR_REG); - hwif->OUTSL(IDE_DATA_REG, buffer, wcount); + ata_vlb_sync(drive, hwif->io_ports[IDE_NSECTOR_OFFSET]); + hwif->OUTSL(hwif->io_ports[IDE_DATA_OFFSET], buffer, + wcount); local_irq_restore(flags); } else - hwif->OUTSL(IDE_DATA_REG, buffer, wcount); - } else { - hwif->OUTSW(IDE_DATA_REG, buffer, wcount<<1); - } + hwif->OUTSL(hwif->io_ports[IDE_DATA_OFFSET], buffer, + wcount); + } else + hwif->OUTSW(hwif->io_ports[IDE_DATA_OFFSET], buffer, + wcount << 1); } /* @@ -243,13 +255,15 @@ static void atapi_input_bytes(ide_drive_t *drive, void *buffer, u32 bytecount) #if defined(CONFIG_ATARI) || defined(CONFIG_Q40) if (MACH_IS_ATARI || MACH_IS_Q40) { /* Atari has a byte-swapped IDE interface */ - insw_swapw(IDE_DATA_REG, buffer, bytecount / 2); + insw_swapw(hwif->io_ports[IDE_DATA_OFFSET], buffer, + bytecount / 2); return; } #endif /* CONFIG_ATARI || CONFIG_Q40 */ hwif->ata_input_data(drive, buffer, bytecount / 4); if ((bytecount & 0x03) >= 2) - hwif->INSW(IDE_DATA_REG, ((u8 *)buffer)+(bytecount & ~0x03), 1); + hwif->INSW(hwif->io_ports[IDE_DATA_OFFSET], + (u8 *)buffer + (bytecount & ~0x03), 1); } static void atapi_output_bytes(ide_drive_t *drive, void *buffer, u32 bytecount) @@ -260,13 +274,15 @@ static void atapi_output_bytes(ide_drive_t *drive, void *buffer, u32 bytecount) #if defined(CONFIG_ATARI) || defined(CONFIG_Q40) if (MACH_IS_ATARI || MACH_IS_Q40) { /* Atari has a byte-swapped IDE interface */ - outsw_swapw(IDE_DATA_REG, buffer, bytecount / 2); + outsw_swapw(hwif->io_ports[IDE_DATA_OFFSET], buffer, + bytecount / 2); return; } #endif /* CONFIG_ATARI || CONFIG_Q40 */ hwif->ata_output_data(drive, buffer, bytecount / 4); if ((bytecount & 0x03) >= 2) - hwif->OUTSW(IDE_DATA_REG, ((u8*)buffer)+(bytecount & ~0x03), 1); + hwif->OUTSW(hwif->io_ports[IDE_DATA_OFFSET], + (u8 *)buffer + (bytecount & ~0x03), 1); } void default_hwif_transport(ide_hwif_t *hwif) @@ -429,7 +445,7 @@ int drive_is_ready (ide_drive_t *drive) * an interrupt with another pci card/device. We make no assumptions * about possible isa-pnp and pci-pnp issues yet. */ - if (IDE_CONTROL_REG) + if (hwif->io_ports[IDE_CONTROL_OFFSET]) stat = ide_read_altstatus(drive); else /* Note: this may clear a pending IRQ!! */ @@ -595,6 +611,7 @@ u8 eighty_ninty_three (ide_drive_t *drive) /* * FIXME: + * - change master/slave IDENTIFY order * - force bit13 (80c cable present) check also for !ivb devices * (unless the slave device is pre-ATA3) */ @@ -630,7 +647,7 @@ int ide_driveid_update(ide_drive_t *drive) SELECT_MASK(drive, 1); ide_set_irq(drive, 1); msleep(50); - hwif->OUTB(WIN_IDENTIFY, IDE_COMMAND_REG); + hwif->OUTB(WIN_IDENTIFY, hwif->io_ports[IDE_COMMAND_OFFSET]); timeout = jiffies + WAIT_WORSTCASE; do { if (time_after(jiffies, timeout)) { @@ -657,7 +674,7 @@ int ide_driveid_update(ide_drive_t *drive) local_irq_restore(flags); return 0; } - ata_input_data(drive, id, SECTOR_WORDS); + hwif->ata_input_data(drive, id, SECTOR_WORDS); (void)ide_read_status(drive); /* clear drive IRQ */ local_irq_enable(); local_irq_restore(flags); @@ -717,9 +734,10 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) SELECT_MASK(drive, 0); udelay(1); ide_set_irq(drive, 0); - hwif->OUTB(speed, IDE_NSECTOR_REG); - hwif->OUTB(SETFEATURES_XFER, IDE_FEATURE_REG); - hwif->OUTBSYNC(drive, WIN_SETFEATURES, IDE_COMMAND_REG); + 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]); if (drive->quirk_list == 2) ide_set_irq(drive, 1); @@ -786,15 +804,11 @@ static void __ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, { ide_hwgroup_t *hwgroup = HWGROUP(drive); - if (hwgroup->handler != NULL) { - printk(KERN_CRIT "%s: ide_set_handler: handler not null; " - "old=%p, new=%p\n", - drive->name, hwgroup->handler, handler); - } + BUG_ON(hwgroup->handler); hwgroup->handler = handler; hwgroup->expiry = expiry; hwgroup->timer.expires = jiffies + timeout; - hwgroup->req_gen_timer = hwgroup->req_gen; + hwgroup->req_gen_timer = hwgroup->req_gen; add_timer(&hwgroup->timer); } @@ -827,13 +841,11 @@ void ide_execute_command(ide_drive_t *drive, u8 cmd, ide_handler_t *handler, unsigned timeout, ide_expiry_t *expiry) { unsigned long flags; - ide_hwgroup_t *hwgroup = HWGROUP(drive); ide_hwif_t *hwif = HWIF(drive); spin_lock_irqsave(&ide_lock, flags); - BUG_ON(hwgroup->handler); __ide_set_handler(drive, handler, timeout, expiry); - hwif->OUTBSYNC(drive, cmd, IDE_COMMAND_REG); + hwif->OUTBSYNC(drive, cmd, hwif->io_ports[IDE_COMMAND_OFFSET]); /* * Drive takes 400nS to respond, we must avoid the IRQ being * serviced before that. @@ -896,10 +908,11 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive) { ide_hwgroup_t *hwgroup = HWGROUP(drive); ide_hwif_t *hwif = HWIF(drive); + const struct ide_port_ops *port_ops = hwif->port_ops; u8 tmp; - if (hwif->reset_poll != NULL) { - if (hwif->reset_poll(drive)) { + if (port_ops && port_ops->reset_poll) { + if (port_ops->reset_poll(drive)) { printk(KERN_ERR "%s: host reset_poll failure for %s.\n", hwif->name, drive->name); return ide_stopped; @@ -965,6 +978,8 @@ static void ide_disk_pre_reset(ide_drive_t *drive) static void pre_reset(ide_drive_t *drive) { + const struct ide_port_ops *port_ops = drive->hwif->port_ops; + if (drive->media == ide_disk) ide_disk_pre_reset(drive); else @@ -985,8 +1000,8 @@ static void pre_reset(ide_drive_t *drive) return; } - if (HWIF(drive)->pre_reset != NULL) - HWIF(drive)->pre_reset(drive); + if (port_ops && port_ops->pre_reset) + port_ops->pre_reset(drive); if (drive->current_speed != 0xff) drive->desired_speed = drive->current_speed; @@ -1014,7 +1029,9 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) unsigned long flags; ide_hwif_t *hwif; ide_hwgroup_t *hwgroup; - + const struct ide_port_ops *port_ops; + u8 ctl; + spin_lock_irqsave(&ide_lock, flags); hwif = HWIF(drive); hwgroup = HWGROUP(drive); @@ -1028,7 +1045,8 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) pre_reset(drive); SELECT_DRIVE(drive); udelay (20); - hwif->OUTBSYNC(drive, WIN_SRST, IDE_COMMAND_REG); + hwif->OUTBSYNC(drive, WIN_SRST, + hwif->io_ports[IDE_COMMAND_OFFSET]); ndelay(400); hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; hwgroup->polling = 1; @@ -1044,7 +1062,7 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) for (unit = 0; unit < MAX_DRIVES; ++unit) pre_reset(&hwif->drives[unit]); - if (!IDE_CONTROL_REG) { + if (hwif->io_ports[IDE_CONTROL_OFFSET] == 0) { spin_unlock_irqrestore(&ide_lock, flags); return ide_stopped; } @@ -1059,16 +1077,14 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) * recover from reset very quickly, saving us the first 50ms wait time. */ /* set SRST and nIEN */ - hwif->OUTBSYNC(drive, drive->ctl|6,IDE_CONTROL_REG); + hwif->OUTBSYNC(drive, drive->ctl|6, hwif->io_ports[IDE_CONTROL_OFFSET]); /* more than enough time */ udelay(10); - if (drive->quirk_list == 2) { - /* clear SRST and nIEN */ - hwif->OUTBSYNC(drive, drive->ctl, IDE_CONTROL_REG); - } else { - /* clear SRST, leave nIEN */ - hwif->OUTBSYNC(drive, drive->ctl|2, IDE_CONTROL_REG); - } + 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]); /* more than enough time */ udelay(10); hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; @@ -1080,8 +1096,9 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) * state when the disks are reset this way. At least, the Winbond * 553 documentation says that */ - if (hwif->resetproc) - hwif->resetproc(drive); + port_ops = hwif->port_ops; + if (port_ops && port_ops->resetproc) + port_ops->resetproc(drive); spin_unlock_irqrestore(&ide_lock, flags); return ide_started;