/* * Handler for command with PIO data-in phase (Read/Read Multiple). */ static ide_startstop_t task_in_intr(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; struct request *rq = hwif->rq; u8 stat = hwif->tp_ops->read_status(hwif); /* Error? */ if (stat & ATA_ERR) return task_error(drive, rq, __func__, stat); /* Didn't want any data? Odd. */ if ((stat & ATA_DRQ) == 0) return task_in_unexpected(drive, rq, stat); ide_pio_datablock(drive, rq, 0); /* Are we done? Check status and finish transfer. */ if (!hwif->nleft) { stat = wait_drive_not_busy(drive); if (!OK_STAT(stat, 0, BAD_STAT)) return task_error(drive, rq, __func__, stat); task_end_request(drive, rq, stat); return ide_stopped; } /* Still data left to transfer. */ ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL); return ide_started; }
static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, struct request *rq) { ide_startstop_t startstop; if (ide_wait_stat(&startstop, drive, ATA_DRQ, drive->bad_wstat, WAIT_DRQ)) { printk(KERN_ERR "%s: no DRQ after issuing %sWRITE%s\n", drive->name, drive->hwif->data_phase ? "MULT" : "", (drive->dev_flags & IDE_DFLAG_LBA48) ? "_EXT" : ""); return startstop; } if ((drive->dev_flags & IDE_DFLAG_UNMASK) == 0) local_irq_disable(); ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL); ide_pio_datablock(drive, rq, 1); return ide_started; }
static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, struct request *rq) { ide_startstop_t startstop; if (ide_wait_stat(&startstop, drive, DRQ_STAT, drive->bad_wstat, WAIT_DRQ)) { printk(KERN_ERR "%s: no DRQ after issuing %sWRITE%s\n", drive->name, drive->hwif->data_phase ? "MULT" : "", drive->addressing ? "_EXT" : ""); return startstop; } if (!drive->unmask) local_irq_disable(); ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL); ide_pio_datablock(drive, rq, 1); return ide_started; }
/* * Handler for command with PIO data-out phase (Write/Write Multiple). */ static ide_startstop_t task_out_intr (ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; struct request *rq = hwif->rq; u8 stat = hwif->tp_ops->read_status(hwif); if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat)) return task_error(drive, rq, __func__, stat); /* Deal with unexpected ATA data phase. */ if (((stat & ATA_DRQ) == 0) ^ !hwif->nleft) return task_error(drive, rq, __func__, stat); if (!hwif->nleft) { task_end_request(drive, rq, stat); return ide_stopped; } /* Still data left to transfer. */ ide_pio_datablock(drive, rq, 1); ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL); return ide_started; }