diff options
Diffstat (limited to 'drivers/ide/ide-io.c')
-rw-r--r-- | drivers/ide/ide-io.c | 55 |
1 files changed, 34 insertions, 21 deletions
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 1c51949833be..5f0ed59bac6b 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
@@ -184,7 +184,8 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request * | |||
184 | if (drive->media != ide_disk) | 184 | if (drive->media != ide_disk) |
185 | break; | 185 | break; |
186 | /* Not supported? Switch to next step now. */ | 186 | /* Not supported? Switch to next step now. */ |
187 | if (!drive->wcache || ata_id_flush_enabled(drive->id) == 0) { | 187 | if (ata_id_flush_enabled(drive->id) == 0 || |
188 | (drive->dev_flags & IDE_DFLAG_WCACHE) == 0) { | ||
188 | ide_complete_power_step(drive, rq, 0, 0); | 189 | ide_complete_power_step(drive, rq, 0, 0); |
189 | return ide_stopped; | 190 | return ide_stopped; |
190 | } | 191 | } |
@@ -222,7 +223,7 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request * | |||
222 | if (drive->hwif->dma_ops == NULL) | 223 | if (drive->hwif->dma_ops == NULL) |
223 | break; | 224 | break; |
224 | /* | 225 | /* |
225 | * TODO: respect ->using_dma setting | 226 | * TODO: respect IDE_DFLAG_USING_DMA |
226 | */ | 227 | */ |
227 | ide_set_dma(drive); | 228 | ide_set_dma(drive); |
228 | break; | 229 | break; |
@@ -287,7 +288,7 @@ static void ide_complete_pm_request (ide_drive_t *drive, struct request *rq) | |||
287 | if (blk_pm_suspend_request(rq)) { | 288 | if (blk_pm_suspend_request(rq)) { |
288 | blk_stop_queue(drive->queue); | 289 | blk_stop_queue(drive->queue); |
289 | } else { | 290 | } else { |
290 | drive->blocked = 0; | 291 | drive->dev_flags &= ~IDE_DFLAG_BLOCKED; |
291 | blk_start_queue(drive->queue); | 292 | blk_start_queue(drive->queue); |
292 | } | 293 | } |
293 | HWGROUP(drive)->rq = NULL; | 294 | HWGROUP(drive)->rq = NULL; |
@@ -374,7 +375,8 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8 | |||
374 | { | 375 | { |
375 | ide_hwif_t *hwif = drive->hwif; | 376 | ide_hwif_t *hwif = drive->hwif; |
376 | 377 | ||
377 | if ((stat & ATA_BUSY) || ((stat & ATA_DF) && !drive->nowerr)) { | 378 | if ((stat & ATA_BUSY) || |
379 | ((stat & ATA_DF) && (drive->dev_flags & IDE_DFLAG_NOWERR) == 0)) { | ||
378 | /* other bits are useless when BUSY */ | 380 | /* other bits are useless when BUSY */ |
379 | rq->errors |= ERROR_RESET; | 381 | rq->errors |= ERROR_RESET; |
380 | } else if (stat & ATA_ERR) { | 382 | } else if (stat & ATA_ERR) { |
@@ -428,7 +430,8 @@ static ide_startstop_t ide_atapi_error(ide_drive_t *drive, struct request *rq, u | |||
428 | { | 430 | { |
429 | ide_hwif_t *hwif = drive->hwif; | 431 | ide_hwif_t *hwif = drive->hwif; |
430 | 432 | ||
431 | if ((stat & ATA_BUSY) || ((stat & ATA_DF) && !drive->nowerr)) { | 433 | if ((stat & ATA_BUSY) || |
434 | ((stat & ATA_DF) && (drive->dev_flags & IDE_DFLAG_NOWERR) == 0)) { | ||
432 | /* other bits are useless when BUSY */ | 435 | /* other bits are useless when BUSY */ |
433 | rq->errors |= ERROR_RESET; | 436 | rq->errors |= ERROR_RESET; |
434 | } else { | 437 | } else { |
@@ -607,7 +610,7 @@ static ide_startstop_t do_special (ide_drive_t *drive) | |||
607 | 610 | ||
608 | if (set_pio_mode_abuse(drive->hwif, req_pio)) { | 611 | if (set_pio_mode_abuse(drive->hwif, req_pio)) { |
609 | /* | 612 | /* |
610 | * take ide_lock for drive->[no_]unmask/[no_]io_32bit | 613 | * take ide_lock for IDE_DFLAG_[NO_]UNMASK/[NO_]IO_32BIT |
611 | */ | 614 | */ |
612 | if (req_pio == 8 || req_pio == 9) { | 615 | if (req_pio == 8 || req_pio == 9) { |
613 | unsigned long flags; | 616 | unsigned long flags; |
@@ -618,7 +621,8 @@ static ide_startstop_t do_special (ide_drive_t *drive) | |||
618 | } else | 621 | } else |
619 | port_ops->set_pio_mode(drive, req_pio); | 622 | port_ops->set_pio_mode(drive, req_pio); |
620 | } else { | 623 | } else { |
621 | int keep_dma = drive->using_dma; | 624 | int keep_dma = |
625 | !!(drive->dev_flags & IDE_DFLAG_USING_DMA); | ||
622 | 626 | ||
623 | ide_set_pio(drive, req_pio); | 627 | ide_set_pio(drive, req_pio); |
624 | 628 | ||
@@ -775,7 +779,7 @@ static void ide_check_pm_state(ide_drive_t *drive, struct request *rq) | |||
775 | if (blk_pm_suspend_request(rq) && | 779 | if (blk_pm_suspend_request(rq) && |
776 | pm->pm_step == ide_pm_state_start_suspend) | 780 | pm->pm_step == ide_pm_state_start_suspend) |
777 | /* Mark drive blocked when starting the suspend sequence. */ | 781 | /* Mark drive blocked when starting the suspend sequence. */ |
778 | drive->blocked = 1; | 782 | drive->dev_flags |= IDE_DFLAG_BLOCKED; |
779 | else if (blk_pm_resume_request(rq) && | 783 | else if (blk_pm_resume_request(rq) && |
780 | pm->pm_step == ide_pm_state_start_resume) { | 784 | pm->pm_step == ide_pm_state_start_resume) { |
781 | /* | 785 | /* |
@@ -895,7 +899,7 @@ void ide_stall_queue (ide_drive_t *drive, unsigned long timeout) | |||
895 | if (timeout > WAIT_WORSTCASE) | 899 | if (timeout > WAIT_WORSTCASE) |
896 | timeout = WAIT_WORSTCASE; | 900 | timeout = WAIT_WORSTCASE; |
897 | drive->sleep = timeout + jiffies; | 901 | drive->sleep = timeout + jiffies; |
898 | drive->sleeping = 1; | 902 | drive->dev_flags |= IDE_DFLAG_SLEEPING; |
899 | } | 903 | } |
900 | 904 | ||
901 | EXPORT_SYMBOL(ide_stall_queue); | 905 | EXPORT_SYMBOL(ide_stall_queue); |
@@ -935,18 +939,23 @@ repeat: | |||
935 | } | 939 | } |
936 | 940 | ||
937 | do { | 941 | do { |
938 | if ((!drive->sleeping || time_after_eq(jiffies, drive->sleep)) | 942 | u8 dev_s = !!(drive->dev_flags & IDE_DFLAG_SLEEPING); |
939 | && !elv_queue_empty(drive->queue)) { | 943 | u8 best_s = (best && !!(best->dev_flags & IDE_DFLAG_SLEEPING)); |
940 | if (!best | 944 | |
941 | || (drive->sleeping && (!best->sleeping || time_before(drive->sleep, best->sleep))) | 945 | if ((dev_s == 0 || time_after_eq(jiffies, drive->sleep)) && |
942 | || (!best->sleeping && time_before(WAKEUP(drive), WAKEUP(best)))) | 946 | !elv_queue_empty(drive->queue)) { |
943 | { | 947 | if (best == NULL || |
948 | (dev_s && (best_s == 0 || time_before(drive->sleep, best->sleep))) || | ||
949 | (best_s == 0 && time_before(WAKEUP(drive), WAKEUP(best)))) { | ||
944 | if (!blk_queue_plugged(drive->queue)) | 950 | if (!blk_queue_plugged(drive->queue)) |
945 | best = drive; | 951 | best = drive; |
946 | } | 952 | } |
947 | } | 953 | } |
948 | } while ((drive = drive->next) != hwgroup->drive); | 954 | } while ((drive = drive->next) != hwgroup->drive); |
949 | if (best && best->nice1 && !best->sleeping && best != hwgroup->drive && best->service_time > WAIT_MIN_SLEEP) { | 955 | |
956 | if (best && (best->dev_flags & IDE_DFLAG_NICE1) && | ||
957 | (best->dev_flags & IDE_DFLAG_SLEEPING) == 0 && | ||
958 | best != hwgroup->drive && best->service_time > WAIT_MIN_SLEEP) { | ||
950 | long t = (signed long)(WAKEUP(best) - jiffies); | 959 | long t = (signed long)(WAKEUP(best) - jiffies); |
951 | if (t >= WAIT_MIN_SLEEP) { | 960 | if (t >= WAIT_MIN_SLEEP) { |
952 | /* | 961 | /* |
@@ -955,7 +964,7 @@ repeat: | |||
955 | */ | 964 | */ |
956 | drive = best->next; | 965 | drive = best->next; |
957 | do { | 966 | do { |
958 | if (!drive->sleeping | 967 | if ((drive->dev_flags & IDE_DFLAG_SLEEPING) == 0 |
959 | && time_before(jiffies - best->service_time, WAKEUP(drive)) | 968 | && time_before(jiffies - best->service_time, WAKEUP(drive)) |
960 | && time_before(WAKEUP(drive), jiffies + t)) | 969 | && time_before(WAKEUP(drive), jiffies + t)) |
961 | { | 970 | { |
@@ -1026,7 +1035,9 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) | |||
1026 | hwgroup->rq = NULL; | 1035 | hwgroup->rq = NULL; |
1027 | drive = hwgroup->drive; | 1036 | drive = hwgroup->drive; |
1028 | do { | 1037 | do { |
1029 | if (drive->sleeping && (!sleeping || time_before(drive->sleep, sleep))) { | 1038 | if ((drive->dev_flags & IDE_DFLAG_SLEEPING) && |
1039 | (sleeping == 0 || | ||
1040 | time_before(drive->sleep, sleep))) { | ||
1030 | sleeping = 1; | 1041 | sleeping = 1; |
1031 | sleep = drive->sleep; | 1042 | sleep = drive->sleep; |
1032 | } | 1043 | } |
@@ -1075,7 +1086,7 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) | |||
1075 | } | 1086 | } |
1076 | hwgroup->hwif = hwif; | 1087 | hwgroup->hwif = hwif; |
1077 | hwgroup->drive = drive; | 1088 | hwgroup->drive = drive; |
1078 | drive->sleeping = 0; | 1089 | drive->dev_flags &= ~IDE_DFLAG_SLEEPING; |
1079 | drive->service_start = jiffies; | 1090 | drive->service_start = jiffies; |
1080 | 1091 | ||
1081 | if (blk_queue_plugged(drive->queue)) { | 1092 | if (blk_queue_plugged(drive->queue)) { |
@@ -1109,7 +1120,9 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) | |||
1109 | * We count how many times we loop here to make sure we service | 1120 | * We count how many times we loop here to make sure we service |
1110 | * all drives in the hwgroup without looping for ever | 1121 | * all drives in the hwgroup without looping for ever |
1111 | */ | 1122 | */ |
1112 | if (drive->blocked && !blk_pm_request(rq) && !(rq->cmd_flags & REQ_PREEMPT)) { | 1123 | if ((drive->dev_flags & IDE_DFLAG_BLOCKED) && |
1124 | blk_pm_request(rq) == 0 && | ||
1125 | (rq->cmd_flags & REQ_PREEMPT) == 0) { | ||
1113 | drive = drive->next ? drive->next : hwgroup->drive; | 1126 | drive = drive->next ? drive->next : hwgroup->drive; |
1114 | if (loops++ < 4 && !blk_queue_plugged(drive->queue)) | 1127 | if (loops++ < 4 && !blk_queue_plugged(drive->queue)) |
1115 | goto again; | 1128 | goto again; |
@@ -1491,7 +1504,7 @@ irqreturn_t ide_intr (int irq, void *dev_id) | |||
1491 | */ | 1504 | */ |
1492 | hwif->ide_dma_clear_irq(drive); | 1505 | hwif->ide_dma_clear_irq(drive); |
1493 | 1506 | ||
1494 | if (drive->unmask) | 1507 | if (drive->dev_flags & IDE_DFLAG_UNMASK) |
1495 | local_irq_enable_in_hardirq(); | 1508 | local_irq_enable_in_hardirq(); |
1496 | /* service this interrupt, may set handler for next interrupt */ | 1509 | /* service this interrupt, may set handler for next interrupt */ |
1497 | startstop = handler(drive); | 1510 | startstop = handler(drive); |