#include <linux/delay.h>
#include <linux/hdreg.h>
#include <linux/ide.h>
-#include <linux/bitops.h>
#include <asm/byteorder.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <asm/io.h>
+#include <asm/bitops.h>
/*
* Conventional PIO operations for ATA devices
*/
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<<i))
+ hssbd++;
+
+ switch (hssbd) {
+ case 7:
+ case 6:
+ case 5:
+ /* ATA-4 and older do not support above Ultra 33 */
+ default:
+ return 0;
+ }
+ }
+
+ return ((u8) (
#ifndef CONFIG_IDEDMA_IVB
- if(!(drive->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);
return 0;
}
+EXPORT_SYMBOL(ide_ata66_check);
+
/*
* Backside of HDIO_DRIVE_CMD call of SETFEATURES_XFER.
* 1 : Safe to update drive->id DMA registers.
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;
default: return XFER_PIO_4;
}
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+
+EXPORT_SYMBOL(ide_auto_reduce_xfer);
/*
* Update the
#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,
* 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)
{
/*
* 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);
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.
*
* 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);
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)
{