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.c123
1 files changed, 46 insertions, 77 deletions
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 4e6181c7bbda..64dfa7458f8d 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;
@@ -400,7 +384,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) 384static void idetape_analyze_error(ide_drive_t *drive, u8 *sense)
401{ 385{
402 idetape_tape_t *tape = drive->driver_data; 386 idetape_tape_t *tape = drive->driver_data;
403 struct ide_atapi_pc *pc = tape->failed_pc; 387 struct ide_atapi_pc *pc = drive->failed_pc;
404 388
405 tape->sense_key = sense[2] & 0xF; 389 tape->sense_key = sense[2] & 0xF;
406 tape->asc = sense[12]; 390 tape->asc = sense[12];
@@ -433,19 +417,19 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense)
433 } 417 }
434 } 418 }
435 if (pc->c[0] == READ_6 && (sense[2] & 0x80)) { 419 if (pc->c[0] == READ_6 && (sense[2] & 0x80)) {
436 pc->error = IDETAPE_ERROR_FILEMARK; 420 pc->error = IDE_DRV_ERROR_FILEMARK;
437 pc->flags |= PC_FLAG_ABORT; 421 pc->flags |= PC_FLAG_ABORT;
438 } 422 }
439 if (pc->c[0] == WRITE_6) { 423 if (pc->c[0] == WRITE_6) {
440 if ((sense[2] & 0x40) || (tape->sense_key == 0xd 424 if ((sense[2] & 0x40) || (tape->sense_key == 0xd
441 && tape->asc == 0x0 && tape->ascq == 0x2)) { 425 && tape->asc == 0x0 && tape->ascq == 0x2)) {
442 pc->error = IDETAPE_ERROR_EOD; 426 pc->error = IDE_DRV_ERROR_EOD;
443 pc->flags |= PC_FLAG_ABORT; 427 pc->flags |= PC_FLAG_ABORT;
444 } 428 }
445 } 429 }
446 if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) { 430 if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) {
447 if (tape->sense_key == 8) { 431 if (tape->sense_key == 8) {
448 pc->error = IDETAPE_ERROR_EOD; 432 pc->error = IDE_DRV_ERROR_EOD;
449 pc->flags |= PC_FLAG_ABORT; 433 pc->flags |= PC_FLAG_ABORT;
450 } 434 }
451 if (!(pc->flags & PC_FLAG_ABORT) && 435 if (!(pc->flags & PC_FLAG_ABORT) &&
@@ -477,52 +461,23 @@ static void ide_tape_kfree_buffer(idetape_tape_t *tape)
477 } 461 }
478} 462}
479 463
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 *); 464static void ide_tape_handle_dsc(ide_drive_t *);
512 465
513static void ide_tape_callback(ide_drive_t *drive, int dsc) 466static int ide_tape_callback(ide_drive_t *drive, int dsc)
514{ 467{
515 idetape_tape_t *tape = drive->driver_data; 468 idetape_tape_t *tape = drive->driver_data;
516 struct ide_atapi_pc *pc = drive->pc; 469 struct ide_atapi_pc *pc = drive->pc;
470 struct request *rq = drive->hwif->rq;
517 int uptodate = pc->error ? 0 : 1; 471 int uptodate = pc->error ? 0 : 1;
472 int err = uptodate ? 0 : IDE_DRV_ERROR_GENERAL;
518 473
519 debug_log(DBG_PROCS, "Enter %s\n", __func__); 474 debug_log(DBG_PROCS, "Enter %s\n", __func__);
520 475
521 if (dsc) 476 if (dsc)
522 ide_tape_handle_dsc(drive); 477 ide_tape_handle_dsc(drive);
523 478
524 if (tape->failed_pc == pc) 479 if (drive->failed_pc == pc)
525 tape->failed_pc = NULL; 480 drive->failed_pc = NULL;
526 481
527 if (pc->c[0] == REQUEST_SENSE) { 482 if (pc->c[0] == REQUEST_SENSE) {
528 if (uptodate) 483 if (uptodate)
@@ -531,7 +486,6 @@ static void ide_tape_callback(ide_drive_t *drive, int dsc)
531 printk(KERN_ERR "ide-tape: Error in REQUEST SENSE " 486 printk(KERN_ERR "ide-tape: Error in REQUEST SENSE "
532 "itself - Aborting request!\n"); 487 "itself - Aborting request!\n");
533 } else if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) { 488 } 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; 489 int blocks = pc->xferred / tape->blk_size;
536 490
537 tape->avg_size += blocks * tape->blk_size; 491 tape->avg_size += blocks * tape->blk_size;
@@ -546,8 +500,10 @@ static void ide_tape_callback(ide_drive_t *drive, int dsc)
546 tape->first_frame += blocks; 500 tape->first_frame += blocks;
547 rq->current_nr_sectors -= blocks; 501 rq->current_nr_sectors -= blocks;
548 502
549 if (pc->error) 503 if (pc->error) {
550 uptodate = pc->error; 504 uptodate = 0;
505 err = pc->error;
506 }
551 } else if (pc->c[0] == READ_POSITION && uptodate) { 507 } else if (pc->c[0] == READ_POSITION && uptodate) {
552 u8 *readpos = pc->buf; 508 u8 *readpos = pc->buf;
553 509
@@ -561,6 +517,7 @@ static void ide_tape_callback(ide_drive_t *drive, int dsc)
561 "to the tape\n"); 517 "to the tape\n");
562 clear_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags); 518 clear_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags);
563 uptodate = 0; 519 uptodate = 0;
520 err = IDE_DRV_ERROR_GENERAL;
564 } else { 521 } else {
565 debug_log(DBG_SENSE, "Block Location - %u\n", 522 debug_log(DBG_SENSE, "Block Location - %u\n",
566 be32_to_cpup((__be32 *)&readpos[4])); 523 be32_to_cpup((__be32 *)&readpos[4]));
@@ -571,7 +528,9 @@ static void ide_tape_callback(ide_drive_t *drive, int dsc)
571 } 528 }
572 } 529 }
573 530
574 idetape_end_request(drive, uptodate, 0); 531 rq->errors = err;
532
533 return uptodate;
575} 534}
576 535
577/* 536/*
@@ -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}
@@ -2192,8 +2164,6 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor)
2192 drive->pc_update_buffers = idetape_update_buffers; 2164 drive->pc_update_buffers = idetape_update_buffers;
2193 drive->pc_io_buffers = ide_tape_io_buffers; 2165 drive->pc_io_buffers = ide_tape_io_buffers;
2194 2166
2195 spin_lock_init(&tape->lock);
2196
2197 drive->dev_flags |= IDE_DFLAG_DSC_OVERLAP; 2167 drive->dev_flags |= IDE_DFLAG_DSC_OVERLAP;
2198 2168
2199 if (drive->hwif->host_flags & IDE_HFLAG_NO_DSC) { 2169 if (drive->hwif->host_flags & IDE_HFLAG_NO_DSC) {
@@ -2325,7 +2295,6 @@ static struct ide_driver idetape_driver = {
2325 .remove = ide_tape_remove, 2295 .remove = ide_tape_remove,
2326 .version = IDETAPE_VERSION, 2296 .version = IDETAPE_VERSION,
2327 .do_request = idetape_do_request, 2297 .do_request = idetape_do_request,
2328 .end_request = idetape_end_request,
2329#ifdef CONFIG_IDE_PROC_FS 2298#ifdef CONFIG_IDE_PROC_FS
2330 .proc_entries = ide_tape_proc_entries, 2299 .proc_entries = ide_tape_proc_entries,
2331 .proc_devsets = ide_tape_proc_devsets, 2300 .proc_devsets = ide_tape_proc_devsets,