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 | ||
