diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-15 14:15:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-15 14:15:36 -0400 |
commit | 98339cbd360b77c3167db287fd611468c2c44559 (patch) | |
tree | 06779e040c18aa40fc5a6e15b132fa1f70ec45f6 /drivers/ide/ide-tape.c | |
parent | e4e0fadcd929138aa82130a1c5f22206d86d7bb2 (diff) | |
parent | cbbc4e818de4451cdef75a112b7fc8a523d5d2a0 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6: (80 commits)
ide-floppy: fix unfortunate function naming
ide-tape: unify idetape_create_read/write_cmd
ide: add ide_pc_intr() helper
ide-{floppy,scsi}: read Status Register before stopping DMA engine
ide-scsi: add more debugging to idescsi_pc_intr()
ide-scsi: use pc->callback
ide-floppy: add more debugging to idefloppy_pc_intr()
ide-tape: always log debug info in idetape_pc_intr() if debugging is enabled
ide-tape: add ide_tape_io_buffers() helper
ide-tape: factor out DSC handling from idetape_pc_intr()
ide-{floppy,tape}: move checking of ->failed_pc to ->callback
ide: add ide_issue_pc() helper
ide: add PC_FLAG_DRQ_INTERRUPT pc flag
ide-scsi: move idescsi_map_sg() call out from idescsi_issue_pc()
ide: add ide_transfer_pc() helper
ide-scsi: set drive->scsi flag for devices handled by the driver
ide-{cd,floppy,tape}: remove checking for drive->scsi
ide: add PC_FLAG_ZIP_DRIVE pc flag
ide-tape: factor out waiting for good ireason from idetape_transfer_pc()
ide-tape: set PC_FLAG_DMA_IN_PROGRESS flag in idetape_transfer_pc()
...
Diffstat (limited to 'drivers/ide/ide-tape.c')
-rw-r--r-- | drivers/ide/ide-tape.c | 561 |
1 files changed, 158 insertions, 403 deletions
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index a3d228302d20..f9cf1670e4e1 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c | |||
@@ -144,9 +144,6 @@ enum { | |||
144 | 144 | ||
145 | /*************************** End of tunable parameters ***********************/ | 145 | /*************************** End of tunable parameters ***********************/ |
146 | 146 | ||
147 | /* Read/Write error simulation */ | ||
148 | #define SIMULATE_ERRORS 0 | ||
149 | |||
150 | /* tape directions */ | 147 | /* tape directions */ |
151 | enum { | 148 | enum { |
152 | IDETAPE_DIR_NONE = (1 << 0), | 149 | IDETAPE_DIR_NONE = (1 << 0), |
@@ -442,7 +439,7 @@ static void idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, | |||
442 | } | 439 | } |
443 | } | 440 | } |
444 | 441 | ||
445 | static void idetape_update_buffers(struct ide_atapi_pc *pc) | 442 | static void idetape_update_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc) |
446 | { | 443 | { |
447 | struct idetape_bh *bh = pc->bh; | 444 | struct idetape_bh *bh = pc->bh; |
448 | int count; | 445 | int count; |
@@ -506,18 +503,6 @@ static struct request *idetape_next_rq_storage(ide_drive_t *drive) | |||
506 | return (&tape->rq_stack[tape->rq_stack_index++]); | 503 | return (&tape->rq_stack[tape->rq_stack_index++]); |
507 | } | 504 | } |
508 | 505 | ||
509 | static void idetape_init_pc(struct ide_atapi_pc *pc) | ||
510 | { | ||
511 | memset(pc->c, 0, 12); | ||
512 | pc->retries = 0; | ||
513 | pc->flags = 0; | ||
514 | pc->req_xfer = 0; | ||
515 | pc->buf = pc->pc_buf; | ||
516 | pc->buf_size = IDETAPE_PC_BUFFER_SIZE; | ||
517 | pc->bh = NULL; | ||
518 | pc->b_data = NULL; | ||
519 | } | ||
520 | |||
521 | /* | 506 | /* |
522 | * called on each failed packet command retry to analyze the request sense. We | 507 | * called on each failed packet command retry to analyze the request sense. We |
523 | * currently do not utilize this information. | 508 | * currently do not utilize this information. |
@@ -538,8 +523,8 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense) | |||
538 | if (pc->flags & PC_FLAG_DMA_ERROR) { | 523 | if (pc->flags & PC_FLAG_DMA_ERROR) { |
539 | pc->xferred = pc->req_xfer - | 524 | pc->xferred = pc->req_xfer - |
540 | tape->blk_size * | 525 | tape->blk_size * |
541 | be32_to_cpu(get_unaligned((u32 *)&sense[3])); | 526 | get_unaligned_be32(&sense[3]); |
542 | idetape_update_buffers(pc); | 527 | idetape_update_buffers(drive, pc); |
543 | } | 528 | } |
544 | 529 | ||
545 | /* | 530 | /* |
@@ -634,21 +619,78 @@ static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects) | |||
634 | return 0; | 619 | return 0; |
635 | } | 620 | } |
636 | 621 | ||
637 | static ide_startstop_t idetape_request_sense_callback(ide_drive_t *drive) | 622 | static void ide_tape_callback(ide_drive_t *drive) |
638 | { | 623 | { |
639 | idetape_tape_t *tape = drive->driver_data; | 624 | idetape_tape_t *tape = drive->driver_data; |
625 | struct ide_atapi_pc *pc = tape->pc; | ||
626 | int uptodate = pc->error ? 0 : 1; | ||
640 | 627 | ||
641 | debug_log(DBG_PROCS, "Enter %s\n", __func__); | 628 | debug_log(DBG_PROCS, "Enter %s\n", __func__); |
642 | 629 | ||
643 | if (!tape->pc->error) { | 630 | if (tape->failed_pc == pc) |
644 | idetape_analyze_error(drive, tape->pc->buf); | 631 | tape->failed_pc = NULL; |
645 | idetape_end_request(drive, 1, 0); | 632 | |
646 | } else { | 633 | if (pc->c[0] == REQUEST_SENSE) { |
647 | printk(KERN_ERR "ide-tape: Error in REQUEST SENSE itself - " | 634 | if (uptodate) |
648 | "Aborting request!\n"); | 635 | idetape_analyze_error(drive, pc->buf); |
649 | idetape_end_request(drive, 0, 0); | 636 | else |
637 | printk(KERN_ERR "ide-tape: Error in REQUEST SENSE " | ||
638 | "itself - Aborting request!\n"); | ||
639 | } else if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) { | ||
640 | struct request *rq = drive->hwif->hwgroup->rq; | ||
641 | int blocks = pc->xferred / tape->blk_size; | ||
642 | |||
643 | tape->avg_size += blocks * tape->blk_size; | ||
644 | |||
645 | if (time_after_eq(jiffies, tape->avg_time + HZ)) { | ||
646 | tape->avg_speed = tape->avg_size * HZ / | ||
647 | (jiffies - tape->avg_time) / 1024; | ||
648 | tape->avg_size = 0; | ||
649 | tape->avg_time = jiffies; | ||
650 | } | ||
651 | |||
652 | tape->first_frame += blocks; | ||
653 | rq->current_nr_sectors -= blocks; | ||
654 | |||
655 | if (pc->error) | ||
656 | uptodate = pc->error; | ||
657 | } else if (pc->c[0] == READ_POSITION && uptodate) { | ||
658 | u8 *readpos = tape->pc->buf; | ||
659 | |||
660 | debug_log(DBG_SENSE, "BOP - %s\n", | ||
661 | (readpos[0] & 0x80) ? "Yes" : "No"); | ||
662 | debug_log(DBG_SENSE, "EOP - %s\n", | ||
663 | (readpos[0] & 0x40) ? "Yes" : "No"); | ||
664 | |||
665 | if (readpos[0] & 0x4) { | ||
666 | printk(KERN_INFO "ide-tape: Block location is unknown" | ||
667 | "to the tape\n"); | ||
668 | clear_bit(IDETAPE_FLAG_ADDRESS_VALID, &tape->flags); | ||
669 | uptodate = 0; | ||
670 | } else { | ||
671 | debug_log(DBG_SENSE, "Block Location - %u\n", | ||
672 | be32_to_cpu(*(u32 *)&readpos[4])); | ||
673 | |||
674 | tape->partition = readpos[1]; | ||
675 | tape->first_frame = be32_to_cpu(*(u32 *)&readpos[4]); | ||
676 | set_bit(IDETAPE_FLAG_ADDRESS_VALID, &tape->flags); | ||
677 | } | ||
650 | } | 678 | } |
651 | return ide_stopped; | 679 | |
680 | idetape_end_request(drive, uptodate, 0); | ||
681 | } | ||
682 | |||
683 | static void idetape_init_pc(struct ide_atapi_pc *pc) | ||
684 | { | ||
685 | memset(pc->c, 0, 12); | ||
686 | pc->retries = 0; | ||
687 | pc->flags = 0; | ||
688 | pc->req_xfer = 0; | ||
689 | pc->buf = pc->pc_buf; | ||
690 | pc->buf_size = IDETAPE_PC_BUFFER_SIZE; | ||
691 | pc->bh = NULL; | ||
692 | pc->b_data = NULL; | ||
693 | pc->callback = ide_tape_callback; | ||
652 | } | 694 | } |
653 | 695 | ||
654 | static void idetape_create_request_sense_cmd(struct ide_atapi_pc *pc) | 696 | static void idetape_create_request_sense_cmd(struct ide_atapi_pc *pc) |
@@ -657,7 +699,6 @@ static void idetape_create_request_sense_cmd(struct ide_atapi_pc *pc) | |||
657 | pc->c[0] = REQUEST_SENSE; | 699 | pc->c[0] = REQUEST_SENSE; |
658 | pc->c[4] = 20; | 700 | pc->c[4] = 20; |
659 | pc->req_xfer = 20; | 701 | pc->req_xfer = 20; |
660 | pc->idetape_callback = &idetape_request_sense_callback; | ||
661 | } | 702 | } |
662 | 703 | ||
663 | static void idetape_init_rq(struct request *rq, u8 cmd) | 704 | static void idetape_init_rq(struct request *rq, u8 cmd) |
@@ -688,9 +729,10 @@ static void idetape_queue_pc_head(ide_drive_t *drive, struct ide_atapi_pc *pc, | |||
688 | struct ide_tape_obj *tape = drive->driver_data; | 729 | struct ide_tape_obj *tape = drive->driver_data; |
689 | 730 | ||
690 | idetape_init_rq(rq, REQ_IDETAPE_PC1); | 731 | idetape_init_rq(rq, REQ_IDETAPE_PC1); |
732 | rq->cmd_flags |= REQ_PREEMPT; | ||
691 | rq->buffer = (char *) pc; | 733 | rq->buffer = (char *) pc; |
692 | rq->rq_disk = tape->disk; | 734 | rq->rq_disk = tape->disk; |
693 | (void) ide_do_drive_cmd(drive, rq, ide_preempt); | 735 | ide_do_drive_cmd(drive, rq); |
694 | } | 736 | } |
695 | 737 | ||
696 | /* | 738 | /* |
@@ -698,7 +740,7 @@ static void idetape_queue_pc_head(ide_drive_t *drive, struct ide_atapi_pc *pc, | |||
698 | * last packet command. We queue a request sense packet command in | 740 | * last packet command. We queue a request sense packet command in |
699 | * the head of the request list. | 741 | * the head of the request list. |
700 | */ | 742 | */ |
701 | static ide_startstop_t idetape_retry_pc (ide_drive_t *drive) | 743 | static void idetape_retry_pc(ide_drive_t *drive) |
702 | { | 744 | { |
703 | idetape_tape_t *tape = drive->driver_data; | 745 | idetape_tape_t *tape = drive->driver_data; |
704 | struct ide_atapi_pc *pc; | 746 | struct ide_atapi_pc *pc; |
@@ -710,7 +752,6 @@ static ide_startstop_t idetape_retry_pc (ide_drive_t *drive) | |||
710 | idetape_create_request_sense_cmd(pc); | 752 | idetape_create_request_sense_cmd(pc); |
711 | set_bit(IDETAPE_FLAG_IGNORE_DSC, &tape->flags); | 753 | set_bit(IDETAPE_FLAG_IGNORE_DSC, &tape->flags); |
712 | idetape_queue_pc_head(drive, pc, rq); | 754 | idetape_queue_pc_head(drive, pc, rq); |
713 | return ide_stopped; | ||
714 | } | 755 | } |
715 | 756 | ||
716 | /* | 757 | /* |
@@ -727,7 +768,26 @@ static void idetape_postpone_request(ide_drive_t *drive) | |||
727 | ide_stall_queue(drive, tape->dsc_poll_freq); | 768 | ide_stall_queue(drive, tape->dsc_poll_freq); |
728 | } | 769 | } |
729 | 770 | ||
730 | typedef void idetape_io_buf(ide_drive_t *, struct ide_atapi_pc *, unsigned int); | 771 | static void ide_tape_handle_dsc(ide_drive_t *drive) |
772 | { | ||
773 | idetape_tape_t *tape = drive->driver_data; | ||
774 | |||
775 | /* Media access command */ | ||
776 | tape->dsc_polling_start = jiffies; | ||
777 | tape->dsc_poll_freq = IDETAPE_DSC_MA_FAST; | ||
778 | tape->dsc_timeout = jiffies + IDETAPE_DSC_MA_TIMEOUT; | ||
779 | /* Allow ide.c to handle other requests */ | ||
780 | idetape_postpone_request(drive); | ||
781 | } | ||
782 | |||
783 | static void ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, | ||
784 | unsigned int bcount, int write) | ||
785 | { | ||
786 | if (write) | ||
787 | idetape_output_buffers(drive, pc, bcount); | ||
788 | else | ||
789 | idetape_input_buffers(drive, pc, bcount); | ||
790 | } | ||
731 | 791 | ||
732 | /* | 792 | /* |
733 | * This is the usual interrupt handler which will be called during a packet | 793 | * This is the usual interrupt handler which will be called during a packet |
@@ -738,169 +798,11 @@ typedef void idetape_io_buf(ide_drive_t *, struct ide_atapi_pc *, unsigned int); | |||
738 | */ | 798 | */ |
739 | static ide_startstop_t idetape_pc_intr(ide_drive_t *drive) | 799 | static ide_startstop_t idetape_pc_intr(ide_drive_t *drive) |
740 | { | 800 | { |
741 | ide_hwif_t *hwif = drive->hwif; | ||
742 | idetape_tape_t *tape = drive->driver_data; | 801 | idetape_tape_t *tape = drive->driver_data; |
743 | struct ide_atapi_pc *pc = tape->pc; | ||
744 | xfer_func_t *xferfunc; | ||
745 | idetape_io_buf *iobuf; | ||
746 | unsigned int temp; | ||
747 | #if SIMULATE_ERRORS | ||
748 | static int error_sim_count; | ||
749 | #endif | ||
750 | u16 bcount; | ||
751 | u8 stat, ireason; | ||
752 | |||
753 | debug_log(DBG_PROCS, "Enter %s - interrupt handler\n", __func__); | ||
754 | |||
755 | /* Clear the interrupt */ | ||
756 | stat = ide_read_status(drive); | ||
757 | |||
758 | if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { | ||
759 | if (hwif->dma_ops->dma_end(drive) || (stat & ERR_STAT)) { | ||
760 | /* | ||
761 | * A DMA error is sometimes expected. For example, | ||
762 | * if the tape is crossing a filemark during a | ||
763 | * READ command, it will issue an irq and position | ||
764 | * itself before the filemark, so that only a partial | ||
765 | * data transfer will occur (which causes the DMA | ||
766 | * error). In that case, we will later ask the tape | ||
767 | * how much bytes of the original request were | ||
768 | * actually transferred (we can't receive that | ||
769 | * information from the DMA engine on most chipsets). | ||
770 | */ | ||
771 | |||
772 | /* | ||
773 | * On the contrary, a DMA error is never expected; | ||
774 | * it usually indicates a hardware error or abort. | ||
775 | * If the tape crosses a filemark during a READ | ||
776 | * command, it will issue an irq and position itself | ||
777 | * after the filemark (not before). Only a partial | ||
778 | * data transfer will occur, but no DMA error. | ||
779 | * (AS, 19 Apr 2001) | ||
780 | */ | ||
781 | pc->flags |= PC_FLAG_DMA_ERROR; | ||
782 | } else { | ||
783 | pc->xferred = pc->req_xfer; | ||
784 | idetape_update_buffers(pc); | ||
785 | } | ||
786 | debug_log(DBG_PROCS, "DMA finished\n"); | ||
787 | |||
788 | } | ||
789 | |||
790 | /* No more interrupts */ | ||
791 | if ((stat & DRQ_STAT) == 0) { | ||
792 | debug_log(DBG_SENSE, "Packet command completed, %d bytes" | ||
793 | " transferred\n", pc->xferred); | ||
794 | |||
795 | pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; | ||
796 | local_irq_enable(); | ||
797 | |||
798 | #if SIMULATE_ERRORS | ||
799 | if ((pc->c[0] == WRITE_6 || pc->c[0] == READ_6) && | ||
800 | (++error_sim_count % 100) == 0) { | ||
801 | printk(KERN_INFO "ide-tape: %s: simulating error\n", | ||
802 | tape->name); | ||
803 | stat |= ERR_STAT; | ||
804 | } | ||
805 | #endif | ||
806 | if ((stat & ERR_STAT) && pc->c[0] == REQUEST_SENSE) | ||
807 | stat &= ~ERR_STAT; | ||
808 | if ((stat & ERR_STAT) || (pc->flags & PC_FLAG_DMA_ERROR)) { | ||
809 | /* Error detected */ | ||
810 | debug_log(DBG_ERR, "%s: I/O error\n", tape->name); | ||
811 | |||
812 | if (pc->c[0] == REQUEST_SENSE) { | ||
813 | printk(KERN_ERR "ide-tape: I/O error in request" | ||
814 | " sense command\n"); | ||
815 | return ide_do_reset(drive); | ||
816 | } | ||
817 | debug_log(DBG_ERR, "[cmd %x]: check condition\n", | ||
818 | pc->c[0]); | ||
819 | |||
820 | /* Retry operation */ | ||
821 | return idetape_retry_pc(drive); | ||
822 | } | ||
823 | pc->error = 0; | ||
824 | if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && | ||
825 | (stat & SEEK_STAT) == 0) { | ||
826 | /* Media access command */ | ||
827 | tape->dsc_polling_start = jiffies; | ||
828 | tape->dsc_poll_freq = IDETAPE_DSC_MA_FAST; | ||
829 | tape->dsc_timeout = jiffies + IDETAPE_DSC_MA_TIMEOUT; | ||
830 | /* Allow ide.c to handle other requests */ | ||
831 | idetape_postpone_request(drive); | ||
832 | return ide_stopped; | ||
833 | } | ||
834 | if (tape->failed_pc == pc) | ||
835 | tape->failed_pc = NULL; | ||
836 | /* Command finished - Call the callback function */ | ||
837 | return pc->idetape_callback(drive); | ||
838 | } | ||
839 | |||
840 | if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { | ||
841 | pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; | ||
842 | printk(KERN_ERR "ide-tape: The tape wants to issue more " | ||
843 | "interrupts in DMA mode\n"); | ||
844 | printk(KERN_ERR "ide-tape: DMA disabled, reverting to PIO\n"); | ||
845 | ide_dma_off(drive); | ||
846 | return ide_do_reset(drive); | ||
847 | } | ||
848 | /* Get the number of bytes to transfer on this interrupt. */ | ||
849 | bcount = (hwif->INB(hwif->io_ports.lbah_addr) << 8) | | ||
850 | hwif->INB(hwif->io_ports.lbam_addr); | ||
851 | |||
852 | ireason = hwif->INB(hwif->io_ports.nsect_addr); | ||
853 | |||
854 | if (ireason & CD) { | ||
855 | printk(KERN_ERR "ide-tape: CoD != 0 in %s\n", __func__); | ||
856 | return ide_do_reset(drive); | ||
857 | } | ||
858 | if (((ireason & IO) == IO) == !!(pc->flags & PC_FLAG_WRITING)) { | ||
859 | /* Hopefully, we will never get here */ | ||
860 | printk(KERN_ERR "ide-tape: We wanted to %s, ", | ||
861 | (ireason & IO) ? "Write" : "Read"); | ||
862 | printk(KERN_ERR "ide-tape: but the tape wants us to %s !\n", | ||
863 | (ireason & IO) ? "Read" : "Write"); | ||
864 | return ide_do_reset(drive); | ||
865 | } | ||
866 | if (!(pc->flags & PC_FLAG_WRITING)) { | ||
867 | /* Reading - Check that we have enough space */ | ||
868 | temp = pc->xferred + bcount; | ||
869 | if (temp > pc->req_xfer) { | ||
870 | if (temp > pc->buf_size) { | ||
871 | printk(KERN_ERR "ide-tape: The tape wants to " | ||
872 | "send us more data than expected " | ||
873 | "- discarding data\n"); | ||
874 | ide_pad_transfer(drive, 0, bcount); | ||
875 | ide_set_handler(drive, &idetape_pc_intr, | ||
876 | IDETAPE_WAIT_CMD, NULL); | ||
877 | return ide_started; | ||
878 | } | ||
879 | debug_log(DBG_SENSE, "The tape wants to send us more " | ||
880 | "data than expected - allowing transfer\n"); | ||
881 | } | ||
882 | iobuf = &idetape_input_buffers; | ||
883 | xferfunc = hwif->input_data; | ||
884 | } else { | ||
885 | iobuf = &idetape_output_buffers; | ||
886 | xferfunc = hwif->output_data; | ||
887 | } | ||
888 | |||
889 | if (pc->bh) | ||
890 | iobuf(drive, pc, bcount); | ||
891 | else | ||
892 | xferfunc(drive, NULL, pc->cur_pos, bcount); | ||
893 | |||
894 | /* Update the current position */ | ||
895 | pc->xferred += bcount; | ||
896 | pc->cur_pos += bcount; | ||
897 | |||
898 | debug_log(DBG_SENSE, "[cmd %x] transferred %d bytes on that intr.\n", | ||
899 | pc->c[0], bcount); | ||
900 | 802 | ||
901 | /* And set the interrupt handler again */ | 803 | return ide_pc_intr(drive, tape->pc, idetape_pc_intr, IDETAPE_WAIT_CMD, |
902 | ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); | 804 | NULL, idetape_update_buffers, idetape_retry_pc, |
903 | return ide_started; | 805 | ide_tape_handle_dsc, ide_tape_io_buffers); |
904 | } | 806 | } |
905 | 807 | ||
906 | /* | 808 | /* |
@@ -941,56 +843,16 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive) | |||
941 | */ | 843 | */ |
942 | static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive) | 844 | static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive) |
943 | { | 845 | { |
944 | ide_hwif_t *hwif = drive->hwif; | ||
945 | idetape_tape_t *tape = drive->driver_data; | 846 | idetape_tape_t *tape = drive->driver_data; |
946 | struct ide_atapi_pc *pc = tape->pc; | ||
947 | int retries = 100; | ||
948 | ide_startstop_t startstop; | ||
949 | u8 ireason; | ||
950 | |||
951 | if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) { | ||
952 | printk(KERN_ERR "ide-tape: Strange, packet command initiated " | ||
953 | "yet DRQ isn't asserted\n"); | ||
954 | return startstop; | ||
955 | } | ||
956 | ireason = hwif->INB(hwif->io_ports.nsect_addr); | ||
957 | while (retries-- && ((ireason & CD) == 0 || (ireason & IO))) { | ||
958 | printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while issuing " | ||
959 | "a packet command, retrying\n"); | ||
960 | udelay(100); | ||
961 | ireason = hwif->INB(hwif->io_ports.nsect_addr); | ||
962 | if (retries == 0) { | ||
963 | printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while " | ||
964 | "issuing a packet command, ignoring\n"); | ||
965 | ireason |= CD; | ||
966 | ireason &= ~IO; | ||
967 | } | ||
968 | } | ||
969 | if ((ireason & CD) == 0 || (ireason & IO)) { | ||
970 | printk(KERN_ERR "ide-tape: (IO,CoD) != (0,1) while issuing " | ||
971 | "a packet command\n"); | ||
972 | return ide_do_reset(drive); | ||
973 | } | ||
974 | /* Set the interrupt routine */ | ||
975 | ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); | ||
976 | #ifdef CONFIG_BLK_DEV_IDEDMA | ||
977 | /* Begin DMA, if necessary */ | ||
978 | if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) | ||
979 | hwif->dma_ops->dma_start(drive); | ||
980 | #endif | ||
981 | /* Send the actual packet */ | ||
982 | hwif->output_data(drive, NULL, pc->c, 12); | ||
983 | 847 | ||
984 | return ide_started; | 848 | return ide_transfer_pc(drive, tape->pc, idetape_pc_intr, |
849 | IDETAPE_WAIT_CMD, NULL); | ||
985 | } | 850 | } |
986 | 851 | ||
987 | static ide_startstop_t idetape_issue_pc(ide_drive_t *drive, | 852 | static ide_startstop_t idetape_issue_pc(ide_drive_t *drive, |
988 | struct ide_atapi_pc *pc) | 853 | struct ide_atapi_pc *pc) |
989 | { | 854 | { |
990 | ide_hwif_t *hwif = drive->hwif; | ||
991 | idetape_tape_t *tape = drive->driver_data; | 855 | idetape_tape_t *tape = drive->driver_data; |
992 | int dma_ok = 0; | ||
993 | u16 bcount; | ||
994 | 856 | ||
995 | if (tape->pc->c[0] == REQUEST_SENSE && | 857 | if (tape->pc->c[0] == REQUEST_SENSE && |
996 | pc->c[0] == REQUEST_SENSE) { | 858 | pc->c[0] == REQUEST_SENSE) { |
@@ -1025,50 +887,15 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive, | |||
1025 | pc->error = IDETAPE_ERROR_GENERAL; | 887 | pc->error = IDETAPE_ERROR_GENERAL; |
1026 | } | 888 | } |
1027 | tape->failed_pc = NULL; | 889 | tape->failed_pc = NULL; |
1028 | return pc->idetape_callback(drive); | 890 | pc->callback(drive); |
891 | return ide_stopped; | ||
1029 | } | 892 | } |
1030 | debug_log(DBG_SENSE, "Retry #%d, cmd = %02X\n", pc->retries, pc->c[0]); | 893 | debug_log(DBG_SENSE, "Retry #%d, cmd = %02X\n", pc->retries, pc->c[0]); |
1031 | 894 | ||
1032 | pc->retries++; | 895 | pc->retries++; |
1033 | /* We haven't transferred any data yet */ | ||
1034 | pc->xferred = 0; | ||
1035 | pc->cur_pos = pc->buf; | ||
1036 | /* Request to transfer the entire buffer at once */ | ||
1037 | bcount = pc->req_xfer; | ||
1038 | 896 | ||
1039 | if (pc->flags & PC_FLAG_DMA_ERROR) { | 897 | return ide_issue_pc(drive, pc, idetape_transfer_pc, |
1040 | pc->flags &= ~PC_FLAG_DMA_ERROR; | 898 | IDETAPE_WAIT_CMD, NULL); |
1041 | printk(KERN_WARNING "ide-tape: DMA disabled, " | ||
1042 | "reverting to PIO\n"); | ||
1043 | ide_dma_off(drive); | ||
1044 | } | ||
1045 | if ((pc->flags & PC_FLAG_DMA_RECOMMENDED) && drive->using_dma) | ||
1046 | dma_ok = !hwif->dma_ops->dma_setup(drive); | ||
1047 | |||
1048 | ide_pktcmd_tf_load(drive, IDE_TFLAG_NO_SELECT_MASK | | ||
1049 | IDE_TFLAG_OUT_DEVICE, bcount, dma_ok); | ||
1050 | |||
1051 | if (dma_ok) | ||
1052 | /* Will begin DMA later */ | ||
1053 | pc->flags |= PC_FLAG_DMA_IN_PROGRESS; | ||
1054 | if (test_bit(IDETAPE_FLAG_DRQ_INTERRUPT, &tape->flags)) { | ||
1055 | ide_execute_command(drive, WIN_PACKETCMD, &idetape_transfer_pc, | ||
1056 | IDETAPE_WAIT_CMD, NULL); | ||
1057 | return ide_started; | ||
1058 | } else { | ||
1059 | ide_execute_pkt_cmd(drive); | ||
1060 | return idetape_transfer_pc(drive); | ||
1061 | } | ||
1062 | } | ||
1063 | |||
1064 | static ide_startstop_t idetape_pc_callback(ide_drive_t *drive) | ||
1065 | { | ||
1066 | idetape_tape_t *tape = drive->driver_data; | ||
1067 | |||
1068 | debug_log(DBG_PROCS, "Enter %s\n", __func__); | ||
1069 | |||
1070 | idetape_end_request(drive, tape->pc->error ? 0 : 1, 0); | ||
1071 | return ide_stopped; | ||
1072 | } | 899 | } |
1073 | 900 | ||
1074 | /* A mode sense command is used to "sense" tape parameters. */ | 901 | /* A mode sense command is used to "sense" tape parameters. */ |
@@ -1096,7 +923,6 @@ static void idetape_create_mode_sense_cmd(struct ide_atapi_pc *pc, u8 page_code) | |||
1096 | pc->req_xfer = 24; | 923 | pc->req_xfer = 24; |
1097 | else | 924 | else |
1098 | pc->req_xfer = 50; | 925 | pc->req_xfer = 50; |
1099 | pc->idetape_callback = &idetape_pc_callback; | ||
1100 | } | 926 | } |
1101 | 927 | ||
1102 | static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive) | 928 | static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive) |
@@ -1114,80 +940,41 @@ static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive) | |||
1114 | printk(KERN_ERR "ide-tape: %s: I/O error, ", | 940 | printk(KERN_ERR "ide-tape: %s: I/O error, ", |
1115 | tape->name); | 941 | tape->name); |
1116 | /* Retry operation */ | 942 | /* Retry operation */ |
1117 | return idetape_retry_pc(drive); | 943 | idetape_retry_pc(drive); |
944 | return ide_stopped; | ||
1118 | } | 945 | } |
1119 | pc->error = 0; | 946 | pc->error = 0; |
1120 | if (tape->failed_pc == pc) | ||
1121 | tape->failed_pc = NULL; | ||
1122 | } else { | 947 | } else { |
1123 | pc->error = IDETAPE_ERROR_GENERAL; | 948 | pc->error = IDETAPE_ERROR_GENERAL; |
1124 | tape->failed_pc = NULL; | 949 | tape->failed_pc = NULL; |
1125 | } | 950 | } |
1126 | return pc->idetape_callback(drive); | 951 | pc->callback(drive); |
1127 | } | ||
1128 | |||
1129 | static ide_startstop_t idetape_rw_callback(ide_drive_t *drive) | ||
1130 | { | ||
1131 | idetape_tape_t *tape = drive->driver_data; | ||
1132 | struct request *rq = HWGROUP(drive)->rq; | ||
1133 | int blocks = tape->pc->xferred / tape->blk_size; | ||
1134 | |||
1135 | tape->avg_size += blocks * tape->blk_size; | ||
1136 | |||
1137 | if (time_after_eq(jiffies, tape->avg_time + HZ)) { | ||
1138 | tape->avg_speed = tape->avg_size * HZ / | ||
1139 | (jiffies - tape->avg_time) / 1024; | ||
1140 | tape->avg_size = 0; | ||
1141 | tape->avg_time = jiffies; | ||
1142 | } | ||
1143 | debug_log(DBG_PROCS, "Enter %s\n", __func__); | ||
1144 | |||
1145 | tape->first_frame += blocks; | ||
1146 | rq->current_nr_sectors -= blocks; | ||
1147 | |||
1148 | if (!tape->pc->error) | ||
1149 | idetape_end_request(drive, 1, 0); | ||
1150 | else | ||
1151 | idetape_end_request(drive, tape->pc->error, 0); | ||
1152 | return ide_stopped; | 952 | return ide_stopped; |
1153 | } | 953 | } |
1154 | 954 | ||
1155 | static void idetape_create_read_cmd(idetape_tape_t *tape, | 955 | static void ide_tape_create_rw_cmd(idetape_tape_t *tape, |
1156 | struct ide_atapi_pc *pc, | 956 | struct ide_atapi_pc *pc, unsigned int length, |
1157 | unsigned int length, struct idetape_bh *bh) | 957 | struct idetape_bh *bh, u8 opcode) |
1158 | { | 958 | { |
1159 | idetape_init_pc(pc); | 959 | idetape_init_pc(pc); |
1160 | pc->c[0] = READ_6; | ||
1161 | put_unaligned(cpu_to_be32(length), (unsigned int *) &pc->c[1]); | 960 | put_unaligned(cpu_to_be32(length), (unsigned int *) &pc->c[1]); |
1162 | pc->c[1] = 1; | 961 | pc->c[1] = 1; |
1163 | pc->idetape_callback = &idetape_rw_callback; | ||
1164 | pc->bh = bh; | 962 | pc->bh = bh; |
1165 | atomic_set(&bh->b_count, 0); | ||
1166 | pc->buf = NULL; | 963 | pc->buf = NULL; |
1167 | pc->buf_size = length * tape->blk_size; | 964 | pc->buf_size = length * tape->blk_size; |
1168 | pc->req_xfer = pc->buf_size; | 965 | pc->req_xfer = pc->buf_size; |
1169 | if (pc->req_xfer == tape->buffer_size) | 966 | if (pc->req_xfer == tape->buffer_size) |
1170 | pc->flags |= PC_FLAG_DMA_RECOMMENDED; | 967 | pc->flags |= PC_FLAG_DMA_OK; |
1171 | } | ||
1172 | 968 | ||
1173 | static void idetape_create_write_cmd(idetape_tape_t *tape, | 969 | if (opcode == READ_6) { |
1174 | struct ide_atapi_pc *pc, | 970 | pc->c[0] = READ_6; |
1175 | unsigned int length, struct idetape_bh *bh) | 971 | atomic_set(&bh->b_count, 0); |
1176 | { | 972 | } else if (opcode == WRITE_6) { |
1177 | idetape_init_pc(pc); | 973 | pc->c[0] = WRITE_6; |
1178 | pc->c[0] = WRITE_6; | 974 | pc->flags |= PC_FLAG_WRITING; |
1179 | put_unaligned(cpu_to_be32(length), (unsigned int *) &pc->c[1]); | 975 | pc->b_data = bh->b_data; |
1180 | pc->c[1] = 1; | 976 | pc->b_count = atomic_read(&bh->b_count); |
1181 | pc->idetape_callback = &idetape_rw_callback; | 977 | } |
1182 | pc->flags |= PC_FLAG_WRITING; | ||
1183 | pc->bh = bh; | ||
1184 | pc->b_data = bh->b_data; | ||
1185 | pc->b_count = atomic_read(&bh->b_count); | ||
1186 | pc->buf = NULL; | ||
1187 | pc->buf_size = length * tape->blk_size; | ||
1188 | pc->req_xfer = pc->buf_size; | ||
1189 | if (pc->req_xfer == tape->buffer_size) | ||
1190 | pc->flags |= PC_FLAG_DMA_RECOMMENDED; | ||
1191 | } | 978 | } |
1192 | 979 | ||
1193 | static ide_startstop_t idetape_do_request(ide_drive_t *drive, | 980 | static ide_startstop_t idetape_do_request(ide_drive_t *drive, |
@@ -1211,8 +998,10 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, | |||
1211 | } | 998 | } |
1212 | 999 | ||
1213 | /* Retry a failed packet command */ | 1000 | /* Retry a failed packet command */ |
1214 | if (tape->failed_pc && tape->pc->c[0] == REQUEST_SENSE) | 1001 | if (tape->failed_pc && tape->pc->c[0] == REQUEST_SENSE) { |
1215 | return idetape_issue_pc(drive, tape->failed_pc); | 1002 | pc = tape->failed_pc; |
1003 | goto out; | ||
1004 | } | ||
1216 | 1005 | ||
1217 | if (postponed_rq != NULL) | 1006 | if (postponed_rq != NULL) |
1218 | if (rq != postponed_rq) { | 1007 | if (rq != postponed_rq) { |
@@ -1262,14 +1051,16 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, | |||
1262 | } | 1051 | } |
1263 | if (rq->cmd[0] & REQ_IDETAPE_READ) { | 1052 | if (rq->cmd[0] & REQ_IDETAPE_READ) { |
1264 | pc = idetape_next_pc_storage(drive); | 1053 | pc = idetape_next_pc_storage(drive); |
1265 | idetape_create_read_cmd(tape, pc, rq->current_nr_sectors, | 1054 | ide_tape_create_rw_cmd(tape, pc, rq->current_nr_sectors, |
1266 | (struct idetape_bh *)rq->special); | 1055 | (struct idetape_bh *)rq->special, |
1056 | READ_6); | ||
1267 | goto out; | 1057 | goto out; |
1268 | } | 1058 | } |
1269 | if (rq->cmd[0] & REQ_IDETAPE_WRITE) { | 1059 | if (rq->cmd[0] & REQ_IDETAPE_WRITE) { |
1270 | pc = idetape_next_pc_storage(drive); | 1060 | pc = idetape_next_pc_storage(drive); |
1271 | idetape_create_write_cmd(tape, pc, rq->current_nr_sectors, | 1061 | ide_tape_create_rw_cmd(tape, pc, rq->current_nr_sectors, |
1272 | (struct idetape_bh *)rq->special); | 1062 | (struct idetape_bh *)rq->special, |
1063 | WRITE_6); | ||
1273 | goto out; | 1064 | goto out; |
1274 | } | 1065 | } |
1275 | if (rq->cmd[0] & REQ_IDETAPE_PC1) { | 1066 | if (rq->cmd[0] & REQ_IDETAPE_PC1) { |
@@ -1284,6 +1075,9 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, | |||
1284 | } | 1075 | } |
1285 | BUG(); | 1076 | BUG(); |
1286 | out: | 1077 | out: |
1078 | if (test_bit(IDETAPE_FLAG_DRQ_INTERRUPT, &tape->flags)) | ||
1079 | pc->flags |= PC_FLAG_DRQ_INTERRUPT; | ||
1080 | |||
1287 | return idetape_issue_pc(drive, pc); | 1081 | return idetape_issue_pc(drive, pc); |
1288 | } | 1082 | } |
1289 | 1083 | ||
@@ -1447,40 +1241,6 @@ static void idetape_init_merge_buffer(idetape_tape_t *tape) | |||
1447 | } | 1241 | } |
1448 | } | 1242 | } |
1449 | 1243 | ||
1450 | static ide_startstop_t idetape_read_position_callback(ide_drive_t *drive) | ||
1451 | { | ||
1452 | idetape_tape_t *tape = drive->driver_data; | ||
1453 | u8 *readpos = tape->pc->buf; | ||
1454 | |||
1455 | debug_log(DBG_PROCS, "Enter %s\n", __func__); | ||
1456 | |||
1457 | if (!tape->pc->error) { | ||
1458 | debug_log(DBG_SENSE, "BOP - %s\n", | ||
1459 | (readpos[0] & 0x80) ? "Yes" : "No"); | ||
1460 | debug_log(DBG_SENSE, "EOP - %s\n", | ||
1461 | (readpos[0] & 0x40) ? "Yes" : "No"); | ||
1462 | |||
1463 | if (readpos[0] & 0x4) { | ||
1464 | printk(KERN_INFO "ide-tape: Block location is unknown" | ||
1465 | "to the tape\n"); | ||
1466 | clear_bit(IDETAPE_FLAG_ADDRESS_VALID, &tape->flags); | ||
1467 | idetape_end_request(drive, 0, 0); | ||
1468 | } else { | ||
1469 | debug_log(DBG_SENSE, "Block Location - %u\n", | ||
1470 | be32_to_cpu(*(u32 *)&readpos[4])); | ||
1471 | |||
1472 | tape->partition = readpos[1]; | ||
1473 | tape->first_frame = | ||
1474 | be32_to_cpu(*(u32 *)&readpos[4]); | ||
1475 | set_bit(IDETAPE_FLAG_ADDRESS_VALID, &tape->flags); | ||
1476 | idetape_end_request(drive, 1, 0); | ||
1477 | } | ||
1478 | } else { | ||
1479 | idetape_end_request(drive, 0, 0); | ||
1480 | } | ||
1481 | return ide_stopped; | ||
1482 | } | ||
1483 | |||
1484 | /* | 1244 | /* |
1485 | * Write a filemark if write_filemark=1. Flush the device buffers without | 1245 | * Write a filemark if write_filemark=1. Flush the device buffers without |
1486 | * writing a filemark otherwise. | 1246 | * writing a filemark otherwise. |
@@ -1492,14 +1252,12 @@ static void idetape_create_write_filemark_cmd(ide_drive_t *drive, | |||
1492 | pc->c[0] = WRITE_FILEMARKS; | 1252 | pc->c[0] = WRITE_FILEMARKS; |
1493 | pc->c[4] = write_filemark; | 1253 | pc->c[4] = write_filemark; |
1494 | pc->flags |= PC_FLAG_WAIT_FOR_DSC; | 1254 | pc->flags |= PC_FLAG_WAIT_FOR_DSC; |
1495 | pc->idetape_callback = &idetape_pc_callback; | ||
1496 | } | 1255 | } |
1497 | 1256 | ||
1498 | static void idetape_create_test_unit_ready_cmd(struct ide_atapi_pc *pc) | 1257 | static void idetape_create_test_unit_ready_cmd(struct ide_atapi_pc *pc) |
1499 | { | 1258 | { |
1500 | idetape_init_pc(pc); | 1259 | idetape_init_pc(pc); |
1501 | pc->c[0] = TEST_UNIT_READY; | 1260 | pc->c[0] = TEST_UNIT_READY; |
1502 | pc->idetape_callback = &idetape_pc_callback; | ||
1503 | } | 1261 | } |
1504 | 1262 | ||
1505 | /* | 1263 | /* |
@@ -1518,12 +1276,16 @@ static void idetape_create_test_unit_ready_cmd(struct ide_atapi_pc *pc) | |||
1518 | static int idetape_queue_pc_tail(ide_drive_t *drive, struct ide_atapi_pc *pc) | 1276 | static int idetape_queue_pc_tail(ide_drive_t *drive, struct ide_atapi_pc *pc) |
1519 | { | 1277 | { |
1520 | struct ide_tape_obj *tape = drive->driver_data; | 1278 | struct ide_tape_obj *tape = drive->driver_data; |
1521 | struct request rq; | 1279 | struct request *rq; |
1280 | int error; | ||
1522 | 1281 | ||
1523 | idetape_init_rq(&rq, REQ_IDETAPE_PC1); | 1282 | rq = blk_get_request(drive->queue, READ, __GFP_WAIT); |
1524 | rq.buffer = (char *) pc; | 1283 | rq->cmd_type = REQ_TYPE_SPECIAL; |
1525 | rq.rq_disk = tape->disk; | 1284 | rq->cmd[0] = REQ_IDETAPE_PC1; |
1526 | return ide_do_drive_cmd(drive, &rq, ide_wait); | 1285 | rq->buffer = (char *)pc; |
1286 | error = blk_execute_rq(drive->queue, tape->disk, rq, 0); | ||
1287 | blk_put_request(rq); | ||
1288 | return error; | ||
1527 | } | 1289 | } |
1528 | 1290 | ||
1529 | static void idetape_create_load_unload_cmd(ide_drive_t *drive, | 1291 | static void idetape_create_load_unload_cmd(ide_drive_t *drive, |
@@ -1533,7 +1295,6 @@ static void idetape_create_load_unload_cmd(ide_drive_t *drive, | |||
1533 | pc->c[0] = START_STOP; | 1295 | pc->c[0] = START_STOP; |
1534 | pc->c[4] = cmd; | 1296 | pc->c[4] = cmd; |
1535 | pc->flags |= PC_FLAG_WAIT_FOR_DSC; | 1297 | pc->flags |= PC_FLAG_WAIT_FOR_DSC; |
1536 | pc->idetape_callback = &idetape_pc_callback; | ||
1537 | } | 1298 | } |
1538 | 1299 | ||
1539 | static int idetape_wait_ready(ide_drive_t *drive, unsigned long timeout) | 1300 | static int idetape_wait_ready(ide_drive_t *drive, unsigned long timeout) |
@@ -1585,7 +1346,6 @@ static void idetape_create_read_position_cmd(struct ide_atapi_pc *pc) | |||
1585 | idetape_init_pc(pc); | 1346 | idetape_init_pc(pc); |
1586 | pc->c[0] = READ_POSITION; | 1347 | pc->c[0] = READ_POSITION; |
1587 | pc->req_xfer = 20; | 1348 | pc->req_xfer = 20; |
1588 | pc->idetape_callback = &idetape_read_position_callback; | ||
1589 | } | 1349 | } |
1590 | 1350 | ||
1591 | static int idetape_read_position(ide_drive_t *drive) | 1351 | static int idetape_read_position(ide_drive_t *drive) |
@@ -1613,7 +1373,6 @@ static void idetape_create_locate_cmd(ide_drive_t *drive, | |||
1613 | put_unaligned(cpu_to_be32(block), (unsigned int *) &pc->c[3]); | 1373 | put_unaligned(cpu_to_be32(block), (unsigned int *) &pc->c[3]); |
1614 | pc->c[8] = partition; | 1374 | pc->c[8] = partition; |
1615 | pc->flags |= PC_FLAG_WAIT_FOR_DSC; | 1375 | pc->flags |= PC_FLAG_WAIT_FOR_DSC; |
1616 | pc->idetape_callback = &idetape_pc_callback; | ||
1617 | } | 1376 | } |
1618 | 1377 | ||
1619 | static int idetape_create_prevent_cmd(ide_drive_t *drive, | 1378 | static int idetape_create_prevent_cmd(ide_drive_t *drive, |
@@ -1628,7 +1387,6 @@ static int idetape_create_prevent_cmd(ide_drive_t *drive, | |||
1628 | idetape_init_pc(pc); | 1387 | idetape_init_pc(pc); |
1629 | pc->c[0] = ALLOW_MEDIUM_REMOVAL; | 1388 | pc->c[0] = ALLOW_MEDIUM_REMOVAL; |
1630 | pc->c[4] = prevent; | 1389 | pc->c[4] = prevent; |
1631 | pc->idetape_callback = &idetape_pc_callback; | ||
1632 | return 1; | 1390 | return 1; |
1633 | } | 1391 | } |
1634 | 1392 | ||
@@ -1700,26 +1458,33 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks, | |||
1700 | struct idetape_bh *bh) | 1458 | struct idetape_bh *bh) |
1701 | { | 1459 | { |
1702 | idetape_tape_t *tape = drive->driver_data; | 1460 | idetape_tape_t *tape = drive->driver_data; |
1703 | struct request rq; | 1461 | struct request *rq; |
1462 | int ret, errors; | ||
1704 | 1463 | ||
1705 | debug_log(DBG_SENSE, "%s: cmd=%d\n", __func__, cmd); | 1464 | debug_log(DBG_SENSE, "%s: cmd=%d\n", __func__, cmd); |
1706 | 1465 | ||
1707 | idetape_init_rq(&rq, cmd); | 1466 | rq = blk_get_request(drive->queue, READ, __GFP_WAIT); |
1708 | rq.rq_disk = tape->disk; | 1467 | rq->cmd_type = REQ_TYPE_SPECIAL; |
1709 | rq.special = (void *)bh; | 1468 | rq->cmd[0] = cmd; |
1710 | rq.sector = tape->first_frame; | 1469 | rq->rq_disk = tape->disk; |
1711 | rq.nr_sectors = blocks; | 1470 | rq->special = (void *)bh; |
1712 | rq.current_nr_sectors = blocks; | 1471 | rq->sector = tape->first_frame; |
1713 | (void) ide_do_drive_cmd(drive, &rq, ide_wait); | 1472 | rq->nr_sectors = blocks; |
1473 | rq->current_nr_sectors = blocks; | ||
1474 | blk_execute_rq(drive->queue, tape->disk, rq, 0); | ||
1475 | |||
1476 | errors = rq->errors; | ||
1477 | ret = tape->blk_size * (blocks - rq->current_nr_sectors); | ||
1478 | blk_put_request(rq); | ||
1714 | 1479 | ||
1715 | if ((cmd & (REQ_IDETAPE_READ | REQ_IDETAPE_WRITE)) == 0) | 1480 | if ((cmd & (REQ_IDETAPE_READ | REQ_IDETAPE_WRITE)) == 0) |
1716 | return 0; | 1481 | return 0; |
1717 | 1482 | ||
1718 | if (tape->merge_bh) | 1483 | if (tape->merge_bh) |
1719 | idetape_init_merge_buffer(tape); | 1484 | idetape_init_merge_buffer(tape); |
1720 | if (rq.errors == IDETAPE_ERROR_GENERAL) | 1485 | if (errors == IDETAPE_ERROR_GENERAL) |
1721 | return -EIO; | 1486 | return -EIO; |
1722 | return (tape->blk_size * (blocks-rq.current_nr_sectors)); | 1487 | return ret; |
1723 | } | 1488 | } |
1724 | 1489 | ||
1725 | static void idetape_create_inquiry_cmd(struct ide_atapi_pc *pc) | 1490 | static void idetape_create_inquiry_cmd(struct ide_atapi_pc *pc) |
@@ -1728,7 +1493,6 @@ static void idetape_create_inquiry_cmd(struct ide_atapi_pc *pc) | |||
1728 | pc->c[0] = INQUIRY; | 1493 | pc->c[0] = INQUIRY; |
1729 | pc->c[4] = 254; | 1494 | pc->c[4] = 254; |
1730 | pc->req_xfer = 254; | 1495 | pc->req_xfer = 254; |
1731 | pc->idetape_callback = &idetape_pc_callback; | ||
1732 | } | 1496 | } |
1733 | 1497 | ||
1734 | static void idetape_create_rewind_cmd(ide_drive_t *drive, | 1498 | static void idetape_create_rewind_cmd(ide_drive_t *drive, |
@@ -1737,7 +1501,6 @@ static void idetape_create_rewind_cmd(ide_drive_t *drive, | |||
1737 | idetape_init_pc(pc); | 1501 | idetape_init_pc(pc); |
1738 | pc->c[0] = REZERO_UNIT; | 1502 | pc->c[0] = REZERO_UNIT; |
1739 | pc->flags |= PC_FLAG_WAIT_FOR_DSC; | 1503 | pc->flags |= PC_FLAG_WAIT_FOR_DSC; |
1740 | pc->idetape_callback = &idetape_pc_callback; | ||
1741 | } | 1504 | } |
1742 | 1505 | ||
1743 | static void idetape_create_erase_cmd(struct ide_atapi_pc *pc) | 1506 | static void idetape_create_erase_cmd(struct ide_atapi_pc *pc) |
@@ -1746,7 +1509,6 @@ static void idetape_create_erase_cmd(struct ide_atapi_pc *pc) | |||
1746 | pc->c[0] = ERASE; | 1509 | pc->c[0] = ERASE; |
1747 | pc->c[1] = 1; | 1510 | pc->c[1] = 1; |
1748 | pc->flags |= PC_FLAG_WAIT_FOR_DSC; | 1511 | pc->flags |= PC_FLAG_WAIT_FOR_DSC; |
1749 | pc->idetape_callback = &idetape_pc_callback; | ||
1750 | } | 1512 | } |
1751 | 1513 | ||
1752 | static void idetape_create_space_cmd(struct ide_atapi_pc *pc, int count, u8 cmd) | 1514 | static void idetape_create_space_cmd(struct ide_atapi_pc *pc, int count, u8 cmd) |
@@ -1756,7 +1518,6 @@ static void idetape_create_space_cmd(struct ide_atapi_pc *pc, int count, u8 cmd) | |||
1756 | put_unaligned(cpu_to_be32(count), (unsigned int *) &pc->c[1]); | 1518 | put_unaligned(cpu_to_be32(count), (unsigned int *) &pc->c[1]); |
1757 | pc->c[1] = cmd; | 1519 | pc->c[1] = cmd; |
1758 | pc->flags |= PC_FLAG_WAIT_FOR_DSC; | 1520 | pc->flags |= PC_FLAG_WAIT_FOR_DSC; |
1759 | pc->idetape_callback = &idetape_pc_callback; | ||
1760 | } | 1521 | } |
1761 | 1522 | ||
1762 | /* Queue up a character device originated write request. */ | 1523 | /* Queue up a character device originated write request. */ |
@@ -2751,9 +2512,8 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor) | |||
2751 | * Ensure that the number we got makes sense; limit it within | 2512 | * Ensure that the number we got makes sense; limit it within |
2752 | * IDETAPE_DSC_RW_MIN and IDETAPE_DSC_RW_MAX. | 2513 | * IDETAPE_DSC_RW_MIN and IDETAPE_DSC_RW_MAX. |
2753 | */ | 2514 | */ |
2754 | tape->best_dsc_rw_freq = max_t(unsigned long, | 2515 | tape->best_dsc_rw_freq = clamp_t(unsigned long, t, IDETAPE_DSC_RW_MIN, |
2755 | min_t(unsigned long, t, IDETAPE_DSC_RW_MAX), | 2516 | IDETAPE_DSC_RW_MAX); |
2756 | IDETAPE_DSC_RW_MIN); | ||
2757 | printk(KERN_INFO "ide-tape: %s <-> %s: %dKBps, %d*%dkB buffer, " | 2517 | printk(KERN_INFO "ide-tape: %s <-> %s: %dKBps, %d*%dkB buffer, " |
2758 | "%lums tDSC%s\n", | 2518 | "%lums tDSC%s\n", |
2759 | drive->name, tape->name, *(u16 *)&tape->caps[14], | 2519 | drive->name, tape->name, *(u16 *)&tape->caps[14], |
@@ -2905,11 +2665,6 @@ static int ide_tape_probe(ide_drive_t *drive) | |||
2905 | " the driver\n", drive->name); | 2665 | " the driver\n", drive->name); |
2906 | goto failed; | 2666 | goto failed; |
2907 | } | 2667 | } |
2908 | if (drive->scsi) { | ||
2909 | printk(KERN_INFO "ide-tape: passing drive %s to ide-scsi" | ||
2910 | " emulation.\n", drive->name); | ||
2911 | goto failed; | ||
2912 | } | ||
2913 | tape = kzalloc(sizeof(idetape_tape_t), GFP_KERNEL); | 2668 | tape = kzalloc(sizeof(idetape_tape_t), GFP_KERNEL); |
2914 | if (tape == NULL) { | 2669 | if (tape == NULL) { |
2915 | printk(KERN_ERR "ide-tape: %s: Can't allocate a tape struct\n", | 2670 | printk(KERN_ERR "ide-tape: %s: Can't allocate a tape struct\n", |