/*1* Functions related to setting various queue properties from drivers2*/3#include <linux/kernel.h>4#include <linux/module.h>5#include <linux/bio.h>6#include <linux/blkdev.h>78#include "blk.h"910/*11* for max sense size12*/13#include <scsi/scsi_cmnd.h>1415/**16* blk_end_sync_rq - executes a completion event on a request17* @rq: request to complete18* @error: end I/O status of the request19*/20static void blk_end_sync_rq(struct request *rq, int error)21{22struct completion *waiting = rq->end_io_data;2324rq->end_io_data = NULL;25__blk_put_request(rq->q, rq);2627/*28* complete last, if this is a stack request the process (and thus29* the rq pointer) could be invalid right after this complete()30*/31complete(waiting);32}3334/**35* blk_execute_rq_nowait - insert a request into queue for execution36* @q: queue to insert the request in37* @bd_disk: matching gendisk38* @rq: request to insert39* @at_head: insert request at head or tail of queue40* @done: I/O completion handler41*42* Description:43* Insert a fully prepared request at the back of the I/O scheduler queue44* for execution. Don't wait for completion.45*/46void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk,47struct request *rq, int at_head,48rq_end_io_fn *done)49{50int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK;5152rq->rq_disk = bd_disk;53rq->end_io = done;54WARN_ON(irqs_disabled());55spin_lock_irq(q->queue_lock);56__elv_add_request(q, rq, where);57__blk_run_queue(q);58/* the queue is stopped so it won't be run */59if (rq->cmd_type == REQ_TYPE_PM_RESUME)60q->request_fn(q);61spin_unlock_irq(q->queue_lock);62}63EXPORT_SYMBOL_GPL(blk_execute_rq_nowait);6465/**66* blk_execute_rq - insert a request into queue for execution67* @q: queue to insert the request in68* @bd_disk: matching gendisk69* @rq: request to insert70* @at_head: insert request at head or tail of queue71*72* Description:73* Insert a fully prepared request at the back of the I/O scheduler queue74* for execution and wait for completion.75*/76int blk_execute_rq(struct request_queue *q, struct gendisk *bd_disk,77struct request *rq, int at_head)78{79DECLARE_COMPLETION_ONSTACK(wait);80char sense[SCSI_SENSE_BUFFERSIZE];81int err = 0;82unsigned long hang_check;8384/*85* we need an extra reference to the request, so we can look at86* it after io completion87*/88rq->ref_count++;8990if (!rq->sense) {91memset(sense, 0, sizeof(sense));92rq->sense = sense;93rq->sense_len = 0;94}9596rq->end_io_data = &wait;97blk_execute_rq_nowait(q, bd_disk, rq, at_head, blk_end_sync_rq);9899/* Prevent hang_check timer from firing at us during very long I/O */100hang_check = sysctl_hung_task_timeout_secs;101if (hang_check)102while (!wait_for_completion_timeout(&wait, hang_check * (HZ/2)));103else104wait_for_completion(&wait);105106if (rq->errors)107err = -EIO;108109return err;110}111EXPORT_SYMBOL(blk_execute_rq);112113114