X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fide%2Fide-iops.c;h=1ee780e1b35369b40e208a33799c38da10355b5c;hb=9e1bf581d67d87a1d7fc0ea500729e3a03643a26;hp=2d9b028e8e708fbe09f45ff03a13f9499e499967;hpb=8d40237c730b8be87c1b80a5d96b9c603fefa829;p=linux-2.6.git diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 2d9b028e8..1ee780e1b 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -23,12 +23,12 @@ #include #include #include -#include #include #include #include #include +#include /* * Conventional PIO operations for ATA devices @@ -674,15 +674,44 @@ EXPORT_SYMBOL(ide_wait_stat); */ u8 eighty_ninty_three (ide_drive_t *drive) { - if(HWIF(drive)->udma_four == 0) - return 0; - if (!(drive->id->hw_config & 0x6000)) +#if 0 + if (!HWIF(drive)->udma_four) return 0; + + if (drive->id->major_rev_num) { + int hssbd = 0; + int i; + /* + * Determine highest Supported SPEC + */ + for (i=1; i<=15; i++) + if (drive->id->major_rev_num & (1<id->hw_config & 0x4000)) - return 0; + (drive->id->hw_config & 0x4000) && #endif /* CONFIG_IDEDMA_IVB */ - return 1; + (drive->id->hw_config & 0x6000)) ? 1 : 0); + +#else + + return ((u8) ((HWIF(drive)->udma_four) && +#ifndef CONFIG_IDEDMA_IVB + (drive->id->hw_config & 0x4000) && +#endif /* CONFIG_IDEDMA_IVB */ + (drive->id->hw_config & 0x6000)) ? 1 : 0); +#endif } EXPORT_SYMBOL(eighty_ninty_three); @@ -712,6 +741,8 @@ int ide_ata66_check (ide_drive_t *drive, ide_task_t *args) return 0; } +EXPORT_SYMBOL(ide_ata66_check); + /* * Backside of HDIO_DRIVE_CMD call of SETFEATURES_XFER. * 1 : Safe to update drive->id DMA registers. @@ -730,8 +761,9 @@ int set_transfer (ide_drive_t *drive, ide_task_t *args) return 0; } -#ifdef CONFIG_BLK_DEV_IDEDMA -static u8 ide_auto_reduce_xfer (ide_drive_t *drive) +EXPORT_SYMBOL(set_transfer); + +u8 ide_auto_reduce_xfer (ide_drive_t *drive) { if (!drive->crc_count) return drive->current_speed; @@ -755,7 +787,8 @@ static u8 ide_auto_reduce_xfer (ide_drive_t *drive) default: return XFER_PIO_4; } } -#endif /* CONFIG_BLK_DEV_IDEDMA */ + +EXPORT_SYMBOL(ide_auto_reduce_xfer); /* * Update the @@ -830,6 +863,8 @@ int ide_driveid_update (ide_drive_t *drive) #endif } +EXPORT_SYMBOL(ide_driveid_update); + /* * Similar to ide_wait_stat(), except it never calls ide_error internally. * This is a kludge to handle the new ide_config_drive_speed() function, @@ -840,11 +875,6 @@ int ide_driveid_update (ide_drive_t *drive) * It is gone.......... * * const char *msg == consider adding for verbose errors. - * - * Beware. If we timed out from a series of CRC errors and the timer - * expiry caused a switch to PIO mode and we take an IRQ as the drive times - * out about the same moment we may be entering this function with a - * pending interrupt. */ int ide_config_drive_speed (ide_drive_t *drive, u8 speed) { @@ -862,20 +892,20 @@ int ide_config_drive_speed (ide_drive_t *drive, u8 speed) /* * Don't use ide_wait_cmd here - it will - * attempt to set_geometry and recalibrate, We can't - * do that here as we may be in the IRQ handler already - * - * Select the drive, and issue the SETFEATURES command in - * polled mode. + * attempt to set_geometry and recalibrate, + * but for some reason these don't work at + * this point (lost interrupt). + */ + /* + * Select the drive, and issue the SETFEATURES command */ disable_irq_nosync(hwif->irq); /* - * We race against the running IRQ here if + * FIXME: we race against the running IRQ here if * this is called from non IRQ context. If we use - * disable_irq() we hang on the error path. Instead we - * must let the core code know the hwif is doing a polling - * recovery. + * disable_irq() we hang on the error path. Work + * is needed. */ udelay(1); @@ -886,43 +916,23 @@ int ide_config_drive_speed (ide_drive_t *drive, u8 speed) hwif->OUTB(drive->ctl | 2, IDE_CONTROL_REG); hwif->OUTB(speed, IDE_NSECTOR_REG); hwif->OUTB(SETFEATURES_XFER, IDE_FEATURE_REG); - hwif->OUTBSYNC(drive, WIN_SETFEATURES, IDE_COMMAND_REG); - /* The status bits are not valid for 400nS */ - udelay(1); - - /* Drive status is now valid which means we can allow interrupts - to occur as they will see the drive as busy and will not - interfere erroneously. IRQ's for this drive will also be off - providing control and quirks allow for it */ - - if ((IDE_CONTROL_REG) && drive->quirk_list == 2) + hwif->OUTB(WIN_SETFEATURES, IDE_COMMAND_REG); + if ((IDE_CONTROL_REG) && (drive->quirk_list == 2)) hwif->OUTB(drive->ctl, IDE_CONTROL_REG); udelay(1); - - /* - * Tell the interrupt layer that we are doing polled recovery. - * Eventually this should use the same mechanism do_reset does - * internally. - */ - - hwif->polling = 1; - /* * Wait for drive to become non-BUSY */ if ((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) { - unsigned long timeout; - /* FIXME */ -/* spin_unlock_irq(&ide_lock); */ + unsigned long flags, timeout; + local_irq_set(flags); timeout = jiffies + WAIT_CMD; while ((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) { if (time_after(jiffies, timeout)) break; } -/* spin_lock_irq(&ide_lock); */ + local_irq_restore(flags); } - - hwif->polling = 0; /* * Allow status to settle, then read it again. @@ -994,7 +1004,7 @@ EXPORT_SYMBOL(ide_config_drive_speed); * * See also ide_execute_command */ -static void __ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, +void __ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry) { ide_hwgroup_t *hwgroup = HWGROUP(drive); @@ -1010,6 +1020,8 @@ static void __ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, add_timer(&hwgroup->timer); } +EXPORT_SYMBOL(__ide_set_handler); + void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry) {