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.c161
1 files changed, 67 insertions, 94 deletions
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index bb450a7608c2..cb942a9b580f 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -152,11 +152,6 @@ struct idetape_bh {
152#define IDETAPE_LU_RETENSION_MASK 2 152#define IDETAPE_LU_RETENSION_MASK 2
153#define IDETAPE_LU_EOT_MASK 4 153#define IDETAPE_LU_EOT_MASK 4
154 154
155/* Error codes returned in rq->errors to the higher part of the driver. */
156#define IDETAPE_ERROR_GENERAL 101
157#define IDETAPE_ERROR_FILEMARK 102
158#define IDETAPE_ERROR_EOD 103
159
160/* Structures related to the SELECT SENSE / MODE SENSE packet commands. */ 155/* Structures related to the SELECT SENSE / MODE SENSE packet commands. */
161#define IDETAPE_BLOCK_DESCRIPTOR 0 156#define IDETAPE_BLOCK_DESCRIPTOR 0
162#define IDETAPE_CAPABILITIES_PAGE 0x2a 157#define IDETAPE_CAPABILITIES_PAGE 0x2a
@@ -171,14 +166,6 @@ typedef struct ide_tape_obj {
171 struct gendisk *disk; 166 struct gendisk *disk;
172 struct device dev; 167 struct device dev;
173 168
174 /*
175 * failed_pc points to the last failed packet command, or contains
176 * NULL if we do not need to retry any packet command. This is
177 * required since an additional packet command is needed before the
178 * retry, to get detailed information on what went wrong.
179 */
180 /* Last failed packet command */
181 struct ide_atapi_pc *failed_pc;
182 /* used by REQ_IDETAPE_{READ,WRITE} requests */ 169 /* used by REQ_IDETAPE_{READ,WRITE} requests */
183 struct ide_atapi_pc queued_pc; 170 struct ide_atapi_pc queued_pc;
184 171
@@ -245,9 +232,6 @@ typedef struct ide_tape_obj {
245 /* Wasted space in each stage */ 232 /* Wasted space in each stage */
246 int excess_bh_size; 233 int excess_bh_size;
247 234
248 /* protects the ide-tape queue */
249 spinlock_t lock;
250
251 /* Measures average tape speed */ 235 /* Measures average tape speed */
252 unsigned long avg_time; 236 unsigned long avg_time;
253 int avg_size; 237 int avg_size;
@@ -313,19 +297,15 @@ static struct ide_tape_obj *ide_tape_chrdev_get(unsigned int i)
313 return tape; 297 return tape;
314} 298}
315 299
316static void idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, 300static int idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
317 unsigned int bcount) 301 unsigned int bcount)
318{ 302{
319 struct idetape_bh *bh = pc->bh; 303 struct idetape_bh *bh = pc->bh;
320 int count; 304 int count;
321 305
322 while (bcount) { 306 while (bcount) {
323 if (bh == NULL) { 307 if (bh == NULL)
324 printk(KERN_ERR "ide-tape: bh == NULL in " 308 break;
325 "idetape_input_buffers\n");
326 ide_pad_transfer(drive, 0, bcount);
327 return;
328 }
329 count = min( 309 count = min(
330 (unsigned int)(bh->b_size - atomic_read(&bh->b_count)), 310 (unsigned int)(bh->b_size - atomic_read(&bh->b_count)),
331 bcount); 311 bcount);
@@ -339,21 +319,21 @@ static void idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
339 atomic_set(&bh->b_count, 0); 319 atomic_set(&bh->b_count, 0);
340 } 320 }
341 } 321 }
322
342 pc->bh = bh; 323 pc->bh = bh;
324
325 return bcount;
343} 326}
344 327
345static void idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, 328static int idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
346 unsigned int bcount) 329 unsigned int bcount)
347{ 330{
348 struct idetape_bh *bh = pc->bh; 331 struct idetape_bh *bh = pc->bh;
349 int count; 332 int count;
350 333
351 while (bcount) { 334 while (bcount) {
352 if (bh == NULL) { 335 if (bh == NULL)
353 printk(KERN_ERR "ide-tape: bh == NULL in %s\n", 336 break;
354 __func__);
355 return;
356 }
357 count = min((unsigned int)pc->b_count, (unsigned int)bcount); 337 count = min((unsigned int)pc->b_count, (unsigned int)bcount);
358 drive->hwif->tp_ops->output_data(drive, NULL, pc->b_data, count); 338 drive->hwif->tp_ops->output_data(drive, NULL, pc->b_data, count);
359 bcount -= count; 339 bcount -= count;
@@ -368,6 +348,8 @@ static void idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
368 } 348 }
369 } 349 }
370 } 350 }
351
352 return bcount;
371} 353}
372 354
373static void idetape_update_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc) 355static void idetape_update_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc)
@@ -400,7 +382,7 @@ static void idetape_update_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc)
400static void idetape_analyze_error(ide_drive_t *drive, u8 *sense) 382static void idetape_analyze_error(ide_drive_t *drive, u8 *sense)
401{ 383{
402 idetape_tape_t *tape = drive->driver_data; 384 idetape_tape_t *tape = drive->driver_data;
403 struct ide_atapi_pc *pc = tape->failed_pc; 385 struct ide_atapi_pc *pc = drive->failed_pc;
404 386
405 tape->sense_key = sense[2] & 0xF; 387 tape->sense_key = sense[2] & 0xF;
406 tape->asc = sense[12]; 388 tape->asc = sense[12];
@@ -433,19 +415,19 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense)
433 } 415 }
434 } 416 }
435 if (pc->c[0] == READ_6 && (sense[2] & 0x80)) { 417 if (pc->c[0] == READ_6 && (sense[2] & 0x80)) {
436 pc->error = IDETAPE_ERROR_FILEMARK; 418 pc->error = IDE_DRV_ERROR_FILEMARK;
437 pc->flags |= PC_FLAG_ABORT; 419 pc->flags |= PC_FLAG_ABORT;
438 } 420 }
439 if (pc->c[0] == WRITE_6) { 421 if (pc->c[0] == WRITE_6) {
440 if ((sense[2] & 0x40) || (tape->sense_key == 0xd 422 if ((sense[2] & 0x40) || (tape->sense_key == 0xd
441 && tape->asc == 0x0 && tape->ascq == 0x2)) { 423 && tape->asc == 0x0 && tape->ascq == 0x2)) {
442 pc->error = IDETAPE_ERROR_EOD; 424 pc->error = IDE_DRV_ERROR_EOD;
443 pc->flags |= PC_FLAG_ABORT; 425 pc->flags |= PC_FLAG_ABORT;
444 } 426 }
445 } 427 }
446 if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) { 428 if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) {
447 if (tape->sense_key == 8) { 429 if (tape->sense_key == 8) {
448 pc->error = IDETAPE_ERROR_EOD; 430 pc->error = IDE_DRV_ERROR_EOD;
449 pc->flags |= PC_FLAG_ABORT; 431 pc->flags |= PC_FLAG_ABORT;
450 } 432 }
451 if (!(pc->flags & PC_FLAG_ABORT) && 433 if (!(pc->flags & PC_FLAG_ABORT) &&
@@ -477,52 +459,23 @@ static void ide_tape_kfree_buffer(idetape_tape_t *tape)
477 } 459 }
478} 460}
479 461
480static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects)
481{
482 struct request *rq = drive->hwif->rq;
483 idetape_tape_t *tape = drive->driver_data;
484 unsigned long flags;
485 int error;
486
487 debug_log(DBG_PROCS, "Enter %s\n", __func__);
488
489 switch (uptodate) {
490 case 0: error = IDETAPE_ERROR_GENERAL; break;
491 case 1: error = 0; break;
492 default: error = uptodate;
493 }
494 rq->errors = error;
495 if (error)
496 tape->failed_pc = NULL;
497
498 if (!blk_special_request(rq)) {
499 ide_end_request(drive, uptodate, nr_sects);
500 return 0;
501 }
502
503 spin_lock_irqsave(&tape->lock, flags);
504
505 ide_end_drive_cmd(drive, 0, 0);
506
507 spin_unlock_irqrestore(&tape->lock, flags);
508 return 0;
509}
510
511static void ide_tape_handle_dsc(ide_drive_t *); 462static void ide_tape_handle_dsc(ide_drive_t *);
512 463
513static void ide_tape_callback(ide_drive_t *drive, int dsc) 464static int ide_tape_callback(ide_drive_t *drive, int dsc)
514{ 465{
515 idetape_tape_t *tape = drive->driver_data; 466 idetape_tape_t *tape = drive->driver_data;
516 struct ide_atapi_pc *pc = drive->pc; 467 struct ide_atapi_pc *pc = drive->pc;
468 struct request *rq = drive->hwif->rq;
517 int uptodate = pc->error ? 0 : 1; 469 int uptodate = pc->error ? 0 : 1;
470 int err = uptodate ? 0 : IDE_DRV_ERROR_GENERAL;
518 471
519 debug_log(DBG_PROCS, "Enter %s\n", __func__); 472 debug_log(DBG_PROCS, "Enter %s\n", __func__);
520 473
521 if (dsc) 474 if (dsc)
522 ide_tape_handle_dsc(drive); 475 ide_tape_handle_dsc(drive);
523 476
524 if (tape->failed_pc == pc) 477 if (drive->failed_pc == pc)
525 tape->failed_pc = NULL; 478 drive->failed_pc = NULL;
526 479
527 if (pc->c[0] == REQUEST_SENSE) { 480 if (pc->c[0] == REQUEST_SENSE) {
528 if (uptodate) 481 if (uptodate)
@@ -531,7 +484,6 @@ static void ide_tape_callback(ide_drive_t *drive, int dsc)
531 printk(KERN_ERR "ide-tape: Error in REQUEST SENSE " 484 printk(KERN_ERR "ide-tape: Error in REQUEST SENSE "
532 "itself - Aborting request!\n"); 485 "itself - Aborting request!\n");
533 } else if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) { 486 } else if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) {
534 struct request *rq = drive->hwif->rq;
535 int blocks = pc->xferred / tape->blk_size; 487 int blocks = pc->xferred / tape->blk_size;
536 488
537 tape->avg_size += blocks * tape->blk_size; 489 tape->avg_size += blocks * tape->blk_size;
@@ -546,8 +498,10 @@ static void ide_tape_callback(ide_drive_t *drive, int dsc)
546 tape->first_frame += blocks; 498 tape->first_frame += blocks;
547 rq->current_nr_sectors -= blocks; 499 rq->current_nr_sectors -= blocks;
548 500
549 if (pc->error) 501 if (pc->error) {
550 uptodate = pc->error; 502 uptodate = 0;
503 err = pc->error;
504 }
551 } else if (pc->c[0] == READ_POSITION && uptodate) { 505 } else if (pc->c[0] == READ_POSITION && uptodate) {
552 u8 *readpos = pc->buf; 506 u8 *readpos = pc->buf;
553 507
@@ -561,6 +515,7 @@ static void ide_tape_callback(ide_drive_t *drive, int dsc)
561 "to the tape\n"); 515 "to the tape\n");
562 clear_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags); 516 clear_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags);
563 uptodate = 0; 517 uptodate = 0;
518 err = IDE_DRV_ERROR_GENERAL;
564 } else { 519 } else {
565 debug_log(DBG_SENSE, "Block Location - %u\n", 520 debug_log(DBG_SENSE, "Block Location - %u\n",
566 be32_to_cpup((__be32 *)&readpos[4])); 521 be32_to_cpup((__be32 *)&readpos[4]));
@@ -571,7 +526,9 @@ static void ide_tape_callback(ide_drive_t *drive, int dsc)
571 } 526 }
572 } 527 }
573 528
574 idetape_end_request(drive, uptodate, 0); 529 rq->errors = err;
530
531 return uptodate;
575} 532}
576 533
577/* 534/*
@@ -604,12 +561,14 @@ static void ide_tape_handle_dsc(ide_drive_t *drive)
604static int ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, 561static int ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
605 unsigned int bcount, int write) 562 unsigned int bcount, int write)
606{ 563{
564 unsigned int bleft;
565
607 if (write) 566 if (write)
608 idetape_output_buffers(drive, pc, bcount); 567 bleft = idetape_output_buffers(drive, pc, bcount);
609 else 568 else
610 idetape_input_buffers(drive, pc, bcount); 569 bleft = idetape_input_buffers(drive, pc, bcount);
611 570
612 return bcount; 571 return bcount - bleft;
613} 572}
614 573
615/* 574/*
@@ -621,7 +580,7 @@ static int ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
621 * 580 *
622 * The handling will be done in three stages: 581 * The handling will be done in three stages:
623 * 582 *
624 * 1. idetape_issue_pc will send the packet command to the drive, and will set 583 * 1. ide_tape_issue_pc will send the packet command to the drive, and will set
625 * the interrupt handler to ide_pc_intr. 584 * the interrupt handler to ide_pc_intr.
626 * 585 *
627 * 2. On each interrupt, ide_pc_intr will be called. This step will be 586 * 2. On each interrupt, ide_pc_intr will be called. This step will be
@@ -649,8 +608,9 @@ static int ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
649 * request. 608 * request.
650 */ 609 */
651 610
652static ide_startstop_t idetape_issue_pc(ide_drive_t *drive, 611static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive,
653 struct ide_atapi_pc *pc) 612 struct ide_cmd *cmd,
613 struct ide_atapi_pc *pc)
654{ 614{
655 idetape_tape_t *tape = drive->driver_data; 615 idetape_tape_t *tape = drive->driver_data;
656 616
@@ -660,8 +620,8 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,
660 "Two request sense in serial were issued\n"); 620 "Two request sense in serial were issued\n");
661 } 621 }
662 622
663 if (tape->failed_pc == NULL && pc->c[0] != REQUEST_SENSE) 623 if (drive->failed_pc == NULL && pc->c[0] != REQUEST_SENSE)
664 tape->failed_pc = pc; 624 drive->failed_pc = pc;
665 625
666 /* Set the current packet command */ 626 /* Set the current packet command */
667 drive->pc = pc; 627 drive->pc = pc;
@@ -685,9 +645,9 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,
685 tape->ascq); 645 tape->ascq);
686 } 646 }
687 /* Giving up */ 647 /* Giving up */
688 pc->error = IDETAPE_ERROR_GENERAL; 648 pc->error = IDE_DRV_ERROR_GENERAL;
689 } 649 }
690 tape->failed_pc = NULL; 650 drive->failed_pc = NULL;
691 drive->pc_callback(drive, 0); 651 drive->pc_callback(drive, 0);
692 return ide_stopped; 652 return ide_stopped;
693 } 653 }
@@ -695,7 +655,7 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,
695 655
696 pc->retries++; 656 pc->retries++;
697 657
698 return ide_issue_pc(drive); 658 return ide_issue_pc(drive, cmd);
699} 659}
700 660
701/* A mode sense command is used to "sense" tape parameters. */ 661/* A mode sense command is used to "sense" tape parameters. */
@@ -746,8 +706,8 @@ static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive)
746 } 706 }
747 pc->error = 0; 707 pc->error = 0;
748 } else { 708 } else {
749 pc->error = IDETAPE_ERROR_GENERAL; 709 pc->error = IDE_DRV_ERROR_GENERAL;
750 tape->failed_pc = NULL; 710 drive->failed_pc = NULL;
751 } 711 }
752 drive->pc_callback(drive, 0); 712 drive->pc_callback(drive, 0);
753 return ide_stopped; 713 return ide_stopped;
@@ -790,6 +750,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
790 idetape_tape_t *tape = drive->driver_data; 750 idetape_tape_t *tape = drive->driver_data;
791 struct ide_atapi_pc *pc = NULL; 751 struct ide_atapi_pc *pc = NULL;
792 struct request *postponed_rq = tape->postponed_rq; 752 struct request *postponed_rq = tape->postponed_rq;
753 struct ide_cmd cmd;
793 u8 stat; 754 u8 stat;
794 755
795 debug_log(DBG_SENSE, "sector: %llu, nr_sectors: %lu," 756 debug_log(DBG_SENSE, "sector: %llu, nr_sectors: %lu,"
@@ -801,13 +762,15 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
801 /* We do not support buffer cache originated requests. */ 762 /* We do not support buffer cache originated requests. */
802 printk(KERN_NOTICE "ide-tape: %s: Unsupported request in " 763 printk(KERN_NOTICE "ide-tape: %s: Unsupported request in "
803 "request queue (%d)\n", drive->name, rq->cmd_type); 764 "request queue (%d)\n", drive->name, rq->cmd_type);
804 ide_end_request(drive, 0, 0); 765 if (blk_fs_request(rq) == 0 && rq->errors == 0)
766 rq->errors = -EIO;
767 ide_complete_rq(drive, -EIO, ide_rq_bytes(rq));
805 return ide_stopped; 768 return ide_stopped;
806 } 769 }
807 770
808 /* Retry a failed packet command */ 771 /* Retry a failed packet command */
809 if (tape->failed_pc && drive->pc->c[0] == REQUEST_SENSE) { 772 if (drive->failed_pc && drive->pc->c[0] == REQUEST_SENSE) {
810 pc = tape->failed_pc; 773 pc = drive->failed_pc;
811 goto out; 774 goto out;
812 } 775 }
813 776
@@ -815,7 +778,9 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
815 if (rq != postponed_rq) { 778 if (rq != postponed_rq) {
816 printk(KERN_ERR "ide-tape: ide-tape.c bug - " 779 printk(KERN_ERR "ide-tape: ide-tape.c bug - "
817 "Two DSC requests were queued\n"); 780 "Two DSC requests were queued\n");
818 idetape_end_request(drive, 0, 0); 781 drive->failed_pc = NULL;
782 rq->errors = 0;
783 ide_complete_rq(drive, 0, blk_rq_bytes(rq));
819 return ide_stopped; 784 return ide_stopped;
820 } 785 }
821 786
@@ -881,7 +846,14 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
881 BUG(); 846 BUG();
882 847
883out: 848out:
884 return idetape_issue_pc(drive, pc); 849 memset(&cmd, 0, sizeof(cmd));
850
851 if (rq_data_dir(rq))
852 cmd.tf_flags |= IDE_TFLAG_WRITE;
853
854 cmd.rq = rq;
855
856 return ide_tape_issue_pc(drive, &cmd, pc);
885} 857}
886 858
887/* 859/*
@@ -1226,7 +1198,7 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks,
1226 1198
1227 if (tape->merge_bh) 1199 if (tape->merge_bh)
1228 idetape_init_merge_buffer(tape); 1200 idetape_init_merge_buffer(tape);
1229 if (errors == IDETAPE_ERROR_GENERAL) 1201 if (errors == IDE_DRV_ERROR_GENERAL)
1230 return -EIO; 1202 return -EIO;
1231 return ret; 1203 return ret;
1232} 1204}
@@ -2042,9 +2014,13 @@ static void idetape_get_inquiry_results(ide_drive_t *drive)
2042{ 2014{
2043 idetape_tape_t *tape = drive->driver_data; 2015 idetape_tape_t *tape = drive->driver_data;
2044 struct ide_atapi_pc pc; 2016 struct ide_atapi_pc pc;
2017 u8 pc_buf[256];
2045 char fw_rev[4], vendor_id[8], product_id[16]; 2018 char fw_rev[4], vendor_id[8], product_id[16];
2046 2019
2047 idetape_create_inquiry_cmd(&pc); 2020 idetape_create_inquiry_cmd(&pc);
2021 pc.buf = &pc_buf[0];
2022 pc.buf_size = sizeof(pc_buf);
2023
2048 if (ide_queue_pc_tail(drive, tape->disk, &pc)) { 2024 if (ide_queue_pc_tail(drive, tape->disk, &pc)) {
2049 printk(KERN_ERR "ide-tape: %s: can't get INQUIRY results\n", 2025 printk(KERN_ERR "ide-tape: %s: can't get INQUIRY results\n",
2050 tape->name); 2026 tape->name);
@@ -2166,7 +2142,7 @@ static const struct ide_proc_devset idetape_settings[] = {
2166 __IDE_PROC_DEVSET(speed, 0, 0xffff, NULL, NULL), 2142 __IDE_PROC_DEVSET(speed, 0, 0xffff, NULL, NULL),
2167 __IDE_PROC_DEVSET(tdsc, IDETAPE_DSC_RW_MIN, IDETAPE_DSC_RW_MAX, 2143 __IDE_PROC_DEVSET(tdsc, IDETAPE_DSC_RW_MIN, IDETAPE_DSC_RW_MAX,
2168 mulf_tdsc, divf_tdsc), 2144 mulf_tdsc, divf_tdsc),
2169 { 0 }, 2145 { NULL },
2170}; 2146};
2171#endif 2147#endif
2172 2148
@@ -2192,8 +2168,6 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor)
2192 drive->pc_update_buffers = idetape_update_buffers; 2168 drive->pc_update_buffers = idetape_update_buffers;
2193 drive->pc_io_buffers = ide_tape_io_buffers; 2169 drive->pc_io_buffers = ide_tape_io_buffers;
2194 2170
2195 spin_lock_init(&tape->lock);
2196
2197 drive->dev_flags |= IDE_DFLAG_DSC_OVERLAP; 2171 drive->dev_flags |= IDE_DFLAG_DSC_OVERLAP;
2198 2172
2199 if (drive->hwif->host_flags & IDE_HFLAG_NO_DSC) { 2173 if (drive->hwif->host_flags & IDE_HFLAG_NO_DSC) {
@@ -2325,7 +2299,6 @@ static struct ide_driver idetape_driver = {
2325 .remove = ide_tape_remove, 2299 .remove = ide_tape_remove,
2326 .version = IDETAPE_VERSION, 2300 .version = IDETAPE_VERSION,
2327 .do_request = idetape_do_request, 2301 .do_request = idetape_do_request,
2328 .end_request = idetape_end_request,
2329#ifdef CONFIG_IDE_PROC_FS 2302#ifdef CONFIG_IDE_PROC_FS
2330 .proc_entries = ide_tape_proc_entries, 2303 .proc_entries = ide_tape_proc_entries,
2331 .proc_devsets = ide_tape_proc_devsets, 2304 .proc_devsets = ide_tape_proc_devsets,