diff options
Diffstat (limited to 'drivers/ide')
-rw-r--r-- | drivers/ide/ide-cd.c | 55 | ||||
-rw-r--r-- | drivers/ide/ide-io.c | 25 |
2 files changed, 50 insertions, 30 deletions
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 44b033ec0ab0..74c6087ada38 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
@@ -655,9 +655,9 @@ static void cdrom_end_request (ide_drive_t *drive, int uptodate) | |||
655 | BUG(); | 655 | BUG(); |
656 | } else { | 656 | } else { |
657 | spin_lock_irqsave(&ide_lock, flags); | 657 | spin_lock_irqsave(&ide_lock, flags); |
658 | end_that_request_chunk(failed, 0, | 658 | if (__blk_end_request(failed, -EIO, |
659 | failed->data_len); | 659 | failed->data_len)) |
660 | end_that_request_last(failed, 0); | 660 | BUG(); |
661 | spin_unlock_irqrestore(&ide_lock, flags); | 661 | spin_unlock_irqrestore(&ide_lock, flags); |
662 | } | 662 | } |
663 | } else | 663 | } else |
@@ -1647,6 +1647,17 @@ static int cdrom_write_check_ireason(ide_drive_t *drive, int len, int ireason) | |||
1647 | return 1; | 1647 | return 1; |
1648 | } | 1648 | } |
1649 | 1649 | ||
1650 | /* | ||
1651 | * Called from blk_end_request_callback() after the data of the request | ||
1652 | * is completed and before the request is completed. | ||
1653 | * By returning value '1', blk_end_request_callback() returns immediately | ||
1654 | * without completing the request. | ||
1655 | */ | ||
1656 | static int cdrom_newpc_intr_dummy_cb(struct request *rq) | ||
1657 | { | ||
1658 | return 1; | ||
1659 | } | ||
1660 | |||
1650 | typedef void (xfer_func_t)(ide_drive_t *, void *, u32); | 1661 | typedef void (xfer_func_t)(ide_drive_t *, void *, u32); |
1651 | 1662 | ||
1652 | /* | 1663 | /* |
@@ -1685,9 +1696,13 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
1685 | return ide_error(drive, "dma error", stat); | 1696 | return ide_error(drive, "dma error", stat); |
1686 | } | 1697 | } |
1687 | 1698 | ||
1688 | end_that_request_chunk(rq, 1, rq->data_len); | 1699 | spin_lock_irqsave(&ide_lock, flags); |
1689 | rq->data_len = 0; | 1700 | if (__blk_end_request(rq, 0, rq->data_len)) |
1690 | goto end_request; | 1701 | BUG(); |
1702 | HWGROUP(drive)->rq = NULL; | ||
1703 | spin_unlock_irqrestore(&ide_lock, flags); | ||
1704 | |||
1705 | return ide_stopped; | ||
1691 | } | 1706 | } |
1692 | 1707 | ||
1693 | /* | 1708 | /* |
@@ -1705,8 +1720,15 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
1705 | /* | 1720 | /* |
1706 | * If DRQ is clear, the command has completed. | 1721 | * If DRQ is clear, the command has completed. |
1707 | */ | 1722 | */ |
1708 | if ((stat & DRQ_STAT) == 0) | 1723 | if ((stat & DRQ_STAT) == 0) { |
1709 | goto end_request; | 1724 | spin_lock_irqsave(&ide_lock, flags); |
1725 | if (__blk_end_request(rq, 0, 0)) | ||
1726 | BUG(); | ||
1727 | HWGROUP(drive)->rq = NULL; | ||
1728 | spin_unlock_irqrestore(&ide_lock, flags); | ||
1729 | |||
1730 | return ide_stopped; | ||
1731 | } | ||
1710 | 1732 | ||
1711 | /* | 1733 | /* |
1712 | * check which way to transfer data | 1734 | * check which way to transfer data |
@@ -1759,7 +1781,14 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
1759 | rq->data_len -= blen; | 1781 | rq->data_len -= blen; |
1760 | 1782 | ||
1761 | if (rq->bio) | 1783 | if (rq->bio) |
1762 | end_that_request_chunk(rq, 1, blen); | 1784 | /* |
1785 | * The request can't be completed until DRQ is cleared. | ||
1786 | * So complete the data, but don't complete the request | ||
1787 | * using the dummy function for the callback feature | ||
1788 | * of blk_end_request_callback(). | ||
1789 | */ | ||
1790 | blk_end_request_callback(rq, 0, blen, | ||
1791 | cdrom_newpc_intr_dummy_cb); | ||
1763 | else | 1792 | else |
1764 | rq->data += blen; | 1793 | rq->data += blen; |
1765 | } | 1794 | } |
@@ -1780,14 +1809,6 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
1780 | 1809 | ||
1781 | ide_set_handler(drive, cdrom_newpc_intr, rq->timeout, NULL); | 1810 | ide_set_handler(drive, cdrom_newpc_intr, rq->timeout, NULL); |
1782 | return ide_started; | 1811 | return ide_started; |
1783 | |||
1784 | end_request: | ||
1785 | spin_lock_irqsave(&ide_lock, flags); | ||
1786 | blkdev_dequeue_request(rq); | ||
1787 | end_that_request_last(rq, 1); | ||
1788 | HWGROUP(drive)->rq = NULL; | ||
1789 | spin_unlock_irqrestore(&ide_lock, flags); | ||
1790 | return ide_stopped; | ||
1791 | } | 1812 | } |
1792 | 1813 | ||
1793 | static ide_startstop_t cdrom_write_intr(ide_drive_t *drive) | 1814 | static ide_startstop_t cdrom_write_intr(ide_drive_t *drive) |
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 6f8f544392a8..e6bb9cf24e3d 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
@@ -58,15 +58,19 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq, | |||
58 | int uptodate, unsigned int nr_bytes, int dequeue) | 58 | int uptodate, unsigned int nr_bytes, int dequeue) |
59 | { | 59 | { |
60 | int ret = 1; | 60 | int ret = 1; |
61 | int error = 0; | ||
62 | |||
63 | if (uptodate <= 0) | ||
64 | error = uptodate ? uptodate : -EIO; | ||
61 | 65 | ||
62 | /* | 66 | /* |
63 | * if failfast is set on a request, override number of sectors and | 67 | * if failfast is set on a request, override number of sectors and |
64 | * complete the whole request right now | 68 | * complete the whole request right now |
65 | */ | 69 | */ |
66 | if (blk_noretry_request(rq) && end_io_error(uptodate)) | 70 | if (blk_noretry_request(rq) && error) |
67 | nr_bytes = rq->hard_nr_sectors << 9; | 71 | nr_bytes = rq->hard_nr_sectors << 9; |
68 | 72 | ||
69 | if (!blk_fs_request(rq) && end_io_error(uptodate) && !rq->errors) | 73 | if (!blk_fs_request(rq) && error && !rq->errors) |
70 | rq->errors = -EIO; | 74 | rq->errors = -EIO; |
71 | 75 | ||
72 | /* | 76 | /* |
@@ -78,14 +82,9 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq, | |||
78 | ide_dma_on(drive); | 82 | ide_dma_on(drive); |
79 | } | 83 | } |
80 | 84 | ||
81 | if (!end_that_request_chunk(rq, uptodate, nr_bytes)) { | 85 | if (!__blk_end_request(rq, error, nr_bytes)) { |
82 | add_disk_randomness(rq->rq_disk); | 86 | if (dequeue) |
83 | if (dequeue) { | ||
84 | if (!list_empty(&rq->queuelist)) | ||
85 | blkdev_dequeue_request(rq); | ||
86 | HWGROUP(drive)->rq = NULL; | 87 | HWGROUP(drive)->rq = NULL; |
87 | } | ||
88 | end_that_request_last(rq, uptodate); | ||
89 | ret = 0; | 88 | ret = 0; |
90 | } | 89 | } |
91 | 90 | ||
@@ -290,9 +289,9 @@ static void ide_complete_pm_request (ide_drive_t *drive, struct request *rq) | |||
290 | drive->blocked = 0; | 289 | drive->blocked = 0; |
291 | blk_start_queue(drive->queue); | 290 | blk_start_queue(drive->queue); |
292 | } | 291 | } |
293 | blkdev_dequeue_request(rq); | ||
294 | HWGROUP(drive)->rq = NULL; | 292 | HWGROUP(drive)->rq = NULL; |
295 | end_that_request_last(rq, 1); | 293 | if (__blk_end_request(rq, 0, 0)) |
294 | BUG(); | ||
296 | spin_unlock_irqrestore(&ide_lock, flags); | 295 | spin_unlock_irqrestore(&ide_lock, flags); |
297 | } | 296 | } |
298 | 297 | ||
@@ -387,10 +386,10 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) | |||
387 | } | 386 | } |
388 | 387 | ||
389 | spin_lock_irqsave(&ide_lock, flags); | 388 | spin_lock_irqsave(&ide_lock, flags); |
390 | blkdev_dequeue_request(rq); | ||
391 | HWGROUP(drive)->rq = NULL; | 389 | HWGROUP(drive)->rq = NULL; |
392 | rq->errors = err; | 390 | rq->errors = err; |
393 | end_that_request_last(rq, !rq->errors); | 391 | if (__blk_end_request(rq, (rq->errors ? -EIO : 0), 0)) |
392 | BUG(); | ||
394 | spin_unlock_irqrestore(&ide_lock, flags); | 393 | spin_unlock_irqrestore(&ide_lock, flags); |
395 | } | 394 | } |
396 | 395 | ||