diff options
Diffstat (limited to 'drivers/ide')
-rw-r--r-- | drivers/ide/ide-io.c | 107 |
1 files changed, 46 insertions, 61 deletions
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 2fe5a7088744..cc163319dfbd 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -920,60 +920,55 @@ void ide_timer_expiry (unsigned long data) * Either way, we don't really want to complain about anything. */ } else { + ide_expiry_t *expiry = hwif->expiry; + ide_startstop_t startstop = ide_stopped; + drive = hwif->cur_dev; - if (!drive) { - printk(KERN_ERR "%s: ->cur_dev was NULL\n", __func__); - hwif->handler = NULL; - } else { - ide_expiry_t *expiry = hwif->expiry; - ide_startstop_t startstop = ide_stopped; - - if (expiry) { - /* continue */ - if ((wait = expiry(drive)) > 0) { - /* reset timer */ - hwif->timer.expires = jiffies + wait; - hwif->req_gen_timer = hwif->req_gen; - add_timer(&hwif->timer); - spin_unlock_irqrestore(&hwif->lock, flags); - return; - } - } - hwif->handler = NULL; - /* - * We need to simulate a real interrupt when invoking - * the handler() function, which means we need to - * globally mask the specific IRQ: - */ - spin_unlock(&hwif->lock); - /* disable_irq_nosync ?? */ - disable_irq(hwif->irq); - /* local CPU only, - * as if we were handling an interrupt */ - local_irq_disable(); - if (hwif->polling) { - startstop = handler(drive); - } else if (drive_is_ready(drive)) { - if (drive->waiting_for_dma) - hwif->dma_ops->dma_lost_irq(drive); - (void)ide_ack_intr(hwif); - printk(KERN_WARNING "%s: lost interrupt\n", drive->name); - startstop = handler(drive); - } else { - if (drive->waiting_for_dma) { - startstop = ide_dma_timeout_retry(drive, wait); - } else - startstop = - ide_error(drive, "irq timeout", - hwif->tp_ops->read_status(hwif)); - } - spin_lock_irq(&hwif->lock); - enable_irq(hwif->irq); - if (startstop == ide_stopped) { - ide_unlock_port(hwif); - plug_device = 1; + + if (expiry) { + wait = expiry(drive); + if (wait > 0) { /* continue */ + /* reset timer */ + hwif->timer.expires = jiffies + wait; + hwif->req_gen_timer = hwif->req_gen; + add_timer(&hwif->timer); + spin_unlock_irqrestore(&hwif->lock, flags); + return; } } + hwif->handler = NULL; + /* + * We need to simulate a real interrupt when invoking + * the handler() function, which means we need to + * globally mask the specific IRQ: + */ + spin_unlock(&hwif->lock); + /* disable_irq_nosync ?? */ + disable_irq(hwif->irq); + /* local CPU only, as if we were handling an interrupt */ + local_irq_disable(); + if (hwif->polling) { + startstop = handler(drive); + } else if (drive_is_ready(drive)) { + if (drive->waiting_for_dma) + hwif->dma_ops->dma_lost_irq(drive); + (void)ide_ack_intr(hwif); + printk(KERN_WARNING "%s: lost interrupt\n", + drive->name); + startstop = handler(drive); + } else { + if (drive->waiting_for_dma) + startstop = ide_dma_timeout_retry(drive, wait); + else + startstop = ide_error(drive, "irq timeout", + hwif->tp_ops->read_status(hwif)); + } + spin_lock_irq(&hwif->lock); + enable_irq(hwif->irq); + if (startstop == ide_stopped) { + ide_unlock_port(hwif); + plug_device = 1; + } } spin_unlock_irqrestore(&hwif->lock, flags); @@ -1115,15 +1110,6 @@ irqreturn_t ide_intr (int irq, void *dev_id) } drive = hwif->cur_dev; - if (!drive) { - /* - * This should NEVER happen, and there isn't much - * we could do about it here. - * - * [Note - this can occur if the drive is hot unplugged] - */ - goto out_handled; - } if (!drive_is_ready(drive)) /* @@ -1162,7 +1148,6 @@ irqreturn_t ide_intr (int irq, void *dev_id) ide_unlock_port(hwif); plug_device = 1; } -out_handled: irq_ret = IRQ_HANDLED; out: spin_unlock_irqrestore(&hwif->lock, flags); |