Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

block: move PM request support to IDE

This removes the request types and hacks from the block code and into the
old IDE driver. There is a small amunt of code duplication due to this,
but it's not too bad.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jens Axboe <axboe@fb.com>

authored by

Christoph Hellwig and committed by
Jens Axboe
a7928c15 ac7cdff0

+70 -51
+1
block/blk-core.c
··· 285 285 q->request_fn(q); 286 286 q->request_fn_active--; 287 287 } 288 + EXPORT_SYMBOL_GPL(__blk_run_queue_uncond); 288 289 289 290 /** 290 291 * __blk_run_queue - run a single device queue
-10
block/blk-exec.c
··· 53 53 rq_end_io_fn *done) 54 54 { 55 55 int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK; 56 - bool is_pm_resume; 57 56 58 57 WARN_ON(irqs_disabled()); 59 58 WARN_ON(rq->cmd_type == REQ_TYPE_FS); ··· 69 70 return; 70 71 } 71 72 72 - /* 73 - * need to check this before __blk_run_queue(), because rq can 74 - * be freed before that returns. 75 - */ 76 - is_pm_resume = rq->cmd_type == REQ_TYPE_PM_RESUME; 77 - 78 73 spin_lock_irq(q->queue_lock); 79 74 80 75 if (unlikely(blk_queue_dying(q))) { ··· 81 88 82 89 __elv_add_request(q, rq, where); 83 90 __blk_run_queue(q); 84 - /* the queue is stopped so it won't be run */ 85 - if (is_pm_resume) 86 - __blk_run_queue_uncond(q); 87 91 spin_unlock_irq(q->queue_lock); 88 92 } 89 93 EXPORT_SYMBOL_GPL(blk_execute_rq_nowait);
-2
block/blk.h
··· 193 193 194 194 void blk_queue_congestion_threshold(struct request_queue *q); 195 195 196 - void __blk_run_queue_uncond(struct request_queue *q); 197 - 198 196 int blk_dev_init(void); 199 197 200 198
+1 -1
drivers/ide/ide-eh.c
··· 129 129 130 130 if (cmd) 131 131 ide_complete_cmd(drive, cmd, stat, err); 132 - } else if (blk_pm_request(rq)) { 132 + } else if (ata_pm_request(rq)) { 133 133 rq->errors = 1; 134 134 ide_complete_pm_rq(drive, rq); 135 135 return ide_stopped;
+4 -4
drivers/ide/ide-io.c
··· 320 320 goto kill_rq; 321 321 } 322 322 323 - if (blk_pm_request(rq)) 323 + if (ata_pm_request(rq)) 324 324 ide_check_pm_state(drive, rq); 325 325 326 326 drive->hwif->tp_ops->dev_select(drive); ··· 342 342 343 343 if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) 344 344 return execute_drive_cmd(drive, rq); 345 - else if (blk_pm_request(rq)) { 346 - struct request_pm_state *pm = rq->special; 345 + else if (ata_pm_request(rq)) { 346 + struct ide_pm_state *pm = rq->special; 347 347 #ifdef DEBUG_PM 348 348 printk("%s: start_power_step(step: %d)\n", 349 349 drive->name, pm->pm_step); ··· 538 538 * state machine. 539 539 */ 540 540 if ((drive->dev_flags & IDE_DFLAG_BLOCKED) && 541 - blk_pm_request(rq) == 0 && 541 + ata_pm_request(rq) == 0 && 542 542 (rq->cmd_flags & REQ_PREEMPT) == 0) { 543 543 /* there should be no pending command at this point */ 544 544 ide_unlock_port(hwif);
+43 -13
drivers/ide/ide-pm.c
··· 8 8 ide_drive_t *pair = ide_get_pair_dev(drive); 9 9 ide_hwif_t *hwif = drive->hwif; 10 10 struct request *rq; 11 - struct request_pm_state rqpm; 11 + struct ide_pm_state rqpm; 12 12 int ret; 13 13 14 14 if (ide_port_acpi(hwif)) { ··· 19 19 20 20 memset(&rqpm, 0, sizeof(rqpm)); 21 21 rq = blk_get_request(drive->queue, READ, __GFP_WAIT); 22 - rq->cmd_type = REQ_TYPE_PM_SUSPEND; 22 + rq->cmd_type = REQ_TYPE_ATA_PM_SUSPEND; 23 23 rq->special = &rqpm; 24 24 rqpm.pm_step = IDE_PM_START_SUSPEND; 25 25 if (mesg.event == PM_EVENT_PRETHAW) ··· 38 38 return ret; 39 39 } 40 40 41 + static void ide_end_sync_rq(struct request *rq, int error) 42 + { 43 + complete(rq->end_io_data); 44 + } 45 + 46 + static int ide_pm_execute_rq(struct request *rq) 47 + { 48 + struct request_queue *q = rq->q; 49 + DECLARE_COMPLETION_ONSTACK(wait); 50 + 51 + rq->end_io_data = &wait; 52 + rq->end_io = ide_end_sync_rq; 53 + 54 + spin_lock_irq(q->queue_lock); 55 + if (unlikely(blk_queue_dying(q))) { 56 + rq->cmd_flags |= REQ_QUIET; 57 + rq->errors = -ENXIO; 58 + __blk_end_request_all(rq, rq->errors); 59 + spin_unlock_irq(q->queue_lock); 60 + return -ENXIO; 61 + } 62 + __elv_add_request(q, rq, ELEVATOR_INSERT_FRONT); 63 + __blk_run_queue_uncond(q); 64 + spin_unlock_irq(q->queue_lock); 65 + 66 + wait_for_completion_io(&wait); 67 + 68 + return rq->errors ? -EIO : 0; 69 + } 70 + 41 71 int generic_ide_resume(struct device *dev) 42 72 { 43 73 ide_drive_t *drive = to_ide_device(dev); 44 74 ide_drive_t *pair = ide_get_pair_dev(drive); 45 75 ide_hwif_t *hwif = drive->hwif; 46 76 struct request *rq; 47 - struct request_pm_state rqpm; 77 + struct ide_pm_state rqpm; 48 78 int err; 49 79 50 80 if (ide_port_acpi(hwif)) { ··· 89 59 90 60 memset(&rqpm, 0, sizeof(rqpm)); 91 61 rq = blk_get_request(drive->queue, READ, __GFP_WAIT); 92 - rq->cmd_type = REQ_TYPE_PM_RESUME; 62 + rq->cmd_type = REQ_TYPE_ATA_PM_RESUME; 93 63 rq->cmd_flags |= REQ_PREEMPT; 94 64 rq->special = &rqpm; 95 65 rqpm.pm_step = IDE_PM_START_RESUME; 96 66 rqpm.pm_state = PM_EVENT_ON; 97 67 98 - err = blk_execute_rq(drive->queue, NULL, rq, 1); 68 + err = ide_pm_execute_rq(rq); 99 69 blk_put_request(rq); 100 70 101 71 if (err == 0 && dev->driver) { ··· 110 80 111 81 void ide_complete_power_step(ide_drive_t *drive, struct request *rq) 112 82 { 113 - struct request_pm_state *pm = rq->special; 83 + struct ide_pm_state *pm = rq->special; 114 84 115 85 #ifdef DEBUG_PM 116 86 printk(KERN_INFO "%s: complete_power_step(step: %d)\n", ··· 140 110 141 111 ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq) 142 112 { 143 - struct request_pm_state *pm = rq->special; 113 + struct ide_pm_state *pm = rq->special; 144 114 struct ide_cmd cmd = { }; 145 115 146 116 switch (pm->pm_step) { ··· 212 182 void ide_complete_pm_rq(ide_drive_t *drive, struct request *rq) 213 183 { 214 184 struct request_queue *q = drive->queue; 215 - struct request_pm_state *pm = rq->special; 185 + struct ide_pm_state *pm = rq->special; 216 186 unsigned long flags; 217 187 218 188 ide_complete_power_step(drive, rq); ··· 221 191 222 192 #ifdef DEBUG_PM 223 193 printk("%s: completing PM request, %s\n", drive->name, 224 - (rq->cmd_type == REQ_TYPE_PM_SUSPEND) ? "suspend" : "resume"); 194 + (rq->cmd_type == REQ_TYPE_ATA_PM_SUSPEND) ? "suspend" : "resume"); 225 195 #endif 226 196 spin_lock_irqsave(q->queue_lock, flags); 227 - if (rq->cmd_type == REQ_TYPE_PM_SUSPEND) 197 + if (rq->cmd_type == REQ_TYPE_ATA_PM_SUSPEND) 228 198 blk_stop_queue(q); 229 199 else 230 200 drive->dev_flags &= ~IDE_DFLAG_BLOCKED; ··· 238 208 239 209 void ide_check_pm_state(ide_drive_t *drive, struct request *rq) 240 210 { 241 - struct request_pm_state *pm = rq->special; 211 + struct ide_pm_state *pm = rq->special; 242 212 243 - if (rq->cmd_type == REQ_TYPE_PM_SUSPEND && 213 + if (rq->cmd_type == REQ_TYPE_ATA_PM_SUSPEND && 244 214 pm->pm_step == IDE_PM_START_SUSPEND) 245 215 /* Mark drive blocked when starting the suspend sequence. */ 246 216 drive->dev_flags |= IDE_DFLAG_BLOCKED; 247 - else if (rq->cmd_type == REQ_TYPE_PM_RESUME && 217 + else if (rq->cmd_type == REQ_TYPE_ATA_PM_RESUME && 248 218 pm->pm_step == IDE_PM_START_RESUME) { 249 219 /* 250 220 * The first thing we do on wakeup is to wait for BSY bit to
+1 -1
drivers/ide/ide-taskfile.c
··· 186 186 tf->command == ATA_CMD_CHK_POWER) { 187 187 struct request *rq = hwif->rq; 188 188 189 - if (blk_pm_request(rq)) 189 + if (ata_pm_request(rq)) 190 190 ide_complete_pm_rq(drive, rq); 191 191 else 192 192 ide_finish_cmd(drive, cmd, stat);
+1 -20
include/linux/blkdev.h
··· 30 30 31 31 struct request_queue; 32 32 struct elevator_queue; 33 - struct request_pm_state; 34 33 struct blk_trace; 35 34 struct request; 36 35 struct sg_io_hdr; ··· 74 75 enum rq_cmd_type_bits { 75 76 REQ_TYPE_FS = 1, /* fs request */ 76 77 REQ_TYPE_BLOCK_PC, /* scsi command */ 77 - REQ_TYPE_PM_SUSPEND, /* suspend request */ 78 - REQ_TYPE_PM_RESUME, /* resume request */ 79 78 REQ_TYPE_DRV_PRIV, /* driver defined types from here */ 80 79 }; 81 80 ··· 203 206 { 204 207 return req->ioprio; 205 208 } 206 - 207 - /* 208 - * State information carried for REQ_TYPE_PM_SUSPEND and REQ_TYPE_PM_RESUME 209 - * requests. Some step values could eventually be made generic. 210 - */ 211 - struct request_pm_state 212 - { 213 - /* PM state machine step value, currently driver specific */ 214 - int pm_step; 215 - /* requested PM state value (S1, S2, S3, S4, ...) */ 216 - u32 pm_state; 217 - void* data; /* for driver use */ 218 - }; 219 209 220 210 #include <linux/elevator.h> 221 211 ··· 585 601 (((rq)->cmd_flags & REQ_STARTED) && \ 586 602 ((rq)->cmd_type == REQ_TYPE_FS)) 587 603 588 - #define blk_pm_request(rq) \ 589 - ((rq)->cmd_type == REQ_TYPE_PM_SUSPEND || \ 590 - (rq)->cmd_type == REQ_TYPE_PM_RESUME) 591 - 592 604 #define blk_rq_cpu_valid(rq) ((rq)->cpu != -1) 593 605 #define blk_bidi_rq(rq) ((rq)->next_rq != NULL) 594 606 /* rq->queuelist of dequeued request must be list_empty() */ ··· 818 838 extern void blk_sync_queue(struct request_queue *q); 819 839 extern void __blk_stop_queue(struct request_queue *q); 820 840 extern void __blk_run_queue(struct request_queue *q); 841 + extern void __blk_run_queue_uncond(struct request_queue *q); 821 842 extern void blk_run_queue(struct request_queue *); 822 843 extern void blk_run_queue_async(struct request_queue *q); 823 844 extern int blk_rq_map_user(struct request_queue *, struct request *,
+19
include/linux/ide.h
··· 44 44 REQ_TYPE_ATA_TASKFILE = REQ_TYPE_DRV_PRIV + 1, 45 45 REQ_TYPE_ATA_PC, 46 46 REQ_TYPE_ATA_SENSE, /* sense request */ 47 + REQ_TYPE_ATA_PM_SUSPEND,/* suspend request */ 48 + REQ_TYPE_ATA_PM_RESUME, /* resume request */ 47 49 }; 50 + 51 + #define ata_pm_request(rq) \ 52 + ((rq)->cmd_type == REQ_TYPE_ATA_PM_SUSPEND || \ 53 + (rq)->cmd_type == REQ_TYPE_ATA_PM_RESUME) 48 54 49 55 /* Error codes returned in rq->errors to the higher part of the driver. */ 50 56 enum { ··· 1326 1320 u8 mwdma_mask; 1327 1321 u8 udma_mask; 1328 1322 }; 1323 + 1324 + /* 1325 + * State information carried for REQ_TYPE_ATA_PM_SUSPEND and REQ_TYPE_ATA_PM_RESUME 1326 + * requests. 1327 + */ 1328 + struct ide_pm_state { 1329 + /* PM state machine step value, currently driver specific */ 1330 + int pm_step; 1331 + /* requested PM state value (S1, S2, S3, S4, ...) */ 1332 + u32 pm_state; 1333 + void* data; /* for driver use */ 1334 + }; 1335 + 1329 1336 1330 1337 int ide_pci_init_one(struct pci_dev *, const struct ide_port_info *, void *); 1331 1338 int ide_pci_init_two(struct pci_dev *, struct pci_dev *,