diff options
Diffstat (limited to 'drivers/ide')
55 files changed, 1510 insertions, 995 deletions
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 6adf8649764..49234e32fd1 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -800,6 +800,14 @@ config BLK_DEV_IDEDMA_PMAC to transfer data to and from memory. Saying Y is safe and improves performance. +config BLK_DEV_IDE_CELLEB + bool "Toshiba's Cell Reference Set IDE support" + depends on PPC_CELLEB + help + This driver provides support for the built-in IDE controller on + Toshiba Cell Reference Board. + If unsure, say Y. + config BLK_DEV_IDE_SWARM tristate "IDE for Sibyte evaluation boards" depends on SIBYTE_SB1xxx_SOC diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index d9f029e8ff7..28feedfbd21 100644 --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile @@ -37,6 +37,7 @@ ide-core-$(CONFIG_BLK_DEV_Q40IDE) += legacy/q40ide.o # built-in only drivers from ppc/ ide-core-$(CONFIG_BLK_DEV_MPC8xx_IDE) += ppc/mpc8xx.o ide-core-$(CONFIG_BLK_DEV_IDE_PMAC) += ppc/pmac.o +ide-core-$(CONFIG_BLK_DEV_IDE_CELLEB) += ppc/scc_pata.o # built-in only drivers from h8300/ ide-core-$(CONFIG_H8300) += h8300/ide-h8300.o diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c index 8a1c27f2869..40e5c66b81c 100644 --- a/drivers/ide/arm/icside.c +++ b/drivers/ide/arm/icside.c @@ -307,26 +307,24 @@ static int icside_set_speed(ide_drive_t *drive, u8 xfer_mode) return on; } -static int icside_dma_host_off(ide_drive_t *drive) +static void icside_dma_host_off(ide_drive_t *drive) { - return 0; } -static int icside_dma_off_quietly(ide_drive_t *drive) +static void icside_dma_off_quietly(ide_drive_t *drive) { drive->using_dma = 0; - return icside_dma_host_off(drive); } -static int icside_dma_host_on(ide_drive_t *drive) +static void icside_dma_host_on(ide_drive_t *drive) { - return 0; } static int icside_dma_on(ide_drive_t *drive) { drive->using_dma = 1; - return icside_dma_host_on(drive); + + return 0; } static int icside_dma_check(ide_drive_t *drive) @@ -365,10 +363,7 @@ static int icside_dma_check(ide_drive_t *drive) out: on = icside_set_speed(drive, xfer_mode); - if (on) - return icside_dma_on(drive); - else - return icside_dma_off_quietly(drive); + return on ? 0 : -1; } static int icside_dma_end(ide_drive_t *drive) @@ -497,9 +492,9 @@ static void icside_dma_init(ide_hwif_t *hwif) hwif->autodma = autodma; hwif->ide_dma_check = icside_dma_check; - hwif->ide_dma_host_off = icside_dma_host_off; - hwif->ide_dma_off_quietly = icside_dma_off_quietly; - hwif->ide_dma_host_on = icside_dma_host_on; + hwif->dma_host_off = icside_dma_host_off; + hwif->dma_off_quietly = icside_dma_off_quietly; + hwif->dma_host_on = icside_dma_host_on; hwif->ide_dma_on = icside_dma_on; hwif->dma_setup = icside_dma_setup; hwif->dma_exec_cmd = icside_dma_exec_cmd; @@ -556,7 +551,7 @@ icside_setup(void __iomem *base, struct cardinfo *info, struct expansion_card *e * Ensure we're using MMIO */ default_hwif_mmiops(hwif); - hwif->mmio = 2; + hwif->mmio = 1; for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { hwif->hw.io_ports[i] = port; diff --git a/drivers/ide/arm/rapide.c b/drivers/ide/arm/rapide.c index 3058217767d..9c6c49fdd2b 100644 --- a/drivers/ide/arm/rapide.c +++ b/drivers/ide/arm/rapide.c @@ -46,7 +46,7 @@ rapide_locate_hwif(void __iomem *base, void __iomem *ctrl, unsigned int sz, int hwif->hw.io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl; hwif->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl; hwif->hw.irq = hwif->irq = irq; - hwif->mmio = 2; + hwif->mmio = 1; default_hwif_mmiops(hwif); return hwif; diff --git a/drivers/ide/cris/ide-cris.c b/drivers/ide/cris/ide-cris.c index 5797e0b5a13..6b2d152351b 100644 --- a/drivers/ide/cris/ide-cris.c +++ b/drivers/ide/cris/ide-cris.c @@ -682,9 +682,12 @@ static void cris_ide_input_data (ide_drive_t *drive, void *, unsigned int); static void cris_ide_output_data (ide_drive_t *drive, void *, unsigned int); static void cris_atapi_input_bytes(ide_drive_t *drive, void *, unsigned int); static void cris_atapi_output_bytes(ide_drive_t *drive, void *, unsigned int); -static int cris_dma_off (ide_drive_t *drive); static int cris_dma_on (ide_drive_t *drive); +static void cris_dma_off(ide_drive_t *drive) +{ +} + static void tune_cris_ide(ide_drive_t *drive, u8 pio) { int setup, strobe, hold; @@ -795,7 +798,7 @@ init_e100_ide (void) 0, 0, cris_ide_ack_intr, ide_default_irq(0)); ide_register_hw(&hw, &hwif); - hwif->mmio = 2; + hwif->mmio = 1; hwif->chipset = ide_etrax100; hwif->tuneproc = &tune_cris_ide; hwif->speedproc = &speed_cris_ide; @@ -814,13 +817,16 @@ init_e100_ide (void) hwif->OUTBSYNC = &cris_ide_outbsync; hwif->INB = &cris_ide_inb; hwif->INW = &cris_ide_inw; - hwif->ide_dma_host_off = &cris_dma_off; - hwif->ide_dma_host_on = &cris_dma_on; - hwif->ide_dma_off_quietly = &cris_dma_off; + hwif->dma_host_off = &cris_dma_off; + hwif->dma_host_on = &cris_dma_on; + hwif->dma_off_quietly = &cris_dma_off; hwif->udma_four = 0; hwif->ultra_mask = cris_ultra_mask; hwif->mwdma_mask = 0x07; /* Multiword DMA 0-2 */ hwif->swdma_mask = 0x07; /* Singleword DMA 0-2 */ + hwif->autodma = 1; + hwif->drives[0].autodma = 1; + hwif->drives[1].autodma = 1; } /* Reset pulse */ @@ -835,11 +841,6 @@ init_e100_ide (void) cris_ide_set_speed(TYPE_UDMA, ATA_UDMA2_CYC, ATA_UDMA2_DVS, 0); } -static int cris_dma_off (ide_drive_t *drive) -{ - return 0; -} - static int cris_dma_on (ide_drive_t *drive) { return 0; @@ -1045,17 +1046,10 @@ static ide_startstop_t cris_dma_intr (ide_drive_t *drive) static int cris_dma_check(ide_drive_t *drive) { - ide_hwif_t *hwif = drive->hwif; - struct hd_driveid* id = drive->id; - - if (id && (id->capability & 1)) { - if (ide_use_dma(drive)) { - if (cris_config_drive_for_dma(drive)) - return hwif->ide_dma_on(drive); - } - } + if (ide_use_dma(drive) && cris_config_drive_for_dma(drive)) + return 0; - return hwif->ide_dma_off_quietly(drive); + return -1; } static int cris_dma_end(ide_drive_t *drive) diff --git a/drivers/ide/h8300/ide-h8300.c b/drivers/ide/h8300/ide-h8300.c index 608ca871744..88750a30033 100644 --- a/drivers/ide/h8300/ide-h8300.c +++ b/drivers/ide/h8300/ide-h8300.c @@ -76,13 +76,11 @@ static inline void hwif_setup(ide_hwif_t *hwif) { default_hwif_iops(hwif); - hwif->mmio = 2; + hwif->mmio = 1; hwif->OUTW = mm_outw; hwif->OUTSW = mm_outsw; hwif->INW = mm_inw; hwif->INSW = mm_insw; - hwif->OUTL = NULL; - hwif->INL = NULL; hwif->OUTSL = NULL; hwif->INSL = NULL; } diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 5969cec58dc..45a928c058c 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -687,15 +687,8 @@ static void ide_dump_status_no_sense(ide_drive_t *drive, const char *msg, u8 sta static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) { struct request *rq = HWGROUP(drive)->rq; - ide_hwif_t *hwif = HWIF(drive); int stat, err, sense_key; - /* We may have bogus DMA interrupts in PIO state here */ - if (HWIF(drive)->dma_status && hwif->atapi_irq_bogon) { - stat = hwif->INB(hwif->dma_status); - /* Should we force the bit as well ? */ - hwif->OUTB(stat, hwif->dma_status); - } /* Check for errors. */ stat = HWIF(drive)->INB(IDE_STATUS_REG); if (stat_ret) @@ -930,6 +923,10 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive, HWIF(drive)->OUTB(drive->ctl, IDE_CONTROL_REG); if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) { + /* waiting for CDB interrupt, not DMA yet. */ + if (info->dma) + drive->waiting_for_dma = 0; + /* packet command */ ide_execute_command(drive, WIN_PACKETCMD, handler, ATAPI_WAIT_PC, cdrom_timer_expiry); return ide_started; @@ -972,6 +969,10 @@ static ide_startstop_t cdrom_transfer_packet_command (ide_drive_t *drive, /* Check for errors. */ if (cdrom_decode_status(drive, DRQ_STAT, NULL)) return ide_stopped; + + /* Ok, next interrupt will be DMA interrupt. */ + if (info->dma) + drive->waiting_for_dma = 1; } else { /* Otherwise, we must wait for DRQ to get set. */ if (ide_wait_stat(&startstop, drive, DRQ_STAT, @@ -1103,7 +1104,7 @@ static ide_startstop_t cdrom_read_intr (ide_drive_t *drive) if (dma) { info->dma = 0; if ((dma_error = HWIF(drive)->ide_dma_end(drive))) - __ide_dma_off(drive); + ide_dma_off(drive); } if (cdrom_decode_status(drive, 0, &stat)) @@ -1699,7 +1700,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) if (dma) { if (dma_error) { printk(KERN_ERR "ide-cd: dma error\n"); - __ide_dma_off(drive); + ide_dma_off(drive); return ide_error(drive, "dma error", stat); } @@ -1825,7 +1826,7 @@ static ide_startstop_t cdrom_write_intr(ide_drive_t *drive) info->dma = 0; if ((dma_error = HWIF(drive)->ide_dma_end(drive))) { printk(KERN_ERR "ide-cd: write dma error\n"); - __ide_dma_off(drive); + ide_dma_off(drive); } } @@ -3254,14 +3255,6 @@ int ide_cdrom_setup (ide_drive_t *drive) if (drive->autotune == IDE_TUNE_DEFAULT || drive->autotune == IDE_TUNE_AUTO) drive->dsc_overlap = (drive->next != drive); -#if 0 - drive->dsc_overlap = (HWIF(drive)->no_dsc) ? 0 : 1; - if (HWIF(drive)->no_dsc) { - printk(KERN_INFO "ide-cd: %s: disabling DSC overlap\n", - drive->name); - drive->dsc_overlap = 0; - } -#endif if (ide_cdrom_register(drive, nslots)) { printk (KERN_ERR "%s: ide_cdrom_setup failed to register device with the cdrom driver.\n", drive->name); @@ -3360,21 +3353,16 @@ static int idecd_open(struct inode * inode, struct file * file) { struct gendisk *disk = inode->i_bdev->bd_disk; struct cdrom_info *info; - ide_drive_t *drive; int rc = -ENOMEM; if (!(info = ide_cd_get(disk))) return -ENXIO; - drive = info->drive; - - drive->usage++; - if (!info->buffer) - info->buffer = kmalloc(SECTOR_BUFFER_SIZE, - GFP_KERNEL|__GFP_REPEAT); - if (!info->buffer || (rc = cdrom_open(&info->devinfo, inode, file))) - drive->usage--; + info->buffer = kmalloc(SECTOR_BUFFER_SIZE, GFP_KERNEL|__GFP_REPEAT); + + if (info->buffer) + rc = cdrom_open(&info->devinfo, inode, file); if (rc < 0) ide_cd_put(info); @@ -3386,10 +3374,8 @@ static int idecd_release(struct inode * inode, struct file * file) { struct gendisk *disk = inode->i_bdev->bd_disk; struct cdrom_info *info = ide_cd_g(disk); - ide_drive_t *drive = info->drive; cdrom_release (&info->devinfo, file); - drive->usage--; ide_cd_put(info); diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 0a05a377d66..e2cea1889c4 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -77,6 +77,7 @@ struct ide_disk_obj { ide_driver_t *driver; struct gendisk *disk; struct kref kref; + unsigned int openers; /* protected by BKL for now */ }; static DEFINE_MUTEX(idedisk_ref_mutex); @@ -1081,8 +1082,9 @@ static int idedisk_open(struct inode *inode, struct file *filp) drive = idkp->drive; - drive->usage++; - if (drive->removable && drive->usage == 1) { + idkp->openers++; + + if (drive->removable && idkp->openers == 1) { ide_task_t args; memset(&args, 0, sizeof(ide_task_t)); args.tfRegister[IDE_COMMAND_OFFSET] = WIN_DOORLOCK; @@ -1106,9 +1108,10 @@ static int idedisk_release(struct inode *inode, struct file *filp) struct ide_disk_obj *idkp = ide_disk_g(disk); ide_drive_t *drive = idkp->drive; - if (drive->usage == 1) + if (idkp->openers == 1) ide_cacheflush_p(drive); - if (drive->removable && drive->usage == 1) { + + if (drive->removable && idkp->openers == 1) { ide_task_t args; memset(&args, 0, sizeof(ide_task_t)); args.tfRegister[IDE_COMMAND_OFFSET] = WIN_DOORUNLOCK; @@ -1117,7 +1120,8 @@ static int idedisk_release(struct inode *inode, struct file *filp) if (drive->doorlocking && ide_raw_taskfile(drive, &args, NULL)) drive->doorlocking = 0; } - drive->usage--; + + idkp->openers--; ide_disk_put(idkp); diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 56efed6742d..08e7cd043bc 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -348,15 +348,14 @@ EXPORT_SYMBOL_GPL(ide_destroy_dmatable); static int config_drive_for_dma (ide_drive_t *drive) { struct hd_driveid *id = drive->id; - ide_hwif_t *hwif = HWIF(drive); - if ((id->capability & 1) && hwif->autodma) { + if ((id->capability & 1) && drive->hwif->autodma) { /* * Enable DMA on any drive that has * UltraDMA (mode 0/1/2/3/4/5/6) enabled */ if ((id->field_valid & 4) && ((id->dma_ultra >> 8) & 0x7f)) - return hwif->ide_dma_on(drive); + return 0; /* * Enable DMA on any drive that has mode2 DMA * (multi or single) enabled @@ -364,14 +363,14 @@ static int config_drive_for_dma (ide_drive_t *drive) if (id->field_valid & 2) /* regular DMA */ if ((id->dma_mword & 0x404) == 0x404 || (id->dma_1word & 0x404) == 0x404) - return hwif->ide_dma_on(drive); + return 0; /* Consult the list of known "good" drives */ if (__ide_dma_good_drive(drive)) - return hwif->ide_dma_on(drive); + return 0; } -// if (hwif->tuneproc != NULL) hwif->tuneproc(drive, 255); - return hwif->ide_dma_off_quietly(drive); + + return -1; } /** @@ -415,72 +414,68 @@ static int dma_timer_expiry (ide_drive_t *drive) } /** - * __ide_dma_host_off - Generic DMA kill + * ide_dma_host_off - Generic DMA kill * @drive: drive to control * * Perform the generic IDE controller DMA off operation. This * works for most IDE bus mastering controllers */ -int __ide_dma_host_off (ide_drive_t *drive) +void ide_dma_host_off(ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); u8 unit = (drive->select.b.unit & 0x01); u8 dma_stat = hwif->INB(hwif->dma_status); hwif->OUTB((dma_stat & ~(1<<(5+unit))), hwif->dma_status); - return 0; } -EXPORT_SYMBOL(__ide_dma_host_off); +EXPORT_SYMBOL(ide_dma_host_off); /** - * __ide_dma_host_off_quietly - Generic DMA kill + * ide_dma_off_quietly - Generic DMA kill * @drive: drive to control * * Turn off the current DMA on this IDE controller. */ -int __ide_dma_off_quietly (ide_drive_t *drive) +void ide_dma_off_quietly(ide_drive_t *drive) { drive->using_dma = 0; ide_toggle_bounce(drive, 0); - if (HWIF(drive)->ide_dma_host_off(drive)) - return 1; - - return 0; + drive->hwif->dma_host_off(drive); } -EXPORT_SYMBOL(__ide_dma_off_quietly); +EXPORT_SYMBOL(ide_dma_off_quietly); #endif /* CONFIG_BLK_DEV_IDEDMA_PCI */ /** - * __ide_dma_off - disable DMA on a device + * ide_dma_off - disable DMA on a device * @drive: drive to disable DMA on * * Disable IDE DMA for a device on this IDE controller. * Inform the user that DMA has been disabled. */ -int __ide_dma_off (ide_drive_t *drive) +void ide_dma_off(ide_drive_t *drive) { printk(KERN_INFO "%s: DMA disabled\n", drive->name); - return HWIF(drive)->ide_dma_off_quietly(drive); + drive->hwif->dma_off_quietly(drive); } -EXPORT_SYMBOL(__ide_dma_off); +EXPORT_SYMBOL(ide_dma_off); #ifdef CONFIG_BLK_DEV_IDEDMA_PCI /** - * __ide_dma_host_on - Enable DMA on a host + * ide_dma_host_on - Enable DMA on a host * @drive: drive to enable for DMA * * Enable DMA on an IDE controller following generic bus mastering * IDE controller behaviour */ - -int __ide_dma_host_on (ide_drive_t *drive) + +void ide_dma_host_on(ide_drive_t *drive) { if (drive->using_dma) { ide_hwif_t *hwif = HWIF(drive); @@ -488,12 +483,10 @@ int __ide_dma_host_on (ide_drive_t *drive) u8 dma_stat = hwif->INB(hwif->dma_status); hwif->OUTB((dma_stat|(1<<(5+unit))), hwif->dma_status); - return 0; } - return 1; } -EXPORT_SYMBOL(__ide_dma_host_on); +EXPORT_SYMBOL(ide_dma_host_on); /** * __ide_dma_on - Enable DMA on a device @@ -511,8 +504,7 @@ int __ide_dma_on (ide_drive_t *drive) drive->using_dma = 1; ide_toggle_bounce(drive, 1); - if (HWIF(drive)->ide_dma_host_on(drive)) - return 1; + drive->hwif->dma_host_on(drive); return 0; } @@ -565,7 +557,10 @@ int ide_dma_setup(ide_drive_t *drive) } /* PRD table */ - hwif->OUTL(hwif->dmatable_dma, hwif->dma_prdtable); + if (hwif->mmio) + writel(hwif->dmatable_dma, (void __iomem *)hwif->dma_prdtable); + else + outl(hwif->dmatable_dma, hwif->dma_prdtable); /* specify r/w */ hwif->OUTB(reading, hwif->dma_command); @@ -680,6 +675,9 @@ int ide_use_dma(ide_drive_t *drive) struct hd_driveid *id = drive->id; ide_hwif_t *hwif = drive->hwif; + if ((id->capability & 1) == 0 || drive->autodma == 0) + return 0; + /* consult the list of known "bad" drives */ if (__ide_dma_bad_drive(drive)) return 0; @@ -753,12 +751,37 @@ void ide_dma_verbose(ide_drive_t *drive) return; bug_dma_off: printk(", BUG DMA OFF"); - hwif->ide_dma_off_quietly(drive); + hwif->dma_off_quietly(drive); return; } EXPORT_SYMBOL(ide_dma_verbose); +int ide_set_dma(ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + int rc; + + rc = hwif->ide_dma_check(drive); + + switch(rc) { + case -1: /* DMA needs to be disabled */ + hwif->dma_off_quietly(drive); + return 0; + case 0: /* DMA needs to be enabled */ + return hwif->ide_dma_on(drive); + case 1: /* DMA setting cannot be changed */ + break; + default: + BUG(); + break; + } + + return rc; +} + +EXPORT_SYMBOL_GPL(ide_set_dma); + #ifdef CONFIG_BLK_DEV_IDEDMA_PCI int __ide_dma_lostirq (ide_drive_t *drive) { @@ -809,7 +832,7 @@ int ide_release_dma(ide_hwif_t *hwif) { ide_release_dma_engine(hwif); - if (hwif->mmio == 2) + if (hwif->mmio) return 1; else return ide_release_iomio_dma(hwif); @@ -878,9 +901,9 @@ static int ide_iomio_dma(ide_hwif_t *hwif, unsigned long base, unsigned int port static int ide_dma_iobase(ide_hwif_t *hwif, unsigned long base, unsigned int ports) { - if (hwif->mmio == 2) + if (hwif->mmio) return ide_mapped_mmio_dma(hwif, base,ports); - BUG_ON(hwif->mmio == 1); + return ide_iomio_dma(hwif, base, ports); } @@ -908,14 +931,14 @@ void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_p if (!(hwif->dma_prdtable)) hwif->dma_prdtable = (hwif->dma_base + 4); - if (!hwif->ide_dma_off_quietly) - hwif->ide_dma_off_quietly = &__ide_dma_off_quietly; - if (!hwif->ide_dma_host_off) - hwif->ide_dma_host_off = &__ide_dma_host_off; + if (!hwif->dma_off_quietly) + hwif->dma_off_quietly = &ide_dma_off_quietly; + if (!hwif->dma_host_off) + hwif->dma_host_off = &ide_dma_host_off; if (!hwif->ide_dma_on) hwif->ide_dma_on = &__ide_dma_on; - if (!hwif->ide_dma_host_on) - hwif->ide_dma_host_on = &__ide_dma_host_on; + if (!hwif->dma_host_on) + hwif->dma_host_on = &ide_dma_host_on; if (!hwif->ide_dma_check) hwif->ide_dma_check = &__ide_dma_check; if (!hwif->dma_setup) diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index d33717c8afd..57cd21c5b2c 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -279,6 +279,7 @@ typedef struct ide_floppy_obj { ide_driver_t *driver; struct gendisk *disk; struct kref kref; + unsigned int openers; /* protected by BKL for now */ /* Current packet command */ idefloppy_pc_t *pc; @@ -866,7 +867,7 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive) if (test_and_clear_bit(PC_DMA_IN_PROGRESS, &pc->flags)) { printk(KERN_ERR "ide-floppy: The floppy wants to issue " "more interrupts in DMA mode\n"); - (void)__ide_dma_off(drive); + ide_dma_off(drive); return ide_do_reset(drive); } @@ -1096,9 +1097,9 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p pc->current_position = pc->buffer; bcount.all = min(pc->request_transfer, 63 * 1024); - if (test_and_clear_bit(PC_DMA_ERROR, &pc->flags)) { - (void)__ide_dma_off(drive); - } + if (test_and_clear_bit(PC_DMA_ERROR, &pc->flags)) + ide_dma_off(drive); + feature.all = 0; if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma) @@ -1433,7 +1434,8 @@ static int idefloppy_get_capacity (ide_drive_t *drive) drive->bios_cyl = 0; drive->bios_head = drive->bios_sect = 0; - floppy->blocks = floppy->bs_factor = 0; + floppy->blocks = 0; + floppy->bs_factor = 1; set_capacity(floppy->disk, 0); idefloppy_create_read_capacity_cmd(&pc); @@ -1949,9 +1951,9 @@ static int idefloppy_open(struct inode *inode, struct file *filp) drive = floppy->drive; - drive->usage++; + floppy->openers++; - if (drive->usage == 1) { + if (floppy->openers == 1) { clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags); /* Just in case */ @@ -1969,13 +1971,11 @@ static int idefloppy_open(struct inode *inode, struct file *filp) ** capacity of the drive or begin the format - Sam */ ) { - drive->usage--; ret = -EIO; goto out_put_floppy; } if (floppy->wp && (filp->f_mode & 2)) { - drive->usage--; ret = -EROFS; goto out_put_floppy; } @@ -1987,13 +1987,13 @@ static int idefloppy_open(struct inode *inode, struct file *filp) } check_disk_change(inode->i_bdev); } else if (test_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags)) { - drive->usage--; ret = -EBUSY; goto out_put_floppy; } return 0; out_put_floppy: + floppy->openers--; ide_floppy_put(floppy); return ret; } @@ -2007,7 +2007,7 @@ static int idefloppy_release(struct inode *inode, struct file *filp) debug_log(KERN_INFO "Reached idefloppy_release\n"); - if (drive->usage == 1) { + if (floppy->openers == 1) { /* IOMEGA Clik! drives do not support lock/unlock commands */ if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags)) { idefloppy_create_prevent_cmd(&pc, 0); @@ -2016,7 +2016,8 @@ static int idefloppy_release(struct inode *inode, struct file *filp) clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags); } - drive->usage--; + + floppy->openers--; ide_floppy_put(floppy); @@ -2050,7 +2051,7 @@ static int idefloppy_ioctl(struct inode *inode, struct file *file, prevent = 0; /* fall through */ case CDROM_LOCKDOOR: - if (drive->usage > 1) + if (floppy->openers > 1) return -EBUSY; /* The IOMEGA Clik! Drive doesn't support this command - no room for an eject mechanism */ @@ -2072,7 +2073,7 @@ static int idefloppy_ioctl(struct inode *inode, struct file *file, if (!(file->f_mode & 2)) return -EPERM; - if (drive->usage > 1) { + if (floppy->openers > 1) { /* Don't format if someone is using the disk */ clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 2614f41b507..c193553f6fe 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -226,7 +226,7 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request * break; if (drive->hwif->ide_dma_check == NULL) break; - drive->hwif->ide_dma_check(drive); + ide_set_dma(drive); break; } pm->pm_step = ide_pm_state_completed; @@ -1351,7 +1351,7 @@ static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error) */ drive->retry_pio++; drive->state = DMA_PIO_RETRY; - (void) hwif->ide_dma_off_quietly(drive); + hwif->dma_off_quietly(drive); /* * un-busy drive etc (hwgroup->busy is cleared on return) and @@ -1646,6 +1646,17 @@ irqreturn_t ide_intr (int irq, void *dev_id) del_timer(&hwgroup->timer); spin_unlock(&ide_lock); + /* Some controllers might set DMA INTR no matter DMA or PIO; + * bmdma status might need to be cleared even for + * PIO interrupts to prevent spurious/lost irq. + */ + if (hwif->ide_dma_clear_irq && !(drive->waiting_for_dma)) + /* ide_dma_end() needs bmdma status for error checking. + * So, skip clearing bmdma status here and leave it + * to ide_dma_end() if this is dma interrupt. + */ + hwif->ide_dma_clear_irq(drive); + if (drive->unmask) local_irq_enable_in_hardirq(); /* service this interrupt, may set handler for next interrupt */ diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index badde633177..c67b3b1e6f4 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -49,11 +49,6 @@ static void ide_insw (unsigned long port, void *addr, u32 count) insw(port, addr, count); } -static u32 ide_inl (unsigned long port) -{ - return (u32) inl(port); -} - static void ide_insl (unsigned long port, void *addr, u32 count) { insl(port, addr, count); @@ -79,11 +74,6 @@ static void ide_outsw (unsigned long port, void *addr, u32 count) outsw(port, addr, count); } -static void ide_outl (u32 val, unsigned long port) -{ - outl(val, port); -} - static void ide_outsl (unsigned long port, void *addr, u32 count) { outsl(port, addr, count); @@ -94,12 +84,10 @@ void default_hwif_iops (ide_hwif_t *hwif) hwif->OUTB = ide_outb; hwif->OUTBSYNC = ide_outbsync; hwif->OUTW = ide_outw; - hwif->OUTL = ide_outl; hwif->OUTSW = ide_outsw; hwif->OUTSL = ide_outsl; hwif->INB = ide_inb; hwif->INW = ide_inw; - hwif->INL = ide_inl; hwif->INSW = ide_insw; hwif->INSL = ide_insl; } @@ -123,11 +111,6 @@ static void ide_mm_insw (unsigned long port, void *addr, u32 count) __ide_mm_insw((void __iomem *) port, addr, count); } -static u32 ide_mm_inl (unsigned long port) -{ - return (u32) readl((void __iomem *) port); -} - static void ide_mm_insl (unsigned long port, void *addr, u32 count) { __ide_mm_insl((void __iomem *) port, addr, count); @@ -153,11 +136,6 @@ static void ide_mm_outsw (unsigned long port, void *addr, u32 count) __ide_mm_outsw((void __iomem *) port, addr, count); } -static void ide_mm_outl (u32 value, unsigned long port) -{ - writel(value, (void __iomem *) port); -} - static void ide_mm_outsl (unsigned long port, void *addr, u32 count) { __ide_mm_outsl((void __iomem *) port, addr, count); @@ -170,12 +148,10 @@ void default_hwif_mmiops (ide_hwif_t *hwif) this one is controller specific! */ hwif->OUTBSYNC = ide_mm_outbsync; hwif->OUTW = ide_mm_outw; - hwif->OUTL = ide_mm_outl; hwif->OUTSW = ide_mm_outsw; hwif->OUTSL = ide_mm_outsl; hwif->INB = ide_mm_inb; hwif->INW = ide_mm_inw; - hwif->INL = ide_mm_inl; hwif->INSW = ide_mm_insw; hwif->INSL = ide_mm_insl; } @@ -777,7 +753,7 @@ int ide_config_drive_speed (ide_drive_t *drive, u8 speed) #ifdef CONFIG_BLK_DEV_IDEDMA if (hwif->ide_dma_check) /* check if host supports DMA */ - hwif->ide_dma_host_off(drive); + hwif->dma_host_off(drive); #endif /* @@ -854,9 +830,9 @@ int ide_config_drive_speed (ide_drive_t *drive, u8 speed) #ifdef CONFIG_BLK_DEV_IDEDMA if (speed >= XFER_SW_DMA_0) - hwif->ide_dma_host_on(drive); + hwif->dma_host_on(drive); else if (hwif->ide_dma_check) /* check if host supports DMA */ - hwif->ide_dma_off_quietly(drive); + hwif->dma_off_quietly(drive); #endif switch(speed) { @@ -1066,12 +1042,12 @@ static void check_dma_crc(ide_drive_t *drive) { #ifdef CONFIG_BLK_DEV_IDEDMA if (drive->crc_count) { - (void) HWIF(drive)->ide_dma_off_quietly(drive); + drive->hwif->dma_off_quietly(drive); ide_set_xfer_rate(drive, ide_auto_reduce_xfer(drive)); if (drive->current_speed >= XFER_SW_DMA_0) (void) HWIF(drive)->ide_dma_on(drive); } else - (void)__ide_dma_off(drive); + ide_dma_off(drive); #endif } diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index 8237d89eec6..8afce4ceea3 100644 --- a/drivers/ide/ide-lib.c +++ b/drivers/ide/ide-lib.c @@ -205,6 +205,21 @@ int ide_dma_enable (ide_drive_t *drive) EXPORT_SYMBOL(ide_dma_enable); +int ide_use_fast_pio(ide_drive_t *drive) +{ + struct hd_driveid *id = drive->id; + + if ((id->capability & 1) && drive->autodma) + return 1; + + if ((id->capability & 8) || (id->field_valid & 2)) + return 1; + + return 0; +} + +EXPORT_SYMBOL_GPL(ide_use_fast_pio); + /* * Standard (generic) timings for PIO modes, from ATA2 specification. * These timings are for access to the IDE data port register *only*. @@ -349,7 +364,6 @@ u8 ide_get_best_pio_mode (ide_drive_t *drive, u8 mode_wanted, u8 max_mode, ide_p int use_iordy = 0; struct hd_driveid* id = drive->id; int overridden = 0; - int blacklisted = 0; if (mode_wanted != 255) { pio_mode = mode_wanted; @@ -357,7 +371,6 @@ u8 ide_get_best_pio_mode (ide_drive_t *drive, u8 mode_wanted, u8 max_mode, ide_p pio_mode = 0; } else if ((pio_mode = ide_scan_pio_blacklist(id->model)) != -1) { overridden = 1; - blacklisted = 1; use_iordy = (pio_mode > 2); } else { pio_mode = id->tPIO; @@ -409,7 +422,6 @@ u8 ide_get_best_pio_mode (ide_drive_t *drive, u8 mode_wanted, u8 max_mode, ide_p d->cycle_time = cycle_time ? cycle_time : ide_pio_timings[pio_mode].cycle_time; d->use_iordy = use_iordy; d->overridden = overridden; - d->blacklisted = blacklisted; } return pio_mode; } @@ -462,8 +474,6 @@ int ide_set_xfer_rate(ide_drive_t *drive, u8 rate) return -1; } -EXPORT_SYMBOL_GPL(ide_set_xfer_rate); - static void ide_dump_opcode(ide_drive_t *drive) { struct request *rq; diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 176bbc850d6..8afbd6cb94b 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -853,11 +853,11 @@ static void probe_hwif(ide_hwif_t *hwif) * things, if not checked and cleared. * PARANOIA!!! */ - hwif->ide_dma_off_quietly(drive); + hwif->dma_off_quietly(drive); #ifdef CONFIG_IDEDMA_ONLYDISK if (drive->media == ide_disk) #endif - hwif->ide_dma_check(drive); + ide_set_dma(drive); } } } diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index c6eec0413a6..4e59239fef7 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -1970,7 +1970,7 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive) printk(KERN_ERR "ide-tape: The tape wants to issue more " "interrupts in DMA mode\n"); printk(KERN_ERR "ide-tape: DMA disabled, reverting to PIO\n"); - (void)__ide_dma_off(drive); + ide_dma_off(drive); return ide_do_reset(drive); } /* Get the number of bytes to transfer on this interrupt. */ @@ -2176,7 +2176,7 @@ static ide_startstop_t idetape_issue_packet_command (ide_drive_t *drive, idetape if (test_and_clear_bit(PC_DMA_ERROR, &pc->flags)) { printk(KERN_WARNING "ide-tape: DMA disabled, " "reverting to PIO\n"); - (void)__ide_dma_off(drive); + ide_dma_off(drive); } if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma) dma_ok = !hwif->dma_setup(drive); @@ -4792,15 +4792,10 @@ static int idetape_open(struct inode *inode, struct file *filp) { struct gendisk *disk = inode->i_bdev->bd_disk; struct ide_tape_obj *tape; - ide_drive_t *drive; if (!(tape = ide_tape_get(disk))) return -ENXIO; - drive = tape->drive; - - drive->usage++; - return 0; } @@ -4808,9 +4803,6 @@ static int idetape_release(struct inode *inode, struct file *filp) { struct gendisk *disk = inode->i_bdev->bd_disk; struct ide_tape_obj *tape = ide_tape_g(disk); - ide_drive_t *drive = tape->drive; - - drive->usage--; ide_tape_put(tape); diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index c750f6ce770..b3c0818c5c6 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -389,9 +389,8 @@ int ide_hwif_request_regions(ide_hwif_t *hwif) unsigned long addr; unsigned int i; - if (hwif->mmio == 2) + if (hwif->mmio) return 0; - BUG_ON(hwif->mmio == 1); addr = hwif->io_ports[IDE_CONTROL_OFFSET]; if (addr && !hwif_request_region(hwif, addr, 1)) goto control_region_busy; @@ -438,7 +437,7 @@ void ide_hwif_release_regions(ide_hwif_t *hwif) { u32 i = 0; - if (hwif->mmio == 2) + if (hwif->mmio) return; if (hwif->io_ports[IDE_CONTROL_OFFSET]) release_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1); @@ -507,23 +506,22 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif) hwif->ide_dma_end = tmp_hwif->ide_dma_end; hwif->ide_dma_check = tmp_hwif->ide_dma_check; hwif->ide_dma_on = tmp_hwif->ide_dma_on; - hwif->ide_dma_off_quietly = tmp_hwif->ide_dma_off_quietly; + hwif->dma_off_quietly = tmp_hwif->dma_off_quietly; hwif->ide_dma_test_irq = tmp_hwif->ide_dma_test_irq; - hwif->ide_dma_host_on = tmp_hwif->ide_dma_host_on; - hwif->ide_dma_host_off = tmp_hwif->ide_dma_host_off; + hwif->ide_dma_clear_irq = tmp_hwif->ide_dma_clear_irq; + hwif->dma_host_on = tmp_hwif->dma_host_on; + hwif->dma_host_off = tmp_hwif->dma_host_off; hwif->ide_dma_lostirq = tmp_hwif->ide_dma_lostirq; hwif->ide_dma_timeout = tmp_hwif->ide_dma_timeout; hwif->OUTB = tmp_hwif->OUTB; hwif->OUTBSYNC = tmp_hwif->OUTBSYNC; hwif->OUTW = tmp_hwif->OUTW; - hwif->OUTL = tmp_hwif->OUTL; hwif->OUTSW = tmp_hwif->OUTSW; hwif->OUTSL = tmp_hwif->OUTSL; hwif->INB = tmp_hwif->INB; hwif->INW = tmp_hwif->INW; - hwif->INL = tmp_hwif->INL; hwif->INSW = tmp_hwif->INSW; hwif->INSL = tmp_hwif->INSL; @@ -551,7 +549,6 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif) hwif->extra_ports = tmp_hwif->extra_ports; hwif->autodma = tmp_hwif->autodma; hwif->udma_four = tmp_hwif->udma_four; - hwif->no_dsc = tmp_hwif->no_dsc; hwif->hwif_data = tmp_hwif->hwif_data; } @@ -1138,12 +1135,11 @@ static int set_using_dma (ide_drive_t *drive, int arg) if (HWIF(drive)->ide_dma_check == NULL) return -EPERM; if (arg) { - if (HWIF(drive)->ide_dma_check(drive)) return -EIO; - if (HWIF(drive)->ide_dma_on(drive)) return -EIO; - } else { - if (__ide_dma_off(drive)) + if (ide_set_dma(drive)) return -EIO; - } + if (HWIF(drive)->ide_dma_on(drive)) return -EIO; + } else + ide_dma_off(drive); return 0; #else return -EPERM; diff --git a/drivers/ide/legacy/buddha.c b/drivers/ide/legacy/buddha.c index 0391a312287..1ed224a01f7 100644 --- a/drivers/ide/legacy/buddha.c +++ b/drivers/ide/legacy/buddha.c @@ -215,7 +215,7 @@ fail_base2: index = ide_register_hw(&hw, &hwif); if (index != -1) { - hwif->mmio = 2; + hwif->mmio = 1; printk("ide%d: ", index); switch(type) { case BOARD_BUDDHA: diff --git a/drivers/ide/legacy/gayle.c b/drivers/ide/legacy/gayle.c index 64d42619ab0..dcfadbbf55d 100644 --- a/drivers/ide/legacy/gayle.c +++ b/drivers/ide/legacy/gayle.c @@ -167,7 +167,7 @@ found: index = ide_register_hw(&hw, &hwif); if (index != -1) { - hwif->mmio = 2; + hwif->mmio = 1; switch (i) { case 0: printk("ide%d: Gayle IDE interface (A%d style)\n", index, diff --git a/drivers/ide/legacy/ht6560b.c b/drivers/ide/legacy/ht6560b.c index c48e87e512d..19ccd006f20 100644 --- a/drivers/ide/legacy/ht6560b.c +++ b/drivers/ide/legacy/ht6560b.c @@ -143,16 +143,16 @@ static void ht6560b_selectproc (ide_drive_t *drive) current_timing = timing; if (drive->media != ide_disk || !drive->present) select |= HT_PREFETCH_MODE; - (void) HWIF(drive)->INB(HT_CONFIG_PORT); - (void) HWIF(drive)->INB(HT_CONFIG_PORT); - (void) HWIF(drive)->INB(HT_CONFIG_PORT); - (void) HWIF(drive)->INB(HT_CONFIG_PORT); - HWIF(drive)->OUTB(select, HT_CONFIG_PORT); + (void)inb(HT_CONFIG_PORT); + (void)inb(HT_CONFIG_PORT); + (void)inb(HT_CONFIG_PORT); + (void)inb(HT_CONFIG_PORT); + outb(select, HT_CONFIG_PORT); /* * Set timing for this drive: */ - HWIF(drive)->OUTB(timing, IDE_SELECT_REG); - (void) HWIF(drive)->INB(IDE_STATUS_REG); + outb(timing, IDE_SELECT_REG); + (void)inb(IDE_STATUS_REG); #ifdef DEBUG printk("ht6560b: %s: select=%#x timing=%#x\n", drive->name, select, timing); diff --git a/drivers/ide/legacy/macide.c b/drivers/ide/legacy/macide.c index b1730d7e414..4c0079ad52a 100644 --- a/drivers/ide/legacy/macide.c +++ b/drivers/ide/legacy/macide.c @@ -141,7 +141,7 @@ void macide_init(void) } if (index != -1) { - hwif->mmio = 2; + hwif->mmio = 1; if (macintosh_config->ide_type == MAC_IDE_QUADRA) printk(KERN_INFO "ide%d: Macintosh Quadra IDE interface\n", index); else if (macintosh_config->ide_type == MAC_IDE_PB) diff --git a/drivers/ide/legacy/q40ide.c b/drivers/ide/legacy/q40ide.c index 434a94faa3b..74f08124eab 100644 --- a/drivers/ide/legacy/q40ide.c +++ b/drivers/ide/legacy/q40ide.c @@ -145,7 +145,7 @@ void q40ide_init(void) index = ide_register_hw(&hw, &hwif); // **FIXME** if (index != -1) - hwif->mmio = 2; + hwif->mmio = 1; } } diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c index c7854ea57b5..0a59d5ef159 100644 --- a/drivers/ide/mips/au1xxx-ide.c +++ b/drivers/ide/mips/au1xxx-ide.c @@ -181,12 +181,6 @@ static int auide_tune_chipset (ide_drive_t *drive, u8 speed) { int mem_sttime; int mem_stcfg; - unsigned long mode; - -#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA - if (ide_use_dma(drive)) - mode = ide_dma_speed(drive, 0); -#endif mem_sttime = 0; mem_stcfg = au_readl(MEM_STCFG2); @@ -195,7 +189,7 @@ static int auide_tune_chipset (ide_drive_t *drive, u8 speed) auide_tune_drive(drive, speed - XFER_PIO_0); return 0; } - + switch(speed) { #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA case XFER_MW_DMA_2: @@ -207,7 +201,6 @@ static int auide_tune_chipset (ide_drive_t *drive, u8 speed) mem_stcfg &= ~TOECS_MASK; mem_stcfg |= SBC_IDE_MDMA2_TCSOE | SBC_IDE_MDMA2_TOECS; - mode = XFER_MW_DMA_2; break; case XFER_MW_DMA_1: mem_sttime = SBC_IDE_TIMING(MDMA1); @@ -218,7 +211,6 @@ static int auide_tune_chipset (ide_drive_t *drive, u8 speed) mem_stcfg &= ~TOECS_MASK; mem_stcfg |= SBC_IDE_MDMA1_TCSOE | SBC_IDE_MDMA1_TOECS; - mode = XFER_MW_DMA_1; break; case XFER_MW_DMA_0: mem_sttime = SBC_IDE_TIMING(MDMA0); @@ -229,14 +221,13 @@ static int auide_tune_chipset (ide_drive_t *drive, u8 speed) mem_stcfg &= ~TOECS_MASK; mem_stcfg |= SBC_IDE_MDMA0_TCSOE | SBC_IDE_MDMA0_TOECS; - mode = XFER_MW_DMA_0; break; #endif default: return 1; } - - if (ide_config_drive_speed(drive, mode)) + + if (ide_config_drive_speed(drive, speed)) return 1; au_writel(mem_sttime,MEM_STTIME2); @@ -423,9 +414,9 @@ static int auide_dma_check(ide_drive_t *drive) speed = ide_find_best_mode(drive, XFER_PIO | XFER_MWDMA); if (drive->autodma && (speed & XFER_MODE) != XFER_PIO) - return HWIF(drive)->ide_dma_on(drive); + return 0; - return HWIF(drive)->ide_dma_off_quietly(drive); + return -1; } static int auide_dma_test_irq(ide_drive_t *drive) @@ -447,27 +438,24 @@ static int auide_dma_test_irq(ide_drive_t *drive) return 0; } -static int auide_dma_host_on(ide_drive_t *drive) +static void auide_dma_host_on(ide_drive_t *drive) { - return 0; } static int auide_dma_on(ide_drive_t *drive) { drive->using_dma = 1; - return auide_dma_host_on(drive); -} + return 0; +} -static int auide_dma_host_off(ide_drive_t *drive) +static void auide_dma_host_off(ide_drive_t *drive) { - return 0; } -static int auide_dma_off_quietly(ide_drive_t *drive) +static void auide_dma_off_quietly(ide_drive_t *drive) { drive->using_dma = 0; - return auide_dma_host_off(drive); } static int auide_dma_lostirq(ide_drive_t *drive) @@ -717,7 +705,8 @@ static int au_ide_probe(struct device *dev) /* hold should be on in all cases */ hwif->hold = 1; - hwif->mmio = 2; + + hwif->mmio = 1; /* If the user has selected DDMA assisted copies, then set up a few local I/O function entry points @@ -732,7 +721,7 @@ static int au_ide_probe(struct device *dev) hwif->speedproc = &auide_tune_chipset; #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA - hwif->ide_dma_off_quietly = &auide_dma_off_quietly; + hwif->dma_off_quietly = &auide_dma_off_quietly; hwif->ide_dma_timeout = &auide_dma_timeout; hwif->ide_dma_check = &auide_dma_check; @@ -741,8 +730,8 @@ static int au_ide_probe(struct device *dev) hwif->ide_dma_end = &auide_dma_end; hwif->dma_setup = &auide_dma_setup; hwif->ide_dma_test_irq = &auide_dma_test_irq; - hwif->ide_dma_host_off = &auide_dma_host_off; - hwif->ide_dma_host_on = &auide_dma_host_on; + hwif->dma_host_off = &auide_dma_host_off; + hwif->dma_host_on = &auide_dma_host_on; hwif->ide_dma_lostirq = &auide_dma_lostirq; hwif->ide_dma_on = &auide_dma_on; diff --git a/drivers/ide/mips/swarm.c b/drivers/ide/mips/swarm.c index 09c9e7936b0..81fa06851b2 100644 --- a/drivers/ide/mips/swarm.c +++ b/drivers/ide/mips/swarm.c @@ -115,7 +115,7 @@ static int __devinit swarm_ide_probe(struct device *dev) /* Setup MMIO ops. */ default_hwif_mmiops(hwif); /* Prevent resource map manipulation. */ - hwif->mmio = 2; + hwif->mmio = 1; hwif->noprobe = 0; for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c index d261bfbad22..990eafe5ea1 100644 --- a/drivers/ide/pci/aec62xx.c +++ b/drivers/ide/pci/aec62xx.c @@ -94,9 +94,9 @@ static u8 aec62xx_ratemask (ide_drive_t *drive) switch(hwif->pci_dev->device) { case PCI_DEVICE_ID_ARTOP_ATP865: case PCI_DEVICE_ID_ARTOP_ATP865R: - mode = (hwif->INB(((hwif->channel) ? - hwif->mate->dma_status : - hwif->dma_status)) & 0x10) ? 4 : 3; + mode = (inb(hwif->channel ? + hwif->mate->dma_status : + hwif->dma_status) & 0x10) ? 4 : 3; break; case PCI_DEVICE_ID_ARTOP_ATP860: case PCI_DEVICE_ID_ARTOP_ATP860R: @@ -209,25 +209,13 @@ static void aec62xx_tune_drive (ide_drive_t *drive, u8 pio) static int aec62xx_config_drive_xfer_rate (ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct hd_driveid *id = drive->id; - - if ((id->capability & 1) && drive->autodma) { - - if (ide_use_dma(drive)) { - if (config_chipset_for_dma(drive)) - return hwif->ide_dma_on(drive); - } - - goto fast_ata_pio; + if (ide_use_dma(drive) && config_chipset_for_dma(drive)) + return 0; - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: + if (ide_use_fast_pio(drive)) aec62xx_tune_drive(drive, 5); - return hwif->ide_dma_off_quietly(drive); - } - /* IORDY not supported */ - return 0; + + return -1; } static int aec62xx_irq_timeout (ide_drive_t *drive) @@ -286,10 +274,8 @@ static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif) hwif->tuneproc = &aec62xx_tune_drive; hwif->speedproc = &aec62xx_tune_chipset; - if (hwif->pci_dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) { + if (hwif->pci_dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) hwif->serialized = hwif->channel; - hwif->no_dsc = 1; - } if (hwif->mate) hwif->mate->serialized = hwif->serialized; diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c index 68df77ec502..4debd18d52f 100644 --- a/drivers/ide/pci/alim15x3.c +++ b/drivers/ide/pci/alim15x3.c @@ -507,17 +507,15 @@ static int config_chipset_for_dma (ide_drive_t *drive) * * Configure a drive for DMA operation. If DMA is not possible we * drop the drive into PIO mode instead. - * - * FIXME: exactly what are we trying to return here */ - + static int ali15x3_config_drive_for_dma(ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); struct hd_driveid *id = drive->id; if ((m5229_revision<=0x20) && (drive->media!=ide_disk)) - return hwif->ide_dma_off_quietly(drive); + goto no_dma_set; drive->init_speed = 0; @@ -552,9 +550,10 @@ try_dma_modes: ata_pio: hwif->tuneproc(drive, 255); no_dma_set: - return hwif->ide_dma_off_quietly(drive); + return -1; } - return hwif->ide_dma_on(drive); + + return 0; } /** @@ -852,8 +851,8 @@ static void __devinit init_dma_ali15x3 (ide_hwif_t *hwif, unsigned long dmabase) { if (m5229_revision < 0x20) return; - if (!(hwif->channel)) - hwif->OUTB(hwif->INB(dmabase+2) & 0x60, dmabase+2); + if (!hwif->channel) + outb(inb(dmabase + 2) & 0x60, dmabase + 2); ide_setup_dma(hwif, dmabase, 8); } diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c index a4336995a41..7989bdd842a 100644 --- a/drivers/ide/pci/amd74xx.c +++ b/drivers/ide/pci/amd74xx.c @@ -304,8 +304,9 @@ static int amd74xx_ide_dma_check(ide_drive_t *drive) amd_set_drive(drive, speed); if (drive->autodma && (speed & XFER_MODE) != XFER_PIO) - return HWIF(drive)->ide_dma_on(drive); - return HWIF(drive)->ide_dma_off_quietly(drive); + return 0; + + return -1; } /* diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c index 982ac31fa99..2d48af32e3f 100644 --- a/drivers/ide/pci/atiixp.c +++ b/drivers/ide/pci/atiixp.c @@ -101,7 +101,7 @@ static u8 atiixp_dma_2_pio(u8 xfer_rate) { } } -static int atiixp_ide_dma_host_on(ide_drive_t *drive) +static void atiixp_dma_host_on(ide_drive_t *drive) { struct pci_dev *dev = drive->hwif->pci_dev; unsigned long flags; @@ -118,10 +118,10 @@ static int atiixp_ide_dma_host_on(ide_drive_t *drive) spin_unlock_irqrestore(&atiixp_lock, flags); - return __ide_dma_host_on(drive); + ide_dma_host_on(drive); } -static int atiixp_ide_dma_host_off(ide_drive_t *drive) +static void atiixp_dma_host_off(ide_drive_t *drive) { struct pci_dev *dev = drive->hwif->pci_dev; unsigned long flags; @@ -135,7 +135,7 @@ static int atiixp_ide_dma_host_off(ide_drive_t *drive) spin_unlock_irqrestore(&atiixp_lock, flags); - return __ide_dma_host_off(drive); + ide_dma_host_off(drive); } /** @@ -235,11 +235,8 @@ static int atiixp_config_drive_for_dma(ide_drive_t *drive) { u8 speed = ide_dma_speed(drive, atiixp_ratemask(drive)); - /* If no DMA speed was available then disable DMA and use PIO. */ - if (!speed) { - u8 tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL); - speed = atiixp_dma_2_pio(XFER_PIO_0 + tspeed) + XFER_PIO_0; - } + if (!speed) + return 0; (void) atiixp_speedproc(drive, speed); return ide_dma_enable(drive); @@ -255,30 +252,20 @@ static int atiixp_config_drive_for_dma(ide_drive_t *drive) static int atiixp_dma_check(ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct hd_driveid *id = drive->id; u8 tspeed, speed; drive->init_speed = 0; - if ((id->capability & 1) && drive->autodma) { - - if (ide_use_dma(drive)) { - if (atiixp_config_drive_for_dma(drive)) - return hwif->ide_dma_on(drive); - } - - goto fast_ata_pio; + if (ide_use_dma(drive) && atiixp_config_drive_for_dma(drive)) + return 0; - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: + if (ide_use_fast_pio(drive)) { tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL); speed = atiixp_dma_2_pio(XFER_PIO_0 + tspeed) + XFER_PIO_0; - hwif->speedproc(drive, speed); - return hwif->ide_dma_off_quietly(drive); + atiixp_speedproc(drive, speed); } - /* IORDY not supported */ - return 0; + + return -1; } /** @@ -318,8 +305,8 @@ static void __devinit init_hwif_atiixp(ide_hwif_t *hwif) else hwif->udma_four = 0; - hwif->ide_dma_host_on = &atiixp_ide_dma_host_on; - hwif->ide_dma_host_off = &atiixp_ide_dma_host_off; + hwif->dma_host_on = &atiixp_dma_host_on; + hwif->dma_host_off = &atiixp_dma_host_off; hwif->ide_dma_check = &atiixp_dma_check; if (!noautodma) hwif->autodma = 1; diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c index aee947e8fc3..49df27513da 100644 --- a/drivers/ide/pci/cmd64x.c +++ b/drivers/ide/pci/cmd64x.c @@ -466,36 +466,21 @@ static int config_chipset_for_dma (ide_drive_t *drive) if (!speed) return 0; - if(ide_set_xfer_rate(drive, speed)) - return 0; - - if (!drive->init_speed) - drive->init_speed = speed; + if (cmd64x_tune_chipset(drive, speed)) + return 0; return ide_dma_enable(drive); } static int cmd64x_config_drive_for_dma (ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct hd_driveid *id = drive->id; - - if ((id != NULL) && ((id->capability & 1) != 0) && drive->autodma) { - - if (ide_use_dma(drive)) { - if (config_chipset_for_dma(drive)) - return hwif->ide_dma_on(drive); - } - - goto fast_ata_pio; + if (ide_use_dma(drive) && config_chipset_for_dma(drive)) + return 0; - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: + if (ide_use_fast_pio(drive)) config_chipset_for_pio(drive, 1); - return hwif->ide_dma_off_quietly(drive); - } - /* IORDY not supported */ - return 0; + + return -1; } static int cmd64x_alt_dma_status (struct pci_dev *dev) @@ -518,13 +503,13 @@ static int cmd64x_ide_dma_end (ide_drive_t *drive) drive->waiting_for_dma = 0; /* read DMA command state */ - dma_cmd = hwif->INB(hwif->dma_command); + dma_cmd = inb(hwif->dma_command); /* stop DMA */ - hwif->OUTB((dma_cmd & ~1), hwif->dma_command); + outb(dma_cmd & ~1, hwif->dma_command); /* get DMA status */ - dma_stat = hwif->INB(hwif->dma_status); + dma_stat = inb(hwif->dma_status); /* clear the INTR & ERROR bits */ - hwif->OUTB(dma_stat|6, hwif->dma_status); + outb(dma_stat | 6, hwif->dma_status); if (cmd64x_alt_dma_status(dev)) { u8 dma_intr = 0; u8 dma_mask = (hwif->channel) ? ARTTIM23_INTR_CH1 : @@ -546,7 +531,7 @@ static int cmd64x_ide_dma_test_irq (ide_drive_t *drive) struct pci_dev *dev = hwif->pci_dev; u8 dma_alt_stat = 0, mask = (hwif->channel) ? MRDMODE_INTR_CH1 : MRDMODE_INTR_CH0; - u8 dma_stat = hwif->INB(hwif->dma_status); + u8 dma_stat = inb(hwif->dma_status); (void) pci_read_config_byte(dev, MRDMODE, &dma_alt_stat); #ifdef DEBUG @@ -576,13 +561,13 @@ static int cmd646_1_ide_dma_end (ide_drive_t *drive) drive->waiting_for_dma = 0; /* get DMA status */ - dma_stat = hwif->INB(hwif->dma_status); + dma_stat = inb(hwif->dma_status); /* read DMA command state */ - dma_cmd = hwif->INB(hwif->dma_command); + dma_cmd = inb(hwif->dma_command); /* stop DMA */ - hwif->OUTB((dma_cmd & ~1), hwif->dma_command); + outb(dma_cmd & ~1, hwif->dma_command); /* clear the INTR & ERROR bits */ - hwif->OUTB(dma_stat|6, hwif->dma_status); + outb(dma_stat | 6, hwif->dma_status); /* and free any DMA resources */ ide_destroy_dmatable(drive); /* verify good DMA status */ diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c index ba6786aabf3..400859a839f 100644 --- a/drivers/ide/pci/cs5520.c +++ b/drivers/ide/pci/cs5520.c @@ -132,12 +132,11 @@ static void cs5520_tune_drive(ide_drive_t *drive, u8 pio) static int cs5520_config_drive_xfer_rate(ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - /* Tune the drive for PIO modes up to PIO 4 */ cs5520_tune_drive(drive, 4); + /* Then tell the core to use DMA operations */ - return hwif->ide_dma_on(drive); + return 0; } /* diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c index 9bf5fdfc5b1..b2d7c132ef4 100644 --- a/drivers/ide/pci/cs5530.c +++ b/drivers/ide/pci/cs5530.c @@ -81,8 +81,8 @@ static void cs5530_tuneproc (ide_drive_t *drive, u8 pio) /* pio=255 means "autot pio = ide_get_best_pio_mode(drive, pio, 4, NULL); if (!cs5530_set_xfer_mode(drive, modes[pio])) { - format = (hwif->INL(basereg+4) >> 31) & 1; - hwif->OUTL(cs5530_pio_timings[format][pio], + format = (inl(basereg + 4) >> 31) & 1; + outl(cs5530_pio_timings[format][pio], basereg+(drive->select.b.unit<<3)); } } @@ -103,16 +103,13 @@ static int cs5530_config_dma (ide_drive_t *drive) int unit = drive->select.b.unit; ide_drive_t *mate = &hwif->drives[unit^1]; struct hd_driveid *id = drive->id; - unsigned int reg, timings; + unsigned int reg, timings = 0; unsigned long basereg; /* * Default to DMA-off in case we run into trouble here. */ - hwif->ide_dma_off_quietly(drive); - /* turn off DMA while we fiddle */ - hwif->ide_dma_host_off(drive); - /* clear DMA_capable bit */ + hwif->dma_off_quietly(drive); /* * The CS5530 specifies that two drives sharing a cable cannot @@ -182,30 +179,24 @@ static int cs5530_config_dma (ide_drive_t *drive) case XFER_MW_DMA_1: timings = 0x00012121; break; case XFER_MW_DMA_2: timings = 0x00002020; break; default: - printk(KERN_ERR "%s: cs5530_config_dma: huh? mode=%02x\n", - drive->name, mode); - return 1; /* failure */ + BUG(); + break; } basereg = CS5530_BASEREG(hwif); - reg = hwif->INL(basereg+4); /* get drive0 config register */ + reg = inl(basereg + 4); /* get drive0 config register */ timings |= reg & 0x80000000; /* preserve PIO format bit */ if (unit == 0) { /* are we configuring drive0? */ - hwif->OUTL(timings, basereg+4); /* write drive0 config register */ + outl(timings, basereg + 4); /* write drive0 config register */ } else { if (timings & 0x00100000) reg |= 0x00100000; /* enable UDMA timings for both drives */ else reg &= ~0x00100000; /* disable UDMA timings for both drives */ - hwif->OUTL(reg, basereg+4); /* write drive0 config register */ - hwif->OUTL(timings, basereg+12); /* write drive1 config register */ + outl(reg, basereg + 4); /* write drive0 config register */ + outl(timings, basereg + 12); /* write drive1 config register */ } - (void) hwif->ide_dma_host_on(drive); - /* set DMA_capable bit */ - /* - * Finally, turn DMA on in software, and exit. - */ - return hwif->ide_dma_on(drive); /* success */ + return 0; /* success */ } /** @@ -321,17 +312,17 @@ static void __devinit init_hwif_cs5530 (ide_hwif_t *hwif) hwif->tuneproc = &cs5530_tuneproc; basereg = CS5530_BASEREG(hwif); - d0_timings = hwif->INL(basereg+0); + d0_timings = inl(basereg + 0); if (CS5530_BAD_PIO(d0_timings)) { /* PIO timings not initialized? */ - hwif->OUTL(cs5530_pio_timings[(d0_timings>>31)&1][0], basereg+0); + outl(cs5530_pio_timings[(d0_timings >> 31) & 1][0], basereg + 0); if (!hwif->drives[0].autotune) hwif->drives[0].autotune = 1; /* needs autotuning later */ } - if (CS5530_BAD_PIO(hwif->INL(basereg+8))) { - /* PIO timings not initialized? */ - hwif->OUTL(cs5530_pio_timings[(d0_timings>>31)&1][0], basereg+8); + if (CS5530_BAD_PIO(inl(basereg + 8))) { + /* PIO timings not initialized? */ + outl(cs5530_pio_timings[(d0_timings >> 31) & 1][0], basereg + 8); if (!hwif->drives[1].autotune) hwif->drives[1].autotune = 1; /* needs autotuning later */ diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c index 5c5aec28e67..45f43efbf92 100644 --- a/drivers/ide/pci/cs5535.c +++ b/drivers/ide/pci/cs5535.c @@ -195,28 +195,19 @@ static int cs5535_config_drive_for_dma(ide_drive_t *drive) static int cs5535_dma_check(ide_drive_t *drive) { - ide_hwif_t *hwif = drive->hwif; - struct hd_driveid *id = drive->id; u8 speed; drive->init_speed = 0; - if ((id->capability & 1) && drive->autodma) { - if (ide_use_dma(drive)) { - if (cs5535_config_drive_for_dma(drive)) - return hwif->ide_dma_on(drive); - } - - goto fast_ata_pio; + if (ide_use_dma(drive) && cs5535_config_drive_for_dma(drive)) + return 0; - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: + if (ide_use_fast_pio(drive)) { speed = ide_get_best_pio_mode(drive, 255, 4, NULL); cs5535_set_drive(drive, speed); - return hwif->ide_dma_off_quietly(drive); } - /* IORDY not supported */ - return 0; + + return -1; } static u8 __devinit cs5535_cable_detect(struct pci_dev *dev) diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c index 9eafcbf444f..103b9db9785 100644 --- a/drivers/ide/pci/cy82c693.c +++ b/drivers/ide/pci/cy82c693.c @@ -197,8 +197,8 @@ static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single) #if CY82C693_DEBUG_LOGS /* for debug let's show the previous values */ - HWIF(drive)->OUTB(index, CY82_INDEX_PORT); - data = HWIF(drive)->INB(CY82_DATA_PORT); + outb(index, CY82_INDEX_PORT); + data = inb(CY82_DATA_PORT); printk (KERN_INFO "%s (ch=%d, dev=%d): DMA mode is %d (single=%d)\n", drive->name, HWIF(drive)->channel, drive->select.b.unit, @@ -207,8 +207,8 @@ static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single) data = (u8)mode|(u8)(single<<2); - HWIF(drive)->OUTB(index, CY82_INDEX_PORT); - HWIF(drive)->OUTB(data, CY82_DATA_PORT); + outb(index, CY82_INDEX_PORT); + outb(data, CY82_DATA_PORT); #if CY82C693_DEBUG_INFO printk(KERN_INFO "%s (ch=%d, dev=%d): set DMA mode to %d (single=%d)\n", @@ -227,8 +227,8 @@ static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single) */ data = BUSMASTER_TIMEOUT; - HWIF(drive)->OUTB(CY82_INDEX_TIMEOUT, CY82_INDEX_PORT); - HWIF(drive)->OUTB(data, CY82_DATA_PORT); + outb(CY82_INDEX_TIMEOUT, CY82_INDEX_PORT); + outb(data, CY82_DATA_PORT); #if CY82C693_DEBUG_INFO printk (KERN_INFO "%s: Set IDE Bus Master TimeOut Register to 0x%X\n", @@ -478,21 +478,18 @@ static void __devinit init_iops_cy82c693(ide_hwif_t *hwif) } } -static ide_pci_device_t cy82c693_chipsets[] __devinitdata = { - { /* 0 */ - .name = "CY82C693", - .init_chipset = init_chipset_cy82c693, - .init_iops = init_iops_cy82c693, - .init_hwif = init_hwif_cy82c693, - .channels = 1, - .autodma = AUTODMA, - .bootable = ON_BOARD, - } +static ide_pci_device_t cy82c693_chipset __devinitdata = { + .name = "CY82C693", + .init_chipset = init_chipset_cy82c693, + .init_iops = init_iops_cy82c693, + .init_hwif = init_hwif_cy82c693, + .channels = 1, + .autodma = AUTODMA, + .bootable = ON_BOARD, }; static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_pci_device_t *d = &cy82c693_chipsets[id->driver_data]; struct pci_dev *dev2; int ret = -ENODEV; @@ -501,7 +498,7 @@ static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_dev if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && PCI_FUNC(dev->devfn) == 1) { dev2 = pci_get_slot(dev->bus, dev->devfn + 1); - ret = ide_setup_pci_devices(dev, dev2, d); + ret = ide_setup_pci_devices(dev, dev2, &cy82c693_chipset); /* We leak pci refs here but thats ok - we can't be unloaded */ } return ret; diff --git a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c index ce7b08f08a0..924eaa3a570 100644 --- a/drivers/ide/pci/hpt34x.c +++ b/drivers/ide/pci/hpt34x.c @@ -48,19 +48,6 @@ static u8 hpt34x_ratemask (ide_drive_t *drive) return 1; } -static void hpt34x_clear_chipset (ide_drive_t *drive) -{ - struct pci_dev *dev = HWIF(drive)->pci_dev; - u32 reg1 = 0, tmp1 = 0, reg2 = 0, tmp2 = 0; - - pci_read_config_dword(dev, 0x44, ®1); - pci_read_config_dword(dev, 0x48, ®2); - tmp1 = ((0x00 << (3*drive->dn)) | (reg1 & ~(7 << (3*drive->dn)))); - tmp2 = (reg2 & ~(0x11 << drive->dn)); - pci_write_config_dword(dev, 0x44, tmp1); - pci_write_config_dword(dev, 0x48, tmp2); -} - static int hpt34x_tune_chipset (ide_drive_t *drive, u8 xferspeed) { struct pci_dev *dev = HWIF(drive)->pci_dev; @@ -81,7 +68,7 @@ static int hpt34x_tune_chipset (ide_drive_t *drive, u8 xferspeed) pci_read_config_dword(dev, 0x44, ®1); pci_read_config_dword(dev, 0x48, ®2); tmp1 = ((lo_speed << (3*drive->dn)) | (reg1 & ~(7 << (3*drive->dn)))); - tmp2 = ((hi_speed << drive->dn) | reg2); + tmp2 = ((hi_speed << drive->dn) | (reg2 & ~(0x11 << drive->dn))); pci_write_config_dword(dev, 0x44, tmp1); pci_write_config_dword(dev, 0x48, tmp2); @@ -99,7 +86,6 @@ static int hpt34x_tune_chipset (ide_drive_t *drive, u8 xferspeed) static void hpt34x_tune_drive (ide_drive_t *drive, u8 pio) { pio = ide_get_best_pio_mode(drive, pio, 5, NULL); - hpt34x_clear_chipset(drive); (void) hpt34x_tune_chipset(drive, (XFER_PIO_0 + pio)); } @@ -117,38 +103,25 @@ static int config_chipset_for_dma (ide_drive_t *drive) if (!(speed)) return 0; - hpt34x_clear_chipset(drive); (void) hpt34x_tune_chipset(drive, speed); return ide_dma_enable(drive); } static int hpt34x_config_drive_xfer_rate (ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct hd_driveid *id = drive->id; - drive->init_speed = 0; - if (id && (id->capability & 1) && drive->autodma) { - - if (ide_use_dma(drive)) { - if (config_chipset_for_dma(drive)) + if (ide_use_dma(drive) && config_chipset_for_dma(drive)) #ifndef CONFIG_HPT34X_AUTODMA - return hwif->ide_dma_off_quietly(drive); + return -1; #else - return hwif->ide_dma_on(drive); + return 0; #endif - } - - goto fast_ata_pio; - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: + if (ide_use_fast_pio(drive)) hpt34x_tune_drive(drive, 255); - return hwif->ide_dma_off_quietly(drive); - } - /* IORDY not supported */ - return 0; + + return -1; } /* @@ -209,7 +182,6 @@ static void __devinit init_hwif_hpt34x(ide_hwif_t *hwif) hwif->tuneproc = &hpt34x_tune_drive; hwif->speedproc = &hpt34x_tune_chipset; - hwif->no_dsc = 1; hwif->drives[0].autotune = 1; hwif->drives[1].autotune = 1; diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c index 05be8fadda7..60ecdc258c7 100644 --- a/drivers/ide/pci/hpt366.c +++ b/drivers/ide/pci/hpt366.c @@ -736,24 +736,15 @@ static void hpt3xx_maskproc(ide_drive_t *drive, int mask) static int hpt366_config_drive_xfer_rate(ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct hd_driveid *id = drive->id; - drive->init_speed = 0; - if ((id->capability & 1) && drive->autodma) { - if (ide_use_dma(drive) && config_chipset_for_dma(drive)) - return hwif->ide_dma_on(drive); - - goto fast_ata_pio; + if (ide_use_dma(drive) && config_chipset_for_dma(drive)) + return 0; - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: + if (ide_use_fast_pio(drive)) hpt3xx_tune_drive(drive, 255); - return hwif->ide_dma_off_quietly(drive); - } - /* IORDY not supported */ - return 0; + + return -1; } /* @@ -841,7 +832,7 @@ static int hpt374_ide_dma_test_irq(ide_drive_t *drive) return 0; } - dma_stat = hwif->INB(hwif->dma_status); + dma_stat = inb(hwif->dma_status); /* return 1 if INTR asserted */ if (dma_stat & 4) return 1; @@ -1391,9 +1382,6 @@ static void __devinit init_dma_hpt366(ide_hwif_t *hwif, unsigned long dmabase) u8 dma_new = 0, dma_old = 0; unsigned long flags; - if (!dmabase) - return; - dma_old = hwif->INB(dmabase + 2); local_irq_save(flags); diff --git a/drivers/ide/pci/it8213.c b/drivers/ide/pci/it8213.c index 63248b6909f..424f00bb160 100644 --- a/drivers/ide/pci/it8213.c +++ b/drivers/ide/pci/it8213.c @@ -244,17 +244,15 @@ static int config_chipset_for_dma (ide_drive_t *drive) static int it8213_config_drive_for_dma (ide_drive_t *drive) { - ide_hwif_t *hwif = drive->hwif; + u8 pio; - if (ide_use_dma(drive)) { - if (config_chipset_for_dma(drive)) - return hwif->ide_dma_on(drive); - } + if (ide_use_dma(drive) && config_chipset_for_dma(drive)) + return 0; - hwif->speedproc(drive, XFER_PIO_0 - + ide_get_best_pio_mode(drive, 255, 4, NULL)); + pio = ide_get_best_pio_mode(drive, 255, 4, NULL); + it8213_tune_chipset(drive, XFER_PIO_0 + pio); - return hwif->ide_dma_off_quietly(drive); + return -1; } /** diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c index e9bad185968..a132767f7d9 100644 --- a/drivers/ide/pci/it821x.c +++ b/drivers/ide/pci/it821x.c @@ -520,14 +520,12 @@ static int config_chipset_for_dma (ide_drive_t *drive) static int it821x_config_drive_for_dma (ide_drive_t *drive) { - ide_hwif_t *hwif = drive->hwif; + if (ide_use_dma(drive) && config_chipset_for_dma(drive)) + return 0; - if (ide_use_dma(drive)) { - if (config_chipset_for_dma(drive)) - return hwif->ide_dma_on(drive); - } config_it821x_chipset_for_pio(drive, 1); - return hwif->ide_dma_off_quietly(drive); + + return -1; } /** @@ -608,11 +606,11 @@ static void __devinit it821x_fixups(ide_hwif_t *hwif) printk(".\n"); /* Now the core code will have wrongly decided no DMA so we need to fix this */ - hwif->ide_dma_off_quietly(drive); + hwif->dma_off_quietly(drive); #ifdef CONFIG_IDEDMA_ONLYDISK if (drive->media == ide_disk) #endif - hwif->ide_dma_check(drive); + ide_set_dma(drive); } else { /* Non RAID volume. Fixups to stop the core code doing unsupported things */ diff --git a/drivers/ide/pci/jmicron.c b/drivers/ide/pci/jmicron.c index f07bbbed177..53f25500c22 100644 --- a/drivers/ide/pci/jmicron.c +++ b/drivers/ide/pci/jmicron.c @@ -147,7 +147,9 @@ static int config_chipset_for_dma (ide_drive_t *drive) { u8 speed = ide_dma_speed(drive, jmicron_ratemask(drive)); - config_jmicron_chipset_for_pio(drive, !speed); + if (!speed) + return 0; + jmicron_tune_chipset(drive, speed); return ide_dma_enable(drive); } @@ -162,14 +164,12 @@ static int config_chipset_for_dma (ide_drive_t *drive) static int jmicron_config_drive_for_dma (ide_drive_t *drive) { - ide_hwif_t *hwif = drive->hwif; + if (ide_use_dma(drive) && config_chipset_for_dma(drive)) + return 0; - if (ide_use_dma(drive)) { - if (config_chipset_for_dma(drive)) - return hwif->ide_dma_on(drive); - } config_jmicron_chipset_for_pio(drive, 1); - return hwif->ide_dma_off_quietly(drive); + + return -1; } /** diff --git a/drivers/ide/pci/ns87415.c b/drivers/ide/pci/ns87415.c index 8aaea4ea554..b310c4f5107 100644 --- a/drivers/ide/pci/ns87415.c +++ b/drivers/ide/pci/ns87415.c @@ -166,10 +166,10 @@ static int ns87415_ide_dma_end (ide_drive_t *drive) /* get dma command mode */ dma_cmd = hwif->INB(hwif->dma_command); /* stop DMA */ - hwif->OUTB(dma_cmd & ~1, hwif->dma_command); + outb(dma_cmd & ~1, hwif->dma_command); /* from ERRATA: clear the INTR & ERROR bits */ dma_cmd = hwif->INB(hwif->dma_command); - hwif->OUTB(dma_cmd|6, hwif->dma_command); + outb(dma_cmd | 6, hwif->dma_command); /* and free any DMA resources */ ide_destroy_dmatable(drive); /* verify good DMA status */ @@ -190,7 +190,8 @@ static int ns87415_ide_dma_setup(ide_drive_t *drive) static int ns87415_ide_dma_check (ide_drive_t *drive) { if (drive->media != ide_disk) - return HWIF(drive)->ide_dma_off_quietly(drive); + return -1; + return __ide_dma_check(drive); } @@ -243,9 +244,9 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif) * to SELECT_DRIVE() properly during first probe_hwif(). */ timeout = 10000; - hwif->OUTB(12, hwif->io_ports[IDE_CONTROL_OFFSET]); + outb(12, hwif->io_ports[IDE_CONTROL_OFFSET]); udelay(10); - hwif->OUTB(8, hwif->io_ports[IDE_CONTROL_OFFSET]); + outb(8, hwif->io_ports[IDE_CONTROL_OFFSET]); do { udelay(50); stat = hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]); @@ -263,7 +264,7 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif) if (!hwif->dma_base) return; - hwif->OUTB(0x60, hwif->dma_status); + outb(0x60, hwif->dma_status); hwif->dma_setup = &ns87415_ide_dma_setup; hwif->ide_dma_check = &ns87415_ide_dma_check; hwif->ide_dma_end = &ns87415_ide_dma_end; diff --git a/drivers/ide/pci/opti621.c b/drivers/ide/pci/opti621.c index 22bbf613f94..9ca60dd2185 100644 --- a/drivers/ide/pci/opti621.c +++ b/drivers/ide/pci/opti621.c @@ -176,34 +176,35 @@ static int cmpt_clk(int time, int bus_speed) return ((time*bus_speed+999)/1000); } -static void write_reg(ide_hwif_t *hwif, u8 value, int reg) /* Write value to register reg, base of register * is at reg_base (0x1f0 primary, 0x170 secondary, * if not changed by PCI configuration). * This is from setupvic.exe program. */ +static void write_reg(u8 value, int reg) { - hwif->INW(reg_base+1); - hwif->INW(reg_base+1); - hwif->OUTB(3, reg_base+2); - hwif->OUTB(value, reg_base+reg); - hwif->OUTB(0x83, reg_base+2); + inw(reg_base + 1); + inw(reg_base + 1); + outb(3, reg_base + 2); + outb(value, reg_base + reg); + outb(0x83, reg_base + 2); } -static u8 read_reg(ide_hwif_t *hwif, int reg) /* Read value from register reg, base of register * is at reg_base (0x1f0 primary, 0x170 secondary, * if not changed by PCI configuration). * This is from setupvic.exe program. */ +static u8 read_reg(int reg) { u8 ret = 0; - hwif->INW(reg_base+1); - hwif->INW(reg_base+1); - hwif->OUTB(3, reg_base+2); - ret = hwif->INB(reg_base+reg); - hwif->OUTB(0x83, reg_base+2); + inw(reg_base + 1); + inw(reg_base + 1); + outb(3, reg_base + 2); + ret = inb(reg_base + reg); + outb(0x83, reg_base + 2); + return ret; } @@ -286,39 +287,39 @@ static void opti621_tune_drive (ide_drive_t *drive, u8 pio) reg_base = hwif->io_ports[IDE_DATA_OFFSET]; /* allow Register-B */ - hwif->OUTB(0xc0, reg_base+CNTRL_REG); + outb(0xc0, reg_base + CNTRL_REG); /* hmm, setupvic.exe does this ;-) */ - hwif->OUTB(0xff, reg_base+5); + outb(0xff, reg_base + 5); /* if reads 0xff, adapter not exist? */ - (void) hwif->INB(reg_base+CNTRL_REG); + (void)inb(reg_base + CNTRL_REG); /* if reads 0xc0, no interface exist? */ - read_reg(hwif, CNTRL_REG); + read_reg(CNTRL_REG); /* read version, probably 0 */ - read_reg(hwif, STRAP_REG); + read_reg(STRAP_REG); /* program primary drive */ - /* select Index-0 for Register-A */ - write_reg(hwif, 0, MISC_REG); - /* set read cycle timings */ - write_reg(hwif, cycle1, READ_REG); - /* set write cycle timings */ - write_reg(hwif, cycle1, WRITE_REG); + /* select Index-0 for Register-A */ + write_reg(0, MISC_REG); + /* set read cycle timings */ + write_reg(cycle1, READ_REG); + /* set write cycle timings */ + write_reg(cycle1, WRITE_REG); /* program secondary drive */ - /* select Index-1 for Register-B */ - write_reg(hwif, 1, MISC_REG); - /* set read cycle timings */ - write_reg(hwif, cycle2, READ_REG); - /* set write cycle timings */ - write_reg(hwif, cycle2, WRITE_REG); + /* select Index-1 for Register-B */ + write_reg(1, MISC_REG); + /* set read cycle timings */ + write_reg(cycle2, READ_REG); + /* set write cycle timings */ + write_reg(cycle2, WRITE_REG); /* use Register-A for drive 0 */ /* use Register-B for drive 1 */ - write_reg(hwif, 0x85, CNTRL_REG); + write_reg(0x85, CNTRL_REG); /* set address setup, DRDY timings, */ /* and read prefetch for both drives */ - write_reg(hwif, misc, MISC_REG); + write_reg(misc, MISC_REG); spin_unlock_irqrestore(&ide_lock, flags); } diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c index 236a03144a2..6ceb25bc5a7 100644 --- a/drivers/ide/pci/pdc202xx_new.c +++ b/drivers/ide/pci/pdc202xx_new.c @@ -101,8 +101,8 @@ static u8 get_indexed_reg(ide_hwif_t *hwif, u8 index) { u8 value; - hwif->OUTB(index, hwif->dma_vendor1); - value = hwif->INB(hwif->dma_vendor3); + outb(index, hwif->dma_vendor1); + value = inb(hwif->dma_vendor3); DBG("index[%02X] value[%02X]\n", index, value); return value; @@ -115,8 +115,8 @@ static u8 get_indexed_reg(ide_hwif_t *hwif, u8 index) */ static void set_indexed_reg(ide_hwif_t *hwif, u8 index, u8 value) { - hwif->OUTB(index, hwif->dma_vendor1); - hwif->OUTB(value, hwif->dma_vendor3); + outb(index, hwif->dma_vendor1); + outb(value, hwif->dma_vendor3); DBG("index[%02X] value[%02X]\n", index, value); } @@ -281,25 +281,15 @@ static int config_chipset_for_dma(ide_drive_t *drive) static int pdcnew_config_drive_xfer_rate(ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct hd_driveid *id = drive->id; - drive->init_speed = 0; - if ((id->capability & 1) && drive->autodma) { - - if (ide_use_dma(drive) && config_chipset_for_dma(drive)) - return hwif->ide_dma_on(drive); + if (ide_use_dma(drive) && config_chipset_for_dma(drive)) + return 0; - goto fast_ata_pio; + if (ide_use_fast_pio(drive)) + pdcnew_tune_drive(drive, 255); - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: - hwif->tuneproc(drive, 255); - return hwif->ide_dma_off_quietly(drive); - } - /* IORDY not supported */ - return 0; + return -1; } static int pdcnew_quirkproc(ide_drive_t *drive) diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c index 730e8d1ec2f..a7a639fe1ea 100644 --- a/drivers/ide/pci/pdc202xx_old.c +++ b/drivers/ide/pci/pdc202xx_old.c @@ -2,6 +2,7 @@ * linux/drivers/ide/pci/pdc202xx_old.c Version 0.36 Sept 11, 2002 * * Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org> + * Copyright (C) 2006-2007 MontaVista Software, Inc. * * Promise Ultra33 cards with BIOS v1.20 through 1.28 will need this * compiled into the kernel if you have more than one card installed. @@ -216,21 +217,10 @@ static int pdc202xx_tune_chipset (ide_drive_t *drive, u8 xferspeed) } -/* 0 1 2 3 4 5 6 7 8 - * 960, 480, 390, 300, 240, 180, 120, 90, 60 - * 180, 150, 120, 90, 60 - * DMA_Speed - * 180, 120, 90, 90, 90, 60, 30 - * 11, 5, 4, 3, 2, 1, 0 - */ -static void config_chipset_for_pio (ide_drive_t *drive, u8 pio) +static void pdc202xx_tune_drive(ide_drive_t *drive, u8 pio) { - u8 speed = 0; - - if (pio == 5) pio = 4; - speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, pio, NULL); - - pdc202xx_tune_chipset(drive, speed); + pio = ide_get_best_pio_mode(drive, pio, 4, NULL); + pdc202xx_tune_chipset(drive, XFER_PIO_0 + pio); } static u8 pdc202xx_old_cable_detect (ide_hwif_t *hwif) @@ -250,17 +240,17 @@ static u8 pdc202xx_old_cable_detect (ide_hwif_t *hwif) static void pdc_old_enable_66MHz_clock(ide_hwif_t *hwif) { unsigned long clock_reg = hwif->dma_master + 0x11; - u8 clock = hwif->INB(clock_reg); + u8 clock = inb(clock_reg); - hwif->OUTB(clock | (hwif->channel ? 0x08 : 0x02), clock_reg); + outb(clock | (hwif->channel ? 0x08 : 0x02), clock_reg); } static void pdc_old_disable_66MHz_clock(ide_hwif_t *hwif) { unsigned long clock_reg = hwif->dma_master + 0x11; - u8 clock = hwif->INB(clock_reg); + u8 clock = inb(clock_reg); - hwif->OUTB(clock & ~(hwif->channel ? 0x08 : 0x02), clock_reg); + outb(clock & ~(hwif->channel ? 0x08 : 0x02), clock_reg); } static int config_chipset_for_dma (ide_drive_t *drive) @@ -332,27 +322,15 @@ chipset_is_set: static int pdc202xx_config_drive_xfer_rate (ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct hd_driveid *id = drive->id; - drive->init_speed = 0; - if (id && (id->capability & 1) && drive->autodma) { - - if (ide_use_dma(drive)) { - if (config_chipset_for_dma(drive)) - return hwif->ide_dma_on(drive); - } + if (ide_use_dma(drive) && config_chipset_for_dma(drive)) + return 0; - goto fast_ata_pio; + if (ide_use_fast_pio(drive)) + pdc202xx_tune_drive(drive, 255); - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: - hwif->tuneproc(drive, 5); - return hwif->ide_dma_off_quietly(drive); - } - /* IORDY not supported */ - return 0; + return -1; } static int pdc202xx_quirkproc (ide_drive_t *drive) @@ -375,14 +353,14 @@ static void pdc202xx_old_ide_dma_start(ide_drive_t *drive) unsigned long high_16 = hwif->dma_master; unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20); u32 word_count = 0; - u8 clock = hwif->INB(high_16 + 0x11); + u8 clock = inb(high_16 + 0x11); - hwif->OUTB(clock|(hwif->channel ? 0x08 : 0x02), high_16+0x11); + outb(clock | (hwif->channel ? 0x08 : 0x02), high_16 + 0x11); word_count = (rq->nr_sectors << 8); word_count = (rq_data_dir(rq) == READ) ? word_count | 0x05000000 : word_count | 0x06000000; - hwif->OUTL(word_count, atapi_reg); + outl(word_count, atapi_reg); } ide_dma_start(drive); } @@ -395,9 +373,9 @@ static int pdc202xx_old_ide_dma_end(ide_drive_t *drive) unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20); u8 clock = 0; - hwif->OUTL(0, atapi_reg); /* zero out extra */ - clock = hwif->INB(high_16 + 0x11); - hwif->OUTB(clock & ~(hwif->channel ? 0x08:0x02), high_16+0x11); + outl(0, atapi_reg); /* zero out extra */ + clock = inb(high_16 + 0x11); + outb(clock & ~(hwif->channel ? 0x08:0x02), high_16 + 0x11); } if (drive->current_speed > XFER_UDMA_2) pdc_old_disable_66MHz_clock(drive->hwif); @@ -408,8 +386,8 @@ static int pdc202xx_old_ide_dma_test_irq(ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); unsigned long high_16 = hwif->dma_master; - u8 dma_stat = hwif->INB(hwif->dma_status); - u8 sc1d = hwif->INB((high_16 + 0x001d)); + u8 dma_stat = inb(hwif->dma_status); + u8 sc1d = inb(high_16 + 0x001d); if (hwif->channel) { /* bit7: Error, bit6: Interrupting, bit5: FIFO Full, bit4: FIFO Empty */ @@ -445,11 +423,11 @@ static int pdc202xx_ide_dma_timeout(ide_drive_t *drive) static void pdc202xx_reset_host (ide_hwif_t *hwif) { unsigned long high_16 = hwif->dma_master; - u8 udma_speed_flag = hwif->INB(high_16|0x001f); + u8 udma_speed_flag = inb(high_16 | 0x001f); - hwif->OUTB((udma_speed_flag | 0x10), (high_16|0x001f)); + outb(udma_speed_flag | 0x10, high_16 | 0x001f); mdelay(100); - hwif->OUTB((udma_speed_flag & ~0x10), (high_16|0x001f)); + outb(udma_speed_flag & ~0x10, high_16 | 0x001f); mdelay(2000); /* 2 seconds ?! */ printk(KERN_WARNING "PDC202XX: %s channel reset.\n", @@ -463,7 +441,7 @@ static void pdc202xx_reset (ide_drive_t *drive) pdc202xx_reset_host(hwif); pdc202xx_reset_host(mate); - hwif->tuneproc(drive, 5); + pdc202xx_tune_drive(drive, 255); } static unsigned int __devinit init_chipset_pdc202xx(struct pci_dev *dev, @@ -490,7 +468,7 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif) hwif->rqsize = 256; hwif->autodma = 0; - hwif->tuneproc = &config_chipset_for_pio; + hwif->tuneproc = &pdc202xx_tune_drive; hwif->quirkproc = &pdc202xx_quirkproc; if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246) @@ -537,9 +515,9 @@ static void __devinit init_dma_pdc202xx(ide_hwif_t *hwif, unsigned long dmabase) return; } - udma_speed_flag = hwif->INB((dmabase|0x1f)); - primary_mode = hwif->INB((dmabase|0x1a)); - secondary_mode = hwif->INB((dmabase|0x1b)); + udma_speed_flag = inb(dmabase | 0x1f); + primary_mode = inb(dmabase | 0x1a); + secondary_mode = inb(dmabase | 0x1b); printk(KERN_INFO "%s: (U)DMA Burst Bit %sABLED " \ "Primary %s Mode " \ "Secondary %s Mode.\n", hwif->cds->name, @@ -552,30 +530,10 @@ static void __devinit init_dma_pdc202xx(ide_hwif_t *hwif, unsigned long dmabase) printk(KERN_INFO "%s: FORCING BURST BIT 0x%02x->0x%02x ", hwif->cds->name, udma_speed_flag, (udma_speed_flag|1)); - hwif->OUTB(udma_speed_flag|1,(dmabase|0x1f)); - printk("%sACTIVE\n", - (hwif->INB(dmabase|0x1f)&1) ? "":"IN"); + outb(udma_speed_flag | 1, dmabase | 0x1f); + printk("%sACTIVE\n", (inb(dmabase | 0x1f) & 1) ? "" : "IN"); } #endif /* CONFIG_PDC202XX_BURST */ -#ifdef CONFIG_PDC202XX_MASTER - if (!(primary_mode & 1)) { - printk(KERN_INFO "%s: FORCING PRIMARY MODE BIT " - "0x%02x -> 0x%02x ", hwif->cds->name, - primary_mode, (primary_mode|1)); - hwif->OUTB(primary_mode|1, (dmabase|0x1a)); - printk("%s\n", - (hwif->INB((dmabase|0x1a)) & 1) ? "MASTER" : "PCI"); - } - - if (!(secondary_mode & 1)) { - printk(KERN_INFO "%s: FORCING SECONDARY MODE BIT " - "0x%02x -> 0x%02x ", hwif->cds->name, - secondary_mode, (secondary_mode|1)); - hwif->OUTB(secondary_mode|1, (dmabase|0x1b)); - printk("%s\n", - (hwif->INB((dmabase|0x1b)) & 1) ? "MASTER" : "PCI"); - } -#endif /* CONFIG_PDC202XX_MASTER */ ide_setup_dma(hwif, dmabase, 8); } diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c index 52cfc2ac22c..569822f4cf5 100644 --- a/drivers/ide/pci/piix.c +++ b/drivers/ide/pci/piix.c @@ -369,7 +369,7 @@ static int piix_config_drive_for_dma (ide_drive_t *drive) * If no DMA speed was available or the chipset has DMA bugs * then disable DMA and use PIO */ - if (!speed || no_piix_dma) + if (!speed) return 0; (void) piix_tune_chipset(drive, speed); @@ -386,41 +386,28 @@ static int piix_config_drive_for_dma (ide_drive_t *drive) static int piix_config_drive_xfer_rate (ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct hd_driveid *id = drive->id; - drive->init_speed = 0; - if ((id->capability & 1) && drive->autodma) { - - if (ide_use_dma(drive) && piix_config_drive_for_dma(drive)) - return hwif->ide_dma_on(drive); - - goto fast_ata_pio; + if (ide_use_dma(drive) && piix_config_drive_for_dma(drive)) + return 0; - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: + if (ide_use_fast_pio(drive)) /* Find best PIO mode. */ - (void) hwif->speedproc(drive, XFER_PIO_0 + - ide_get_best_pio_mode(drive, 255, 4, NULL)); - return hwif->ide_dma_off_quietly(drive); - } - /* IORDY not supported */ - return 0; + piix_tune_chipset(drive, XFER_PIO_0 + + ide_get_best_pio_mode(drive, 255, 4, NULL)); + + return -1; } /** - * init_chipset_piix - set up the PIIX chipset - * @dev: PCI device to set up - * @name: Name of the device + * piix_is_ichx - check if ICHx + * @dev: PCI device to check * - * Initialize the PCI device as required. For the PIIX this turns - * out to be nice and simple + * returns 1 if ICHx, 0 otherwise. */ - -static unsigned int __devinit init_chipset_piix (struct pci_dev *dev, const char *name) +static int piix_is_ichx(struct pci_dev *dev) { - switch(dev->device) { + switch (dev->device) { case PCI_DEVICE_ID_INTEL_82801EB_1: case PCI_DEVICE_ID_INTEL_82801AA_1: case PCI_DEVICE_ID_INTEL_82801AB_1: @@ -438,19 +425,61 @@ static unsigned int __devinit init_chipset_piix (struct pci_dev *dev, const char case PCI_DEVICE_ID_INTEL_ICH7_21: case PCI_DEVICE_ID_INTEL_ESB2_18: case PCI_DEVICE_ID_INTEL_ICH8_6: - { - unsigned int extra = 0; - pci_read_config_dword(dev, 0x54, &extra); - pci_write_config_dword(dev, 0x54, extra|0x400); - } - default: - break; + return 1; } return 0; } /** + * init_chipset_piix - set up the PIIX chipset + * @dev: PCI device to set up + * @name: Name of the device + * + * Initialize the PCI device as required. For the PIIX this turns + * out to be nice and simple + */ + +static unsigned int __devinit init_chipset_piix (struct pci_dev *dev, const char *name) +{ + if (piix_is_ichx(dev)) { + unsigned int extra = 0; + pci_read_config_dword(dev, 0x54, &extra); + pci_write_config_dword(dev, 0x54, extra|0x400); + } + + return 0; +} + +/** + * piix_dma_clear_irq - clear BMDMA status + * @drive: IDE drive to clear + * + * Called from ide_intr() for PIO interrupts + * to clear BMDMA status as needed by ICHx + */ +static void piix_dma_clear_irq(ide_drive_t *drive) +{ + ide_hwif_t *hwif = HWIF(drive); + u8 dma_stat; + + /* clear the INTR & ERROR bits */ + dma_stat = hwif->INB(hwif->dma_status); + /* Should we force the bit as well ? */ + hwif->OUTB(dma_stat, hwif->dma_status); +} + +static int __devinit piix_cable_detect(ide_hwif_t *hwif) +{ + struct pci_dev *dev = hwif->pci_dev; + u8 reg54h = 0, mask = hwif->channel ? 0xc0 : 0x30; + + pci_read_config_byte(dev, 0x54, ®54h); + + return (reg54h & mask) ? 1 : 0; +} + +/** * init_hwif_piix - fill in the hwif for the PIIX * @hwif: IDE interface * @@ -460,9 +489,6 @@ static unsigned int __devinit init_chipset_piix (struct pci_dev *dev, const char static void __devinit init_hwif_piix(ide_hwif_t *hwif) { - u8 reg54h = 0, reg55h = 0, ata66 = 0; - u8 mask = hwif->channel ? 0xc0 : 0x30; - #ifndef CONFIG_IA64 if (!hwif->irq) hwif->irq = hwif->channel ? 15 : 14; @@ -472,10 +498,6 @@ static void __devinit init_hwif_piix(ide_hwif_t *hwif) /* This is a painful system best to let it self tune for now */ return; } - /* ESB2 appears to generate spurious DMA interrupts in PIO mode - when in native mode */ - if (hwif->pci_dev->device == PCI_DEVICE_ID_INTEL_ESB2_18) - hwif->atapi_irq_bogon = 1; hwif->autodma = 0; hwif->tuneproc = &piix_tune_drive; @@ -486,15 +508,16 @@ static void __devinit init_hwif_piix(ide_hwif_t *hwif) if (!hwif->dma_base) return; + /* ICHx need to clear the bmdma status for all interrupts */ + if (piix_is_ichx(hwif->pci_dev)) + hwif->ide_dma_clear_irq = &piix_dma_clear_irq; + hwif->atapi_dma = 1; hwif->ultra_mask = 0x3f; hwif->mwdma_mask = 0x06; hwif->swdma_mask = 0x04; switch(hwif->pci_dev->device) { - case PCI_DEVICE_ID_INTEL_82371MX: - hwif->mwdma_mask = 0x80; - hwif->swdma_mask = 0x80; case PCI_DEVICE_ID_INTEL_82371FB_0: case PCI_DEVICE_ID_INTEL_82371FB_1: case PCI_DEVICE_ID_INTEL_82371SB_1: @@ -507,14 +530,14 @@ static void __devinit init_hwif_piix(ide_hwif_t *hwif) hwif->ultra_mask = 0x07; break; default: - pci_read_config_byte(hwif->pci_dev, 0x54, ®54h); - pci_read_config_byte(hwif->pci_dev, 0x55, ®55h); - ata66 = (reg54h & mask) ? 1 : 0; + if (!hwif->udma_four) + hwif->udma_four = piix_cable_detect(hwif); break; } - if (!(hwif->udma_four)) - hwif->udma_four = ata66; + if (no_piix_dma) + hwif->ultra_mask = hwif->mwdma_mask = hwif->swdma_mask = 0; + hwif->ide_dma_check = &piix_config_drive_xfer_rate; if (!noautodma) hwif->autodma = 1; diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c index 8d762d323f8..b5ae0c50e21 100644 --- a/drivers/ide/pci/sc1200.c +++ b/drivers/ide/pci/sc1200.c @@ -161,7 +161,7 @@ static int sc1200_config_dma2 (ide_drive_t *drive, int mode) /* * Default to DMA-off in case we run into trouble here. */ - hwif->ide_dma_off_quietly(drive); /* turn off DMA while we fiddle */ + hwif->dma_off_quietly(drive); /* turn off DMA while we fiddle */ outb(inb(hwif->dma_base+2)&~(unit?0x40:0x20), hwif->dma_base+2); /* clear DMA_capable bit */ /* @@ -241,10 +241,7 @@ static int sc1200_config_dma2 (ide_drive_t *drive, int mode) outb(inb(hwif->dma_base+2)|(unit?0x40:0x20), hwif->dma_base+2); /* set DMA_capable bit */ - /* - * Finally, turn DMA on in software, and exit. - */ - return hwif->ide_dma_on(drive); /* success */ + return 0; /* success */ } /* @@ -442,10 +439,10 @@ static int sc1200_resume (struct pci_dev *dev) ide_drive_t *drive = &(hwif->drives[d]); if (drive->present && !__ide_dma_bad_drive(drive)) { int was_using_dma = drive->using_dma; - hwif->ide_dma_off_quietly(drive); + hwif->dma_off_quietly(drive); sc1200_config_dma(drive); if (!was_using_dma && drive->using_dma) { - hwif->ide_dma_off_quietly(drive); + hwif->dma_off_quietly(drive); } } } diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c index ea9a28a4585..dbcd37a0c65 100644 --- a/drivers/ide/pci/serverworks.c +++ b/drivers/ide/pci/serverworks.c @@ -160,7 +160,7 @@ static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed) if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) || (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) { if (!drive->init_speed) { - u8 dma_stat = hwif->INB(hwif->dma_status); + u8 dma_stat = inb(hwif->dma_status); dma_pio: if (((ultra_enable << (7-drive->dn) & 0x80) == 0x80) && @@ -315,35 +315,15 @@ static int config_chipset_for_dma (ide_drive_t *drive) static int svwks_config_drive_xfer_rate (ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct hd_driveid *id = drive->id; - drive->init_speed = 0; - if ((id->capability & 1) && drive->autodma) { - - if (ide_use_dma(drive)) { - if (config_chipset_for_dma(drive)) - return hwif->ide_dma_on(drive); - } - - goto fast_ata_pio; + if (ide_use_dma(drive) && config_chipset_for_dma(drive)) + return 0; - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: + if (ide_use_fast_pio(drive)) config_chipset_for_pio(drive); - // hwif->tuneproc(drive, 5); - return hwif->ide_dma_off_quietly(drive); - } - /* IORDY not supported */ - return 0; -} - -/* This can go soon */ -static int svwks_ide_dma_end (ide_drive_t *drive) -{ - return __ide_dma_end(drive); + return -1; } static unsigned int __devinit init_chipset_svwks (struct pci_dev *dev, const char *name) @@ -537,35 +517,20 @@ static void __devinit init_hwif_svwks (ide_hwif_t *hwif) } hwif->ide_dma_check = &svwks_config_drive_xfer_rate; - if (hwif->pci_dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) - hwif->ide_dma_end = &svwks_ide_dma_end; - else if (!(hwif->udma_four)) - hwif->udma_four = ata66_svwks(hwif); + if (hwif->pci_dev->device != PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) { + if (!hwif->udma_four) + hwif->udma_four = ata66_svwks(hwif); + } if (!noautodma) hwif->autodma = 1; - dma_stat = hwif->INB(hwif->dma_status); + dma_stat = inb(hwif->dma_status); hwif->drives[0].autodma = (dma_stat & 0x20); hwif->drives[1].autodma = (dma_stat & 0x40); hwif->drives[0].autotune = (!(dma_stat & 0x20)); hwif->drives[1].autotune = (!(dma_stat & 0x40)); } -/* - * We allow the BM-DMA driver to only work on enabled interfaces. - */ -static void __devinit init_dma_svwks (ide_hwif_t *hwif, unsigned long dmabase) -{ - struct pci_dev *dev = hwif->pci_dev; - - if (((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) || - (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) && - (!(PCI_FUNC(dev->devfn) & 1)) && (hwif->channel)) - return; - - ide_setup_dma(hwif, dmabase, 8); -} - static int __devinit init_setup_svwks (struct pci_dev *dev, ide_pci_device_t *d) { return ide_setup_pci_device(dev, d); @@ -600,7 +565,6 @@ static ide_pci_device_t serverworks_chipsets[] __devinitdata = { .init_setup = init_setup_svwks, .init_chipset = init_chipset_svwks, .init_hwif = init_hwif_svwks, - .init_dma = init_dma_svwks, .channels = 2, .autodma = AUTODMA, .bootable = ON_BOARD, @@ -609,7 +573,6 @@ static ide_pci_device_t serverworks_chipsets[] __devinitdata = { .init_setup = init_setup_csb6, .init_chipset = init_chipset_svwks, .init_hwif = init_hwif_svwks, - .init_dma = init_dma_svwks, .channels = 2, .autodma = AUTODMA, .bootable = ON_BOARD, @@ -618,7 +581,6 @@ static ide_pci_device_t serverworks_chipsets[] __devinitdata = { .init_setup = init_setup_csb6, .init_chipset = init_chipset_svwks, .init_hwif = init_hwif_svwks, - .init_dma = init_dma_svwks, .channels = 1, /* 2 */ .autodma = AUTODMA, .bootable = ON_BOARD, @@ -627,7 +589,6 @@ static ide_pci_device_t serverworks_chipsets[] __devinitdata = { .init_setup = init_setup_svwks, .init_chipset = init_chipset_svwks, .init_hwif = init_hwif_svwks, - .init_dma = init_dma_svwks, .channels = 1, /* 2 */ .autodma = AUTODMA, .bootable = ON_BOARD, diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index b0bf0180927..fd09b295a69 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c @@ -110,24 +110,24 @@ sgiioc4_init_hwif_ports(hw_regs_t * hw, unsigned long data_port, static void sgiioc4_maskproc(ide_drive_t * drive, int mask) { - ide_hwif_t *hwif = HWIF(drive); - hwif->OUTB(mask ? (drive->ctl | 2) : (drive->ctl & ~2), - IDE_CONTROL_REG); + writeb(mask ? (drive->ctl | 2) : (drive->ctl & ~2), + (void __iomem *)IDE_CONTROL_REG); } static int sgiioc4_checkirq(ide_hwif_t * hwif) { - u8 intr_reg = - hwif->INL(hwif->io_ports[IDE_IRQ_OFFSET] + IOC4_INTR_REG * 4); + unsigned long intr_addr = + hwif->io_ports[IDE_IRQ_OFFSET] + IOC4_INTR_REG * 4; - if (intr_reg & 0x03) + if ((u8)readl((void __iomem *)intr_addr) & 0x03) return 1; return 0; } +static u8 sgiioc4_INB(unsigned long); static int sgiioc4_clearirq(ide_drive_t * drive) @@ -138,21 +138,21 @@ sgiioc4_clearirq(ide_drive_t * drive) hwif->io_ports[IDE_IRQ_OFFSET] + (IOC4_INTR_REG << 2); /* Code to check for PCI error conditions */ - intr_reg = hwif->INL(other_ir); + intr_reg = readl((void __iomem *)other_ir); if (intr_reg & 0x03) { /* Valid IOC4-IDE interrupt */ /* - * Using hwif->INB to read the IDE_STATUS_REG has a side effect + * Using sgiioc4_INB to read the IDE_STATUS_REG has a side effect * of clearing the interrupt. The first read should clear it * if it is set. The second read should return a "clear" status * if it got cleared. If not, then spin for a bit trying to * clear it. */ - u8 stat = hwif->INB(IDE_STATUS_REG); + u8 stat = sgiioc4_INB(IDE_STATUS_REG); int count = 0; - stat = hwif->INB(IDE_STATUS_REG); + stat = sgiioc4_INB(IDE_STATUS_REG); while ((stat & 0x80) && (count++ < 100)) { udelay(1); - stat = hwif->INB(IDE_STATUS_REG); + stat = sgiioc4_INB(IDE_STATUS_REG); } if (intr_reg & 0x02) { @@ -161,9 +161,9 @@ sgiioc4_clearirq(ide_drive_t * drive) pci_stat_cmd_reg; pci_err_addr_low = - hwif->INL(hwif->io_ports[IDE_IRQ_OFFSET]); + readl((void __iomem *)hwif->io_ports[IDE_IRQ_OFFSET]); pci_err_addr_high = - hwif->INL(hwif->io_ports[IDE_IRQ_OFFSET] + 4); + readl((void __iomem *)(hwif->io_ports[IDE_IRQ_OFFSET] + 4)); pci_read_config_dword(hwif->pci_dev, PCI_COMMAND, &pci_stat_cmd_reg); printk(KERN_ERR @@ -180,9 +180,9 @@ sgiioc4_clearirq(ide_drive_t * drive) } /* Clear the Interrupt, Error bits on the IOC4 */ - hwif->OUTL(0x03, other_ir); + writel(0x03, (void __iomem *)other_ir); - intr_reg = hwif->INL(other_ir); + intr_reg = readl((void __iomem *)other_ir); } return intr_reg & 3; @@ -191,23 +191,25 @@ sgiioc4_clearirq(ide_drive_t * drive) static void sgiioc4_ide_dma_start(ide_drive_t * drive) { ide_hwif_t *hwif = HWIF(drive); - unsigned int reg = hwif->INL(hwif->dma_base + IOC4_DMA_CTRL * 4); + unsigned long ioc4_dma_addr = hwif->dma_base + IOC4_DMA_CTRL * 4; + unsigned int reg = readl((void __iomem *)ioc4_dma_addr); unsigned int temp_reg = reg | IOC4_S_DMA_START; - hwif->OUTL(temp_reg, hwif->dma_base + IOC4_DMA_CTRL * 4); + writel(temp_reg, (void __iomem *)ioc4_dma_addr); } static u32 sgiioc4_ide_dma_stop(ide_hwif_t *hwif, u64 dma_base) { + unsigned long ioc4_dma_addr = dma_base + IOC4_DMA_CTRL * 4; u32 ioc4_dma; int count; count = 0; - ioc4_dma = hwif->INL(dma_base + IOC4_DMA_CTRL * 4); + ioc4_dma = readl((void __iomem *)ioc4_dma_addr); while ((ioc4_dma & IOC4_S_DMA_STOP) && (count++ < 200)) { udelay(1); - ioc4_dma = hwif->INL(dma_base + IOC4_DMA_CTRL * 4); + ioc4_dma = readl((void __iomem *)ioc4_dma_addr); } return ioc4_dma; } @@ -218,11 +220,11 @@ sgiioc4_ide_dma_end(ide_drive_t * drive) { u32 ioc4_dma, bc_dev, bc_mem, num, valid = 0, cnt = 0; ide_hwif_t *hwif = HWIF(drive); - u64 dma_base = hwif->dma_base; + unsigned long dma_base = hwif->dma_base; int dma_stat = 0; unsigned long *ending_dma = ide_get_hwifdata(hwif); - hwif->OUTL(IOC4_S_DMA_STOP, dma_base + IOC4_DMA_CTRL * 4); + writel(IOC4_S_DMA_STOP, (void __iomem *)(dma_base + IOC4_DMA_CTRL * 4)); ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base); @@ -254,8 +256,8 @@ sgiioc4_ide_dma_end(ide_drive_t * drive) dma_stat = 1; } - bc_dev = hwif->INL(dma_base + IOC4_BC_DEV * 4); - bc_mem = hwif->INL(dma_base + IOC4_BC_MEM * 4); + bc_dev = readl((void __iomem *)(dma_base + IOC4_BC_DEV * 4)); + bc_mem = readl((void __iomem *)(dma_base + IOC4_BC_MEM * 4)); if ((bc_dev & 0x01FF) || (bc_mem & 0x1FF)) { if (bc_dev > bc_mem + 8) { @@ -273,34 +275,29 @@ sgiioc4_ide_dma_end(ide_drive_t * drive) } static int -sgiioc4_ide_dma_check(ide_drive_t * drive) +sgiioc4_ide_dma_on(ide_drive_t * drive) { - if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) { - printk(KERN_INFO - "Couldnot set %s in Multimode-2 DMA mode | " - "Drive %s using PIO instead\n", - drive->name, drive->name); - drive->using_dma = 0; - } else - drive->using_dma = 1; + drive->using_dma = 1; return 0; } -static int -sgiioc4_ide_dma_on(ide_drive_t * drive) +static void sgiioc4_dma_off_quietly(ide_drive_t *drive) { - drive->using_dma = 1; + drive->using_dma = 0; - return HWIF(drive)->ide_dma_host_on(drive); + drive->hwif->dma_host_off(drive); } -static int -sgiioc4_ide_dma_off_quietly(ide_drive_t * drive) +static int sgiioc4_ide_dma_check(ide_drive_t *drive) { - drive->using_dma = 0; - - return HWIF(drive)->ide_dma_host_off(drive); + /* FIXME: check for available DMA modes */ + if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) { + printk(KERN_WARNING "%s: couldn't set MWDMA2 mode, " + "using PIO instead\n", drive->name); + return -1; + } else + return 0; } /* returns 1 if dma irq issued, 0 otherwise */ @@ -310,21 +307,13 @@ sgiioc4_ide_dma_test_irq(ide_drive_t * drive) return sgiioc4_checkirq(HWIF(drive)); } -static int -sgiioc4_ide_dma_host_on(ide_drive_t * drive) +static void sgiioc4_dma_host_on(ide_drive_t * drive) { - if (drive->using_dma) - return 0; - - return 1; } -static int -sgiioc4_ide_dma_host_off(ide_drive_t * drive) +static void sgiioc4_dma_host_off(ide_drive_t * drive) { sgiioc4_clearirq(drive); - - return 0; } static int @@ -436,16 +425,17 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive) { u32 ioc4_dma; ide_hwif_t *hwif = HWIF(drive); - u64 dma_base = hwif->dma_base; + unsigned long dma_base = hwif->dma_base; + unsigned long ioc4_dma_addr = dma_base + IOC4_DMA_CTRL * 4; u32 dma_addr, ending_dma_addr; - ioc4_dma = hwif->INL(dma_base + IOC4_DMA_CTRL * 4); + ioc4_dma = readl((void __iomem *)ioc4_dma_addr); if (ioc4_dma & IOC4_S_DMA_ACTIVE) { printk(KERN_WARNING "%s(%s):Warning!! DMA from previous transfer was still active\n", __FUNCTION__, drive->name); - hwif->OUTL(IOC4_S_DMA_STOP, dma_base + IOC4_DMA_CTRL * 4); + writel(IOC4_S_DMA_STOP, (void __iomem *)ioc4_dma_addr); ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base); if (ioc4_dma & IOC4_S_DMA_STOP) @@ -454,13 +444,13 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive) __FUNCTION__, drive->name); } - ioc4_dma = hwif->INL(dma_base + IOC4_DMA_CTRL * 4); + ioc4_dma = readl((void __iomem *)ioc4_dma_addr); if (ioc4_dma & IOC4_S_DMA_ERROR) { printk(KERN_WARNING "%s(%s) : Warning!! - DMA Error during Previous" " transfer | status 0x%x\n", __FUNCTION__, drive->name, ioc4_dma); - hwif->OUTL(IOC4_S_DMA_STOP, dma_base + IOC4_DMA_CTRL * 4); + writel(IOC4_S_DMA_STOP, (void __iomem *)ioc4_dma_addr); ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base); if (ioc4_dma & IOC4_S_DMA_STOP) @@ -471,14 +461,14 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive) /* Address of the Scatter Gather List */ dma_addr = cpu_to_le32(hwif->dmatable_dma); - hwif->OUTL(dma_addr, dma_base + IOC4_DMA_PTR_L * 4); + writel(dma_addr, (void __iomem *)(dma_base + IOC4_DMA_PTR_L * 4)); /* Address of the Ending DMA */ memset(ide_get_hwifdata(hwif), 0, IOC4_IDE_CACHELINE_SIZE); ending_dma_addr = cpu_to_le32(hwif->dma_status); - hwif->OUTL(ending_dma_addr, dma_base + IOC4_DMA_END_ADDR * 4); + writel(ending_dma_addr, (void __iomem *)(dma_base + IOC4_DMA_END_ADDR * 4)); - hwif->OUTL(dma_direction, dma_base + IOC4_DMA_CTRL * 4); + writel(dma_direction, (void __iomem *)ioc4_dma_addr); drive->waiting_for_dma = 1; } @@ -590,7 +580,7 @@ static int sgiioc4_ide_dma_setup(ide_drive_t *drive) static void __devinit ide_init_sgiioc4(ide_hwif_t * hwif) { - hwif->mmio = 2; + hwif->mmio = 1; hwif->autodma = 1; hwif->atapi_dma = 1; hwif->ultra_mask = 0x0; /* Disable Ultra DMA */ @@ -613,10 +603,10 @@ ide_init_sgiioc4(ide_hwif_t * hwif) hwif->ide_dma_end = &sgiioc4_ide_dma_end; hwif->ide_dma_check = &sgiioc4_ide_dma_check; hwif->ide_dma_on = &sgiioc4_ide_dma_on; - hwif->ide_dma_off_quietly = &sgiioc4_ide_dma_off_quietly; + hwif->dma_off_quietly = &sgiioc4_dma_off_quietly; hwif->ide_dma_test_irq = &sgiioc4_ide_dma_test_irq; - hwif->ide_dma_host_on = &sgiioc4_ide_dma_host_on; - hwif->ide_dma_host_off = &sgiioc4_ide_dma_host_off; + hwif->dma_host_on = &sgiioc4_dma_host_on; + hwif->dma_host_off = &sgiioc4_dma_host_off; hwif->ide_dma_lostirq = &sgiioc4_ide_dma_lostirq; hwif->ide_dma_timeout = &__ide_dma_timeout; @@ -688,7 +678,7 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d) default_hwif_mmiops(hwif); /* Initializing chipset IRQ Registers */ - hwif->OUTL(0x03, irqport + IOC4_INTR_SET * 4); + writel(0x03, (void __iomem *)(irqport + IOC4_INTR_SET * 4)); ide_init_sgiioc4(hwif); @@ -729,8 +719,7 @@ out: return ret; } -static ide_pci_device_t sgiioc4_chipsets[] __devinitdata = { - { +static ide_pci_device_t sgiioc4_chipset __devinitdata = { /* Channel 0 */ .name = "SGIIOC4", .init_hwif = ide_init_sgiioc4, @@ -739,7 +728,6 @@ static ide_pci_device_t sgiioc4_chipsets[] __devinitdata = { .autodma = AUTODMA, /* SGI IOC4 doesn't have enablebits. */ .bootable = ON_BOARD, - } }; int @@ -751,8 +739,7 @@ ioc4_ide_attach_one(struct ioc4_driver_data *idd) if (idd->idd_variant == IOC4_VARIANT_PCI_RT) return 0; - return pci_init_sgiioc4(idd->idd_pdev, - &sgiioc4_chipsets[idd->idd_pci_id->driver_data]); + return pci_init_sgiioc4(idd->idd_pdev, &sgiioc4_chipset); } static struct ioc4_submodule ioc4_ide_submodule = { diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c index 4ff89c7d990..7b4c189a9d9 100644 --- a/drivers/ide/pci/siimage.c +++ b/drivers/ide/pci/siimage.c @@ -1,8 +1,9 @@ /* - * linux/drivers/ide/pci/siimage.c Version 1.07 Nov 30, 2003 + * linux/drivers/ide/pci/siimage.c Version 1.11 Jan 27, 2007 * * Copyright (C) 2001-2002 Andre Hedrick <andre@linux-ide.org> * Copyright (C) 2003 Red Hat <alan@redhat.com> + * Copyright (C) 2007 MontaVista Software, Inc. * * May be copied or modified under the terms of the GNU General Public License * @@ -205,41 +206,39 @@ static void siimage_tuneproc (ide_drive_t *drive, byte mode_wanted) unsigned long tfaddr = siimage_selreg(hwif, 0x02); /* cheat for now and use the docs */ - switch(mode_wanted) { - case 4: - speedp = 0x10c1; - speedt = 0x10c1; - break; - case 3: - speedp = 0x10C3; - speedt = 0x10C3; - break; - case 2: - speedp = 0x1104; - speedt = 0x1281; - break; - case 1: - speedp = 0x2283; - speedt = 0x1281; - break; - case 0: - default: - speedp = 0x328A; - speedt = 0x328A; - break; + switch (mode_wanted) { + case 4: + speedp = 0x10c1; + speedt = 0x10c1; + break; + case 3: + speedp = 0x10c3; + speedt = 0x10c3; + break; + case 2: + speedp = 0x1104; + speedt = 0x1281; + break; + case 1: + speedp = 0x2283; + speedt = 0x2283; + break; + case 0: + default: + speedp = 0x328a; + speedt = 0x328a; + break; } - if (hwif->mmio) - { - hwif->OUTW(speedt, addr); - hwif->OUTW(speedp, tfaddr); + + if (hwif->mmio) { + hwif->OUTW(speedp, addr); + hwif->OUTW(speedt, tfaddr); /* Now set up IORDY */ if(mode_wanted == 3 || mode_wanted == 4) hwif->OUTW(hwif->INW(tfaddr-2)|0x200, tfaddr-2); else hwif->OUTW(hwif->INW(tfaddr-2)&~0x200, tfaddr-2); - } - else - { + } else { pci_write_config_word(hwif->pci_dev, addr, speedp); pci_write_config_word(hwif->pci_dev, tfaddr, speedt); pci_read_config_word(hwif->pci_dev, tfaddr-2, &speedp); @@ -397,12 +396,9 @@ static int config_chipset_for_dma (ide_drive_t *drive) if (!speed) return 0; - if (ide_set_xfer_rate(drive, speed)) + if (siimage_tune_chipset(drive, speed)) return 0; - if (!drive->init_speed) - drive->init_speed = speed; - return ide_dma_enable(drive); } @@ -418,25 +414,13 @@ static int config_chipset_for_dma (ide_drive_t *drive) static int siimage_config_drive_for_dma (ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct hd_driveid *id = drive->id; - - if ((id->capability & 1) != 0 && drive->autodma) { - - if (ide_use_dma(drive)) { - if (config_chipset_for_dma(drive)) - return hwif->ide_dma_on(drive); - } - - goto fast_ata_pio; + if (ide_use_dma(drive) && config_chipset_for_dma(drive)) + return 0; - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: + if (ide_use_fast_pio(drive)) config_chipset_for_pio(drive, 1); - return hwif->ide_dma_off_quietly(drive); - } - /* IORDY not supported */ - return 0; + + return -1; } /* returns 1 if dma irq issued, 0 otherwise */ @@ -472,11 +456,11 @@ static int siimage_mmio_ide_dma_test_irq (ide_drive_t *drive) unsigned long addr = siimage_selreg(hwif, 0x1); if (SATA_ERROR_REG) { - u32 ext_stat = hwif->INL(base + 0x10); + u32 ext_stat = readl((void __iomem *)(base + 0x10)); u8 watchdog = 0; if (ext_stat & ((hwif->channel) ? 0x40 : 0x10)) { - u32 sata_error = hwif->INL(SATA_ERROR_REG); - hwif->OUTL(sata_error, SATA_ERROR_REG); + u32 sata_error = readl((void __iomem *)SATA_ERROR_REG); + writel(sata_error, (void __iomem *)SATA_ERROR_REG); watchdog = (sata_error & 0x00680000) ? 1 : 0; printk(KERN_WARNING "%s: sata_error = 0x%08x, " "watchdog = %d, %s\n", @@ -493,11 +477,11 @@ static int siimage_mmio_ide_dma_test_irq (ide_drive_t *drive) } /* return 1 if INTR asserted */ - if ((hwif->INB(hwif->dma_status) & 0x04) == 0x04) + if ((readb((void __iomem *)hwif->dma_status) & 0x04) == 0x04) return 1; /* return 1 if Device INTR asserted */ - if ((hwif->INB(addr) & 8) == 8) + if ((readb((void __iomem *)addr) & 8) == 8) return 0; //return 1; return 0; @@ -519,9 +503,9 @@ static int siimage_busproc (ide_drive_t * drive, int state) u32 stat_config = 0; unsigned long addr = siimage_selreg(hwif, 0); - if (hwif->mmio) { - stat_config = hwif->INL(addr); - } else + if (hwif->mmio) + stat_config = readl((void __iomem *)addr); + else pci_read_config_dword(hwif->pci_dev, addr, &stat_config); switch (state) { @@ -557,9 +541,10 @@ static int siimage_reset_poll (ide_drive_t *drive) if (SATA_STATUS_REG) { ide_hwif_t *hwif = HWIF(drive); - if ((hwif->INL(SATA_STATUS_REG) & 0x03) != 0x03) { + /* SATA_STATUS_REG is valid only when in MMIO mode */ + if ((readl((void __iomem *)SATA_STATUS_REG) & 0x03) != 0x03) { printk(KERN_WARNING "%s: reset phy dead, status=0x%08x\n", - hwif->name, hwif->INL(SATA_STATUS_REG)); + hwif->name, readl((void __iomem *)SATA_STATUS_REG)); HWGROUP(drive)->polling = 0; return ide_started; } @@ -619,7 +604,8 @@ static void siimage_reset (ide_drive_t *drive) } if (SATA_STATUS_REG) { - u32 sata_stat = hwif->INL(SATA_STATUS_REG); + /* SATA_STATUS_REG is valid only when in MMIO mode */ + u32 sata_stat = readl((void __iomem *)SATA_STATUS_REG); printk(KERN_WARNING "%s: reset phy, status=0x%08x, %s\n", hwif->name, sata_stat, __FUNCTION__); if (!(sata_stat)) { @@ -898,7 +884,8 @@ static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif) base = (unsigned long) addr; hwif->dma_base = base + (ch ? 0x08 : 0x00); - hwif->mmio = 2; + + hwif->mmio = 1; } static int is_dev_seagate_sata(ide_drive_t *drive) diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c index 1afff659ab5..2ba0669f36a 100644 --- a/drivers/ide/pci/sis5513.c +++ b/drivers/ide/pci/sis5513.c @@ -667,67 +667,20 @@ static int config_chipset_for_dma (ide_drive_t *drive) return ide_dma_enable(drive); } -static int sis5513_config_drive_xfer_rate (ide_drive_t *drive) +static int sis5513_config_xfer_rate(ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct hd_driveid *id = drive->id; + config_art_rwp_pio(drive, 5); drive->init_speed = 0; - if (id && (id->capability & 1) && drive->autodma) { - - if (ide_use_dma(drive)) { - if (config_chipset_for_dma(drive)) - return hwif->ide_dma_on(drive); - } - - goto fast_ata_pio; + if (ide_use_dma(drive) && config_chipset_for_dma(drive)) + return 0; - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: + if (ide_use_fast_pio(drive)) sis5513_tune_drive(drive, 5); - return hwif->ide_dma_off_quietly(drive); - } - /* IORDY not supported */ - return 0; -} - -/* initiates/aborts (U)DMA read/write operations on a drive. */ -static int sis5513_config_xfer_rate (ide_drive_t *drive) -{ - config_drive_art_rwp(drive); - config_art_rwp_pio(drive, 5); - return sis5513_config_drive_xfer_rate(drive); -} - -/* - Future simpler config_xfer_rate : - When ide_find_best_mode is made bad-drive aware - - remove config_drive_xfer_rate and config_chipset_for_dma, - - replace config_xfer_rate with the following - -static int sis5513_config_xfer_rate (ide_drive_t *drive) -{ - u16 w80 = HWIF(drive)->udma_four; - u16 speed; - - config_drive_art_rwp(drive); - config_art_rwp_pio(drive, 5); - - speed = ide_find_best_mode(drive, - XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA | - (chipset_family >= ATA_33 ? XFER_UDMA : 0) | - (w80 && chipset_family >= ATA_66 ? XFER_UDMA_66 : 0) | - (w80 && chipset_family >= ATA_100a ? XFER_UDMA_100 : 0) | - (w80 && chipset_family >= ATA_133a ? XFER_UDMA_133 : 0)); - - sis5513_tune_chipset(drive, speed); - if (drive->autodma && (speed & XFER_MODE) != XFER_PIO) - return HWIF(drive)->ide_dma_on(drive); - return HWIF(drive)->ide_dma_off_quietly(drive); + return -1; } -*/ /* Chip detection and general config */ static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const char *name) diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c index 170a2619905..3a8a76fc78c 100644 --- a/drivers/ide/pci/sl82c105.c +++ b/drivers/ide/pci/sl82c105.c @@ -161,14 +161,14 @@ static int sl82c105_check_drive (ide_drive_t *drive) if (id->field_valid & 2) { if ((id->dma_mword & hwif->mwdma_mask) || (id->dma_1word & hwif->swdma_mask)) - return hwif->ide_dma_on(drive); + return 0; } - if (__ide_dma_good_drive(drive)) - return hwif->ide_dma_on(drive); + if (__ide_dma_good_drive(drive) && id->eide_dma_time < 150) + return 0; } while (0); - return hwif->ide_dma_off_quietly(drive); + return -1; } /* @@ -215,7 +215,7 @@ static int sl82c105_ide_dma_lost_irq(ide_drive_t *drive) * Was DMA enabled? If so, disable it - we're resetting the * host. The IDE layer will be handling the drive for us. */ - val = hwif->INB(dma_base); + val = inb(dma_base); if (val & 1) { outb(val & ~1, dma_base); printk("sl82c105: DMA was enabled\n"); @@ -259,28 +259,22 @@ static int sl82c105_ide_dma_on (ide_drive_t *drive) { DBG(("sl82c105_ide_dma_on(drive:%s)\n", drive->name)); - if (config_for_dma(drive)) { - config_for_pio(drive, 4, 0, 0); - return HWIF(drive)->ide_dma_off_quietly(drive); - } + if (config_for_dma(drive)) + return 1; printk(KERN_INFO "%s: DMA enabled\n", drive->name); return __ide_dma_on(drive); } -static int sl82c105_ide_dma_off_quietly (ide_drive_t *drive) +static void sl82c105_dma_off_quietly(ide_drive_t *drive) { u8 speed = XFER_PIO_0; - int rc; - - DBG(("sl82c105_ide_dma_off_quietly(drive:%s)\n", drive->name)); - rc = __ide_dma_off_quietly(drive); + DBG(("sl82c105_dma_off_quietly(drive:%s)\n", drive->name)); + + ide_dma_off_quietly(drive); if (drive->pio_speed) speed = drive->pio_speed - XFER_PIO_0; config_for_pio(drive, speed, 0, 1); - drive->current_speed = drive->pio_speed; - - return rc; } /* @@ -401,11 +395,9 @@ static unsigned int __devinit init_chipset_sl82c105(struct pci_dev *dev, const c /* * Initialise the chip */ - static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) { unsigned int rev; - u8 dma_state; DBG(("init_hwif_sl82c105(hwif: ide%d)\n", hwif->index)); @@ -431,7 +423,6 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) if (!hwif->dma_base) return; - dma_state = hwif->INB(hwif->dma_base + 2) & ~0x60; rev = sl82c105_bridge_revision(hwif->pci_dev); if (rev <= 5) { /* @@ -441,15 +432,12 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) printk(" %s: Winbond 553 bridge revision %d, BM-DMA disabled\n", hwif->name, rev); } else { - dma_state |= 0x60; - hwif->atapi_dma = 1; - hwif->mwdma_mask = 0x07; - hwif->swdma_mask = 0x07; + hwif->mwdma_mask = 0x04; hwif->ide_dma_check = &sl82c105_check_drive; hwif->ide_dma_on = &sl82c105_ide_dma_on; - hwif->ide_dma_off_quietly = &sl82c105_ide_dma_off_quietly; + hwif->dma_off_quietly = &sl82c105_dma_off_quietly; hwif->ide_dma_lostirq = &sl82c105_ide_dma_lost_irq; hwif->dma_start = &sl82c105_ide_dma_start; hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout; @@ -462,7 +450,6 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) if (hwif->mate) hwif->serialized = hwif->mate->serialized = 1; } - hwif->OUTB(dma_state, hwif->dma_base + 2); } static ide_pci_device_t sl82c105_chipset __devinitdata = { diff --git a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c index 2663ddbd9b6..ae7eb58d961 100644 --- a/drivers/ide/pci/slc90e66.c +++ b/drivers/ide/pci/slc90e66.c @@ -179,26 +179,16 @@ static int slc90e66_config_drive_for_dma (ide_drive_t *drive) static int slc90e66_config_drive_xfer_rate (ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct hd_driveid *id = drive->id; - drive->init_speed = 0; - if ((id->capability & 1) && drive->autodma) { - - if (ide_use_dma(drive) && slc90e66_config_drive_for_dma(drive)) - return hwif->ide_dma_on(drive); + if (ide_use_dma(drive) && slc90e66_config_drive_for_dma(drive)) + return 0; - goto fast_ata_pio; + if (ide_use_fast_pio(drive)) + (void)slc90e66_tune_chipset(drive, XFER_PIO_0 + + ide_get_best_pio_mode(drive, 255, 4, NULL)); - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: - (void) hwif->speedproc(drive, XFER_PIO_0 + - ide_get_best_pio_mode(drive, 255, 4, NULL)); - return hwif->ide_dma_off_quietly(drive); - } - /* IORDY not supported */ - return 0; + return -1; } static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif) diff --git a/drivers/ide/pci/tc86c001.c b/drivers/ide/pci/tc86c001.c index 2ad72bbda34..0b6d81d6ce4 100644 --- a/drivers/ide/pci/tc86c001.c +++ b/drivers/ide/pci/tc86c001.c @@ -45,7 +45,7 @@ static int tc86c001_tune_chipset(ide_drive_t *drive, u8 speed) scr &= (speed < XFER_MW_DMA_0) ? 0xf8ff : 0xff0f; scr |= mode; - hwif->OUTW(scr, scr_port); + outw(scr, scr_port); return ide_config_drive_speed(drive, speed); } @@ -89,15 +89,15 @@ static int tc86c001_timer_expiry(ide_drive_t *drive) "attempting recovery...\n", drive->name); /* Stop DMA */ - hwif->OUTB(dma_cmd & ~0x01, hwif->dma_command); + outb(dma_cmd & ~0x01, hwif->dma_command); /* Setup the dummy DMA transfer */ - hwif->OUTW(0, sc_base + 0x0a); /* Sector Count */ - hwif->OUTW(0, twcr_port); /* Transfer Word Count 1 or 2 */ + outw(0, sc_base + 0x0a); /* Sector Count */ + outw(0, twcr_port); /* Transfer Word Count 1 or 2 */ /* Start the dummy DMA transfer */ - hwif->OUTB(0x00, hwif->dma_command); /* clear R_OR_WCTR for write */ - hwif->OUTB(0x01, hwif->dma_command); /* set START_STOPBM */ + outb(0x00, hwif->dma_command); /* clear R_OR_WCTR for write */ + outb(0x01, hwif->dma_command); /* set START_STOPBM */ /* * If an interrupt was pending, it should come thru shortly. @@ -128,8 +128,8 @@ static void tc86c001_dma_start(ide_drive_t *drive) * the appropriate system control registers for DMA to work * with LBA48 and ATAPI devices... */ - hwif->OUTW(nsectors, sc_base + 0x0a); /* Sector Count */ - hwif->OUTW(SECTOR_SIZE / 2, twcr_port); /* Transfer Word Count 1/2 */ + outw(nsectors, sc_base + 0x0a); /* Sector Count */ + outw(SECTOR_SIZE / 2, twcr_port); /* Transfer Word Count 1/2 */ /* Install our timeout expiry hook, saving the current handler... */ ide_set_hwifdata(hwif, hwgroup->expiry); @@ -168,7 +168,7 @@ static int tc86c001_busproc(ide_drive_t *drive, int state) } /* System Control 1 Register bit 11 (ATA Hard Reset) write */ - hwif->OUTW(scr1, sc_base + 0x00); + outw(scr1, sc_base + 0x00); return 0; } @@ -185,23 +185,13 @@ static int config_chipset_for_dma(ide_drive_t *drive) static int tc86c001_config_drive_xfer_rate(ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct hd_driveid *id = drive->id; - - if ((id->capability & 1) && drive->autodma) { - - if (ide_use_dma(drive) && config_chipset_for_dma(drive)) - return hwif->ide_dma_on(drive); - - goto fast_ata_pio; + if (ide_use_dma(drive) && config_chipset_for_dma(drive)) + return 0; - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: + if (ide_use_fast_pio(drive)) tc86c001_tune_drive(drive, 255); - return hwif->ide_dma_off_quietly(drive); - } - /* IORDY not supported */ - return 0; + + return -1; } static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif) @@ -210,13 +200,13 @@ static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif) u16 scr1 = hwif->INW(sc_base + 0x00);; /* System Control 1 Register bit 15 (Soft Reset) set */ - hwif->OUTW(scr1 | 0x8000, sc_base + 0x00); + outw(scr1 | 0x8000, sc_base + 0x00); /* System Control 1 Register bit 14 (FIFO Reset) set */ - hwif->OUTW(scr1 | 0x4000, sc_base + 0x00); + outw(scr1 | 0x4000, sc_base + 0x00); /* System Control 1 Register: reset clear */ - hwif->OUTW(scr1 & ~0xc000, sc_base + 0x00); + outw(scr1 & ~0xc000, sc_base + 0x00); /* Store the system control register base for convenience... */ hwif->config_data = sc_base; @@ -234,7 +224,7 @@ static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif) * Sector Count Control Register bits 0 and 1 set: * software sets Sector Count Register for master and slave device */ - hwif->OUTW(0x0003, sc_base + 0x0c); + outw(0x0003, sc_base + 0x0c); /* Sector Count Register limit */ hwif->rqsize = 0xffff; diff --git a/drivers/ide/pci/triflex.c b/drivers/ide/pci/triflex.c index b13cce1fd1a..5e06179c346 100644 --- a/drivers/ide/pci/triflex.c +++ b/drivers/ide/pci/triflex.c @@ -104,29 +104,21 @@ static int triflex_config_drive_for_dma(ide_drive_t *drive) { int speed = ide_dma_speed(drive, 0); /* No ultra speeds */ - if (!speed) { - u8 pspeed = ide_get_best_pio_mode(drive, 255, 4, NULL); - speed = XFER_PIO_0 + pspeed; - } - + if (!speed) + return 0; + (void) triflex_tune_chipset(drive, speed); return ide_dma_enable(drive); } static int triflex_config_drive_xfer_rate(ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct hd_driveid *id = drive->id; - - if ((id->capability & 1) && drive->autodma) { - if (ide_use_dma(drive)) { - if (triflex_config_drive_for_dma(drive)) - return hwif->ide_dma_on(drive); - } - } + if (ide_use_dma(drive) && triflex_config_drive_for_dma(drive)) + return 0; + + triflex_tune_drive(drive, 255); - hwif->tuneproc(drive, 255); - return hwif->ide_dma_off_quietly(drive); + return -1; } static void __devinit init_hwif_triflex(ide_hwif_t *hwif) diff --git a/drivers/ide/pci/trm290.c b/drivers/ide/pci/trm290.c index 174b88c4780..cbb1b11119a 100644 --- a/drivers/ide/pci/trm290.c +++ b/drivers/ide/pci/trm290.c @@ -157,16 +157,16 @@ static void trm290_prepare_drive (ide_drive_t *drive, unsigned int use_dma) if (reg != hwif->select_data) { hwif->select_data = reg; /* set PIO/DMA */ - hwif->OUTB(0x51|(hwif->channel<<3), hwif->config_data+1); - hwif->OUTW(reg & 0xff, hwif->config_data); + outb(0x51 | (hwif->channel << 3), hwif->config_data + 1); + outw(reg & 0xff, hwif->config_data); } /* enable IRQ if not probing */ if (drive->present) { - reg = hwif->INW(hwif->config_data + 3); + reg = inw(hwif->config_data + 3); reg &= 0x13; reg &= ~(1 << hwif->channel); - hwif->OUTW(reg, hwif->config_data+3); + outw(reg, hwif->config_data + 3); } local_irq_restore(flags); @@ -177,15 +177,12 @@ static void trm290_selectproc (ide_drive_t *drive) trm290_prepare_drive(drive, drive->using_dma); } -#ifdef CONFIG_BLK_DEV_IDEDMA static void trm290_ide_dma_exec_cmd(ide_drive_t *drive, u8 command) { - ide_hwif_t *hwif = HWIF(drive); - BUG_ON(HWGROUP(drive)->handler != NULL); /* paranoia check */ ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); /* issue cmd to drive */ - hwif->OUTB(command, IDE_COMMAND_REG); + outb(command, IDE_COMMAND_REG); } static int trm290_ide_dma_setup(ide_drive_t *drive) @@ -211,10 +208,10 @@ static int trm290_ide_dma_setup(ide_drive_t *drive) } /* select DMA xfer */ trm290_prepare_drive(drive, 1); - hwif->OUTL(hwif->dmatable_dma|rw, hwif->dma_command); + outl(hwif->dmatable_dma | rw, hwif->dma_command); drive->waiting_for_dma = 1; /* start DMA */ - hwif->OUTW((count * 2) - 1, hwif->dma_status); + outw((count * 2) - 1, hwif->dma_status); return 0; } @@ -230,7 +227,7 @@ static int trm290_ide_dma_end (ide_drive_t *drive) drive->waiting_for_dma = 0; /* purge DMA mappings */ ide_destroy_dmatable(drive); - status = hwif->INW(hwif->dma_status); + status = inw(hwif->dma_status); return (status != 0x00ff); } @@ -239,10 +236,9 @@ static int trm290_ide_dma_test_irq (ide_drive_t *drive) ide_hwif_t *hwif = HWIF(drive); u16 status = 0; - status = hwif->INW(hwif->dma_status); + status = inw(hwif->dma_status); return (status == 0x00ff); } -#endif /* CONFIG_BLK_DEV_IDEDMA */ /* * Invoked from ide-dma.c at boot time. @@ -269,15 +265,15 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif) local_irq_save(flags); /* put config reg into first byte of hwif->select_data */ - hwif->OUTB(0x51|(hwif->channel<<3), hwif->config_data+1); + outb(0x51 | (hwif->channel << 3), hwif->config_data + 1); /* select PIO as default */ hwif->select_data = 0x21; - hwif->OUTB(hwif->select_data, hwif->config_data); + outb(hwif->select_data, hwif->config_data); /* get IRQ info */ - reg = hwif->INB(hwif->config_data+3); + reg = inb(hwif->config_data + 3); /* mask IRQs for both ports */ reg = (reg & 0x10) | 0x03; - hwif->OUTB(reg, hwif->config_data+3); + outb(reg, hwif->config_data + 3); local_irq_restore(flags); if ((reg & 0x10)) @@ -289,13 +285,11 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif) ide_setup_dma(hwif, (hwif->config_data + 4) ^ (hwif->channel ? 0x0080 : 0x0000), 3); -#ifdef CONFIG_BLK_DEV_IDEDMA hwif->dma_setup = &trm290_ide_dma_setup; hwif->dma_exec_cmd = &trm290_ide_dma_exec_cmd; hwif->dma_start = &trm290_ide_dma_start; hwif->ide_dma_end = &trm290_ide_dma_end; hwif->ide_dma_test_irq = &trm290_ide_dma_test_irq; -#endif /* CONFIG_BLK_DEV_IDEDMA */ hwif->selectproc = &trm290_selectproc; hwif->autodma = 0; /* play it safe for now */ @@ -312,16 +306,16 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif) static u16 next_offset = 0; u8 old_mask; - hwif->OUTB(0x54|(hwif->channel<<3), hwif->config_data+1); - old = hwif->INW(hwif->config_data); + outb(0x54 | (hwif->channel << 3), hwif->config_data + 1); + old = inw(hwif->config_data); old &= ~1; - old_mask = hwif->INB(old+2); + old_mask = inb(old + 2); if (old != compat && old_mask == 0xff) { /* leave lower 10 bits untouched */ compat += (next_offset += 0x400); hwif->io_ports[IDE_CONTROL_OFFSET] = compat + 2; - hwif->OUTW(compat|1, hwif->config_data); - new = hwif->INW(hwif->config_data); + outw(compat | 1, hwif->config_data); + new = inw(hwif->config_data); printk(KERN_INFO "%s: control basereg workaround: " "old=0x%04x, new=0x%04x\n", hwif->name, old, new & ~1); diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c index 6fb6e50b823..a508550c409 100644 --- a/drivers/ide/pci/via82cxxx.c +++ b/drivers/ide/pci/via82cxxx.c @@ -240,8 +240,9 @@ static int via82cxxx_ide_dma_check (ide_drive_t *drive) via_set_drive(drive, speed); if (drive->autodma && (speed & XFER_MODE) != XFER_PIO) - return hwif->ide_dma_on(drive); - return hwif->ide_dma_off_quietly(drive); + return 0; + + return -1; } static struct via_isa_bridge *via_config_find(struct pci_dev **isa) diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index d8ea23710bf..395d35253d5 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -1237,7 +1237,7 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) hwif->OUTBSYNC = pmac_outbsync; /* Tell common code _not_ to mess with resources */ - hwif->mmio = 2; + hwif->mmio = 1; hwif->hwif_data = pmif; pmac_ide_init_hwif_ports(&hwif->hw, pmif->regbase, 0, &hwif->irq); memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports)); @@ -1979,16 +1979,12 @@ pmac_ide_dma_test_irq (ide_drive_t *drive) return 1; } -static int -pmac_ide_dma_host_off (ide_drive_t *drive) +static void pmac_ide_dma_host_off(ide_drive_t *drive) { - return 0; } -static int -pmac_ide_dma_host_on (ide_drive_t *drive) +static int pmac_ide_dma_host_on(ide_drive_t *drive) { - return 0; } static int @@ -2034,7 +2030,7 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) return; } - hwif->ide_dma_off_quietly = &__ide_dma_off_quietly; + hwif->dma_off_quietly = &ide_dma_off_quietly; hwif->ide_dma_on = &__ide_dma_on; hwif->ide_dma_check = &pmac_ide_dma_check; hwif->dma_setup = &pmac_ide_dma_setup; @@ -2042,8 +2038,8 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) hwif->dma_start = &pmac_ide_dma_start; hwif->ide_dma_end = &pmac_ide_dma_end; hwif->ide_dma_test_irq = &pmac_ide_dma_test_irq; - hwif->ide_dma_host_off = &pmac_ide_dma_host_off; - hwif->ide_dma_host_on = &pmac_ide_dma_host_on; + hwif->dma_host_off = &pmac_ide_dma_host_off; + hwif->dma_host_on = &pmac_ide_dma_host_on; hwif->ide_dma_timeout = &__ide_dma_timeout; hwif->ide_dma_lostirq = &pmac_ide_dma_lostirq; diff --git a/drivers/ide/ppc/scc_pata.c b/drivers/ide/ppc/scc_pata.c new file mode 100644 index 00000000000..de64b022478 --- /dev/null +++ b/drivers/ide/ppc/scc_pata.c @@ -0,0 +1,831 @@ +/* + * Support for IDE interfaces on Celleb platform + * + * (C) Copyright 2006 TOSHIBA CORPORATION + * + * This code is based on drivers/ide/pci/siimage.c: + * Copyright (C) 2001-2002 Andre Hedrick <andre@linux-ide.org> + * Copyright (C) 2003 Red Hat <alan@redhat.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <linux/types.h> +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/delay.h> +#include <linux/hdreg.h> +#include <linux/ide.h> +#include <linux/init.h> + +#define PCI_DEVICE_ID_TOSHIBA_SCC_ATA 0x01b4 + +#define SCC_PATA_NAME "scc IDE" + +#define TDVHSEL_MASTER 0x00000001 +#define TDVHSEL_SLAVE 0x00000004 + +#define MODE_JCUSFEN 0x00000080 + +#define CCKCTRL_ATARESET 0x00040000 +#define CCKCTRL_BUFCNT 0x00020000 +#define CCKCTRL_CRST 0x00010000 +#define CCKCTRL_OCLKEN 0x00000100 +#define CCKCTRL_ATACLKOEN 0x00000002 +#define CCKCTRL_LCLKEN 0x00000001 + +#define QCHCD_IOS_SS 0x00000001 + +#define QCHSD_STPDIAG 0x00020000 + +#define INTMASK_MSK 0xD1000012 +#define INTSTS_SERROR 0x80000000 +#define INTSTS_PRERR 0x40000000 +#define INTSTS_RERR 0x10000000 +#define INTSTS_ICERR 0x01000000 +#define INTSTS_BMSINT 0x00000010 +#define INTSTS_BMHE 0x00000008 +#define INTSTS_IOIRQS 0x00000004 +#define INTSTS_INTRQ 0x00000002 +#define INTSTS_ACTEINT 0x00000001 + +#define ECMODE_VALUE 0x01 + +static struct scc_ports { + unsigned long ctl, dma; + unsigned char hwif_id; /* for removing hwif from system */ +} scc_ports[MAX_HWIFS]; + +/* PIO transfer mode table */ +/* JCHST */ +static unsigned long JCHSTtbl[2][7] = { + {0x0E, 0x05, 0x02, 0x03, 0x02, 0x00, 0x00}, /* 100MHz */ + {0x13, 0x07, 0x04, 0x04, 0x03, 0x00, 0x00} /* 133MHz */ +}; + +/* JCHHT */ +static unsigned long JCHHTtbl[2][7] = { + {0x0E, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00}, /* 100MHz */ + {0x13, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00} /* 133MHz */ +}; + +/* JCHCT */ +static unsigned long JCHCTtbl[2][7] = { + {0x1D, 0x1D, 0x1C, 0x0B, 0x06, 0x00, 0x00}, /* 100MHz */ + {0x27, 0x26, 0x26, 0x0E, 0x09, 0x00, 0x00} /* 133MHz */ +}; + + +/* DMA transfer mode table */ +/* JCHDCTM/JCHDCTS */ +static unsigned long JCHDCTxtbl[2][7] = { + {0x0A, 0x06, 0x04, 0x03, 0x01, 0x00, 0x00}, /* 100MHz */ + {0x0E, 0x09, 0x06, 0x04, 0x02, 0x01, 0x00} /* 133MHz */ +}; + +/* JCSTWTM/JCSTWTS */ +static unsigned long JCSTWTxtbl[2][7] = { + {0x06, 0x04, 0x03, 0x02, 0x02, 0x02, 0x00}, /* 100MHz */ + {0x09, 0x06, 0x04, 0x02, 0x02, 0x02, 0x02} /* 133MHz */ +}; + +/* JCTSS */ +static unsigned long JCTSStbl[2][7] = { + {0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x00}, /* 100MHz */ + {0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05} /* 133MHz */ +}; + +/* JCENVT */ +static unsigned long JCENVTtbl[2][7] = { + {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00}, /* 100MHz */ + {0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02} /* 133MHz */ +}; + +/* JCACTSELS/JCACTSELM */ +static unsigned long JCACTSELtbl[2][7] = { + {0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00}, /* 100MHz */ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01} /* 133MHz */ +}; + + +static u8 scc_ide_inb(unsigned long port) +{ + u32 data = in_be32((void*)port); + return (u8)data; +} + +static u16 scc_ide_inw(unsigned long port) +{ + u32 data = in_be32((void*)port); + return (u16)data; +} + +static void scc_ide_insw(unsigned long port, void *addr, u32 count) +{ + u16 *ptr = (u16 *)addr; + while (count--) { + *ptr++ = le16_to_cpu(in_be32((void*)port)); + } +} + +static void scc_ide_insl(unsigned long port, void *addr, u32 count) +{ + u16 *ptr = (u16 *)addr; + while (count--) { + *ptr++ = le16_to_cpu(in_be32((void*)port)); + *ptr++ = le16_to_cpu(in_be32((void*)port)); + } +} + +static void scc_ide_outb(u8 addr, unsigned long port) +{ + out_be32((void*)port, addr); +} + +static void scc_ide_outw(u16 addr, unsigned long port) +{ + out_be32((void*)port, addr); +} + +static void +scc_ide_outbsync(ide_drive_t * drive, u8 addr, unsigned long port) +{ + ide_hwif_t *hwif = HWIF(drive); + + out_be32((void*)port, addr); + __asm__ __volatile__("eieio":::"memory"); + in_be32((void*)(hwif->dma_base + 0x01c)); + __asm__ __volatile__("eieio":::"memory"); +} + +static void +scc_ide_outsw(unsigned long port, void *addr, u32 count) +{ + u16 *ptr = (u16 *)addr; + while (count--) { + out_be32((void*)port, cpu_to_le16(*ptr++)); + } +} + +static void +scc_ide_outsl(unsigned long port, void *addr, u32 count) +{ + u16 *ptr = (u16 *)addr; + while (count--) { + out_be32((void*)port, cpu_to_le16(*ptr++)); + out_be32((void*)port, cpu_to_le16(*ptr++)); + } +} + +/** + * scc_ratemask - Compute available modes + * @drive: IDE drive + * + * Compute the available speeds for the devices on the interface. + * Enforce UDMA33 as a limit if there is no 80pin cable present. + */ + +static u8 scc_ratemask(ide_drive_t *drive) +{ + u8 mode = 4; + + if (!eighty_ninty_three(drive)) + mode = min(mode, (u8)1); + return mode; +} + +/** + * scc_tuneproc - tune a drive PIO mode + * @drive: drive to tune + * @mode_wanted: the target operating mode + * + * Load the timing settings for this device mode into the + * controller. + */ + +static void scc_tuneproc(ide_drive_t *drive, byte mode_wanted) +{ + ide_hwif_t *hwif = HWIF(drive); + struct scc_ports *ports = ide_get_hwifdata(hwif); + unsigned long ctl_base = ports->ctl; + unsigned long cckctrl_port = ctl_base + 0xff0; + unsigned long piosht_port = ctl_base + 0x000; + unsigned long pioct_port = ctl_base + 0x004; + unsigned long reg; + unsigned char speed = XFER_PIO_0; + int offset; + + mode_wanted = ide_get_best_pio_mode(drive, mode_wanted, 4, NULL); + switch (mode_wanted) { + case 4: + speed = XFER_PIO_4; + break; + case 3: + speed = XFER_PIO_3; + break; + case 2: + speed = XFER_PIO_2; + break; + case 1: + speed = XFER_PIO_1; + break; + case 0: + default: + speed = XFER_PIO_0; + break; + } + + reg = in_be32((void __iomem *)cckctrl_port); + if (reg & CCKCTRL_ATACLKOEN) { + offset = 1; /* 133MHz */ + } else { + offset = 0; /* 100MHz */ + } + reg = JCHSTtbl[offset][mode_wanted] << 16 | JCHHTtbl[offset][mode_wanted]; + out_be32((void __iomem *)piosht_port, reg); + reg = JCHCTtbl[offset][mode_wanted]; + out_be32((void __iomem *)pioct_port, reg); + + ide_config_drive_speed(drive, speed); +} + +/** + * scc_tune_chipset - tune a drive DMA mode + * @drive: Drive to set up + * @xferspeed: speed we want to achieve + * + * Load the timing settings for this device mode into the + * controller. + */ + +static int scc_tune_chipset(ide_drive_t *drive, byte xferspeed) +{ + ide_hwif_t *hwif = HWIF(drive); + u8 speed = ide_rate_filter(scc_ratemask(drive), xferspeed); + struct scc_ports *ports = ide_get_hwifdata(hwif); + unsigned long ctl_base = ports->ctl; + unsigned long cckctrl_port = ctl_base + 0xff0; + unsigned long mdmact_port = ctl_base + 0x008; + unsigned long mcrcst_port = ctl_base + 0x00c; + unsigned long sdmact_port = ctl_base + 0x010; + unsigned long scrcst_port = ctl_base + 0x014; + unsigned long udenvt_port = ctl_base + 0x018; + unsigned long tdvhsel_port = ctl_base + 0x020; + int is_slave = (&hwif->drives[1] == drive); + int offset, idx; + unsigned long reg; + unsigned long jcactsel; + + reg = in_be32((void __iomem *)cckctrl_port); + if (reg & CCKCTRL_ATACLKOEN) { + offset = 1; /* 133MHz */ + } else { + offset = 0; /* 100MHz */ + } + + switch (speed) { + case XFER_UDMA_6: + idx = 6; + break; + case XFER_UDMA_5: + idx = 5; + break; + case XFER_UDMA_4: + idx = 4; + break; + case XFER_UDMA_3: + idx = 3; + break; + case XFER_UDMA_2: + idx = 2; + break; + case XFER_UDMA_1: + idx = 1; + break; + case XFER_UDMA_0: + idx = 0; + break; + default: + return 1; + } + + jcactsel = JCACTSELtbl[offset][idx]; + if (is_slave) { + out_be32((void __iomem *)sdmact_port, JCHDCTxtbl[offset][idx]); + out_be32((void __iomem *)scrcst_port, JCSTWTxtbl[offset][idx]); + jcactsel = jcactsel << 2; + out_be32((void __iomem *)tdvhsel_port, (in_be32((void __iomem *)tdvhsel_port) & ~TDVHSEL_SLAVE) | jcactsel); + } else { + out_be32((void __iomem *)mdmact_port, JCHDCTxtbl[offset][idx]); + out_be32((void __iomem *)mcrcst_port, JCSTWTxtbl[offset][idx]); + out_be32((void __iomem *)tdvhsel_port, (in_be32((void __iomem *)tdvhsel_port) & ~TDVHSEL_MASTER) | jcactsel); + } + reg = JCTSStbl[offset][idx] << 16 | JCENVTtbl[offset][idx]; + out_be32((void __iomem *)udenvt_port, reg); + + return ide_config_drive_speed(drive, speed); +} + +/** + * scc_config_chipset_for_dma - configure for DMA + * @drive: drive to configure + * + * Called by scc_config_drive_for_dma(). + */ + +static int scc_config_chipset_for_dma(ide_drive_t *drive) +{ + u8 speed = ide_dma_speed(drive, scc_ratemask(drive)); + + if (!speed) + return 0; + + if (scc_tune_chipset(drive, speed)) + return 0; + + return ide_dma_enable(drive); +} + +/** + * scc_configure_drive_for_dma - set up for DMA transfers + * @drive: drive we are going to set up + * + * Set up the drive for DMA, tune the controller and drive as + * required. + * If the drive isn't suitable for DMA or we hit other problems + * then we will drop down to PIO and set up PIO appropriately. + * (return 1) + */ + +static int scc_config_drive_for_dma(ide_drive_t *drive) +{ + if (ide_use_dma(drive) && scc_config_chipset_for_dma(drive)) + return 0; + + if (ide_use_fast_pio(drive)) + scc_tuneproc(drive, 4); + + return -1; +} + +/** + * scc_ide_dma_setup - begin a DMA phase + * @drive: target device + * + * Build an IDE DMA PRD (IDE speak for scatter gather table) + * and then set up the DMA transfer registers. + * + * Returns 0 on success. If a PIO fallback is required then 1 + * is returned. + */ + +static int scc_dma_setup(ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + struct request *rq = HWGROUP(drive)->rq; + unsigned int reading; + u8 dma_stat; + + if (rq_data_dir(rq)) + reading = 0; + else + reading = 1 << 3; + + /* fall back to pio! */ + if (!ide_build_dmatable(drive, rq)) { + ide_map_sg(drive, rq); + return 1; + } + + /* PRD table */ + out_be32((void __iomem *)hwif->dma_prdtable, hwif->dmatable_dma); + + /* specify r/w */ + out_be32((void __iomem *)hwif->dma_command, reading); + + /* read dma_status for INTR & ERROR flags */ + dma_stat = in_be32((void __iomem *)hwif->dma_status); + + /* clear INTR & ERROR flags */ + out_be32((void __iomem *)hwif->dma_status, dma_stat|6); + drive->waiting_for_dma = 1; + return 0; +} + + +/** + * scc_ide_dma_end - Stop DMA + * @drive: IDE drive + * + * Check and clear INT Status register. + * Then call __ide_dma_end(). + */ + +static int scc_ide_dma_end(ide_drive_t * drive) +{ + ide_hwif_t *hwif = HWIF(drive); + unsigned long intsts_port = hwif->dma_base + 0x014; + u32 reg; + + while (1) { + reg = in_be32((void __iomem *)intsts_port); + + if (reg & INTSTS_SERROR) { + printk(KERN_WARNING "%s: SERROR\n", SCC_PATA_NAME); + out_be32((void __iomem *)intsts_port, INTSTS_SERROR|INTSTS_BMSINT); + + out_be32((void __iomem *)hwif->dma_command, in_be32((void __iomem *)hwif->dma_command) & ~QCHCD_IOS_SS); + continue; + } + + if (reg & INTSTS_PRERR) { + u32 maea0, maec0; + unsigned long ctl_base = hwif->config_data; + + maea0 = in_be32((void __iomem *)(ctl_base + 0xF50)); + maec0 = in_be32((void __iomem *)(ctl_base + 0xF54)); + + printk(KERN_WARNING "%s: PRERR [addr:%x cmd:%x]\n", SCC_PATA_NAME, maea0, maec0); + + out_be32((void __iomem *)intsts_port, INTSTS_PRERR|INTSTS_BMSINT); + + out_be32((void __iomem *)hwif->dma_command, in_be32((void __iomem *)hwif->dma_command) & ~QCHCD_IOS_SS); + continue; + } + + if (reg & INTSTS_RERR) { + printk(KERN_WARNING "%s: Response Error\n", SCC_PATA_NAME); + out_be32((void __iomem *)intsts_port, INTSTS_RERR|INTSTS_BMSINT); + + out_be32((void __iomem *)hwif->dma_command, in_be32((void __iomem *)hwif->dma_command) & ~QCHCD_IOS_SS); + continue; + } + + if (reg & INTSTS_ICERR) { + out_be32((void __iomem *)hwif->dma_command, in_be32((void __iomem *)hwif->dma_command) & ~QCHCD_IOS_SS); + + printk(KERN_WARNING "%s: Illegal Configuration\n", SCC_PATA_NAME); + out_be32((void __iomem *)intsts_port, INTSTS_ICERR|INTSTS_BMSINT); + continue; + } + + if (reg & INTSTS_BMSINT) { + printk(KERN_WARNING "%s: Internal Bus Error\n", SCC_PATA_NAME); + out_be32((void __iomem *)intsts_port, INTSTS_BMSINT); + + ide_do_reset(drive); + continue; + } + + if (reg & INTSTS_BMHE) { + out_be32((void __iomem *)intsts_port, INTSTS_BMHE); + continue; + } + + if (reg & INTSTS_ACTEINT) { + out_be32((void __iomem *)intsts_port, INTSTS_ACTEINT); + continue; + } + + if (reg & INTSTS_IOIRQS) { + out_be32((void __iomem *)intsts_port, INTSTS_IOIRQS); + continue; + } + break; + } + + return __ide_dma_end(drive); +} + +/** + * setup_mmio_scc - map CTRL/BMID region + * @dev: PCI device we are configuring + * @name: device name + * + */ + +static int setup_mmio_scc (struct pci_dev *dev, const char *name) +{ + unsigned long ctl_base = pci_resource_start(dev, 0); + unsigned long dma_base = pci_resource_start(dev, 1); + unsigned long ctl_size = pci_resource_len(dev, 0); + unsigned long dma_size = pci_resource_len(dev, 1); + void *ctl_addr; + void *dma_addr; + int i; + + for (i = 0; i < MAX_HWIFS; i++) { + if (scc_ports[i].ctl == 0) + break; + } + if (i >= MAX_HWIFS) + return -ENOMEM; + + if (!request_mem_region(ctl_base, ctl_size, name)) { + printk(KERN_WARNING "%s: IDE controller MMIO ports not available.\n", SCC_PATA_NAME); + goto fail_0; + } + + if (!request_mem_region(dma_base, dma_size, name)) { + printk(KERN_WARNING "%s: IDE controller MMIO ports not available.\n", SCC_PATA_NAME); + goto fail_1; + } + + if ((ctl_addr = ioremap(ctl_base, ctl_size)) == NULL) + goto fail_2; + + if ((dma_addr = ioremap(dma_base, dma_size)) == NULL) + goto fail_3; + + pci_set_master(dev); + scc_ports[i].ctl = (unsigned long)ctl_addr; + scc_ports[i].dma = (unsigned long)dma_addr; + pci_set_drvdata(dev, (void *) &scc_ports[i]); + + return 1; + + fail_3: + iounmap(ctl_addr); + fail_2: + release_mem_region(dma_base, dma_size); + fail_1: + release_mem_region(ctl_base, ctl_size); + fail_0: + return -ENOMEM; +} + +/** + * init_setup_scc - set up an SCC PATA Controller + * @dev: PCI device + * @d: IDE PCI device + * + * Perform the initial set up for this device. + */ + +static int __devinit init_setup_scc(struct pci_dev *dev, ide_pci_device_t *d) +{ + unsigned long ctl_base; + unsigned long dma_base; + unsigned long cckctrl_port; + unsigned long intmask_port; + unsigned long mode_port; + unsigned long ecmode_port; + unsigned long dma_status_port; + u32 reg = 0; + struct scc_ports *ports; + int rc; + + rc = setup_mmio_scc(dev, d->name); + if (rc < 0) { + return rc; + } + + ports = pci_get_drvdata(dev); + ctl_base = ports->ctl; + dma_base = ports->dma; + cckctrl_port = ctl_base + 0xff0; + intmask_port = dma_base + 0x010; + mode_port = ctl_base + 0x024; + ecmode_port = ctl_base + 0xf00; + dma_status_port = dma_base + 0x004; + + /* controller initialization */ + reg = 0; + out_be32((void*)cckctrl_port, reg); + reg |= CCKCTRL_ATACLKOEN; + out_be32((void*)cckctrl_port, reg); + reg |= CCKCTRL_LCLKEN | CCKCTRL_OCLKEN; + out_be32((void*)cckctrl_port, reg); + reg |= CCKCTRL_CRST; + out_be32((void*)cckctrl_port, reg); + + for (;;) { + reg = in_be32((void*)cckctrl_port); + if (reg & CCKCTRL_CRST) + break; + udelay(5000); + } + + reg |= CCKCTRL_ATARESET; + out_be32((void*)cckctrl_port, reg); + + out_be32((void*)ecmode_port, ECMODE_VALUE); + out_be32((void*)mode_port, MODE_JCUSFEN); + out_be32((void*)intmask_port, INTMASK_MSK); + + return ide_setup_pci_device(dev, d); +} + +/** + * init_mmio_iops_scc - set up the iops for MMIO + * @hwif: interface to set up + * + */ + +static void __devinit init_mmio_iops_scc(ide_hwif_t *hwif) +{ + struct pci_dev *dev = hwif->pci_dev; + struct scc_ports *ports = pci_get_drvdata(dev); + unsigned long dma_base = ports->dma; + + ide_set_hwifdata(hwif, ports); + + hwif->INB = scc_ide_inb; + hwif->INW = scc_ide_inw; + hwif->INSW = scc_ide_insw; + hwif->INSL = scc_ide_insl; + hwif->OUTB = scc_ide_outb; + hwif->OUTBSYNC = scc_ide_outbsync; + hwif->OUTW = scc_ide_outw; + hwif->OUTSW = scc_ide_outsw; + hwif->OUTSL = scc_ide_outsl; + + hwif->io_ports[IDE_DATA_OFFSET] = dma_base + 0x20; + hwif->io_ports[IDE_ERROR_OFFSET] = dma_base + 0x24; + hwif->io_ports[IDE_NSECTOR_OFFSET] = dma_base + 0x28; + hwif->io_ports[IDE_SECTOR_OFFSET] = dma_base + 0x2c; + hwif->io_ports[IDE_LCYL_OFFSET] = dma_base + 0x30; + hwif->io_ports[IDE_HCYL_OFFSET] = dma_base + 0x34; + hwif->io_ports[IDE_SELECT_OFFSET] = dma_base + 0x38; + hwif->io_ports[IDE_STATUS_OFFSET] = dma_base + 0x3c; + hwif->io_ports[IDE_CONTROL_OFFSET] = dma_base + 0x40; + + hwif->irq = hwif->pci_dev->irq; + hwif->dma_base = dma_base; + hwif->config_data = ports->ctl; + hwif->mmio = 1; +} + +/** + * init_iops_scc - set up iops + * @hwif: interface to set up + * + * Do the basic setup for the SCC hardware interface + * and then do the MMIO setup. + */ + +static void __devinit init_iops_scc(ide_hwif_t *hwif) +{ + struct pci_dev *dev = hwif->pci_dev; + hwif->hwif_data = NULL; + if (pci_get_drvdata(dev) == NULL) + return; + init_mmio_iops_scc(hwif); +} + +/** + * init_hwif_scc - set up hwif + * @hwif: interface to set up + * + * We do the basic set up of the interface structure. The SCC + * requires several custom handlers so we override the default + * ide DMA handlers appropriately. + */ + +static void __devinit init_hwif_scc(ide_hwif_t *hwif) +{ + struct scc_ports *ports = ide_get_hwifdata(hwif); + + ports->hwif_id = hwif->index; + + hwif->dma_command = hwif->dma_base; + hwif->dma_status = hwif->dma_base + 0x04; + hwif->dma_prdtable = hwif->dma_base + 0x08; + + /* PTERADD */ + out_be32((void __iomem *)(hwif->dma_base + 0x018), hwif->dmatable_dma); + + hwif->dma_setup = scc_dma_setup; + hwif->ide_dma_end = scc_ide_dma_end; + hwif->speedproc = scc_tune_chipset; + hwif->tuneproc = scc_tuneproc; + hwif->ide_dma_check = scc_config_drive_for_dma; + + hwif->drives[0].autotune = IDE_TUNE_AUTO; + hwif->drives[1].autotune = IDE_TUNE_AUTO; + + if (in_be32((void __iomem *)(hwif->config_data + 0xff0)) & CCKCTRL_ATACLKOEN) { + hwif->ultra_mask = 0x7f; /* 133MHz */ + } else { + hwif->ultra_mask = 0x3f; /* 100MHz */ + } + hwif->mwdma_mask = 0x00; + hwif->swdma_mask = 0x00; + hwif->atapi_dma = 1; + + /* we support 80c cable only. */ + hwif->udma_four = 1; + + hwif->autodma = 0; + if (!noautodma) + hwif->autodma = 1; + hwif->drives[0].autodma = hwif->autodma; + hwif->drives[1].autodma = hwif->autodma; +} + +#define DECLARE_SCC_DEV(name_str) \ + { \ + .name = name_str, \ + .init_setup = init_setup_scc, \ + .init_iops = init_iops_scc, \ + .init_hwif = init_hwif_scc, \ + .channels = 1, \ + .autodma = AUTODMA, \ + .bootable = ON_BOARD, \ + } + +static ide_pci_device_t scc_chipsets[] __devinitdata = { + /* 0 */ DECLARE_SCC_DEV("sccIDE"), +}; + +/** + * scc_init_one - pci layer discovery entry + * @dev: PCI device + * @id: ident table entry + * + * Called by the PCI code when it finds an SCC PATA controller. + * We then use the IDE PCI generic helper to do most of the work. + */ + +static int __devinit scc_init_one(struct pci_dev *dev, const struct pci_device_id *id) +{ + ide_pci_device_t *d = &scc_chipsets[id->driver_data]; + return d->init_setup(dev, d); +} + +/** + * scc_remove - pci layer remove entry + * @dev: PCI device + * + * Called by the PCI code when it removes an SCC PATA controller. + */ + +static void __devexit scc_remove(struct pci_dev *dev) +{ + struct scc_ports *ports = pci_get_drvdata(dev); + ide_hwif_t *hwif = &ide_hwifs[ports->hwif_id]; + unsigned long ctl_base = pci_resource_start(dev, 0); + unsigned long dma_base = pci_resource_start(dev, 1); + unsigned long ctl_size = pci_resource_len(dev, 0); + unsigned long dma_size = pci_resource_len(dev, 1); + + if (hwif->dmatable_cpu) { + pci_free_consistent(hwif->pci_dev, + PRD_ENTRIES * PRD_BYTES, + hwif->dmatable_cpu, + hwif->dmatable_dma); + hwif->dmatable_cpu = NULL; + } + + ide_unregister(hwif->index); + + hwif->chipset = ide_unknown; + iounmap((void*)ports->dma); + iounmap((void*)ports->ctl); + release_mem_region(dma_base, dma_size); + release_mem_region(ctl_base, ctl_size); + memset(ports, 0, sizeof(*ports)); +} + +static struct pci_device_id scc_pci_tbl[] = { + { PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_SCC_ATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + { 0, }, +}; +MODULE_DEVICE_TABLE(pci, scc_pci_tbl); + +static struct pci_driver driver = { + .name = "SCC IDE", + .id_table = scc_pci_tbl, + .probe = scc_init_one, + .remove = scc_remove, +}; + +static int scc_ide_init(void) +{ + return ide_pci_register_driver(&driver); +} + +module_init(scc_ide_init); +/* -- No exit code? +static void scc_ide_exit(void) +{ + ide_pci_unregister_driver(&driver); +} +module_exit(scc_ide_exit); + */ + + +MODULE_DESCRIPTION("PCI driver module for Toshiba SCC IDE"); +MODULE_LICENSE("GPL"); |