diff options
| author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-06-24 08:41:41 -0400 |
|---|---|---|
| committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-06-24 13:07:53 -0400 |
| commit | 816724e65c72a90a44fbad0ef0b59b186c85fa90 (patch) | |
| tree | 421fa29aedff988e392f92780637553e275d37a0 /drivers/ide/ide-io.c | |
| parent | 70ac4385a13f78bc478f26d317511893741b05bd (diff) | |
| parent | d384ea691fe4ea8c2dd5b9b8d9042eb181776f18 (diff) | |
Merge branch 'master' of /home/trondmy/kernel/linux-2.6/
Conflicts:
fs/nfs/inode.c
fs/super.c
Fix conflicts between patch 'NFS: Split fs/nfs/inode.c' and patch
'VFS: Permit filesystem to override root dentry on mount'
Diffstat (limited to 'drivers/ide/ide-io.c')
| -rw-r--r-- | drivers/ide/ide-io.c | 91 |
1 files changed, 52 insertions, 39 deletions
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index c01615dec202..4f2f138de2ca 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
| @@ -142,38 +142,41 @@ enum { | |||
| 142 | 142 | ||
| 143 | static void ide_complete_power_step(ide_drive_t *drive, struct request *rq, u8 stat, u8 error) | 143 | static void ide_complete_power_step(ide_drive_t *drive, struct request *rq, u8 stat, u8 error) |
| 144 | { | 144 | { |
| 145 | struct request_pm_state *pm = rq->end_io_data; | ||
| 146 | |||
| 145 | if (drive->media != ide_disk) | 147 | if (drive->media != ide_disk) |
| 146 | return; | 148 | return; |
| 147 | 149 | ||
| 148 | switch (rq->pm->pm_step) { | 150 | switch (pm->pm_step) { |
| 149 | case ide_pm_flush_cache: /* Suspend step 1 (flush cache) complete */ | 151 | case ide_pm_flush_cache: /* Suspend step 1 (flush cache) complete */ |
| 150 | if (rq->pm->pm_state == PM_EVENT_FREEZE) | 152 | if (pm->pm_state == PM_EVENT_FREEZE) |
| 151 | rq->pm->pm_step = ide_pm_state_completed; | 153 | pm->pm_step = ide_pm_state_completed; |
| 152 | else | 154 | else |
| 153 | rq->pm->pm_step = idedisk_pm_standby; | 155 | pm->pm_step = idedisk_pm_standby; |
| 154 | break; | 156 | break; |
| 155 | case idedisk_pm_standby: /* Suspend step 2 (standby) complete */ | 157 | case idedisk_pm_standby: /* Suspend step 2 (standby) complete */ |
| 156 | rq->pm->pm_step = ide_pm_state_completed; | 158 | pm->pm_step = ide_pm_state_completed; |
| 157 | break; | 159 | break; |
| 158 | case idedisk_pm_idle: /* Resume step 1 (idle) complete */ | 160 | case idedisk_pm_idle: /* Resume step 1 (idle) complete */ |
| 159 | rq->pm->pm_step = ide_pm_restore_dma; | 161 | pm->pm_step = ide_pm_restore_dma; |
| 160 | break; | 162 | break; |
| 161 | } | 163 | } |
| 162 | } | 164 | } |
| 163 | 165 | ||
| 164 | static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq) | 166 | static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq) |
| 165 | { | 167 | { |
| 168 | struct request_pm_state *pm = rq->end_io_data; | ||
| 166 | ide_task_t *args = rq->special; | 169 | ide_task_t *args = rq->special; |
| 167 | 170 | ||
| 168 | memset(args, 0, sizeof(*args)); | 171 | memset(args, 0, sizeof(*args)); |
| 169 | 172 | ||
| 170 | if (drive->media != ide_disk) { | 173 | if (drive->media != ide_disk) { |
| 171 | /* skip idedisk_pm_idle for ATAPI devices */ | 174 | /* skip idedisk_pm_idle for ATAPI devices */ |
| 172 | if (rq->pm->pm_step == idedisk_pm_idle) | 175 | if (pm->pm_step == idedisk_pm_idle) |
| 173 | rq->pm->pm_step = ide_pm_restore_dma; | 176 | pm->pm_step = ide_pm_restore_dma; |
| 174 | } | 177 | } |
| 175 | 178 | ||
| 176 | switch (rq->pm->pm_step) { | 179 | switch (pm->pm_step) { |
| 177 | case ide_pm_flush_cache: /* Suspend step 1 (flush cache) */ | 180 | case ide_pm_flush_cache: /* Suspend step 1 (flush cache) */ |
| 178 | if (drive->media != ide_disk) | 181 | if (drive->media != ide_disk) |
| 179 | break; | 182 | break; |
| @@ -215,7 +218,7 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request * | |||
| 215 | drive->hwif->ide_dma_check(drive); | 218 | drive->hwif->ide_dma_check(drive); |
| 216 | break; | 219 | break; |
| 217 | } | 220 | } |
| 218 | rq->pm->pm_step = ide_pm_state_completed; | 221 | pm->pm_step = ide_pm_state_completed; |
| 219 | return ide_stopped; | 222 | return ide_stopped; |
| 220 | } | 223 | } |
| 221 | 224 | ||
| @@ -362,12 +365,13 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) | |||
| 362 | } | 365 | } |
| 363 | } | 366 | } |
| 364 | } else if (blk_pm_request(rq)) { | 367 | } else if (blk_pm_request(rq)) { |
| 368 | struct request_pm_state *pm = rq->end_io_data; | ||
| 365 | #ifdef DEBUG_PM | 369 | #ifdef DEBUG_PM |
| 366 | printk("%s: complete_power_step(step: %d, stat: %x, err: %x)\n", | 370 | printk("%s: complete_power_step(step: %d, stat: %x, err: %x)\n", |
| 367 | drive->name, rq->pm->pm_step, stat, err); | 371 | drive->name, rq->pm->pm_step, stat, err); |
| 368 | #endif | 372 | #endif |
| 369 | ide_complete_power_step(drive, rq, stat, err); | 373 | ide_complete_power_step(drive, rq, stat, err); |
| 370 | if (rq->pm->pm_step == ide_pm_state_completed) | 374 | if (pm->pm_step == ide_pm_state_completed) |
| 371 | ide_complete_pm_request(drive, rq); | 375 | ide_complete_pm_request(drive, rq); |
| 372 | return; | 376 | return; |
| 373 | } | 377 | } |
| @@ -871,6 +875,39 @@ done: | |||
| 871 | return ide_stopped; | 875 | return ide_stopped; |
| 872 | } | 876 | } |
| 873 | 877 | ||
| 878 | static void ide_check_pm_state(ide_drive_t *drive, struct request *rq) | ||
| 879 | { | ||
| 880 | struct request_pm_state *pm = rq->end_io_data; | ||
| 881 | |||
| 882 | if (blk_pm_suspend_request(rq) && | ||
| 883 | pm->pm_step == ide_pm_state_start_suspend) | ||
| 884 | /* Mark drive blocked when starting the suspend sequence. */ | ||
| 885 | drive->blocked = 1; | ||
| 886 | else if (blk_pm_resume_request(rq) && | ||
| 887 | pm->pm_step == ide_pm_state_start_resume) { | ||
| 888 | /* | ||
| 889 | * The first thing we do on wakeup is to wait for BSY bit to | ||
| 890 | * go away (with a looong timeout) as a drive on this hwif may | ||
| 891 | * just be POSTing itself. | ||
| 892 | * We do that before even selecting as the "other" device on | ||
| 893 | * the bus may be broken enough to walk on our toes at this | ||
| 894 | * point. | ||
| 895 | */ | ||
| 896 | int rc; | ||
| 897 | #ifdef DEBUG_PM | ||
| 898 | printk("%s: Wakeup request inited, waiting for !BSY...\n", drive->name); | ||
| 899 | #endif | ||
| 900 | rc = ide_wait_not_busy(HWIF(drive), 35000); | ||
| 901 | if (rc) | ||
| 902 | printk(KERN_WARNING "%s: bus not ready on wakeup\n", drive->name); | ||
| 903 | SELECT_DRIVE(drive); | ||
| 904 | HWIF(drive)->OUTB(8, HWIF(drive)->io_ports[IDE_CONTROL_OFFSET]); | ||
| 905 | rc = ide_wait_not_busy(HWIF(drive), 10000); | ||
| 906 | if (rc) | ||
| 907 | printk(KERN_WARNING "%s: drive not ready on wakeup\n", drive->name); | ||
| 908 | } | ||
| 909 | } | ||
| 910 | |||
| 874 | /** | 911 | /** |
| 875 | * start_request - start of I/O and command issuing for IDE | 912 | * start_request - start of I/O and command issuing for IDE |
| 876 | * | 913 | * |
| @@ -909,33 +946,8 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) | |||
| 909 | if (block == 0 && drive->remap_0_to_1 == 1) | 946 | if (block == 0 && drive->remap_0_to_1 == 1) |
| 910 | block = 1; /* redirect MBR access to EZ-Drive partn table */ | 947 | block = 1; /* redirect MBR access to EZ-Drive partn table */ |
| 911 | 948 | ||
| 912 | if (blk_pm_suspend_request(rq) && | 949 | if (blk_pm_request(rq)) |
| 913 | rq->pm->pm_step == ide_pm_state_start_suspend) | 950 | ide_check_pm_state(drive, rq); |
| 914 | /* Mark drive blocked when starting the suspend sequence. */ | ||
| 915 | drive->blocked = 1; | ||
| 916 | else if (blk_pm_resume_request(rq) && | ||
| 917 | rq->pm->pm_step == ide_pm_state_start_resume) { | ||
| 918 | /* | ||
| 919 | * The first thing we do on wakeup is to wait for BSY bit to | ||
| 920 | * go away (with a looong timeout) as a drive on this hwif may | ||
| 921 | * just be POSTing itself. | ||
| 922 | * We do that before even selecting as the "other" device on | ||
| 923 | * the bus may be broken enough to walk on our toes at this | ||
| 924 | * point. | ||
| 925 | */ | ||
| 926 | int rc; | ||
| 927 | #ifdef DEBUG_PM | ||
| 928 | printk("%s: Wakeup request inited, waiting for !BSY...\n", drive->name); | ||
| 929 | #endif | ||
| 930 | rc = ide_wait_not_busy(HWIF(drive), 35000); | ||
| 931 | if (rc) | ||
| 932 | printk(KERN_WARNING "%s: bus not ready on wakeup\n", drive->name); | ||
| 933 | SELECT_DRIVE(drive); | ||
| 934 | HWIF(drive)->OUTB(8, HWIF(drive)->io_ports[IDE_CONTROL_OFFSET]); | ||
| 935 | rc = ide_wait_not_busy(HWIF(drive), 10000); | ||
| 936 | if (rc) | ||
| 937 | printk(KERN_WARNING "%s: drive not ready on wakeup\n", drive->name); | ||
| 938 | } | ||
| 939 | 951 | ||
| 940 | SELECT_DRIVE(drive); | 952 | SELECT_DRIVE(drive); |
| 941 | if (ide_wait_stat(&startstop, drive, drive->ready_stat, BUSY_STAT|DRQ_STAT, WAIT_READY)) { | 953 | if (ide_wait_stat(&startstop, drive, drive->ready_stat, BUSY_STAT|DRQ_STAT, WAIT_READY)) { |
| @@ -950,13 +962,14 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) | |||
| 950 | else if (rq->flags & REQ_DRIVE_TASKFILE) | 962 | else if (rq->flags & REQ_DRIVE_TASKFILE) |
| 951 | return execute_drive_cmd(drive, rq); | 963 | return execute_drive_cmd(drive, rq); |
| 952 | else if (blk_pm_request(rq)) { | 964 | else if (blk_pm_request(rq)) { |
| 965 | struct request_pm_state *pm = rq->end_io_data; | ||
| 953 | #ifdef DEBUG_PM | 966 | #ifdef DEBUG_PM |
| 954 | printk("%s: start_power_step(step: %d)\n", | 967 | printk("%s: start_power_step(step: %d)\n", |
| 955 | drive->name, rq->pm->pm_step); | 968 | drive->name, rq->pm->pm_step); |
| 956 | #endif | 969 | #endif |
| 957 | startstop = ide_start_power_step(drive, rq); | 970 | startstop = ide_start_power_step(drive, rq); |
| 958 | if (startstop == ide_stopped && | 971 | if (startstop == ide_stopped && |
| 959 | rq->pm->pm_step == ide_pm_state_completed) | 972 | pm->pm_step == ide_pm_state_completed) |
| 960 | ide_complete_pm_request(drive, rq); | 973 | ide_complete_pm_request(drive, rq); |
| 961 | return startstop; | 974 | return startstop; |
| 962 | } | 975 | } |
