aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ide/ide-io.c91
-rw-r--r--drivers/ide/ide.c4
-rw-r--r--include/linux/blkdev.h5
3 files changed, 54 insertions, 46 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
143static void ide_complete_power_step(ide_drive_t *drive, struct request *rq, u8 stat, u8 error) 143static 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
164static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq) 166static 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
878static 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
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 482a21d67627..371c0ce5f630 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -196,11 +196,6 @@ struct request {
196 int retries; 196 int retries;
197 197
198 /* 198 /*
199 * For Power Management requests
200 */
201 struct request_pm_state *pm;
202
203 /*
204 * completion callback. end_io_data should be folded in with waiting 199 * completion callback. end_io_data should be folded in with waiting
205 */ 200 */
206 rq_end_io_fn *end_io; 201 rq_end_io_fn *end_io;