aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-tape.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/ide-tape.c')
-rw-r--r--drivers/ide/ide-tape.c256
1 files changed, 58 insertions, 198 deletions
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 8226d52504d0..b2afbc7bcb6b 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -134,7 +134,6 @@ enum {
134struct idetape_bh { 134struct idetape_bh {
135 u32 b_size; 135 u32 b_size;
136 atomic_t b_count; 136 atomic_t b_count;
137 struct idetape_bh *b_reqnext;
138 char *b_data; 137 char *b_data;
139}; 138};
140 139
@@ -228,10 +227,6 @@ typedef struct ide_tape_obj {
228 char *b_data; 227 char *b_data;
229 int b_count; 228 int b_count;
230 229
231 int pages_per_buffer;
232 /* Wasted space in each stage */
233 int excess_bh_size;
234
235 /* Measures average tape speed */ 230 /* Measures average tape speed */
236 unsigned long avg_time; 231 unsigned long avg_time;
237 int avg_size; 232 int avg_size;
@@ -303,9 +298,7 @@ static int idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
303 struct idetape_bh *bh = pc->bh; 298 struct idetape_bh *bh = pc->bh;
304 int count; 299 int count;
305 300
306 while (bcount) { 301 if (bcount && bh) {
307 if (bh == NULL)
308 break;
309 count = min( 302 count = min(
310 (unsigned int)(bh->b_size - atomic_read(&bh->b_count)), 303 (unsigned int)(bh->b_size - atomic_read(&bh->b_count)),
311 bcount); 304 bcount);
@@ -313,15 +306,10 @@ static int idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
313 atomic_read(&bh->b_count), count); 306 atomic_read(&bh->b_count), count);
314 bcount -= count; 307 bcount -= count;
315 atomic_add(count, &bh->b_count); 308 atomic_add(count, &bh->b_count);
316 if (atomic_read(&bh->b_count) == bh->b_size) { 309 if (atomic_read(&bh->b_count) == bh->b_size)
317 bh = bh->b_reqnext; 310 pc->bh = NULL;
318 if (bh)
319 atomic_set(&bh->b_count, 0);
320 }
321 } 311 }
322 312
323 pc->bh = bh;
324
325 return bcount; 313 return bcount;
326} 314}
327 315
@@ -331,22 +319,14 @@ static int idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
331 struct idetape_bh *bh = pc->bh; 319 struct idetape_bh *bh = pc->bh;
332 int count; 320 int count;
333 321
334 while (bcount) { 322 if (bcount && bh) {
335 if (bh == NULL)
336 break;
337 count = min((unsigned int)pc->b_count, (unsigned int)bcount); 323 count = min((unsigned int)pc->b_count, (unsigned int)bcount);
338 drive->hwif->tp_ops->output_data(drive, NULL, pc->b_data, count); 324 drive->hwif->tp_ops->output_data(drive, NULL, pc->b_data, count);
339 bcount -= count; 325 bcount -= count;
340 pc->b_data += count; 326 pc->b_data += count;
341 pc->b_count -= count; 327 pc->b_count -= count;
342 if (!pc->b_count) { 328 if (!pc->b_count)
343 bh = bh->b_reqnext; 329 pc->bh = NULL;
344 pc->bh = bh;
345 if (bh) {
346 pc->b_data = bh->b_data;
347 pc->b_count = atomic_read(&bh->b_count);
348 }
349 }
350 } 330 }
351 331
352 return bcount; 332 return bcount;
@@ -355,24 +335,20 @@ static int idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
355static void idetape_update_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc) 335static void idetape_update_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc)
356{ 336{
357 struct idetape_bh *bh = pc->bh; 337 struct idetape_bh *bh = pc->bh;
358 int count;
359 unsigned int bcount = pc->xferred; 338 unsigned int bcount = pc->xferred;
360 339
361 if (pc->flags & PC_FLAG_WRITING) 340 if (pc->flags & PC_FLAG_WRITING)
362 return; 341 return;
363 while (bcount) { 342 if (bcount) {
364 if (bh == NULL) { 343 if (bh == NULL || bcount > bh->b_size) {
365 printk(KERN_ERR "ide-tape: bh == NULL in %s\n", 344 printk(KERN_ERR "ide-tape: bh == NULL in %s\n",
366 __func__); 345 __func__);
367 return; 346 return;
368 } 347 }
369 count = min((unsigned int)bh->b_size, (unsigned int)bcount); 348 atomic_set(&bh->b_count, bcount);
370 atomic_set(&bh->b_count, count);
371 if (atomic_read(&bh->b_count) == bh->b_size) 349 if (atomic_read(&bh->b_count) == bh->b_size)
372 bh = bh->b_reqnext; 350 pc->bh = NULL;
373 bcount -= count;
374 } 351 }
375 pc->bh = bh;
376} 352}
377 353
378/* 354/*
@@ -439,24 +415,10 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense)
439/* Free data buffers completely. */ 415/* Free data buffers completely. */
440static void ide_tape_kfree_buffer(idetape_tape_t *tape) 416static void ide_tape_kfree_buffer(idetape_tape_t *tape)
441{ 417{
442 struct idetape_bh *prev_bh, *bh = tape->merge_bh; 418 struct idetape_bh *bh = tape->merge_bh;
443
444 while (bh) {
445 u32 size = bh->b_size;
446
447 while (size) {
448 unsigned int order = fls(size >> PAGE_SHIFT)-1;
449
450 if (bh->b_data)
451 free_pages((unsigned long)bh->b_data, order);
452 419
453 size &= (order-1); 420 kfree(bh->b_data);
454 bh->b_data += (1 << order) * PAGE_SIZE; 421 kfree(bh);
455 }
456 prev_bh = bh;
457 bh = bh->b_reqnext;
458 kfree(prev_bh);
459 }
460} 422}
461 423
462static void ide_tape_handle_dsc(ide_drive_t *); 424static void ide_tape_handle_dsc(ide_drive_t *);
@@ -861,117 +823,50 @@ out:
861} 823}
862 824
863/* 825/*
864 * The function below uses __get_free_pages to allocate a data buffer of size 826 * It returns a pointer to the newly allocated buffer, or NULL in case
865 * tape->buffer_size (or a bit more). We attempt to combine sequential pages as 827 * of failure.
866 * much as possible.
867 *
868 * It returns a pointer to the newly allocated buffer, or NULL in case of
869 * failure.
870 */ 828 */
871static struct idetape_bh *ide_tape_kmalloc_buffer(idetape_tape_t *tape, 829static struct idetape_bh *ide_tape_kmalloc_buffer(idetape_tape_t *tape,
872 int full, int clear) 830 int full)
873{ 831{
874 struct idetape_bh *prev_bh, *bh, *merge_bh; 832 struct idetape_bh *bh;
875 int pages = tape->pages_per_buffer;
876 unsigned int order, b_allocd;
877 char *b_data = NULL;
878
879 merge_bh = kmalloc(sizeof(struct idetape_bh), GFP_KERNEL);
880 bh = merge_bh;
881 if (bh == NULL)
882 goto abort;
883
884 order = fls(pages) - 1;
885 bh->b_data = (char *) __get_free_pages(GFP_KERNEL, order);
886 if (!bh->b_data)
887 goto abort;
888 b_allocd = (1 << order) * PAGE_SIZE;
889 pages &= (order-1);
890
891 if (clear)
892 memset(bh->b_data, 0, b_allocd);
893 bh->b_reqnext = NULL;
894 bh->b_size = b_allocd;
895 atomic_set(&bh->b_count, full ? bh->b_size : 0);
896 833
897 while (pages) { 834 bh = kmalloc(sizeof(struct idetape_bh), GFP_KERNEL);
898 order = fls(pages) - 1; 835 if (!bh)
899 b_data = (char *) __get_free_pages(GFP_KERNEL, order); 836 return NULL;
900 if (!b_data)
901 goto abort;
902 b_allocd = (1 << order) * PAGE_SIZE;
903
904 if (clear)
905 memset(b_data, 0, b_allocd);
906
907 /* newly allocated page frames below buffer header or ...*/
908 if (bh->b_data == b_data + b_allocd) {
909 bh->b_size += b_allocd;
910 bh->b_data -= b_allocd;
911 if (full)
912 atomic_add(b_allocd, &bh->b_count);
913 continue;
914 }
915 /* they are above the header */
916 if (b_data == bh->b_data + bh->b_size) {
917 bh->b_size += b_allocd;
918 if (full)
919 atomic_add(b_allocd, &bh->b_count);
920 continue;
921 }
922 prev_bh = bh;
923 bh = kmalloc(sizeof(struct idetape_bh), GFP_KERNEL);
924 if (!bh) {
925 free_pages((unsigned long) b_data, order);
926 goto abort;
927 }
928 bh->b_reqnext = NULL;
929 bh->b_data = b_data;
930 bh->b_size = b_allocd;
931 atomic_set(&bh->b_count, full ? bh->b_size : 0);
932 prev_bh->b_reqnext = bh;
933 837
934 pages &= (order-1); 838 bh->b_data = kmalloc(tape->buffer_size, GFP_KERNEL);
839 if (!bh->b_data) {
840 kfree(bh);
841 return NULL;
935 } 842 }
936 843
937 bh->b_size -= tape->excess_bh_size; 844 bh->b_size = tape->buffer_size;
938 if (full) 845 atomic_set(&bh->b_count, full ? bh->b_size : 0);
939 atomic_sub(tape->excess_bh_size, &bh->b_count); 846
940 return merge_bh; 847 return bh;
941abort:
942 ide_tape_kfree_buffer(tape);
943 return NULL;
944} 848}
945 849
946static int idetape_copy_stage_from_user(idetape_tape_t *tape, 850static int idetape_copy_stage_from_user(idetape_tape_t *tape,
947 const char __user *buf, int n) 851 const char __user *buf, int n)
948{ 852{
949 struct idetape_bh *bh = tape->bh; 853 struct idetape_bh *bh = tape->bh;
950 int count;
951 int ret = 0; 854 int ret = 0;
952 855
953 while (n) { 856 if (n) {
954 if (bh == NULL) { 857 if (bh == NULL || n > bh->b_size - atomic_read(&bh->b_count)) {
955 printk(KERN_ERR "ide-tape: bh == NULL in %s\n", 858 printk(KERN_ERR "ide-tape: bh == NULL in %s\n",
956 __func__); 859 __func__);
957 return 1; 860 return 1;
958 } 861 }
959 count = min((unsigned int)
960 (bh->b_size - atomic_read(&bh->b_count)),
961 (unsigned int)n);
962 if (copy_from_user(bh->b_data + atomic_read(&bh->b_count), buf, 862 if (copy_from_user(bh->b_data + atomic_read(&bh->b_count), buf,
963 count)) 863 n))
964 ret = 1; 864 ret = 1;
965 n -= count; 865 atomic_add(n, &bh->b_count);
966 atomic_add(count, &bh->b_count); 866 if (atomic_read(&bh->b_count) == bh->b_size)
967 buf += count; 867 tape->bh = NULL;
968 if (atomic_read(&bh->b_count) == bh->b_size) {
969 bh = bh->b_reqnext;
970 if (bh)
971 atomic_set(&bh->b_count, 0);
972 }
973 } 868 }
974 tape->bh = bh; 869
975 return ret; 870 return ret;
976} 871}
977 872
@@ -979,30 +874,20 @@ static int idetape_copy_stage_to_user(idetape_tape_t *tape, char __user *buf,
979 int n) 874 int n)
980{ 875{
981 struct idetape_bh *bh = tape->bh; 876 struct idetape_bh *bh = tape->bh;
982 int count;
983 int ret = 0; 877 int ret = 0;
984 878
985 while (n) { 879 if (n) {
986 if (bh == NULL) { 880 if (bh == NULL || n > tape->b_count) {
987 printk(KERN_ERR "ide-tape: bh == NULL in %s\n", 881 printk(KERN_ERR "ide-tape: bh == NULL in %s\n",
988 __func__); 882 __func__);
989 return 1; 883 return 1;
990 } 884 }
991 count = min(tape->b_count, n); 885 if (copy_to_user(buf, tape->b_data, n))
992 if (copy_to_user(buf, tape->b_data, count))
993 ret = 1; 886 ret = 1;
994 n -= count; 887 tape->b_data += n;
995 tape->b_data += count; 888 tape->b_count -= n;
996 tape->b_count -= count; 889 if (!tape->b_count)
997 buf += count; 890 tape->bh = NULL;
998 if (!tape->b_count) {
999 bh = bh->b_reqnext;
1000 tape->bh = bh;
1001 if (bh) {
1002 tape->b_data = bh->b_data;
1003 tape->b_count = atomic_read(&bh->b_count);
1004 }
1005 }
1006 } 891 }
1007 return ret; 892 return ret;
1008} 893}
@@ -1254,7 +1139,7 @@ static int idetape_add_chrdev_write_request(ide_drive_t *drive, int blocks)
1254static void ide_tape_flush_merge_buffer(ide_drive_t *drive) 1139static void ide_tape_flush_merge_buffer(ide_drive_t *drive)
1255{ 1140{
1256 idetape_tape_t *tape = drive->driver_data; 1141 idetape_tape_t *tape = drive->driver_data;
1257 int blocks, min; 1142 int blocks;
1258 struct idetape_bh *bh; 1143 struct idetape_bh *bh;
1259 1144
1260 if (tape->chrdev_dir != IDETAPE_DIR_WRITE) { 1145 if (tape->chrdev_dir != IDETAPE_DIR_WRITE) {
@@ -1269,31 +1154,16 @@ static void ide_tape_flush_merge_buffer(ide_drive_t *drive)
1269 if (tape->merge_bh_size) { 1154 if (tape->merge_bh_size) {
1270 blocks = tape->merge_bh_size / tape->blk_size; 1155 blocks = tape->merge_bh_size / tape->blk_size;
1271 if (tape->merge_bh_size % tape->blk_size) { 1156 if (tape->merge_bh_size % tape->blk_size) {
1272 unsigned int i; 1157 unsigned int i = tape->blk_size -
1273 1158 tape->merge_bh_size % tape->blk_size;
1274 blocks++; 1159 blocks++;
1275 i = tape->blk_size - tape->merge_bh_size %
1276 tape->blk_size;
1277 bh = tape->bh->b_reqnext;
1278 while (bh) {
1279 atomic_set(&bh->b_count, 0);
1280 bh = bh->b_reqnext;
1281 }
1282 bh = tape->bh; 1160 bh = tape->bh;
1283 while (i) { 1161 if (bh) {
1284 if (bh == NULL) {
1285 printk(KERN_INFO "ide-tape: bug,"
1286 " bh NULL\n");
1287 break;
1288 }
1289 min = min(i, (unsigned int)(bh->b_size -
1290 atomic_read(&bh->b_count)));
1291 memset(bh->b_data + atomic_read(&bh->b_count), 1162 memset(bh->b_data + atomic_read(&bh->b_count),
1292 0, min); 1163 0, i);
1293 atomic_add(min, &bh->b_count); 1164 atomic_add(i, &bh->b_count);
1294 i -= min; 1165 } else
1295 bh = bh->b_reqnext; 1166 printk(KERN_INFO "ide-tape: bug, bh NULL\n");
1296 }
1297 } 1167 }
1298 (void) idetape_add_chrdev_write_request(drive, blocks); 1168 (void) idetape_add_chrdev_write_request(drive, blocks);
1299 tape->merge_bh_size = 0; 1169 tape->merge_bh_size = 0;
@@ -1321,7 +1191,7 @@ static int idetape_init_read(ide_drive_t *drive)
1321 " 0 now\n"); 1191 " 0 now\n");
1322 tape->merge_bh_size = 0; 1192 tape->merge_bh_size = 0;
1323 } 1193 }
1324 tape->merge_bh = ide_tape_kmalloc_buffer(tape, 0, 0); 1194 tape->merge_bh = ide_tape_kmalloc_buffer(tape, 0);
1325 if (!tape->merge_bh) 1195 if (!tape->merge_bh)
1326 return -ENOMEM; 1196 return -ENOMEM;
1327 tape->chrdev_dir = IDETAPE_DIR_READ; 1197 tape->chrdev_dir = IDETAPE_DIR_READ;
@@ -1368,23 +1238,18 @@ static int idetape_add_chrdev_read_request(ide_drive_t *drive, int blocks)
1368static void idetape_pad_zeros(ide_drive_t *drive, int bcount) 1238static void idetape_pad_zeros(ide_drive_t *drive, int bcount)
1369{ 1239{
1370 idetape_tape_t *tape = drive->driver_data; 1240 idetape_tape_t *tape = drive->driver_data;
1371 struct idetape_bh *bh; 1241 struct idetape_bh *bh = tape->merge_bh;
1372 int blocks; 1242 int blocks;
1373 1243
1374 while (bcount) { 1244 while (bcount) {
1375 unsigned int count; 1245 unsigned int count;
1376 1246
1377 bh = tape->merge_bh;
1378 count = min(tape->buffer_size, bcount); 1247 count = min(tape->buffer_size, bcount);
1379 bcount -= count; 1248 bcount -= count;
1380 blocks = count / tape->blk_size; 1249 blocks = count / tape->blk_size;
1381 while (count) { 1250 atomic_set(&bh->b_count, count);
1382 atomic_set(&bh->b_count, 1251 memset(bh->b_data, 0, atomic_read(&bh->b_count));
1383 min(count, (unsigned int)bh->b_size)); 1252
1384 memset(bh->b_data, 0, atomic_read(&bh->b_count));
1385 count -= atomic_read(&bh->b_count);
1386 bh = bh->b_reqnext;
1387 }
1388 idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, blocks, 1253 idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, blocks,
1389 tape->merge_bh); 1254 tape->merge_bh);
1390 } 1255 }
@@ -1596,7 +1461,7 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf,
1596 "should be 0 now\n"); 1461 "should be 0 now\n");
1597 tape->merge_bh_size = 0; 1462 tape->merge_bh_size = 0;
1598 } 1463 }
1599 tape->merge_bh = ide_tape_kmalloc_buffer(tape, 0, 0); 1464 tape->merge_bh = ide_tape_kmalloc_buffer(tape, 0);
1600 if (!tape->merge_bh) 1465 if (!tape->merge_bh)
1601 return -ENOMEM; 1466 return -ENOMEM;
1602 tape->chrdev_dir = IDETAPE_DIR_WRITE; 1467 tape->chrdev_dir = IDETAPE_DIR_WRITE;
@@ -1970,7 +1835,7 @@ static void idetape_write_release(ide_drive_t *drive, unsigned int minor)
1970 idetape_tape_t *tape = drive->driver_data; 1835 idetape_tape_t *tape = drive->driver_data;
1971 1836
1972 ide_tape_flush_merge_buffer(drive); 1837 ide_tape_flush_merge_buffer(drive);
1973 tape->merge_bh = ide_tape_kmalloc_buffer(tape, 1, 0); 1838 tape->merge_bh = ide_tape_kmalloc_buffer(tape, 1);
1974 if (tape->merge_bh != NULL) { 1839 if (tape->merge_bh != NULL) {
1975 idetape_pad_zeros(drive, tape->blk_size * 1840 idetape_pad_zeros(drive, tape->blk_size *
1976 (tape->user_bs_factor - 1)); 1841 (tape->user_bs_factor - 1));
@@ -2201,11 +2066,6 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor)
2201 tape->buffer_size = *ctl * tape->blk_size; 2066 tape->buffer_size = *ctl * tape->blk_size;
2202 } 2067 }
2203 buffer_size = tape->buffer_size; 2068 buffer_size = tape->buffer_size;
2204 tape->pages_per_buffer = buffer_size / PAGE_SIZE;
2205 if (buffer_size % PAGE_SIZE) {
2206 tape->pages_per_buffer++;
2207 tape->excess_bh_size = PAGE_SIZE - buffer_size % PAGE_SIZE;
2208 }
2209 2069
2210 /* select the "best" DSC read/write polling freq */ 2070 /* select the "best" DSC read/write polling freq */
2211 speed = max(*(u16 *)&tape->caps[14], *(u16 *)&tape->caps[8]); 2071 speed = max(*(u16 *)&tape->caps[14], *(u16 *)&tape->caps[8]);