aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-tape.c
diff options
context:
space:
mode:
authorBorislav Petkov <petkovbb@googlemail.com>2008-04-27 09:38:34 -0400
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-04-27 09:38:34 -0400
commit077e3bdb9ec34d7cb5751b5be81a4a0f6f0eb5dc (patch)
tree69a6666e92a8cf3da482abdebc8a7022740f654c /drivers/ide/ide-tape.c
parent01a63aebe4dcfcbe983c40a475e4650a4ae614de (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>
Diffstat (limited to 'drivers/ide/ide-tape.c')
-rw-r--r--drivers/ide/ide-tape.c107
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. */
219typedef 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. */
588static void ide_tape_kfree_buffer(idetape_stage_t *stage) 583static 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
611static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects) 606static 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 */
1302static idetape_stage_t *ide_tape_kmalloc_buffer(idetape_tape_t *tape, int full, 1297static 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;
1378abort: 1367abort:
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
1447static void idetape_init_merge_stage(idetape_tape_t *tape) 1436static 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
1783static void ide_tape_flush_merge_buffer(ide_drive_t *drive) 1772static 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 } 1836 }
1848 if (tape->merge_stage || tape->merge_bh_size) { 1837 if (tape->merge_bh || tape->merge_bh_size) {
1849 printk(KERN_ERR "ide-tape: merge_bh_size should be" 1838 printk(KERN_ERR "ide-tape: merge_bh_size should be"
1850 " 0 now\n"); 1839 " 0 now\n");
1851 tape->merge_bh_size = 0; 1840 tape->merge_bh_size = 0;
1852 } 1841 }
1853 tape->merge_stage = ide_tape_kmalloc_buffer(tape, 0, 0); 1842 tape->merge_bh = ide_tape_kmalloc_buffer(tape, 0, 0);
1854 if (!tape->merge_stage) 1843 if (!tape->merge_bh)
1855 return -ENOMEM; 1844 return -ENOMEM;
1856 tape->chrdev_dir = IDETAPE_DIR_READ; 1845 tape->chrdev_dir = IDETAPE_DIR_READ;
1857 1846
@@ -1864,10 +1853,10 @@ static int idetape_init_read(ide_drive_t *drive)
1864 if (drive->dsc_overlap) { 1853 if (drive->dsc_overlap) {
1865 bytes_read = idetape_queue_rw_tail(drive, 1854 bytes_read = idetape_queue_rw_tail(drive,
1866 REQ_IDETAPE_READ, 0, 1855 REQ_IDETAPE_READ, 0,
1867 tape->merge_stage->bh); 1856 tape->merge_bh);
1868 if (bytes_read < 0) { 1857 if (bytes_read < 0) {
1869 ide_tape_kfree_buffer(tape->merge_stage); 1858 ide_tape_kfree_buffer(tape);
1870 tape->merge_stage = NULL; 1859 tape->merge_bh = NULL;
1871 tape->chrdev_dir = IDETAPE_DIR_NONE; 1860 tape->chrdev_dir = IDETAPE_DIR_NONE;
1872 return bytes_read; 1861 return bytes_read;
1873 } 1862 }
@@ -1891,7 +1880,7 @@ static int idetape_add_chrdev_read_request(ide_drive_t *drive, int blocks)
1891 idetape_init_read(drive); 1880 idetape_init_read(drive);
1892 1881
1893 return idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, blocks, 1882 return idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, blocks,
1894 tape->merge_stage->bh); 1883 tape->merge_bh);
1895} 1884}
1896 1885
1897static void idetape_pad_zeros(ide_drive_t *drive, int bcount) 1886static void idetape_pad_zeros(ide_drive_t *drive, int bcount)
@@ -1903,7 +1892,7 @@ static void idetape_pad_zeros(ide_drive_t *drive, int bcount)
1903 while (bcount) { 1892 while (bcount) {
1904 unsigned int count; 1893 unsigned int count;
1905 1894
1906 bh = tape->merge_stage->bh; 1895 bh = tape->merge_bh;
1907 count = min(tape->buffer_size, bcount); 1896 count = min(tape->buffer_size, bcount);
1908 bcount -= count; 1897 bcount -= count;
1909 blocks = count / tape->blk_size; 1898 blocks = count / tape->blk_size;
@@ -1915,7 +1904,7 @@ static void idetape_pad_zeros(ide_drive_t *drive, int bcount)
1915 bh = bh->b_reqnext; 1904 bh = bh->b_reqnext;
1916 } 1905 }
1917 idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, blocks, 1906 idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, blocks,
1918 tape->merge_stage->bh); 1907 tape->merge_bh);
1919 } 1908 }
1920} 1909}
1921 1910
@@ -2000,10 +1989,6 @@ static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op,
2000 ide_tape_discard_merge_buffer(drive, 0); 1989 ide_tape_discard_merge_buffer(drive, 0);
2001 } 1990 }
2002 1991
2003 /*
2004 * The filemark was not found in our internal pipeline; now we can issue
2005 * the space command.
2006 */
2007 switch (mt_op) { 1992 switch (mt_op) {
2008 case MTFSF: 1993 case MTFSF:
2009 case MTBSF: 1994 case MTBSF:
@@ -2123,16 +2108,16 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf,
2123 if (tape->chrdev_dir != IDETAPE_DIR_WRITE) { 2108 if (tape->chrdev_dir != IDETAPE_DIR_WRITE) {
2124 if (tape->chrdev_dir == IDETAPE_DIR_READ) 2109 if (tape->chrdev_dir == IDETAPE_DIR_READ)
2125 ide_tape_discard_merge_buffer(drive, 1); 2110 ide_tape_discard_merge_buffer(drive, 1);
2126 if (tape->merge_stage || tape->merge_bh_size) { 2111 if (tape->merge_bh || tape->merge_bh_size) {
2127 printk(KERN_ERR "ide-tape: merge_bh_size " 2112 printk(KERN_ERR "ide-tape: merge_bh_size "
2128 "should be 0 now\n"); 2113 "should be 0 now\n");
2129 tape->merge_bh_size = 0; 2114 tape->merge_bh_size = 0;
2130 } 2115 }
2131 tape->merge_stage = ide_tape_kmalloc_buffer(tape, 0, 0); 2116 tape->merge_bh = ide_tape_kmalloc_buffer(tape, 0, 0);
2132 if (!tape->merge_stage) 2117 if (!tape->merge_bh)
2133 return -ENOMEM; 2118 return -ENOMEM;
2134 tape->chrdev_dir = IDETAPE_DIR_WRITE; 2119 tape->chrdev_dir = IDETAPE_DIR_WRITE;
2135 idetape_init_merge_stage(tape); 2120 idetape_init_merge_buffer(tape);
2136 2121
2137 /* 2122 /*
2138 * Issue a write 0 command to ensure that DSC handshake is 2123 * Issue a write 0 command to ensure that DSC handshake is
@@ -2143,10 +2128,10 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf,
2143 if (drive->dsc_overlap) { 2128 if (drive->dsc_overlap) {
2144 ssize_t retval = idetape_queue_rw_tail(drive, 2129 ssize_t retval = idetape_queue_rw_tail(drive,
2145 REQ_IDETAPE_WRITE, 0, 2130 REQ_IDETAPE_WRITE, 0,
2146 tape->merge_stage->bh); 2131 tape->merge_bh);
2147 if (retval < 0) { 2132 if (retval < 0) {
2148 ide_tape_kfree_buffer(tape->merge_stage); 2133 ide_tape_kfree_buffer(tape);
2149 tape->merge_stage = NULL; 2134 tape->merge_bh = NULL;
2150 tape->chrdev_dir = IDETAPE_DIR_NONE; 2135 tape->chrdev_dir = IDETAPE_DIR_NONE;
2151 return retval; 2136 return retval;
2152 } 2137 }
@@ -2508,12 +2493,12 @@ static void idetape_write_release(ide_drive_t *drive, unsigned int minor)
2508 idetape_tape_t *tape = drive->driver_data; 2493 idetape_tape_t *tape = drive->driver_data;
2509 2494
2510 ide_tape_flush_merge_buffer(drive); 2495 ide_tape_flush_merge_buffer(drive);
2511 tape->merge_stage = ide_tape_kmalloc_buffer(tape, 1, 0); 2496 tape->merge_bh = ide_tape_kmalloc_buffer(tape, 1, 0);
2512 if (tape->merge_stage != NULL) { 2497 if (tape->merge_bh != NULL) {
2513 idetape_pad_zeros(drive, tape->blk_size * 2498 idetape_pad_zeros(drive, tape->blk_size *
2514 (tape->user_bs_factor - 1)); 2499 (tape->user_bs_factor - 1));
2515 ide_tape_kfree_buffer(tape->merge_stage); 2500 ide_tape_kfree_buffer(tape);
2516 tape->merge_stage = NULL; 2501 tape->merge_bh = NULL;
2517 } 2502 }
2518 idetape_write_filemark(drive); 2503 idetape_write_filemark(drive);
2519 idetape_flush_tape_buffers(drive); 2504 idetape_flush_tape_buffers(drive);