{
int ret = 1;
- BUG_ON(!blk_rq_started(rq));
-
/*
* if failfast is set on a request, override number of sectors and
* complete the whole request right now
if (!end_that_request_first(rq, uptodate, nr_sectors)) {
add_disk_randomness(rq->rq_disk);
- blkdev_dequeue_request(rq);
+ if (!list_empty(&rq->queuelist))
+ blkdev_dequeue_request(rq);
HWGROUP(drive)->rq = NULL;
end_that_request_last(rq, uptodate);
ret = 0;
ide_pm_flush_cache = ide_pm_state_start_suspend,
idedisk_pm_standby,
- idedisk_pm_idle = ide_pm_state_start_resume,
+ idedisk_pm_restore_pio = ide_pm_state_start_resume,
+ idedisk_pm_idle,
ide_pm_restore_dma,
};
case idedisk_pm_standby: /* Suspend step 2 (standby) complete */
pm->pm_step = ide_pm_state_completed;
break;
- case idedisk_pm_idle: /* Resume step 1 (idle) complete */
+ case idedisk_pm_restore_pio: /* Resume step 1 complete */
+ pm->pm_step = idedisk_pm_idle;
+ break;
+ case idedisk_pm_idle: /* Resume step 2 (idle) complete */
pm->pm_step = ide_pm_restore_dma;
break;
}
memset(args, 0, sizeof(*args));
if (drive->media != ide_disk) {
- /* skip idedisk_pm_idle for ATAPI devices */
- if (pm->pm_step == idedisk_pm_idle)
+ /*
+ * skip idedisk_pm_restore_pio and idedisk_pm_idle for ATAPI
+ * devices
+ */
+ if (pm->pm_step == idedisk_pm_restore_pio)
pm->pm_step = ide_pm_restore_dma;
}
args->handler = &task_no_data_intr;
return do_rw_taskfile(drive, args);
- case idedisk_pm_idle: /* Resume step 1 (idle) */
+ case idedisk_pm_restore_pio: /* Resume step 1 (restore PIO) */
+ if (drive->hwif->tuneproc != NULL)
+ drive->hwif->tuneproc(drive, 255);
+ ide_complete_power_step(drive, rq, 0, 0);
+ return ide_stopped;
+
+ case idedisk_pm_idle: /* Resume step 2 (idle) */
args->tfRegister[IDE_COMMAND_OFFSET] = WIN_IDLEIMMEDIATE;
args->command_type = IDE_DRIVE_TASK_NO_DATA;
args->handler = task_no_data_intr;
return do_rw_taskfile(drive, args);
- case ide_pm_restore_dma: /* Resume step 2 (restore DMA) */
+ case ide_pm_restore_dma: /* Resume step 3 (restore DMA) */
/*
* Right now, all we do is call hwif->ide_dma_check(drive),
* we could be smarter and check for current xfer_speed
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;
*/
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
* make sure request is sane
*/
rq = HWGROUP(drive)->rq;
+
+ if (!rq)
+ goto out;
+
HWGROUP(drive)->rq = NULL;
rq->errors = 0;
* on the hwgroup and the process begins again.
*/
-irqreturn_t ide_intr (int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t ide_intr (int irq, void *dev_id)
{
unsigned long flags;
ide_hwgroup_t *hwgroup = (ide_hwgroup_t *)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 */