diff options
| author | Borislav Petkov <petkovbb@googlemail.com> | 2008-04-27 09:38:34 -0400 |
|---|---|---|
| committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-04-27 09:38:34 -0400 |
| commit | 077e3bdb9ec34d7cb5751b5be81a4a0f6f0eb5dc (patch) | |
| tree | 69a6666e92a8cf3da482abdebc8a7022740f654c | |
| parent | 01a63aebe4dcfcbe983c40a475e4650a4ae614de (diff) | |
ide-tape: remove tape->merge_stage
Get rid of the pipeline merge stage but retain the chrdev req caching
functionality by using a merge buffer tape->merge_bh which is flushed in chunks
of several blocks at a time. Also, remove last references to pipelining, e.g.
typedef idetape_stage_s.
Signed-off-by: Borislav Petkov <petkovbb@gmail.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
| -rw-r--r-- | drivers/ide/ide-tape.c | 107 |
1 files changed, 46 insertions, 61 deletions
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 0b8765c22d7a..29870c415110 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c | |||
| @@ -215,13 +215,6 @@ enum { | |||
| 215 | IDETAPE_FLAG_MEDIUM_PRESENT = (1 << 6), | 215 | IDETAPE_FLAG_MEDIUM_PRESENT = (1 << 6), |
| 216 | }; | 216 | }; |
| 217 | 217 | ||
| 218 | /* A pipeline stage. */ | ||
| 219 | typedef struct idetape_stage_s { | ||
| 220 | struct request rq; /* The corresponding request */ | ||
| 221 | struct idetape_bh *bh; /* The data buffers */ | ||
| 222 | struct idetape_stage_s *next; /* Pointer to the next stage */ | ||
| 223 | } idetape_stage_t; | ||
| 224 | |||
| 225 | /* | 218 | /* |
| 226 | * Most of our global data which we need to save even as we leave the driver due | 219 | * Most of our global data which we need to save even as we leave the driver due |
| 227 | * to an interrupt or a timer event is stored in the struct defined below. | 220 | * to an interrupt or a timer event is stored in the struct defined below. |
| @@ -309,9 +302,11 @@ typedef struct ide_tape_obj { | |||
| 309 | 302 | ||
| 310 | /* Data buffer size chosen based on the tape's recommendation */ | 303 | /* Data buffer size chosen based on the tape's recommendation */ |
| 311 | int buffer_size; | 304 | int buffer_size; |
| 312 | idetape_stage_t *merge_stage; | 305 | /* merge buffer */ |
| 306 | struct idetape_bh *merge_bh; | ||
| 313 | /* size of the merge buffer */ | 307 | /* size of the merge buffer */ |
| 314 | int merge_bh_size; | 308 | int merge_bh_size; |
| 309 | /* pointer to current buffer head within the merge buffer */ | ||
| 315 | struct idetape_bh *bh; | 310 | struct idetape_bh *bh; |
| 316 | char *b_data; | 311 | char *b_data; |
| 317 | int b_count; | 312 | int b_count; |
| @@ -585,9 +580,9 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense) | |||
| 585 | } | 580 | } |
| 586 | 581 | ||
| 587 | /* Free data buffers completely. */ | 582 | /* Free data buffers completely. */ |
| 588 | static void ide_tape_kfree_buffer(idetape_stage_t *stage) | 583 | static void ide_tape_kfree_buffer(idetape_tape_t *tape) |
| 589 | { | 584 | { |
| 590 | struct idetape_bh *prev_bh, *bh = stage->bh; | 585 | struct idetape_bh *prev_bh, *bh = tape->merge_bh; |
| 591 | 586 | ||
| 592 | while (bh) { | 587 | while (bh) { |
| 593 | u32 size = bh->b_size; | 588 | u32 size = bh->b_size; |
| @@ -605,7 +600,7 @@ static void ide_tape_kfree_buffer(idetape_stage_t *stage) | |||
| 605 | bh = bh->b_reqnext; | 600 | bh = bh->b_reqnext; |
| 606 | kfree(prev_bh); | 601 | kfree(prev_bh); |
| 607 | } | 602 | } |
| 608 | kfree(stage); | 603 | kfree(tape->merge_bh); |
| 609 | } | 604 | } |
| 610 | 605 | ||
| 611 | static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects) | 606 | static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects) |
| @@ -1299,22 +1294,16 @@ out: | |||
| 1299 | * It returns a pointer to the newly allocated buffer, or NULL in case of | 1294 | * It returns a pointer to the newly allocated buffer, or NULL in case of |
| 1300 | * failure. | 1295 | * failure. |
| 1301 | */ | 1296 | */ |
| 1302 | static idetape_stage_t *ide_tape_kmalloc_buffer(idetape_tape_t *tape, int full, | 1297 | static struct idetape_bh *ide_tape_kmalloc_buffer(idetape_tape_t *tape, |
| 1303 | int clear) | 1298 | int full, int clear) |
| 1304 | { | 1299 | { |
| 1305 | idetape_stage_t *stage; | 1300 | struct idetape_bh *prev_bh, *bh, *merge_bh; |
| 1306 | struct idetape_bh *prev_bh, *bh; | ||
| 1307 | int pages = tape->pages_per_buffer; | 1301 | int pages = tape->pages_per_buffer; |
| 1308 | unsigned int order, b_allocd; | 1302 | unsigned int order, b_allocd; |
| 1309 | char *b_data = NULL; | 1303 | char *b_data = NULL; |
| 1310 | 1304 | ||
| 1311 | stage = kmalloc(sizeof(idetape_stage_t), GFP_KERNEL); | 1305 | merge_bh = kmalloc(sizeof(struct idetape_bh), GFP_KERNEL); |
| 1312 | if (!stage) | 1306 | bh = merge_bh; |
| 1313 | return NULL; | ||
| 1314 | stage->next = NULL; | ||
| 1315 | |||
| 1316 | stage->bh = kmalloc(sizeof(struct idetape_bh), GFP_KERNEL); | ||
| 1317 | bh = stage->bh; | ||
| 1318 | if (bh == NULL) | 1307 | if (bh == NULL) |
| 1319 | goto abort; | 1308 | goto abort; |
| 1320 | 1309 | ||
| @@ -1374,9 +1363,9 @@ static idetape_stage_t *ide_tape_kmalloc_buffer(idetape_tape_t *tape, int full, | |||
| 1374 | bh->b_size -= tape->excess_bh_size; | 1363 | bh->b_size -= tape->excess_bh_size; |
| 1375 | if (full) | 1364 | if (full) |
| 1376 | atomic_sub(tape->excess_bh_size, &bh->b_count); | 1365 | atomic_sub(tape->excess_bh_size, &bh->b_count); |
| 1377 | return stage; | 1366 | return merge_bh; |
| 1378 | abort: | 1367 | abort: |
| 1379 | ide_tape_kfree_buffer(stage); | 1368 | ide_tape_kfree_buffer(tape); |
| 1380 | return NULL; | 1369 | return NULL; |
| 1381 | } | 1370 | } |
| 1382 | 1371 | ||
| @@ -1444,11 +1433,11 @@ static int idetape_copy_stage_to_user(idetape_tape_t *tape, char __user *buf, | |||
| 1444 | return ret; | 1433 | return ret; |
| 1445 | } | 1434 | } |
| 1446 | 1435 | ||
| 1447 | static void idetape_init_merge_stage(idetape_tape_t *tape) | 1436 | static void idetape_init_merge_buffer(idetape_tape_t *tape) |
| 1448 | { | 1437 | { |
| 1449 | struct idetape_bh *bh = tape->merge_stage->bh; | 1438 | struct idetape_bh *bh = tape->merge_bh; |
| 1439 | tape->bh = tape->merge_bh; | ||
| 1450 | 1440 | ||
| 1451 | tape->bh = bh; | ||
| 1452 | if (tape->chrdev_dir == IDETAPE_DIR_WRITE) | 1441 | if (tape->chrdev_dir == IDETAPE_DIR_WRITE) |
| 1453 | atomic_set(&bh->b_count, 0); | 1442 | atomic_set(&bh->b_count, 0); |
| 1454 | else { | 1443 | else { |
| @@ -1651,9 +1640,9 @@ static void __ide_tape_discard_merge_buffer(ide_drive_t *drive) | |||
| 1651 | 1640 | ||
| 1652 | clear_bit(IDETAPE_FLAG_FILEMARK, &tape->flags); | 1641 | clear_bit(IDETAPE_FLAG_FILEMARK, &tape->flags); |
| 1653 | tape->merge_bh_size = 0; | 1642 | tape->merge_bh_size = 0; |
| 1654 | if (tape->merge_stage != NULL) { | 1643 | if (tape->merge_bh != NULL) { |
| 1655 | ide_tape_kfree_buffer(tape->merge_stage); | 1644 | ide_tape_kfree_buffer(tape); |
| 1656 | tape->merge_stage = NULL; | 1645 | tape->merge_bh = NULL; |
| 1657 | } | 1646 | } |
| 1658 | 1647 | ||
| 1659 | tape->chrdev_dir = IDETAPE_DIR_NONE; | 1648 | tape->chrdev_dir = IDETAPE_DIR_NONE; |
| @@ -1725,8 +1714,8 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks, | |||
| 1725 | if ((cmd & (REQ_IDETAPE_READ | REQ_IDETAPE_WRITE)) == 0) | 1714 | if ((cmd & (REQ_IDETAPE_READ | REQ_IDETAPE_WRITE)) == 0) |
| 1726 | return 0; | 1715 | return 0; |
| 1727 | 1716 | ||
| 1728 | if (tape->merge_stage) | 1717 | if (tape->merge_bh) |
| 1729 | idetape_init_merge_stage(tape); | 1718 | idetape_init_merge_buffer(tape); |
| 1730 | if (rq.errors == IDETAPE_ERROR_GENERAL) | 1719 | if (rq.errors == IDETAPE_ERROR_GENERAL) |
| 1731 | return -EIO; | 1720 | return -EIO; |
| 1732 | return (tape->blk_size * (blocks-rq.current_nr_sectors)); | 1721 | return (tape->blk_size * (blocks-rq.current_nr_sectors)); |
| @@ -1777,7 +1766,7 @@ static int idetape_add_chrdev_write_request(ide_drive_t *drive, int blocks) | |||
| 1777 | debug_log(DBG_CHRDEV, "Enter %s\n", __func__); | 1766 | debug_log(DBG_CHRDEV, "Enter %s\n", __func__); |
| 1778 | 1767 | ||
| 1779 | return idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, | 1768 | return idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, |
| 1780 | blocks, tape->merge_stage->bh); | 1769 | blocks, tape->merge_bh); |
| 1781 | } | 1770 | } |
| 1782 | 1771 | ||
| 1783 | static void ide_tape_flush_merge_buffer(ide_drive_t *drive) | 1772 | static void ide_tape_flush_merge_buffer(ide_drive_t *drive) |
| @@ -1787,7 +1776,7 @@ static void ide_tape_flush_merge_buffer(ide_drive_t *drive) | |||
| 1787 | struct idetape_bh *bh; | 1776 | struct idetape_bh *bh; |
| 1788 | 1777 | ||
| 1789 | if (tape->chrdev_dir != IDETAPE_DIR_WRITE) { | 1778 | if (tape->chrdev_dir != IDETAPE_DIR_WRITE) { |
| 1790 | printk(KERN_ERR "ide-tape: bug: Trying to empty write pipeline," | 1779 | printk(KERN_ERR "ide-tape: bug: Trying to empty merge buffer" |
| 1791 | " but we are not writing.\n"); | 1780 | " but we are not writing.\n"); |
| 1792 | return; | 1781 | return; |
| 1793 | } | 1782 | } |
| @@ -1827,9 +1816,9 @@ static void ide_tape_flush_merge_buffer(ide_drive_t *drive) | |||
| 1827 | (void) idetape_add_chrdev_write_request(drive, blocks); | 1816 | (void) idetape_add_chrdev_write_request(drive, blocks); |
| 1828 | tape->merge_bh_size = 0; | 1817 | tape->merge_bh_size = 0; |
| 1829 | } | 1818 | } |
| 1830 | if (tape->merge_stage != NULL) { | 1819 | if (tape->merge_bh != NULL) { |
| 1831 | ide_tape_kfree_buffer(tape->merge_stage); | 1820 | ide_tape_kfree_buffer(tape); |
| 1832 | tape->merge_stage = NULL; | 1821 | tape->merge_bh = NULL; |
| 1833 | } | 1822 | } |
| 1834 | tape->chrdev_dir = IDETAPE_DIR_NONE; | 1823 | tape->chrdev_dir = IDETAPE_DIR_NONE; |
| 1835 | } | 1824 | } |
| @@ -1845,13 +1834,13 @@ static int idetape_init_read(ide_drive_t *drive) | |||
| 1845 | ide_tape_flush_merge_buffer(drive); | 1834 | ide_tape_flush_merge_buffer(drive); |
| 1846 | idetape_flush_tape_buffers(drive); | 1835 | idetape_flush_tape_buffers(drive); |
| 1847 | } | ||
