diff options
Diffstat (limited to 'drivers/ide/ide-io.c')
-rw-r--r-- | drivers/ide/ide-io.c | 38 |
1 files changed, 26 insertions, 12 deletions
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index c193553f6fe7..8670112f1d39 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
@@ -519,21 +519,24 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8 | |||
519 | if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ && hwif->err_stops_fifo == 0) | 519 | if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ && hwif->err_stops_fifo == 0) |
520 | try_to_flush_leftover_data(drive); | 520 | try_to_flush_leftover_data(drive); |
521 | 521 | ||
522 | if (rq->errors >= ERROR_MAX || blk_noretry_request(rq)) { | ||
523 | ide_kill_rq(drive, rq); | ||
524 | return ide_stopped; | ||
525 | } | ||
526 | |||
522 | if (hwif->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT)) | 527 | if (hwif->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT)) |
523 | /* force an abort */ | 528 | rq->errors |= ERROR_RESET; |
524 | hwif->OUTB(WIN_IDLEIMMEDIATE, IDE_COMMAND_REG); | ||
525 | 529 | ||
526 | if (rq->errors >= ERROR_MAX || blk_noretry_request(rq)) | 530 | if ((rq->errors & ERROR_RESET) == ERROR_RESET) { |
527 | ide_kill_rq(drive, rq); | ||
528 | else { | ||
529 | if ((rq->errors & ERROR_RESET) == ERROR_RESET) { | ||
530 | ++rq->errors; | ||
531 | return ide_do_reset(drive); | ||
532 | } | ||
533 | if ((rq->errors & ERROR_RECAL) == ERROR_RECAL) | ||
534 | drive->special.b.recalibrate = 1; | ||
535 | ++rq->errors; | 531 | ++rq->errors; |
532 | return ide_do_reset(drive); | ||
536 | } | 533 | } |
534 | |||
535 | if ((rq->errors & ERROR_RECAL) == ERROR_RECAL) | ||
536 | drive->special.b.recalibrate = 1; | ||
537 | |||
538 | ++rq->errors; | ||
539 | |||
537 | return ide_stopped; | 540 | return ide_stopped; |
538 | } | 541 | } |
539 | 542 | ||
@@ -1025,6 +1028,13 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) | |||
1025 | if (!drive->special.all) { | 1028 | if (!drive->special.all) { |
1026 | ide_driver_t *drv; | 1029 | ide_driver_t *drv; |
1027 | 1030 | ||
1031 | /* | ||
1032 | * We reset the drive so we need to issue a SETFEATURES. | ||
1033 | * Do it _after_ do_special() restored device parameters. | ||
1034 | */ | ||
1035 | if (drive->current_speed == 0xff) | ||
1036 | ide_config_drive_speed(drive, drive->desired_speed); | ||
1037 | |||
1028 | if (rq->cmd_type == REQ_TYPE_ATA_CMD || | 1038 | if (rq->cmd_type == REQ_TYPE_ATA_CMD || |
1029 | rq->cmd_type == REQ_TYPE_ATA_TASK || | 1039 | rq->cmd_type == REQ_TYPE_ATA_TASK || |
1030 | rq->cmd_type == REQ_TYPE_ATA_TASKFILE) | 1040 | rq->cmd_type == REQ_TYPE_ATA_TASKFILE) |
@@ -1216,6 +1226,7 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) | |||
1216 | #endif | 1226 | #endif |
1217 | /* so that ide_timer_expiry knows what to do */ | 1227 | /* so that ide_timer_expiry knows what to do */ |
1218 | hwgroup->sleeping = 1; | 1228 | hwgroup->sleeping = 1; |
1229 | hwgroup->req_gen_timer = hwgroup->req_gen; | ||
1219 | mod_timer(&hwgroup->timer, sleep); | 1230 | mod_timer(&hwgroup->timer, sleep); |
1220 | /* we purposely leave hwgroup->busy==1 | 1231 | /* we purposely leave hwgroup->busy==1 |
1221 | * while sleeping */ | 1232 | * while sleeping */ |
@@ -1401,7 +1412,8 @@ void ide_timer_expiry (unsigned long data) | |||
1401 | 1412 | ||
1402 | spin_lock_irqsave(&ide_lock, flags); | 1413 | spin_lock_irqsave(&ide_lock, flags); |
1403 | 1414 | ||
1404 | if ((handler = hwgroup->handler) == NULL) { | 1415 | if (((handler = hwgroup->handler) == NULL) || |
1416 | (hwgroup->req_gen != hwgroup->req_gen_timer)) { | ||
1405 | /* | 1417 | /* |
1406 | * Either a marginal timeout occurred | 1418 | * Either a marginal timeout occurred |
1407 | * (got the interrupt just as timer expired), | 1419 | * (got the interrupt just as timer expired), |
@@ -1429,6 +1441,7 @@ void ide_timer_expiry (unsigned long data) | |||
1429 | if ((wait = expiry(drive)) > 0) { | 1441 | if ((wait = expiry(drive)) > 0) { |
1430 | /* reset timer */ | 1442 | /* reset timer */ |
1431 | hwgroup->timer.expires = jiffies + wait; | 1443 | hwgroup->timer.expires = jiffies + wait; |
1444 | hwgroup->req_gen_timer = hwgroup->req_gen; | ||
1432 | add_timer(&hwgroup->timer); | 1445 | add_timer(&hwgroup->timer); |
1433 | spin_unlock_irqrestore(&ide_lock, flags); | 1446 | spin_unlock_irqrestore(&ide_lock, flags); |
1434 | return; | 1447 | return; |
@@ -1643,6 +1656,7 @@ irqreturn_t ide_intr (int irq, void *dev_id) | |||
1643 | printk(KERN_ERR "%s: ide_intr: hwgroup->busy was 0 ??\n", drive->name); | 1656 | printk(KERN_ERR "%s: ide_intr: hwgroup->busy was 0 ??\n", drive->name); |
1644 | } | 1657 | } |
1645 | hwgroup->handler = NULL; | 1658 | hwgroup->handler = NULL; |
1659 | hwgroup->req_gen++; | ||
1646 | del_timer(&hwgroup->timer); | 1660 | del_timer(&hwgroup->timer); |
1647 | spin_unlock(&ide_lock); | 1661 | spin_unlock(&ide_lock); |
1648 | 1662 | ||