diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ide/ide-io.c | 91 | ||||
-rw-r--r-- | drivers/ide/ide.c | 4 |
2 files changed, 54 insertions, 41 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 | } |
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 9799aed772e1..59fe358048b3 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c | |||
@@ -1226,7 +1226,7 @@ static int generic_ide_suspend(struct device *dev, pm_message_t state) | |||
1226 | memset(&args, 0, sizeof(args)); | 1226 | memset(&args, 0, sizeof(args)); |
1227 | rq.flags = REQ_PM_SUSPEND; | 1227 | rq.flags = REQ_PM_SUSPEND; |
1228 | rq.special = &args; | 1228 | rq.special = &args; |
1229 | rq.pm = &rqpm; | 1229 | rq.end_io_data = &rqpm; |
1230 | rqpm.pm_step = ide_pm_state_start_suspend; | 1230 | rqpm.pm_step = ide_pm_state_start_suspend; |
1231 | rqpm.pm_state = state.event; | 1231 | rqpm.pm_state = state.event; |
1232 | 1232 | ||
@@ -1245,7 +1245,7 @@ static int generic_ide_resume(struct device *dev) | |||
1245 | memset(&args, 0, sizeof(args)); | 1245 | memset(&args, 0, sizeof(args)); |
1246 | rq.flags = REQ_PM_RESUME; | 1246 | rq.flags = REQ_PM_RESUME; |
1247 | rq.special = &args; | 1247 | rq.special = &args; |
1248 | rq.pm = &rqpm; | 1248 | rq.end_io_data = &rqpm; |
1249 | rqpm.pm_step = ide_pm_state_start_resume; | 1249 | rqpm.pm_step = ide_pm_state_start_resume; |
1250 | rqpm.pm_state = PM_EVENT_ON; | 1250 | rqpm.pm_state = PM_EVENT_ON; |
1251 | 1251 | ||