block: move PM request support to IDE
authorChristoph Hellwig <hch@lst.de>
Fri, 17 Apr 2015 20:37:20 +0000 (22:37 +0200)
committerJens Axboe <axboe@fb.com>
Tue, 5 May 2015 19:40:42 +0000 (13:40 -0600)
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>
block/blk-core.c
block/blk-exec.c
block/blk.h
drivers/ide/ide-eh.c
drivers/ide/ide-io.c
drivers/ide/ide-pm.c
drivers/ide/ide-taskfile.c
include/linux/blkdev.h
include/linux/ide.h

index fd154b94447a25788f48d5e8cc04bc803d1efdb8..2e5020f37d55af2f944a1fbaa93dd19b161492b7 100644 (file)
@@ -285,6 +285,7 @@ inline void __blk_run_queue_uncond(struct request_queue *q)
        q->request_fn(q);
        q->request_fn_active--;
 }
+EXPORT_SYMBOL_GPL(__blk_run_queue_uncond);
 
 /**
  * __blk_run_queue - run a single device queue
index 9924725fa50dcac5563d2654a24df0d85cfada7a..3fec8a29d0fae16f3c0398ff292a75dbce38cf77 100644 (file)
@@ -53,7 +53,6 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk,
                           rq_end_io_fn *done)
 {
        int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK;
-       bool is_pm_resume;
 
        WARN_ON(irqs_disabled());
        WARN_ON(rq->cmd_type == REQ_TYPE_FS);
@@ -70,12 +69,6 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk,
                return;
        }
 
-       /*
-        * need to check this before __blk_run_queue(), because rq can
-        * be freed before that returns.
-        */
-       is_pm_resume = rq->cmd_type == REQ_TYPE_PM_RESUME;
-
        spin_lock_irq(q->queue_lock);
 
        if (unlikely(blk_queue_dying(q))) {
@@ -88,9 +81,6 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk,
 
        __elv_add_request(q, rq, where);
        __blk_run_queue(q);
-       /* the queue is stopped so it won't be run */
-       if (is_pm_resume)
-               __blk_run_queue_uncond(q);
        spin_unlock_irq(q->queue_lock);
 }
 EXPORT_SYMBOL_GPL(blk_execute_rq_nowait);
index 43b036185712c25f66d04a3c9e49565297c94ccd..4b48d55e588effaf2b47d1679af46634ca68768d 100644 (file)
@@ -193,8 +193,6 @@ int blk_try_merge(struct request *rq, struct bio *bio);
 
 void blk_queue_congestion_threshold(struct request_queue *q);
 
-void __blk_run_queue_uncond(struct request_queue *q);
-
 int blk_dev_init(void);
 
 
index 19d809c48a8d1a84c7e70e71ad834616530d02c1..d6da011299f582934bf50c1c05c0719577d41ba6 100644 (file)
@@ -129,7 +129,7 @@ ide_startstop_t ide_error(ide_drive_t *drive, const char *msg, u8 stat)
 
                        if (cmd)
                                ide_complete_cmd(drive, cmd, stat, err);
-               } else if (blk_pm_request(rq)) {
+               } else if (ata_pm_request(rq)) {
                        rq->errors = 1;
                        ide_complete_pm_rq(drive, rq);
                        return ide_stopped;
index 8e55abd03a24026f6e58cc7b9f2b2d6d47e78ca6..669ea1e457958699849687e0efc78809758f8f92 100644 (file)
@@ -320,7 +320,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
                goto kill_rq;
        }
 
-       if (blk_pm_request(rq))
+       if (ata_pm_request(rq))
                ide_check_pm_state(drive, rq);
 
        drive->hwif->tp_ops->dev_select(drive);
@@ -342,8 +342,8 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
 
                if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE)
                        return execute_drive_cmd(drive, rq);
-               else if (blk_pm_request(rq)) {
-                       struct request_pm_state *pm = rq->special;
+               else if (ata_pm_request(rq)) {
+                       struct ide_pm_state *pm = rq->special;
 #ifdef DEBUG_PM
                        printk("%s: start_power_step(step: %d)\n",
                                drive->name, pm->pm_step);
@@ -538,7 +538,7 @@ repeat:
                 * state machine.
                 */
                if ((drive->dev_flags & IDE_DFLAG_BLOCKED) &&
-                   blk_pm_request(rq) == 0 &&
+                   ata_pm_request(rq) == 0 &&
                    (rq->cmd_flags & REQ_PREEMPT) == 0) {
                        /* there should be no pending command at this point */
                        ide_unlock_port(hwif);
index 8d1e32d7cd9767db4e1c99db627681f03f233139..081e43458d50f745671f9c5c4476d760e33b7fc0 100644 (file)
@@ -8,7 +8,7 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg)
        ide_drive_t *pair = ide_get_pair_dev(drive);
        ide_hwif_t *hwif = drive->hwif;
        struct request *rq;
-       struct request_pm_state rqpm;
+       struct ide_pm_state rqpm;
        int ret;
 
        if (ide_port_acpi(hwif)) {
@@ -19,7 +19,7 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg)
 
        memset(&rqpm, 0, sizeof(rqpm));
        rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
-       rq->cmd_type = REQ_TYPE_PM_SUSPEND;
+       rq->cmd_type = REQ_TYPE_ATA_PM_SUSPEND;
        rq->special = &rqpm;
        rqpm.pm_step = IDE_PM_START_SUSPEND;
        if (mesg.event == PM_EVENT_PRETHAW)
@@ -38,13 +38,43 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg)
        return ret;
 }
 
+static void ide_end_sync_rq(struct request *rq, int error)
+{
+       complete(rq->end_io_data);
+}
+
+static int ide_pm_execute_rq(struct request *rq)
+{
+       struct request_queue *q = rq->q;
+       DECLARE_COMPLETION_ONSTACK(wait);
+
+       rq->end_io_data = &wait;
+       rq->end_io = ide_end_sync_rq;
+
+       spin_lock_irq(q->queue_lock);
+       if (unlikely(blk_queue_dying(q))) {
+               rq->cmd_flags |= REQ_QUIET;
+               rq->errors = -ENXIO;
+               __blk_end_request_all(rq, rq->errors);
+               spin_unlock_irq(q->queue_lock);
+               return -ENXIO;
+       }
+       __elv_add_request(q, rq, ELEVATOR_INSERT_FRONT);
+       __blk_run_queue_uncond(q);
+       spin_unlock_irq(q->queue_lock);
+
+       wait_for_completion_io(&wait);
+
+       return rq->errors ? -EIO : 0;
+}
+
 int generic_ide_resume(struct device *dev)
 {
        ide_drive_t *drive = to_ide_device(dev);
        ide_drive_t *pair = ide_get_pair_dev(drive);
        ide_hwif_t *hwif = drive->hwif;
        struct request *rq;
-       struct request_pm_state rqpm;
+       struct ide_pm_state rqpm;
        int err;
 
        if (ide_port_acpi(hwif)) {
@@ -59,13 +89,13 @@ int generic_ide_resume(struct device *dev)
 
        memset(&rqpm, 0, sizeof(rqpm));
        rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
-       rq->cmd_type = REQ_TYPE_PM_RESUME;
+       rq->cmd_type = REQ_TYPE_ATA_PM_RESUME;
        rq->cmd_flags |= REQ_PREEMPT;
        rq->special = &rqpm;
        rqpm.pm_step = IDE_PM_START_RESUME;
        rqpm.pm_state = PM_EVENT_ON;
 
-       err = blk_execute_rq(drive->queue, NULL, rq, 1);
+       err = ide_pm_execute_rq(rq);
        blk_put_request(rq);
 
        if (err == 0 && dev->driver) {
@@ -80,7 +110,7 @@ int generic_ide_resume(struct device *dev)
 
 void ide_complete_power_step(ide_drive_t *drive, struct request *rq)
 {
-       struct request_pm_state *pm = rq->special;
+       struct ide_pm_state *pm = rq->special;
 
 #ifdef DEBUG_PM
        printk(KERN_INFO "%s: complete_power_step(step: %d)\n",
@@ -110,7 +140,7 @@ void ide_complete_power_step(ide_drive_t *drive, struct request *rq)
 
 ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq)
 {
-       struct request_pm_state *pm = rq->special;
+       struct ide_pm_state *pm = rq->special;
        struct ide_cmd cmd = { };
 
        switch (pm->pm_step) {
@@ -182,7 +212,7 @@ out_do_tf:
 void ide_complete_pm_rq(ide_drive_t *drive, struct request *rq)
 {
        struct request_queue *q = drive->queue;
-       struct request_pm_state *pm = rq->special;
+       struct ide_pm_state *pm = rq->special;
        unsigned long flags;
 
        ide_complete_power_step(drive, rq);
@@ -191,10 +221,10 @@ void ide_complete_pm_rq(ide_drive_t *drive, struct request *rq)
 
 #ifdef DEBUG_PM
        printk("%s: completing PM request, %s\n", drive->name,
-              (rq->cmd_type == REQ_TYPE_PM_SUSPEND) ? "suspend" : "resume");
+              (rq->cmd_type == REQ_TYPE_ATA_PM_SUSPEND) ? "suspend" : "resume");
 #endif
        spin_lock_irqsave(q->queue_lock, flags);
-       if (rq->cmd_type == REQ_TYPE_PM_SUSPEND)
+       if (rq->cmd_type == REQ_TYPE_ATA_PM_SUSPEND)
                blk_stop_queue(q);
        else
                drive->dev_flags &= ~IDE_DFLAG_BLOCKED;
@@ -208,13 +238,13 @@ void ide_complete_pm_rq(ide_drive_t *drive, struct request *rq)
 
 void ide_check_pm_state(ide_drive_t *drive, struct request *rq)
 {
-       struct request_pm_state *pm = rq->special;
+       struct ide_pm_state *pm = rq->special;
 
-       if (rq->cmd_type == REQ_TYPE_PM_SUSPEND &&
+       if (rq->cmd_type == REQ_TYPE_ATA_PM_SUSPEND &&
            pm->pm_step == IDE_PM_START_SUSPEND)
                /* Mark drive blocked when starting the suspend sequence. */
                drive->dev_flags |= IDE_DFLAG_BLOCKED;
-       else if (rq->cmd_type == REQ_TYPE_PM_RESUME &&
+       else if (rq->cmd_type == REQ_TYPE_ATA_PM_RESUME &&
                 pm->pm_step == IDE_PM_START_RESUME) {
                /*
                 * The first thing we do on wakeup is to wait for BSY bit to
index dabb88b1cbec69052d32eb5e84b7f647534a4599..0979e126fff1e69ee3b3f8df19e5a443cbae5194 100644 (file)
@@ -186,7 +186,7 @@ static ide_startstop_t task_no_data_intr(ide_drive_t *drive)
            tf->command == ATA_CMD_CHK_POWER) {
                struct request *rq = hwif->rq;
 
-               if (blk_pm_request(rq))
+               if (ata_pm_request(rq))
                        ide_complete_pm_rq(drive, rq);
                else
                        ide_finish_cmd(drive, cmd, stat);
index c2829ba5e738b8ef64584578f00d73dd625845b6..2da818a480975ea28cd82b7beeef9621982120c6 100644 (file)
@@ -30,7 +30,6 @@ struct scsi_ioctl_command;
 
 struct request_queue;
 struct elevator_queue;
-struct request_pm_state;
 struct blk_trace;
 struct request;
 struct sg_io_hdr;
@@ -75,8 +74,6 @@ struct request_list {
 enum rq_cmd_type_bits {
        REQ_TYPE_FS             = 1,    /* fs request */
        REQ_TYPE_BLOCK_PC,              /* scsi command */
-       REQ_TYPE_PM_SUSPEND,            /* suspend request */
-       REQ_TYPE_PM_RESUME,             /* resume request */
        REQ_TYPE_DRV_PRIV,              /* driver defined types from here */
 };
 
@@ -207,19 +204,6 @@ static inline unsigned short req_get_ioprio(struct request *req)
        return req->ioprio;
 }
 
-/*
- * State information carried for REQ_TYPE_PM_SUSPEND and REQ_TYPE_PM_RESUME
- * requests. Some step values could eventually be made generic.
- */
-struct request_pm_state
-{
-       /* PM state machine step value, currently driver specific */
-       int     pm_step;
-       /* requested PM state value (S1, S2, S3, S4, ...) */
-       u32     pm_state;
-       void*   data;           /* for driver use */
-};
-
 #include <linux/elevator.h>
 
 struct blk_queue_ctx;
@@ -601,10 +585,6 @@ static inline void queue_flag_clear(unsigned int flag, struct request_queue *q)
        (((rq)->cmd_flags & REQ_STARTED) && \
         ((rq)->cmd_type == REQ_TYPE_FS))
 
-#define blk_pm_request(rq)     \
-       ((rq)->cmd_type == REQ_TYPE_PM_SUSPEND || \
-        (rq)->cmd_type == REQ_TYPE_PM_RESUME)
-
 #define blk_rq_cpu_valid(rq)   ((rq)->cpu != -1)
 #define blk_bidi_rq(rq)                ((rq)->next_rq != NULL)
 /* rq->queuelist of dequeued request must be list_empty() */
@@ -838,6 +818,7 @@ extern void blk_stop_queue(struct request_queue *q);
 extern void blk_sync_queue(struct request_queue *q);
 extern void __blk_stop_queue(struct request_queue *q);
 extern void __blk_run_queue(struct request_queue *q);
+extern void __blk_run_queue_uncond(struct request_queue *q);
 extern void blk_run_queue(struct request_queue *);
 extern void blk_run_queue_async(struct request_queue *q);
 extern int blk_rq_map_user(struct request_queue *, struct request *,
index 9856b7d455d9060d65c95e9331d7ca2958efac6f..a633898f36ac83f387f6de86350f7768a3d73b6e 100644 (file)
@@ -44,8 +44,14 @@ enum ata_cmd_type_bits {
        REQ_TYPE_ATA_TASKFILE = REQ_TYPE_DRV_PRIV + 1,
        REQ_TYPE_ATA_PC,
        REQ_TYPE_ATA_SENSE,     /* sense request */
+       REQ_TYPE_ATA_PM_SUSPEND,/* suspend request */
+       REQ_TYPE_ATA_PM_RESUME, /* resume request */
 };
 
+#define ata_pm_request(rq)     \
+       ((rq)->cmd_type == REQ_TYPE_ATA_PM_SUSPEND || \
+        (rq)->cmd_type == REQ_TYPE_ATA_PM_RESUME)
+
 /* Error codes returned in rq->errors to the higher part of the driver. */
 enum {
        IDE_DRV_ERROR_GENERAL   = 101,
@@ -1321,6 +1327,19 @@ struct ide_port_info {
        u8                      udma_mask;
 };
 
+/*
+ * State information carried for REQ_TYPE_ATA_PM_SUSPEND and REQ_TYPE_ATA_PM_RESUME
+ * requests.
+ */
+struct ide_pm_state {
+       /* PM state machine step value, currently driver specific */
+       int     pm_step;
+       /* requested PM state value (S1, S2, S3, S4, ...) */
+       u32     pm_state;
+       void*   data;           /* for driver use */
+};
+
+
 int ide_pci_init_one(struct pci_dev *, const struct ide_port_info *, void *);
 int ide_pci_init_two(struct pci_dev *, struct pci_dev *,
                     const struct ide_port_info *, void *);