Commit f0f00520 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'blk-end-request' of git://git.kernel.dk/linux-2.6-block

* 'blk-end-request' of git://git.kernel.dk/linux-2.6-block: (30 commits)
  blk_end_request: changing xsysace (take 4)
  blk_end_request: changing ub (take 4)
  blk_end_request: cleanup of request completion (take 4)
  blk_end_request: cleanup 'uptodate' related code (take 4)
  blk_end_request: remove/unexport end_that_request_* (take 4)
  blk_end_request: changing scsi (take 4)
  blk_end_request: add bidi completion interface (take 4)
  blk_end_request: changing ide-cd (take 4)
  blk_end_request: add callback feature (take 4)
  blk_end_request: changing ide normal caller (take 4)
  blk_end_request: changing cpqarray (take 4)
  blk_end_request: changing cciss (take 4)
  blk_end_request: changing ide-scsi (take 4)
  blk_end_request: changing s390 (take 4)
  blk_end_request: changing mmc (take 4)
  blk_end_request: changing i2o_block (take 4)
  blk_end_request: changing viocd (take 4)
  blk_end_request: changing xen-blkfront (take 4)
  blk_end_request: changing viodasd (take 4)
  blk_end_request: changing sx8 (take 4)
  ...
parents 68fbda7d a65b5866
...@@ -116,8 +116,8 @@ static void mbox_tx_work(struct work_struct *work) ...@@ -116,8 +116,8 @@ static void mbox_tx_work(struct work_struct *work)
} }
spin_lock(q->queue_lock); spin_lock(q->queue_lock);
blkdev_dequeue_request(rq); if (__blk_end_request(rq, 0, 0))
end_that_request_last(rq, 0); BUG();
spin_unlock(q->queue_lock); spin_unlock(q->queue_lock);
} }
} }
...@@ -149,10 +149,8 @@ static void mbox_rx_work(struct work_struct *work) ...@@ -149,10 +149,8 @@ static void mbox_rx_work(struct work_struct *work)
msg = (mbox_msg_t) rq->data; msg = (mbox_msg_t) rq->data;
spin_lock_irqsave(q->queue_lock, flags); if (blk_end_request(rq, 0, 0))
blkdev_dequeue_request(rq); BUG();
end_that_request_last(rq, 0);
spin_unlock_irqrestore(q->queue_lock, flags);
mbox->rxq->callback((void *)msg); mbox->rxq->callback((void *)msg);
} }
...@@ -263,10 +261,8 @@ omap_mbox_read(struct device *dev, struct device_attribute *attr, char *buf) ...@@ -263,10 +261,8 @@ omap_mbox_read(struct device *dev, struct device_attribute *attr, char *buf)
*p = (mbox_msg_t) rq->data; *p = (mbox_msg_t) rq->data;
spin_lock_irqsave(q->queue_lock, flags); if (blk_end_request(rq, 0, 0))
blkdev_dequeue_request(rq); BUG();
end_that_request_last(rq, 0);
spin_unlock_irqrestore(q->queue_lock, flags);
if (unlikely(mbox_seq_test(mbox, *p))) { if (unlikely(mbox_seq_test(mbox, *p))) {
pr_info("mbox: Illegal seq bit!(%08x) ignored\n", *p); pr_info("mbox: Illegal seq bit!(%08x) ignored\n", *p);
......
...@@ -475,17 +475,9 @@ static void do_ubd_request(struct request_queue * q); ...@@ -475,17 +475,9 @@ static void do_ubd_request(struct request_queue * q);
/* Only changed by ubd_init, which is an initcall. */ /* Only changed by ubd_init, which is an initcall. */
int thread_fd = -1; int thread_fd = -1;
static void ubd_end_request(struct request *req, int bytes, int uptodate) static void ubd_end_request(struct request *req, int bytes, int error)
{ {
if (!end_that_request_first(req, uptodate, bytes >> 9)) { blk_end_request(req, error, bytes);
struct ubd *dev = req->rq_disk->private_data;
unsigned long flags;
add_disk_randomness(req->rq_disk);
spin_lock_irqsave(&dev->lock, flags);
end_that_request_last(req, uptodate);
spin_unlock_irqrestore(&dev->lock, flags);
}
} }
/* Callable only from interrupt context - otherwise you need to do /* Callable only from interrupt context - otherwise you need to do
...@@ -493,10 +485,10 @@ static void ubd_end_request(struct request *req, int bytes, int uptodate) ...@@ -493,10 +485,10 @@ static void ubd_end_request(struct request *req, int bytes, int uptodate)
static inline void ubd_finish(struct request *req, int bytes) static inline void ubd_finish(struct request *req, int bytes)
{ {
if(bytes < 0){ if(bytes < 0){
ubd_end_request(req, 0, 0); ubd_end_request(req, 0, -EIO);
return; return;
} }
ubd_end_request(req, bytes, 1); ubd_end_request(req, bytes, 0);
} }
static LIST_HEAD(restart); static LIST_HEAD(restart);
......
This diff is collapsed.
...@@ -3455,19 +3455,12 @@ static inline bool DAC960_ProcessCompletedRequest(DAC960_Command_T *Command, ...@@ -3455,19 +3455,12 @@ static inline bool DAC960_ProcessCompletedRequest(DAC960_Command_T *Command,
bool SuccessfulIO) bool SuccessfulIO)
{ {
struct request *Request = Command->Request; struct request *Request = Command->Request;
int UpToDate; int Error = SuccessfulIO ? 0 : -EIO;
UpToDate = 0;
if (SuccessfulIO)
UpToDate = 1;
pci_unmap_sg(Command->Controller->PCIDevice, Command->cmd_sglist, pci_unmap_sg(Command->Controller->PCIDevice, Command->cmd_sglist,
Command->SegmentCount, Command->DmaDirection); Command->SegmentCount, Command->DmaDirection);
if (!end_that_request_first(Request, UpToDate, Command->BlockCount)) { if (!__blk_end_request(Request, Error, Command->BlockCount << 9)) {
add_disk_randomness(Request->rq_disk);
end_that_request_last(Request, UpToDate);
if (Command->Completion) { if (Command->Completion) {
complete(Command->Completion); complete(Command->Completion);
Command->Completion = NULL; Command->Completion = NULL;
......
...@@ -1187,17 +1187,6 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, ...@@ -1187,17 +1187,6 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
} }
} }
static inline void complete_buffers(struct bio *bio, int status)
{
while (bio) {
struct bio *xbh = bio->bi_next;
bio->bi_next = NULL;
bio_endio(bio, status ? 0 : -EIO);
bio = xbh;
}
}
static void cciss_check_queues(ctlr_info_t *h) static void cciss_check_queues(ctlr_info_t *h)
{ {
int start_queue = h->next_to_run; int start_queue = h->next_to_run;
...@@ -1263,21 +1252,14 @@ static void cciss_softirq_done(struct request *rq) ...@@ -1263,21 +1252,14 @@ static void cciss_softirq_done(struct request *rq)
pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir); pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir);
} }
complete_buffers(rq->bio, (rq->errors == 0));
if (blk_fs_request(rq)) {
const int rw = rq_data_dir(rq);
disk_stat_add(rq->rq_disk, sectors[rw], rq->nr_sectors);
}
#ifdef CCISS_DEBUG #ifdef CCISS_DEBUG
printk("Done with %p\n", rq); printk("Done with %p\n", rq);
#endif /* CCISS_DEBUG */ #endif /* CCISS_DEBUG */
add_disk_randomness(rq->rq_disk); if (blk_end_request(rq, (rq->errors == 0) ? 0 : -EIO, blk_rq_bytes(rq)))
BUG();
spin_lock_irqsave(&h->lock, flags); spin_lock_irqsave(&h->lock, flags);
end_that_request_last(rq, (rq->errors == 0));
cmd_free(h, cmd, 1); cmd_free(h, cmd, 1);
cciss_check_queues(h); cciss_check_queues(h);
spin_unlock_irqrestore(&h->lock, flags); spin_unlock_irqrestore(&h->lock, flags);
...@@ -2544,7 +2526,6 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd, ...@@ -2544,7 +2526,6 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd,
} }
cmd->rq->data_len = 0; cmd->rq->data_len = 0;
cmd->rq->completion_data = cmd; cmd->rq->completion_data = cmd;
blk_add_trace_rq(cmd->rq->q, cmd->rq, BLK_TA_COMPLETE);
blk_complete_request(cmd->rq); blk_complete_request(cmd->rq);
} }
......
...@@ -167,7 +167,6 @@ static void start_io(ctlr_info_t *h); ...@@ -167,7 +167,6 @@ static void start_io(ctlr_info_t *h);
static inline void addQ(cmdlist_t **Qptr, cmdlist_t *c); static inline void addQ(cmdlist_t **Qptr, cmdlist_t *c);
static inline cmdlist_t *removeQ(cmdlist_t **Qptr, cmdlist_t *c); static inline cmdlist_t *removeQ(cmdlist_t **Qptr, cmdlist_t *c);
static inline void complete_buffers(struct bio *bio, int ok);
static inline void complete_command(cmdlist_t *cmd, int timeout); static inline void complete_command(cmdlist_t *cmd, int timeout);
static irqreturn_t do_ida_intr(int irq, void *dev_id); static irqreturn_t do_ida_intr(int irq, void *dev_id);
...@@ -980,26 +979,13 @@ static void start_io(ctlr_info_t *h) ...@@ -980,26 +979,13 @@ static void start_io(ctlr_info_t *h)
} }
} }
static inline void complete_buffers(struct bio *bio, int ok)
{
struct bio *xbh;
while (bio) {
xbh = bio->bi_next;
bio->bi_next = NULL;
bio_endio(bio, ok ? 0 : -EIO);
bio = xbh;
}
}
/* /*
* Mark all buffers that cmd was responsible for * Mark all buffers that cmd was responsible for
*/ */
static inline void complete_command(cmdlist_t *cmd, int timeout) static inline void complete_command(cmdlist_t *cmd, int timeout)
{ {
struct request *rq = cmd->rq; struct request *rq = cmd->rq;
int ok=1; int error = 0;
int i, ddir; int i, ddir;
if (cmd->req.hdr.rcode & RCODE_NONFATAL && if (cmd->req.hdr.rcode & RCODE_NONFATAL &&
...@@ -1011,16 +997,17 @@ static inline void complete_command(cmdlist_t *cmd, int timeout) ...@@ -1011,16 +997,17 @@ static inline void complete_command(cmdlist_t *cmd, int timeout)
if (cmd->req.hdr.rcode & RCODE_FATAL) { if (cmd->req.hdr.rcode & RCODE_FATAL) {
printk(KERN_WARNING "Fatal error on ida/c%dd%d\n", printk(KERN_WARNING "Fatal error on ida/c%dd%d\n",
cmd->ctlr, cmd->hdr.unit); cmd->ctlr, cmd->hdr.unit);
ok = 0; error = -EIO;
} }
if (cmd->req.hdr.rcode & RCODE_INVREQ) { if (cmd->req.hdr.rcode & RCODE_INVREQ) {
printk(KERN_WARNING "Invalid request on ida/c%dd%d = (cmd=%x sect=%d cnt=%d sg=%d ret=%x)\n", printk(KERN_WARNING "Invalid request on ida/c%dd%d = (cmd=%x sect=%d cnt=%d sg=%d ret=%x)\n",
cmd->ctlr, cmd->hdr.unit, cmd->req.hdr.cmd, cmd->ctlr, cmd->hdr.unit, cmd->req.hdr.cmd,
cmd->req.hdr.blk, cmd->req.hdr.blk_cnt, cmd->req.hdr.blk, cmd->req.hdr.blk_cnt,
cmd->req.hdr.sg_cnt, cmd->req.hdr.rcode); cmd->req.hdr.sg_cnt, cmd->req.hdr.rcode);
ok = 0; error = -EIO;
} }
if (timeout) ok = 0; if (timeout)
error = -EIO;
/* unmap the DMA mapping for all the scatter gather elements */ /* unmap the DMA mapping for all the scatter gather elements */
if (cmd->req.hdr.cmd == IDA_READ) if (cmd->req.hdr.cmd == IDA_READ)
ddir = PCI_DMA_FROMDEVICE; ddir = PCI_DMA_FROMDEVICE;
...@@ -1030,18 +1017,9 @@ static inline void complete_command(cmdlist_t *cmd, int timeout) ...@@ -1030,18 +1017,9 @@ static inline void complete_command(cmdlist_t *cmd, int timeout)
pci_unmap_page(hba[cmd->ctlr]->pci_dev, cmd->req.sg[i].addr, pci_unmap_page(hba[cmd->ctlr]->pci_dev, cmd->req.sg[i].addr,
cmd->req.sg[i].size, ddir); cmd->req.sg[i].size, ddir);
complete_buffers(rq->bio, ok);
if (blk_fs_request(rq)) {
const int rw = rq_data_dir(rq);
disk_stat_add(rq->rq_disk, sectors[rw], rq->nr_sectors);
}
add_disk_randomness(rq->rq_disk);
DBGPX(printk("Done with %p\n", rq);); DBGPX(printk("Done with %p\n", rq););
end_that_request_last(rq, ok ? 1 : -EIO); if (__blk_end_request(rq, error, blk_rq_bytes(rq)))
BUG();
} }
/* /*
......
...@@ -2287,21 +2287,19 @@ static int do_format(int drive, struct format_descr *tmp_format_req) ...@@ -2287,21 +2287,19 @@ static int do_format(int drive, struct format_descr *tmp_format_req)
* ============================= * =============================
*/ */
static void floppy_end_request(struct request *req, int uptodate) static void floppy_end_request(struct request *req, int error)
{ {
unsigned int nr_sectors = current_count_sectors; unsigned int nr_sectors = current_count_sectors;
unsigned int drive = (unsigned long)req->rq_disk->private_data;
/* current_count_sectors can be zero if transfer failed */ /* current_count_sectors can be zero if transfer failed */
if (!uptodate) if (error)
nr_sectors = req->current_nr_sectors; nr_sectors = req->current_nr_sectors;
if (end_that_request_first(req, uptodate, nr_sectors)) if (__blk_end_request(req, error, nr_sectors << 9))
return; return;
add_disk_randomness(req->rq_disk);
floppy_off((long)req->rq_disk->private_data);
blkdev_dequeue_request(req);
end_that_request_last(req, uptodate);
/* We're done with the request */ /* We're done with the request */
floppy_off(drive);
current_req = NULL; current_req = NULL;
} }
...@@ -2332,7 +2330,7 @@ static void request_done(int uptodate) ...@@ -2332,7 +2330,7 @@ static void request_done(int uptodate)
/* unlock chained buffers */ /* unlock chained buffers */
spin_lock_irqsave(q->queue_lock, flags); spin_lock_irqsave(q->queue_lock, flags);
floppy_end_request(req, 1); floppy_end_request(req, 0);
spin_unlock_irqrestore(q->queue_lock, flags); spin_unlock_irqrestore(q->queue_lock, flags);
} else { } else {
if (rq_data_dir(req) == WRITE) { if (rq_data_dir(req) == WRITE) {
...@@ -2346,7 +2344,7 @@ static void request_done(int uptodate) ...@@ -2346,7 +2344,7 @@ static void request_done(int uptodate)
DRWE->last_error_generation = DRS->generation; DRWE->last_error_generation = DRS->generation;
} }
spin_lock_irqsave(q->queue_lock, flags); spin_lock_irqsave(q->queue_lock, flags);
floppy_end_request(req, 0); floppy_end_request(req, -EIO);
spin_unlock_irqrestore(q->queue_lock, flags); spin_unlock_irqrestore(q->queue_lock, flags);
} }
} }
......
...@@ -100,17 +100,15 @@ static const char *nbdcmd_to_ascii(int cmd) ...@@ -100,17 +100,15 @@ static const char *nbdcmd_to_ascii(int cmd)
static void nbd_end_request(struct request *req) static void nbd_end_request(struct request *req)
{ {
int uptodate = (req->errors == 0) ? 1 : 0; int error = req->errors ? -EIO : 0;
struct request_queue *q = req->q; struct request_queue *q = req->q;
unsigned long flags; unsigned long flags;
dprintk(DBG_BLKDEV, "%s: request %p: %s\n", req->rq_disk->disk_name, dprintk(DBG_BLKDEV, "%s: request %p: %s\n", req->rq_disk->disk_name,
req, uptodate? "done": "failed"); req, error ? "failed" : "done");
spin_lock_irqsave(q->queue_lock, flags); spin_lock_irqsave(q->queue_lock, flags);
if (!end_that_request_first(req, uptodate, req->nr_sectors)) { __blk_end_request(req, error, req->nr_sectors << 9);
end_that_request_last(req, uptodate);
}
spin_unlock_irqrestore(q->queue_lock, flags); spin_unlock_irqrestore(q->queue_lock, flags);
} }
......
...@@ -229,7 +229,7 @@ static irqreturn_t ps3disk_interrupt(int irq, void *data) ...@@ -229,7 +229,7 @@ static irqreturn_t ps3disk_interrupt(int irq, void *data)
struct ps3_storage_device *dev = data; struct ps3_storage_device *dev = data;
struct ps3disk_private *priv; struct ps3disk_private *priv;
struct request *req; struct request *req;
int res, read, uptodate; int res, read, error;
u64 tag, status; u64 tag, status;
unsigned long num_sectors; unsigned long num_sectors;
const char *op; const char *op;
...@@ -270,21 +270,17 @@ static irqreturn_t ps3disk_interrupt(int irq, void *data) ...@@ -270,21 +270,17 @@ static irqreturn_t ps3disk_interrupt(int irq, void *data)
if (status) { if (status) {
dev_dbg(&dev->sbd.core, "%s:%u: %s failed 0x%lx\n", __func__, dev_dbg(&dev->sbd.core, "%s:%u: %s failed 0x%lx\n", __func__,
__LINE__, op, status); __LINE__, op, status);
uptodate = 0; error = -EIO;
} else { } else {
dev_dbg(&dev->sbd.core, "%s:%u: %s completed\n", __func__, dev_dbg(&dev->sbd.core, "%s:%u: %s completed\n", __func__,
__LINE__, op); __LINE__, op);
uptodate = 1; error = 0;
if (read) if (read)
ps3disk_scatter_gather(dev, req, 0); ps3disk_scatter_gather(dev, req, 0);
} }
spin_lock(&priv->lock); spin_lock(&priv->lock);
if (!end_that_request_first(req, uptodate, num_sectors)) { __blk_end_request(req, error, num_sectors << 9);
add_disk_randomness(req->rq_disk);
blkdev_dequeue_request(req);
end_that_request_last(req, uptodate);
}
priv->req = NULL; priv->req = NULL;
ps3disk_do_request(dev, priv->queue); ps3disk_do_request(dev, priv->queue);
spin_unlock(&priv->lock); spin_unlock(&priv->lock);
......
...@@ -212,12 +212,9 @@ static void vdc_end_special(struct vdc_port *port, struct vio_disk_desc *desc) ...@@ -212,12 +212,9 @@ static void vdc_end_special(struct vdc_port *port, struct vio_disk_desc *desc)
vdc_finish(&port->vio, -err, WAITING_FOR_GEN_CMD); vdc_finish(&port->vio, -err, WAITING_FOR_GEN_CMD);
} }
static void vdc_end_request(struct request *req, int uptodate, int num_sectors) static void vdc_end_request(struct request *req, int error, int num_sectors)
{ {
if (end_that_request_first(req, uptodate, num_sectors)) __blk_end_request(req, error, num_sectors << 9);
return;
add_disk_randomness(req->rq_disk);
end_that_request_last(req, uptodate);
} }
static void vdc_end_one(struct vdc_port *port, struct vio_dring_state *dr, static void vdc_end_one(struct vdc_port *port, struct vio_dring_state *dr,
...@@ -242,7 +239,7 @@ static void vdc_end_one(struct vdc_port *port, struct vio_dring_state *dr, ...@@ -242,7 +239,7 @@ static void vdc_end_one(struct vdc_port *port, struct vio_dring_state *dr,
rqe->req = NULL; rqe->req = NULL;
vdc_end_request(req, !desc->status, desc->size >> 9); vdc_end_request(req, (desc->status ? -EIO : 0), desc->size >> 9);
if (blk_queue_stopped(port->disk->queue)) if (blk_queue_stopped(port->disk->queue))
blk_start_queue(port->disk->queue); blk_start_queue(port->disk->queue);
...@@ -456,7 +453,7 @@ static void do_vdc_request(struct request_queue *q) ...@@ -456,7 +453,7 @@ static void do_vdc_request(struct request_queue *q)
blkdev_dequeue_request(req); blkdev_dequeue_request(req);
if (__send_request(req) < 0) if (__send_request(req) < 0)
vdc_end_request(req, 0, req->hard_nr_sectors); vdc_end_request(req, -EIO, req->hard_nr_sectors);
} }
} }
......
...@@ -744,16 +744,14 @@ static unsigned int carm_fill_get_fw_ver(struct carm_host *host, ...@@ -744,16 +744,14 @@ static unsigned int carm_fill_get_fw_ver(struct carm_host *host,
static inline void carm_end_request_queued(struct carm_host *host, static inline void carm_end_request_queued(struct carm_host *host,
struct carm_request *crq, struct carm_request *crq,
int uptodate) int error)
{ {
struct request *req = crq->rq; struct request *req = crq->rq;
int rc; int rc;
rc = end_that_request_first(req, uptodate, req->hard_nr_sectors); rc = __blk_end_request(req, error, blk_rq_bytes(req));
assert(rc == 0); assert(rc == 0);
end_that_request_last(req, uptodate);
rc = carm_put_request(host, crq); rc = carm_put_request(host, crq);
assert(rc == 0); assert(rc == 0);
} }
...@@ -793,9 +791,9 @@ static inline void carm_round_robin(struct carm_host *host) ...@@ -793,9 +791,9 @@ static inline void carm_round_robin(struct carm_host *host)
} }
static inline void carm_end_rq(struct carm_host *host, struct carm_request *crq, static inline void carm_end_rq(struct carm_host *host, struct carm_request *crq,
int is_ok) int error)
{ {
carm_end_request_queued(host, crq, is_ok); carm_end_request_queued(host, crq, error);
if (max_queue == 1) if (max_queue == 1)
carm_round_robin(host); carm_round_robin(host);
else if ((host->n_msgs <= CARM_MSG_LOW_WATER) && else if ((host->n_msgs <= CARM_MSG_LOW_WATER) &&
...@@ -873,14 +871,14 @@ static void carm_rq_fn(struct request_queue *q) ...@@ -873,14 +871,14 @@ static void carm_rq_fn(struct request_queue *q)
sg = &crq->sg[0]; sg = &crq->sg[0];
n_elem = blk_rq_map_sg(q, rq, sg); n_elem = blk_rq_map_sg(q, rq, sg);
if (n_elem <= 0) { if (n_elem <= 0) {
carm_end_rq(host, crq, 0); carm_end_rq(host, crq, -EIO);
return; /* request with no s/g entries? */ return; /* request with no s/g entries? */
} }
/* map scatterlist to PCI bus addresses */ /* map scatterlist to PCI bus addresses */
n_elem = pci_map_sg(host->pdev, sg, n_elem, pci_dir); n_elem = pci_map_sg(host->pdev, sg, n_elem, pci_dir);
if (n_elem <= 0) { if (n_elem <= 0) {
carm_end_rq(host, crq, 0); carm_end_rq(host, crq, -EIO);
return; /* request with no s/g entries? */ return; /* request with no s/g entries? */
} }
crq->n_elem = n_elem; crq->n_elem = n_elem;
...@@ -941,7 +939,7 @@ static void carm_rq_fn(struct request_queue *q) ...@@ -941,7 +939,7 @@ static void carm_rq_fn(struct request_queue *q)
static void carm_handle_array_info(struct carm_host *host, static void carm_handle_array_info(struct carm_host *host,
struct carm_request *crq, u8 *mem, struct carm_request *crq, u8 *mem,
int is_ok) int error)
{ {
struct carm_port *port; struct carm_port *port;
u8 *msg_data = mem + sizeof(struct carm_array_info); u8 *msg_data = mem + sizeof(struct carm_array_info);
...@@ -952,9 +950,9 @@ static void carm_handle_array_info(struct carm_host *host, ...@@ -952,9 +950,9 @@ static void carm_handle_array_info(struct carm_host *host,
DPRINTK("ENTER\n"); DPRINTK("ENTER\n");
carm_end_rq(host, crq, is_ok); carm_end_rq(host, crq, error);
if (!is_ok) if (error)
goto out; goto out;
if (le32_to_cpu(desc->array_status) & ARRAY_NO_EXIST) if (le32_to_cpu(desc->array_status) & ARRAY_NO_EXIST)
goto out; goto out;
...@@ -1001,7 +999,7 @@ static void carm_handle_array_info(struct carm_host *host, ...@@ -1001,7 +999,7 @@ static void carm_handle_array_info(struct carm_host *host,
static void carm_handle_scan_chan(struct carm_host *host, static void carm_handle_scan_chan(struct carm_host *host,
struct carm_request *crq, u8 *mem, struct carm_request *crq, u8 *mem,
int is_ok) int error)
{ {
u8 *msg_data = mem + IOC_SCAN_CHAN_OFFSET; u8 *msg_data = mem + IOC_SCAN_CHAN_OFFSET;
unsigned int i, dev_count = 0; unsigned int i, dev_count = 0;
...@@ -1009,9 +1007,9 @@ static void carm_handle_scan_chan(struct carm_host *host, ...@@ -1009,9 +1007,9 @@ static void carm_handle_scan_chan(struct carm_host *host,
DPRINTK("ENTER\n"); DPRINTK("ENTER\n");
carm_end_rq(host, crq, is_ok); carm_end_rq(host, crq, error);
if (!is_ok) { if (error) {
new_state = HST_ERROR; new_state = HST_ERROR;
goto out; goto out;
} }
...@@ -1033,23 +1031,23 @@ static void carm_handle_scan_chan(struct carm_host *host, ...@@ -1033,23 +1031,23 @@ static void carm_handle_scan_chan(struct carm_host *host,
} }
static void carm_handle_generic(struct carm_host *host, static void carm_handle_generic(struct carm_host *host,
struct carm_request *crq, int is_ok, struct carm_request *crq, int error,
int cur_state, int next_state) int cur_state, int next_state)
{ {
DPRINTK("ENTER\n"); DPRINTK("ENTER\n");
carm_end_rq(host, crq, is_ok); carm_end_rq(host, crq, error);
assert(host->state == cur_state); assert(host->state == cur_state);
if (is_ok) if (error)
host->state = next_state;
else
host->state = HST_ERROR; host->state = HST_ERROR;
else
host->state = next_state;
schedule_work(&host->fsm_task); schedule_work(&host->fsm_task);
} }
static inline void carm_handle_rw(struct carm_host *host, static inline void carm_handle_rw(struct carm_host *host,
struct carm_request *crq, int is_ok) struct carm_request *crq, int error)
{ {
int pci_dir; int pci_dir;
...@@ -1062,7 +1060,7 @@ static inline void carm_handle_rw(struct carm_host *host, ...@@ -1062,7 +1060,7 @@ static inline void carm_handle_rw(struct carm_host *host,
pci_unmap_sg(host->pdev, &crq->sg[0], crq->n_elem, pci_dir); pci_unmap_sg(host->pdev, &crq->sg[0], crq->n_elem, pci_dir);
carm_end_rq(host, crq, is_ok); carm_end_rq(host, crq, error);
} }
static inline void carm_handle_resp(struct carm_host *host, static inline void carm_handle_resp(struct carm_host *host,
...@@ -1071,7 +1069,7 @@ static inline void carm_handle_resp(struct carm_host *host, ...@@ -1071,7 +1069,7 @@ static inline void carm_handle_resp(struct carm_host *host,
u32 handle = le32_to_cpu(ret_handle_le); u32 handle = le32_to_cpu(ret_handle_le);
unsigned int msg_idx; unsigned int msg_idx;
struct carm_request *crq; struct carm_request *crq;
int is_ok = (status == RMSG_OK); int error = (status == RMSG_OK) ? 0 : -EIO;
u8 *mem; u8 *mem;
VPRINTK("ENTER, handle == 0x%x\n", handle); VPRINTK("ENTER, handle == 0x%x\n", handle);
...@@ -1090,7 +1088,7 @@ static inline void carm_handle_resp(struct carm_host *host, ...@@ -1090,7 +1088,7 @@ static inline void carm_handle_resp(struct carm_host *host,
/* fast path */ /* fast path */
if (likely(crq->msg_type == CARM_MSG_READ || if (likely(crq->msg_type == CARM_MSG_READ ||
crq->msg_type == CARM_MSG_WRITE)) { crq->msg_type == CARM_MSG_WRITE)) {
carm_handle_rw(host, crq, is_ok); carm_handle_rw(host, crq, error);
return; return;
} }
...@@ -1100,7 +1098,7 @@ static inline void carm_handle_resp(struct carm_host *host, ...@@ -1100,7 +1098,7 @@ static inline void carm_handle_resp(struct carm_host *host,
case CARM_MSG_IOCTL: { case CARM_MSG_IOCTL: {
switch (crq->msg_subtype) { switch (crq->msg_subtype) {
case CARM_IOC_SCAN_CHAN: case CARM_IOC_SCAN_CHAN:
carm_handle_scan_chan(host, crq, mem, is_ok); carm_handle_scan_chan(host, crq, mem, error);
break; break;
default: default:
/* unknown / invalid response */ /* unknown / invalid response */
...@@ -1112,21 +1110,21 @@ static inline void carm_handle_resp(struct carm_host *host, ...@@ -1112,21 +1110,21 @@ static inline void carm_handle_resp(struct carm_host *host,
case CARM_MSG_MISC: { case CARM_MSG_MISC: {
switch (crq->msg_subtype) { switch (crq->msg_subtype) {
case MISC_ALLOC_MEM: case MISC_ALLOC_MEM:
carm_handle_generic(host, crq, is_ok, carm_handle_generic(host, crq, error,
HST_ALLOC_BUF, HST_SYNC_TIME); HST_ALLOC_BUF, HST_SYNC_TIME);
break; break;
case MISC_SET_TIME: case MISC_SET_TIME:
carm_handle_generic(host, crq, is_ok, carm_handle_generic(host, crq, error,
HST_SYNC_TIME, HST_GET_FW_VER); HST_SYNC_TIME, HST_GET_FW_VER);
break; break;
case MISC_GET_FW_VER: { case MISC_GET_FW_VER: {
struct carm_fw_ver *ver = (struct carm_fw_ver *) struct carm_fw_ver *ver = (struct carm_fw_ver *)
mem + sizeof(struct carm_msg_get_fw_ver); mem + sizeof(struct carm_msg_get_fw_ver);
if (is_ok) { if (!error) {
host->fw_ver = le32_to_cpu(ver->version); host->fw_ver = le32_to_cpu(ver->version);
host->flags |= (ver->features & FL_FW_VER_MASK); host->flags |= (ver->features & FL_FW_VER_MASK);
} }
carm_handle_generic(host, crq, is_ok, carm_handle_generic(host, crq, error,
HST_GET_FW_VER, HST_PORT_SCAN); HST_GET_FW_VER, HST_PORT_SCAN);
break; break;
} }
...@@ -1140,7 +1138,7 @@ static inline void carm_handle_resp(struct carm_host *host, ...@@ -1140,7 +1138,7 @@ static inline void carm_handle_resp(struct carm_host *host,
case CARM_MSG_ARRAY: { case CARM_MSG_ARRAY: {
switch (crq->msg_subtype) { switch (crq->msg_subtype) {
case CARM_ARRAY_INFO: case CARM_ARRAY_INFO:
carm_handle_array_info(host, crq, mem, is_ok); carm_handle_array_info(host, crq, mem, error);
break; break;
default: default:
/* unknown / invalid response */ /* unknown / invalid response */
...@@ -1159,7 +1157,7 @@ static inline void carm_handle_resp(struct carm_host *host, ...@@ -1159,7 +1157,7 @@ static inline void carm_handle_resp(struct carm_host *host,
err_out: err_out:
printk(KERN_WARNING DRV_NAME "(%s): BUG: unhandled message type %d/%d\n", printk(KERN_WARNING DRV_NAME "(%s): BUG: unhandled message type %d/%d\n",
pci_name(host->pdev), crq->msg_type, crq->msg_subtype); pci_name(host->pdev), crq->msg_type, crq->msg_subtype);
carm_end_rq(host, crq, 0); carm_end_rq(host, crq, -EIO);
} }
static inline void carm_handle_responses(struct carm_host *host) static inline void carm_handle_responses(struct carm_host *host)
......
...@@ -808,16 +808,16 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) ...@@ -808,16 +808,16 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
static void ub_end_rq(struct request *rq, unsigned int scsi_status) static void ub_end_rq(struct request *rq, unsigned int scsi_status)
{ {
int uptodate; int error;
if (scsi_status == 0) { if (scsi_status == 0) {
uptodate = 1; error = 0;
} else { } else {
uptodate = 0; error = -EIO;
rq->errors = scsi_status; rq->errors = scsi_status;
} }
end_that_request_first(rq, uptodate, rq->hard_nr_sectors); if (__blk_end_request(rq, error, blk_rq_bytes(rq)))
end_that_request_last(rq, uptodate); BUG();
} }
static int ub_rw_cmd_retry(struct ub_dev *sc, struct ub_lun *lun, static int ub_rw_cmd_retry(struct ub_dev *sc, struct ub_lun *lun,
......
...@@ -229,13 +229,10 @@ static struct block_device_operations viodasd_fops = { ...@@ -229,13 +229,10 @@ static struct block_device_operations viodasd_fops = {
/* /*
* End a request * End a request
*/ */
static void viodasd_end_request(struct request *req, int uptodate, static void viodasd_end_request(struct request *req, int error,
int num_sectors) int num_sectors)
{ {
if (end_that_request_first(req, uptodate, num_sectors)) __blk_end_request(req, error, num_sectors << 9);
return;
add_disk_randomness(req->rq_disk);
end_that_request_last(req, uptodate);
} }
/* /*
...@@ -374,12 +371,12 @@ static void do_viodasd_request(struct request_queue *q) ...@@ -374,12 +371,12 @@ static void do_viodasd_request(struct request_queue *q)
blkdev_dequeue_request(req); blkdev_dequeue_request(req);
/* check that request contains a valid command */ /* check that request contains a valid command */
if (!blk_fs_request(req)) { if (!blk_fs_request(req)) {
viodasd_end_request(req, 0, req->hard_nr_sectors); viodasd_end_request(req, -EIO, req->hard_nr_sectors);
continue; continue;
} }
/* Try sending the request */ /* Try sending the request */
if (send_request(req) != 0) if (send_request(req) != 0)
viodasd_end_request(req, 0, req->hard_nr_sectors); viodasd_end_request(req, -EIO, req->hard_nr_sectors);
} }
} }
...@@ -591,7 +588,7 @@ static int viodasd_handle_read_write(struct vioblocklpevent *bevent) ...@@ -591,7 +588,7 @@ static int viodasd_handle_read_write(struct vioblocklpevent *bevent)
num_req_outstanding--; num_req_outstanding--;
spin_unlock_irqrestore(&viodasd_spinlock, irq_flags); spin_unlock_irqrestore(&viodasd_spinlock, irq_flags);
error = event->xRc != HvLpEvent_Rc_Good; error = (event->xRc == HvLpEvent_Rc_Good) ? 0 : -EIO;
if (error) { if (error) {
const struct vio_error_entry *err; const struct vio_error_entry *err;
err = vio_lookup_rc(viodasd_err_table, bevent->sub_result); err = vio_lookup_rc(viodasd_err_table, bevent->sub_result);
...@@ -601,7 +598,7 @@ static int viodasd_handle_read_write(struct vioblocklpevent *bevent) ...@@ -601,7 +598,7 @@ static int viodasd_handle_read_write(struct vioblocklpevent *bevent)
} }
qlock = req->q->queue_lock; qlock = req->q->queue_lock;
spin_lock_irqsave(qlock, irq_flags); spin_lock_irqsave(qlock, irq_flags);
viodasd_end_request(req, !error, num_sect); viodasd_end_request(req, error, num_sect);
spin_unlock_irqrestore(qlock, irq_flags); spin_unlock_irqrestore(qlock, irq_flags);
/* Finally, try to get more requests off of this device's queue */ /* Finally, try to get more requests off of this device's queue */
......
...@@ -452,7 +452,7 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) ...@@ -452,7 +452,7 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
RING_IDX i, rp; RING_IDX i, rp;
unsigned long flags; unsigned long flags;
struct blkfront_info *info = (struct blkfront_info *)dev_id; struct blkfront_info *info = (struct blkfront_info *)dev_id;
int uptodate; int error;
spin_lock_irqsave(&blkif_io_lock, flags); spin_lock_irqsave(&blkif_io_lock, flags);
...@@ -477,13 +477,13 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) ...@@ -477,13 +477,13 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
add_id_to_freelist(info, id); add_id_to_freelist(info, id);
uptodate = (bret->status == BLKIF_RSP_OKAY); error = (bret->status == BLKIF_RSP_OKAY) ? 0 : -EIO;
switch (bret->operation) { switch (bret->operation) {
case BLKIF_OP_WRITE_BARRIER: case BLKIF_OP_WRITE_BARRIER:
if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) { if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) {
printk(KERN_WARNING "blkfront: %s: write barrier op failed\n", printk(KERN_WARNING "blkfront: %s: write barrier op failed\n",
info->gd->disk_name); info->gd->disk_name);
uptodate = -EOPNOTSUPP; error = -EOPNOTSUPP;
info->feature_barrier = 0; info->feature_barrier = 0;
xlvbd_barrier(info); xlvbd_barrier(info);
} }
...@@ -494,10 +494,8 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) ...@@ -494,10 +494,8 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
dev_dbg(&info->xbdev->dev, "Bad return from blkdev data " dev_dbg(&info->xbdev->dev, "Bad return from blkdev data "
"request: %x\n", bret->status); "request: %x\n", bret->status);
ret = end_that_request_first(req, uptodate, ret = __blk_end_request(req, error, blk_rq_bytes(req));
req->hard_nr_sectors);
BUG_ON(ret); BUG_ON(ret);
end_that_request_last(req, uptodate);
break; break;
default: default:
BUG(); BUG();
......
...@@ -703,7 +703,7 @@ static void ace_fsm_dostate(struct ace_device *ace) ...@@ -703,7 +703,7 @@ static void ace_fsm_dostate(struct ace_device *ace)
/* bio finished; is there another one? */ /* bio finished; is there another one? */
i = ace->req->current_nr_sectors; i = ace->req->current_nr_sectors;
if (end_that_request_first(ace->req, 1, i)) { if (__blk_end_request(ace->req, 0, i)) {
/* dev_dbg(ace->dev, "next block; h=%li c=%i\n", /* dev_dbg(ace->dev, "next block; h=%li c=%i\n",
* ace->req->hard_nr_sectors, * ace->req->hard_nr_sectors,
* ace->req->current_nr_sectors); * ace->req->current_nr_sectors);
...@@ -718,9 +718,6 @@ static void ace_fsm_dostate(struct ace_device *ace) ...@@ -718,9 +718,6 @@ static void ace_fsm_dostate(struct ace_device *ace)
break; break;
case ACE_FSM_STATE_REQ_COMPLETE: case ACE_FSM_STATE_REQ_COMPLETE:
/* Complete the block request */
blkdev_dequeue_request(ace->req);
end_that_request_last(ace->req, 1);
ace->req = NULL; ace->req = NULL;
/* Finished request; go to idle state */ /* Finished request; go to idle state */
......
...@@ -289,7 +289,7 @@ static int send_request(struct request *req) ...@@ -289,7 +289,7 @@ static int send_request(struct request *req)
return 0; return 0;
} }
static void viocd_end_request(struct request *req, int uptodate) static void viocd_end_request(struct request *req, int error)
{ {
int nsectors = req->hard_nr_sectors; int nsectors = req->hard_nr_sectors;
...@@ -302,11 +302,8 @@ static void viocd_end_request(struct request *req, int uptodate) ...@@ -302,11 +302,8 @@ static void viocd_end_request(struct request *req, int uptodate)
if (!nsectors) if (!nsectors)
nsectors = 1; nsectors = 1;
if (end_that_request_first(req, uptodate, nsectors)) if (__blk_end_request(req, error, nsectors << 9))
BUG(); BUG();
add_disk_randomness(req->rq_disk);
blkdev_dequeue_request(req);
end_that_request_last(req, uptodate);
} }
static int rwreq; static int rwreq;
...@@ -317,11 +314,11 @@ static void do_viocd_request(struct request_queue *q) ...@@ -317,11 +314,11 @@ static void do_viocd_request(struct request_queue *q)
while ((rwreq == 0) && ((req = elv_next_request(q)) != NULL)) { while ((rwreq == 0) && ((req = elv_next_request(q)) != NULL)) {
if (!blk_fs_request(req)) if (!blk_fs_request(req))
viocd_end_request(req, 0); viocd_end_request(req, -EIO);
else if (send_request(req) < 0) { else if (send_request(req) < 0) {
printk(VIOCD_KERN_WARNING printk(VIOCD_KERN_WARNING
"unable to send message to OS/400!"); "unable to send message to OS/400!");
viocd_end_request(req, 0); viocd_end_request(req, -EIO);
} else } else
rwreq++; rwreq++;
} }
...@@ -532,9 +529,9 @@ static void vio_handle_cd_event(struct HvLpEvent *event) ...@@ -532,9 +529,9 @@ static void vio_handle_cd_event(struct HvLpEvent *event)
"with rc %d:0x%04X: %s\n", "with rc %d:0x%04X: %s\n",
req, event->xRc, req, event->xRc,
bevent->sub_result, err->msg); bevent->sub_result, err->msg);
viocd_end_request(req, 0); viocd_end_request(req, -EIO);
} else } else
viocd_end_request(req, 1); viocd_end_request(req, 0);
/* restart handling of incoming requests */ /* restart handling of incoming requests */
spin_unlock_irqrestore(&viocd_reqlock, flags); spin_unlock_irqrestore(&viocd_reqlock, flags);
......
...@@ -655,9 +655,9 @@ static void cdrom_end_request (ide_drive_t *drive, int uptodate) ...@@ -655,9 +655,9 @@ static void cdrom_end_request (ide_drive_t *drive, int uptodate)
BUG(); BUG();
} else { } else {
spin_lock_irqsave(&ide_lock, flags); spin_lock_irqsave(&ide_lock, flags);
end_that_request_chunk(failed, 0, if (__blk_end_request(failed, -EIO,
failed->data_len); failed->data_len))
end_that_request_last(failed, 0); BUG();
spin_unlock_irqrestore(&ide_lock, flags); spin_unlock_irqrestore(&ide_lock, flags);
} }
} else } else
...@@ -1647,6 +1647,17 @@ static int cdrom_write_check_ireason(ide_drive_t *drive, int len, int ireason) ...@@ -1647,6 +1647,17 @@ static int cdrom_write_check_ireason(ide_drive_t *drive, int len, int ireason)
return 1; return 1;
} }
/*
* Called from blk_end_request_callback() after the data of the request
* is completed and before the request is completed.
* By returning value '1', blk_end_request_callback() returns immediately
* without completing the request.
*/
static int cdrom_newpc_intr_dummy_cb(struct request *rq)
{
return 1;
}
typedef void (xfer_func_t)(ide_drive_t *, void *, u32); typedef void (xfer_func_t)(ide_drive_t *, void *, u32);
/* /*
...@@ -1685,9 +1696,13 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) ...@@ -1685,9 +1696,13 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
return ide_error(drive, "dma error", stat); return ide_error(drive, "dma error", stat);
} }
end_that_request_chunk(rq, 1, rq->data_len); spin_lock_irqsave(&ide_lock, flags);
rq->data_len = 0; if (__blk_end_request(rq, 0, rq->data_len))
goto end_request; BUG();
HWGROUP(drive)->rq = NULL;
spin_unlock_irqrestore(&ide_lock, flags);
return ide_stopped;
} }
/* /*
...@@ -1705,8 +1720,15 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) ...@@ -1705,8 +1720,15 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
/* /*
* If DRQ is clear, the command has completed. * If DRQ is clear, the command has completed.
*/ */
if ((stat & DRQ_STAT) == 0) if ((stat & DRQ_STAT) == 0) {
goto end_request; spin_lock_irqsave(&ide_lock, flags);
if (__blk_end_request(rq, 0, 0))
BUG();
HWGROUP(drive)->rq = NULL;
spin_unlock_irqrestore(&ide_lock, flags);
return ide_stopped;
}
/* /*
* check which way to transfer data * check which way to transfer data
...@@ -1759,7 +1781,14 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) ...@@ -1759,7 +1781,14 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
rq->data_len -= blen; rq->data_len -= blen;
if (rq->bio) if (rq->bio)
end_that_request_chunk(rq, 1, blen); /*
* The request can't be completed until DRQ is cleared.
* So complete the data, but don't complete the request
* using the dummy function for the callback feature
* of blk_end_request_callback().
*/
blk_end_request_callback(rq, 0, blen,
cdrom_newpc_intr_dummy_cb);
else else
rq->data += blen; rq->data += blen;
} }
...@@ -1780,14 +1809,6 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) ...@@ -1780,14 +1809,6 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
ide_set_handler(drive, cdrom_newpc_intr, rq->timeout, NULL); ide_set_handler(drive, cdrom_newpc_intr, rq->timeout, NULL);
return ide_started; return ide_started;
end_request:
spin_lock_irqsave(&ide_lock, flags);
blkdev_dequeue_request(rq);
end_that_request_last(rq, 1);
HWGROUP(drive)->rq = NULL;
spin_unlock_irqrestore(&ide_lock, flags);
return ide_stopped;
} }
static ide_startstop_t cdrom_write_intr(ide_drive_t *drive) static ide_startstop_t cdrom_write_intr(ide_drive_t *drive)
......
...@@ -58,15 +58,19 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq, ...@@ -58,15 +58,19 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq,
int uptodate, unsigned int nr_bytes, int dequeue) int uptodate, unsigned int nr_bytes, int dequeue)
{ {
int ret = 1; int ret = 1;
int error = 0;
if (uptodate <= 0)
error = uptodate ? uptodate : -EIO;
/* /*
* if failfast is set on a request, override number of sectors and * if failfast is set on a request, override number of sectors and
* complete the whole request right now * complete the whole request right now
*/ */
if (blk_noretry_request(rq) && end_io_error(uptodate)) if (blk_noretry_request(rq) && error)
nr_bytes = rq->hard_nr_sectors << 9; nr_bytes = rq->hard_nr_sectors << 9;
if (!blk_fs_request(rq) && end_io_error(uptodate) && !rq->errors) if (!blk_fs_request(rq) && error && !rq->errors)
rq->errors = -EIO; rq->errors = -EIO;
/* /*
...@@ -78,14 +82,9 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq, ...@@ -78,14 +82,9 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq,
ide_dma_on(drive); ide_dma_on(drive);
} }
if (!end_that_request_chunk(rq, uptodate, nr_bytes)) { if (!__blk_end_request(rq, error, nr_bytes)) {
add_disk_randomness(rq->rq_disk); if (dequeue)
if (dequeue) {
if (!list_empty(&rq->queuelist))
blkdev_dequeue_request(rq);
HWGROUP(drive)->rq = NULL; HWGROUP(drive)->rq = NULL;
}
end_that_request_last(rq, uptodate);
ret = 0; ret = 0;
} }
...@@ -290,9 +289,9 @@ static void ide_complete_pm_request (ide_drive_t *drive, struct request *rq) ...@@ -290,9 +289,9 @@ static void ide_complete_pm_request (ide_drive_t *drive, struct request *rq)
drive->blocked = 0; drive->blocked = 0;
blk_start_queue(drive->queue); blk_start_queue(drive->queue);
} }
blkdev_dequeue_request(rq);
HWGROUP(drive)->rq = NULL; HWGROUP(drive)->rq = NULL;
end_that_request_last(rq, 1); if (__blk_end_request(rq, 0, 0))
BUG();
spin_unlock_irqrestore(&ide_lock, flags); spin_unlock_irqrestore(&ide_lock, flags);
} }
...@@ -387,10 +386,10 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) ...@@ -387,10 +386,10 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
} }
spin_lock_irqsave(&ide_lock, flags); spin_lock_irqsave(&ide_lock, flags);
blkdev_dequeue_request(rq);
HWGROUP(drive)->rq = NULL; HWGROUP(drive)->rq = NULL;
rq->errors = err; rq->errors = err;
end_that_request_last(rq, !rq->errors); if (__blk_end_request(rq, (rq->errors ? -EIO : 0), 0))
BUG();
spin_unlock_irqrestore(&ide_lock, flags); spin_unlock_irqrestore(&ide_lock, flags);
} }
......
...@@ -412,13 +412,13 @@ static void i2o_block_delayed_request_fn(struct work_struct *work) ...@@ -412,13 +412,13 @@ static void i2o_block_delayed_request_fn(struct work_struct *work)
/** /**
* i2o_block_end_request - Post-processing of completed commands * i2o_block_end_request - Post-processing of completed commands
* @req: request which should be completed * @req: request which should be completed
* @uptodate: 1 for success, 0 for I/O error, < 0 for specific error * @error: 0 for success, < 0 for error
* @nr_bytes: number of bytes to complete * @nr_bytes: number of bytes to complete
* *
* Mark the request as complete. The lock must not be held when entering. * Mark the request as complete. The lock must not be held when entering.
* *
*/ */
static void i2o_block_end_request(struct request *req, int uptodate, static void i2o_block_end_request(struct request *req, int error,
int nr_bytes) int nr_bytes)
{ {
struct i2o_block_request *ireq = req->special; struct i2o_block_request *ireq = req->special;
...@@ -426,22 +426,18 @@ static void i2o_block_end_request(struct request *req, int uptodate, ...@@ -426,22 +426,18 @@ static void i2o_block_end_request(struct request *req, int uptodate,
struct request_queue *q = req->q; struct request_queue *q = req->q;
unsigned long flags; unsigned long flags;
if (end_that_request_chunk(req, uptodate, nr_bytes)) { if (blk_end_request(req, error, nr_bytes)) {
int leftover = (req->hard_nr_sectors << KERNEL_SECTOR_SHIFT); int leftover = (req->hard_nr_sectors << KERNEL_SECTOR_SHIFT);
if (blk_pc_request(req)) if (blk_pc_request(req))
leftover = req->data_len; leftover = req->data_len;
if (end_io_error(uptodate)) if (error)
end_that_request_chunk(req, 0, leftover); blk_end_request(req, -EIO, leftover);
} }
add_disk_randomness(req->rq_disk);
spin_lock_irqsave(q->queue_lock, flags); spin_lock_irqsave(q->queue_lock, flags);
end_that_request_last(req, uptodate);
if (likely(dev)) { if (likely(dev)) {
dev->open_queue_depth--; dev->open_queue_depth--;
list_del(&ireq->queue); list_del(&ireq->queue);
...@@ -468,7 +464,7 @@ static int i2o_block_reply(struct i2o_controller *c, u32 m, ...@@ -468,7 +464,7 @@ static int i2o_block_reply(struct i2o_controller *c, u32 m,
struct i2o_message *msg) struct i2o_message *msg)
{ {
struct request *req; struct request *req;
int uptodate = 1; int error = 0;
req = i2o_cntxt_list_get(c, le32_to_cpu(msg->u.s.tcntxt)); req = i2o_cntxt_list_get(c, le32_to_cpu(msg->u.s.tcntxt));
if (unlikely(!req)) { if (unlikely(!req)) {
...@@ -501,10 +497,10 @@ static int i2o_block_reply(struct i2o_controller *c, u32 m, ...@@ -501,10 +497,10 @@ static int i2o_block_reply(struct i2o_controller *c, u32 m,
req->errors++; req->errors++;
uptodate = 0; error = -EIO;
} }
i2o_block_end_request(req, uptodate, le32_to_cpu(msg->body[1])); i2o_block_end_request(req, error, le32_to_cpu(msg->body[1]));
return 1; return 1;
}; };
......
...@@ -348,15 +348,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) ...@@ -348,15 +348,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
* A block was successfully transferred. * A block was successfully transferred.
*/ */
spin_lock_irq(&md->lock); spin_lock_irq(&md->lock);
ret = end_that_request_chunk(req, 1, brq.data.bytes_xfered); ret = __blk_end_request(req, 0, brq.data.bytes_xfered);
if (!ret) {
/*
* The whole request completed successfully.
*/
add_disk_randomness(req->rq_disk);
blkdev_dequeue_request(req);
end_that_request_last(req, 1);
}
spin_unlock_irq(&md->lock); spin_unlock_irq(&md->lock);
} while (ret); } while (ret);
...@@ -386,27 +378,21 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) ...@@ -386,27 +378,21 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
else else
bytes = blocks << 9; bytes = blocks << 9;
spin_lock_irq(&md->lock); spin_lock_irq(&md->lock);
ret = end_that_request_chunk(req, 1, bytes); ret = __blk_end_request(req, 0, bytes);
spin_unlock_irq(&md->lock); spin_unlock_irq(&md->lock);
} }
} else if (rq_data_dir(req) != READ && } else if (rq_data_dir(req) != READ &&
(card->host->caps & MMC_CAP_MULTIWRITE)) { (card->host->caps & MMC_CAP_MULTIWRITE)) {
spin_lock_irq(&md->lock); spin_lock_irq(&md->lock);
ret = end_that_request_chunk(req, 1, brq.data.bytes_xfered); ret = __blk_end_request(req, 0, brq.data.bytes_xfered);
spin_unlock_irq(&md->lock); spin_unlock_irq(&md->lock);
} }
mmc_release_host(card->host); mmc_release_host(card->host);
spin_lock_irq(&md->lock); spin_lock_irq(&md->lock);
while (ret) { while (ret)
ret = end_that_request_chunk(req, 0, ret = __blk_end_request(req, -EIO, blk_rq_cur_bytes(req));
req->current_nr_sectors << 9);
}
add_disk_randomness(req->rq_disk);
blkdev_dequeue_request(req);
end_that_request_last(req, 0);
spin_unlock_irq(&md->lock); spin_unlock_irq(&md->lock);
return 0; return 0;
......
...@@ -94,8 +94,8 @@ static void mmc_request(struct request_queue *q) ...@@ -94,8 +94,8 @@ static void mmc_request(struct request_queue *q)
printk(KERN_ERR "MMC: killing requests for dead queue\n"); printk(KERN_ERR "MMC: killing requests for dead queue\n");
while ((req = elv_next_request(q)) != NULL) { while ((req = elv_next_request(q)) != NULL) {
do { do {
ret = end_that_request_chunk(req, 0, ret = __blk_end_request(req, -EIO,
req->current_nr_sectors << 9); blk_rq_cur_bytes(req));
} while (ret); } while (ret);
} }
return; return;
......
...@@ -1595,12 +1595,10 @@ void dasd_block_clear_timer(struct dasd_block *block) ...@@ -1595,12 +1595,10 @@ void dasd_block_clear_timer(struct dasd_block *block)
/* /*
* posts the buffer_cache about a finalized request * posts the buffer_cache about a finalized request
*/ */
static inline void dasd_end_request(struct request *req, int uptodate) static inline void dasd_end_request(struct request *req, int error)
{ {
if (end_that_request_first(req, uptodate, req->hard_nr_sectors)) if (__blk_end_request(req, error, blk_rq_bytes(req)))
BUG(); BUG();
add_disk_randomness(req->rq_disk);
end_that_request_last(req, uptodate);
} }
/* /*
...@@ -1657,7 +1655,7 @@ static void __dasd_process_request_queue(struct dasd_block *block) ...@@ -1657,7 +1655,7 @@ static void __dasd_process_request_queue(struct dasd_block *block)
"Rejecting write request %p", "Rejecting write request %p",
req); req);
blkdev_dequeue_request(req); blkdev_dequeue_request(req);
dasd_end_request(req, 0); dasd_end_request(req, -EIO);
continue; continue;
} }
cqr = basedev->discipline->build_cp(basedev, block, req); cqr = basedev->discipline->build_cp(basedev, block, req);
...@@ -1686,7 +1684,7 @@ static void __dasd_process_request_queue(struct dasd_block *block) ...@@ -1686,7 +1684,7 @@ static void __dasd_process_request_queue(struct dasd_block *block)
"on request %p", "on request %p",
PTR_ERR(cqr), req); PTR_ERR(cqr), req);
blkdev_dequeue_request(req); blkdev_dequeue_request(req);
dasd_end_request(req, 0); dasd_end_request(req, -EIO);
continue; continue;
} }
/* /*
...@@ -1705,11 +1703,14 @@ static void __dasd_cleanup_cqr(struct dasd_ccw_req *cqr) ...@@ -1705,11 +1703,14 @@ static void __dasd_cleanup_cqr(struct dasd_ccw_req *cqr)
{ {
struct request *req; struct request *req;
int status; int status;
int error = 0;
req = (struct request *) cqr->callback_data; req = (struct request *) cqr->callback_data;
dasd_profile_end(cqr->block, cqr, req); dasd_profile_end(cqr->block, cqr, req);
status = cqr->memdev->discipline->free_cp(cqr, req); status = cqr->memdev->discipline->free_cp(cqr, req);
dasd_end_request(req, status); if (status <= 0)
error = status ? status : -EIO;
dasd_end_request(req, error);
} }
/* /*
...@@ -2009,7 +2010,7 @@ static void dasd_flush_request_queue(struct dasd_block *block) ...@@ -2009,7 +2010,7 @@ static void dasd_flush_request_queue(struct dasd_block *block)
spin_lock_irq(&block->request_queue_lock); spin_lock_irq(&block->request_queue_lock);
while ((req = elv_next_request(block->request_queue))) { while ((req = elv_next_request(block->request_queue))) {
blkdev_dequeue_request(req); blkdev_dequeue_request(req);
dasd_end_request(req, 0); dasd_end_request(req, -EIO);
} }
spin_unlock_irq(&block->request_queue_lock); spin_unlock_irq(&block->request_queue_lock);
} }
......
...@@ -74,11 +74,10 @@ tapeblock_trigger_requeue(struct tape_device *device) ...@@ -74,11 +74,10 @@ tapeblock_trigger_requeue(struct tape_device *device)
* Post finished request. * Post finished request.
*/ */
static void static void
tapeblock_end_request(struct request *req, int uptodate) tapeblock_end_request(struct request *req, int error)
{ {
if (end_that_request_first(req, uptodate, req->hard_nr_sectors)) if (__blk_end_request(req, error, blk_rq_bytes(req)))
BUG(); BUG();
end_that_request_last(req, uptodate);
} }
static void static void
...@@ -91,7 +90,7 @@ __tapeblock_end_request(struct tape_request *ccw_req, void *data) ...@@ -91,7 +90,7 @@ __tapeblock_end_request(struct tape_request *ccw_req, void *data)
device = ccw_req->device; device = ccw_req->device;
req = (struct request *) data; req = (struct request *) data;
tapeblock_end_request(req, ccw_req->rc == 0); tapeblock_end_request(req, (ccw_req->rc == 0) ? 0 : -EIO);
if (ccw_req->rc == 0) if (ccw_req->rc == 0)
/* Update position. */ /* Update position. */
device->blk_data.block_position = device->blk_data.block_position =
...@@ -119,7 +118,7 @@ tapeblock_start_request(struct tape_device *device, struct request *req) ...@@ -119,7 +118,7 @@ tapeblock_start_request(struct tape_device *device, struct request *req)
ccw_req = device->discipline->bread(device, req); ccw_req = device->discipline->bread(device, req);
if (IS_ERR(ccw_req)) { if (IS_ERR(ccw_req)) {
DBF_EVENT(1, "TBLOCK: bread failed\n"); DBF_EVENT(1, "TBLOCK: bread failed\n");
tapeblock_end_request(req, 0); tapeblock_end_request(req, -EIO);
return PTR_ERR(ccw_req); return PTR_ERR(ccw_req);
} }
ccw_req->callback = __tapeblock_end_request; ccw_req->callback = __tapeblock_end_request;
...@@ -132,7 +131,7 @@ tapeblock_start_request(struct tape_device *device, struct request *req) ...@@ -132,7 +131,7 @@ tapeblock_start_request(struct tape_device *device, struct request *req)
* Start/enqueueing failed. No retries in * Start/enqueueing failed. No retries in
* this case. * this case.
*/ */
tapeblock_end_request(req, 0); tapeblock_end_request(req, -EIO);
device->discipline->free_bread(ccw_req); device->discipline->free_bread(ccw_req);
} }
...@@ -177,7 +176,7 @@ tapeblock_requeue(struct work_struct *work) { ...@@ -177,7 +176,7 @@ tapeblock_requeue(struct work_struct *work) {
if (rq_data_dir(req) == WRITE) { if (rq_data_dir(req) == WRITE) {
DBF_EVENT(1, "TBLOCK: Rejecting write request\n"); DBF_EVENT(1, "TBLOCK: Rejecting write request\n");
blkdev_dequeue_request(req); blkdev_dequeue_request(req);
tapeblock_end_request(req, 0); tapeblock_end_request(req, -EIO);
continue; continue;
} }
spin_unlock_irq(&device->blk_data.request_queue_lock); spin_unlock_irq(&device->blk_data.request_queue_lock);
......
...@@ -919,8 +919,8 @@ static int idescsi_eh_reset (struct scsi_cmnd *cmd) ...@@ -919,8 +919,8 @@ static int idescsi_eh_reset (struct scsi_cmnd *cmd)
} }
/* kill current request */ /* kill current request */
blkdev_dequeue_request(req); if (__blk_end_request(req, -EIO, 0))
end_that_request_last(req, 0); BUG();
if (blk_sense_request(req)) if (blk_sense_request(req))
kfree(scsi->pc->buffer); kfree(scsi->pc->buffer);
kfree(scsi->pc); kfree(scsi->pc);
...@@ -929,8 +929,8 @@ static int idescsi_eh_reset (struct scsi_cmnd *cmd) ...@@ -929,8 +929,8 @@ static int idescsi_eh_reset (struct scsi_cmnd *cmd)
/* now nuke the drive queue */ /* now nuke the drive queue */
while ((req = elv_next_request(drive->queue))) { while ((req = elv_next_request(drive->queue))) {
blkdev_dequeue_request(req); if (__blk_end_request(req, -EIO, 0))
end_that_request_last(req, 0); BUG();
} }
HWGROUP(drive)->rq = NULL; HWGROUP(drive)->rq = NULL;
......
...@@ -634,7 +634,7 @@ void scsi_run_host_queues(struct Scsi_Host *shost) ...@@ -634,7 +634,7 @@ void scsi_run_host_queues(struct Scsi_Host *shost)
* of upper level post-processing and scsi_io_completion). * of upper level post-processing and scsi_io_completion).
* *
* Arguments: cmd - command that is complete. * Arguments: cmd - command that is complete.
* uptodate - 1 if I/O indicates success, <= 0 for I/O error. * error - 0 if I/O indicates success, < 0 for I/O error.
* bytes - number of bytes of completed I/O * bytes - number of bytes of completed I/O
* requeue - indicates whether we should requeue leftovers. * requeue - indicates whether we should requeue leftovers.
* *
...@@ -649,26 +649,25 @@ void scsi_run_host_queues(struct Scsi_Host *shost) ...@@ -649,26 +649,25 @@ void scsi_run_host_queues(struct Scsi_Host *shost)
* at some point during this call. * at some point during this call.
* Notes: If cmd was requeued, upon return it will be a stale pointer. * Notes: If cmd was requeued, upon return it will be a stale pointer.
*/ */
static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int uptodate, static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int error,
int bytes, int requeue) int bytes, int requeue)
{ {
struct request_queue *q = cmd->device->request_queue; struct request_queue *q = cmd->device->request_queue;
struct request *req = cmd->request; struct request *req = cmd->request;
unsigned long flags;
/* /*
* If there are blocks left over at the end, set up the command * If there are blocks left over at the end, set up the command
* to queue the remainder of them. * to queue the remainder of them.
*/ */
if (end_that_request_chunk(req, uptodate, bytes)) { if (blk_end_request(req, error, bytes)) {
int leftover = (req->hard_nr_sectors << 9); int leftover = (req->hard_nr_sectors << 9);
if (blk_pc_request(req)) if (blk_pc_request(req))
leftover = req->data_len; leftover = req->data_len;
/* kill remainder if no retrys */ /* kill remainder if no retrys */
if (!uptodate && blk_noretry_request(req)) if (error && blk_noretry_request(req))
end_that_request_chunk(req, 0, leftover); blk_end_request(req, error, leftover);
else { else {
if (requeue) { if (requeue) {
/* /*
...@@ -683,14 +682,6 @@ static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int uptodate, ...@@ -683,14 +682,6 @@ static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int uptodate,
} }
} }
add_disk_randomness(req->rq_disk);
spin_lock_irqsave(q->queue_lock, flags);
if (blk_rq_tagged(req))
blk_queue_end_tag(q, req);
end_that_request_last(req, uptodate);
spin_unlock_irqrestore(q->queue_lock, flags);
/* /*
* This will goose the queue request function at the end, so we don't * This will goose the queue request function at the end, so we don't
* need to worry about launching another command. * need to worry about launching another command.
...@@ -892,7 +883,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) ...@@ -892,7 +883,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
* are leftovers and there is some kind of error * are leftovers and there is some kind of error
* (result != 0), retry the rest. * (result != 0), retry the rest.
*/ */
if (scsi_end_request(cmd, 1, good_bytes, result == 0) == NULL) if (scsi_end_request(cmd, 0, good_bytes, result == 0) == NULL)
return; return;
/* good_bytes = 0, or (inclusive) there were leftovers and /* good_bytes = 0, or (inclusive) there were leftovers and
...@@ -906,7 +897,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) ...@@ -906,7 +897,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
* and quietly refuse further access. * and quietly refuse further access.
*/ */
cmd->device->changed = 1; cmd->device->changed = 1;
scsi_end_request(cmd, 0, this_count, 1); scsi_end_request(cmd, -EIO, this_count, 1);
return; return;
} else { } else {
/* Must have been a power glitch, or a /* Must have been a power glitch, or a
...@@ -938,7 +929,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) ...@@ -938,7 +929,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
scsi_requeue_command(q, cmd); scsi_requeue_command(q, cmd);
return; return;
} else { } else {
scsi_end_request(cmd, 0, this_count, 1); scsi_end_request(cmd, -EIO, this_count, 1);
return; return;
} }
break; break;
...@@ -966,7 +957,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) ...@@ -966,7 +957,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
"Device not ready", "Device not ready",
&sshdr); &sshdr);
scsi_end_request(cmd, 0, this_count, 1); scsi_end_request(cmd, -EIO, this_count, 1);
return; return;
case VOLUME_OVERFLOW: case VOLUME_OVERFLOW:
if (!(req->cmd_flags & REQ_QUIET)) { if (!(req->cmd_flags & REQ_QUIET)) {
...@@ -976,7 +967,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) ...@@ -976,7 +967,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
scsi_print_sense("", cmd); scsi_print_sense("", cmd);
} }
/* See SSC3rXX or current. */ /* See SSC3rXX or current. */
scsi_end_request(cmd, 0, this_count, 1); scsi_end_request(cmd, -EIO, this_count, 1);
return; return;
default: default:
break; break;
...@@ -997,7 +988,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) ...@@ -997,7 +988,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
scsi_print_sense("", cmd); scsi_print_sense("", cmd);
} }
} }
scsi_end_request(cmd, 0, this_count, !result); scsi_end_request(cmd, -EIO, this_count, !result);
} }
/* /*
......
...@@ -464,6 +464,8 @@ enum { ...@@ -464,6 +464,8 @@ enum {
#define blk_fua_rq(rq) ((rq)->cmd_flags & REQ_FUA) #define blk_fua_rq(rq) ((rq)->cmd_flags & REQ_FUA)
#define blk_bidi_rq(rq) ((rq)->next_rq != NULL) #define blk_bidi_rq(rq) ((rq)->next_rq != NULL)
#define blk_empty_barrier(rq) (blk_barrier_rq(rq) && blk_fs_request(rq) && !(rq)->hard_nr_sectors) #define blk_empty_barrier(rq) (blk_barrier_rq(rq) && blk_fs_request(rq) && !(rq)->hard_nr_sectors)
/* rq->queuelist of dequeued request must be list_empty() */
#define blk_queued_rq(rq) (!list_empty(&(rq)->queuelist))
#define list_entry_rq(ptr) list_entry((ptr), struct request, queuelist) #define list_entry_rq(ptr) list_entry((ptr), struct request, queuelist)
...@@ -643,29 +645,32 @@ static inline void blk_run_address_space(struct address_space *mapping) ...@@ -643,29 +645,32 @@ static inline void blk_run_address_space(struct address_space *mapping)
} }
/* /*
* end_request() and friends. Must be called with the request queue spinlock * blk_end_request() and friends.
* acquired. All functions called within end_request() _must_be_ atomic. * __blk_end_request() and end_request() must be called with
* the request queue spinlock acquired.
* *
* Several drivers define their own end_request and call * Several drivers define their own end_request and call
* end_that_request_first() and end_that_request_last() * blk_end_request() for parts of the original function.
* for parts of the original function. This prevents * This prevents code duplication in drivers.
* code duplication in drivers.
*/ */
extern int end_that_request_first(struct request *, int, int); extern int blk_end_request(struct request *rq, int error, int nr_bytes);
extern int end_that_request_chunk(struct request *, int, int); extern int __blk_end_request(struct request *rq, int error, int nr_bytes);
extern void end_that_request_last(struct request *, int); extern int blk_end_bidi_request(struct request *rq, int error, int nr_bytes,
int bidi_bytes);
extern void end_request(struct request *, int); extern void end_request(struct request *, int);
extern void end_queued_request(struct request *, int); extern void end_queued_request(struct request *, int);
extern void end_dequeued_request(struct request *, int); extern void end_dequeued_request(struct request *, int);
extern int blk_end_request_callback(struct request *rq, int error, int nr_bytes,
int (drv_callback)(struct request *));
extern void blk_complete_request(struct request *); extern void blk_complete_request(struct request *);
/* /*
* end_that_request_first/chunk() takes an uptodate argument. we account * blk_end_request() takes bytes instead of sectors as a complete size.
* any value <= as an io error. 0 means -EIO for compatability reasons, * blk_rq_bytes() returns bytes left to complete in the entire request.
* any other < 0 value is the direct error type. An uptodate value of * blk_rq_cur_bytes() returns bytes left to complete in the current segment.
* 1 indicates successful io completion
*/ */
#define end_io_error(uptodate) (unlikely((uptodate) <= 0)) extern unsigned int blk_rq_bytes(struct request *rq);
extern unsigned int blk_rq_cur_bytes(struct request *rq);
static inline void blkdev_dequeue_request(struct request *req) static inline void blkdev_dequeue_request(struct request *req)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment