summaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-probe.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/ide-probe.c')
-rw-r--r--drivers/ide/ide-probe.c67
1 files changed, 37 insertions, 30 deletions
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 168895fb5..decbc9f8d 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -184,22 +184,16 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
* 1 device timed-out (no response to identify request)
* 2 device aborted the command (refused to identify itself)
*/
-static int try_to_identify (ide_drive_t *drive, byte cmd)
+static int actual_try_to_identify (ide_drive_t *drive, byte cmd)
{
int rc;
ide_ioreg_t hd_status;
unsigned long timeout;
- unsigned long irqs = 0;
byte s, a;
if (IDE_CONTROL_REG) {
- if (!HWIF(drive)->irq) { /* already got an IRQ? */
- probe_irq_off(probe_irq_on()); /* clear dangling irqs */
- irqs = probe_irq_on(); /* start monitoring irqs */
- OUT_BYTE(drive->ctl,IDE_CONTROL_REG); /* enable device irq */
- }
-
- ide_delay_50ms(); /* take a deep breath */
+ /* take a deep breath */
+ ide_delay_50ms();
a = IN_BYTE(IDE_ALTSTATUS_REG);
s = IN_BYTE(IDE_STATUS_REG);
if ((a ^ s) & ~INDEX_STAT) {
@@ -222,8 +216,6 @@ static int try_to_identify (ide_drive_t *drive, byte cmd)
/* DC4030 hosted drives need their own identify... */
extern int pdc4030_identify(ide_drive_t *);
if (pdc4030_identify(drive)) {
- if (irqs)
- (void) probe_irq_off(irqs);
return 1;
}
} else
@@ -233,8 +225,6 @@ static int try_to_identify (ide_drive_t *drive, byte cmd)
timeout += jiffies;
do {
if (0 < (signed long)(jiffies - timeout)) {
- if (irqs)
- (void) probe_irq_off(irqs);
return 1; /* drive timed-out */
}
ide_delay_50ms(); /* give drive a breather */
@@ -251,32 +241,49 @@ static int try_to_identify (ide_drive_t *drive, byte cmd)
__restore_flags(flags); /* local CPU only */
} else
rc = 2; /* drive refused ID */
+ return rc;
+}
+
+static int try_to_identify (ide_drive_t *drive, byte cmd)
+{
+ int retval;
+ int autoprobe = 0;
+ unsigned long cookie = 0;
+
if (IDE_CONTROL_REG && !HWIF(drive)->irq) {
- irqs = probe_irq_off(irqs); /* get our irq number */
- if (irqs > 0) {
- HWIF(drive)->irq = irqs; /* save it for later */
- irqs = probe_irq_on();
- OUT_BYTE(drive->ctl|2,IDE_CONTROL_REG); /* mask device irq */
- udelay(5);
- (void) probe_irq_off(irqs);
- (void) probe_irq_off(probe_irq_on()); /* clear self-inflicted irq */
- (void) GET_STAT(); /* clear drive IRQ */
-
- } else { /* Mmmm.. multiple IRQs.. don't know which was ours */
- printk("%s: IRQ probe failed (%ld)\n", drive->name, irqs);
+ autoprobe = 1;
+ cookie = probe_irq_on();
+ OUT_BYTE(drive->ctl,IDE_CONTROL_REG); /* enable device irq */
+ }
+
+ retval = actual_try_to_identify(drive, cmd);
+
+ if (autoprobe) {
+ int irq;
+ OUT_BYTE(drive->ctl|2,IDE_CONTROL_REG); /* mask device irq */
+ (void) GET_STAT(); /* clear drive IRQ */
+ udelay(5);
+ irq = probe_irq_off(cookie);
+ if (!HWIF(drive)->irq) {
+ if (irq > 0) {
+ HWIF(drive)->irq = irq;
+ } else { /* Mmmm.. multiple IRQs.. don't know which was ours */
+ printk("%s: IRQ probe failed (0x%lx)\n", drive->name, cookie);
#ifdef CONFIG_BLK_DEV_CMD640
#ifdef CMD640_DUMP_REGS
- if (HWIF(drive)->chipset == ide_cmd640) {
- printk("%s: Hmmm.. probably a driver problem.\n", drive->name);
- CMD640_DUMP_REGS;
- }
+ if (HWIF(drive)->chipset == ide_cmd640) {
+ printk("%s: Hmmm.. probably a driver problem.\n", drive->name);
+ CMD640_DUMP_REGS;
+ }
#endif /* CMD640_DUMP_REGS */
#endif /* CONFIG_BLK_DEV_CMD640 */
+ }
}
}
- return rc;
+ return retval;
}
+
/*
* do_probe() has the difficult job of finding a drive if it exists,
* without getting hung up if it doesn't exist, without trampling on