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.c132
1 files changed, 6 insertions, 126 deletions
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 10f2d3336286..0afa109ec99a 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -56,8 +56,6 @@ enum {
56 DBG_PROCS = (1 << 3), 56 DBG_PROCS = (1 << 3),
57 /* buffer alloc info (pc_stack & rq_stack) */ 57 /* buffer alloc info (pc_stack & rq_stack) */
58 DBG_PCRQ_STACK = (1 << 4), 58 DBG_PCRQ_STACK = (1 << 4),
59 /* IRQ handler (always log debug info if debugging is on) */
60 DBG_PC_INTR = (1 << 5),
61}; 59};
62 60
63/* define to see debug info */ 61/* define to see debug info */
@@ -66,7 +64,7 @@ enum {
66#if IDETAPE_DEBUG_LOG 64#if IDETAPE_DEBUG_LOG
67#define debug_log(lvl, fmt, args...) \ 65#define debug_log(lvl, fmt, args...) \
68{ \ 66{ \
69 if ((lvl & DBG_PC_INTR) || (tape->debug_mask & lvl)) \ 67 if (tape->debug_mask & lvl) \
70 printk(KERN_INFO "ide-tape: " fmt, ## args); \ 68 printk(KERN_INFO "ide-tape: " fmt, ## args); \
71} 69}
72#else 70#else
@@ -441,7 +439,7 @@ static void idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
441 } 439 }
442} 440}
443 441
444static void idetape_update_buffers(struct ide_atapi_pc *pc) 442static void idetape_update_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc)
445{ 443{
446 struct idetape_bh *bh = pc->bh; 444 struct idetape_bh *bh = pc->bh;
447 int count; 445 int count;
@@ -526,7 +524,7 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense)
526 pc->xferred = pc->req_xfer - 524 pc->xferred = pc->req_xfer -
527 tape->blk_size * 525 tape->blk_size *
528 get_unaligned_be32(&sense[3]); 526 get_unaligned_be32(&sense[3]);
529 idetape_update_buffers(pc); 527 idetape_update_buffers(drive, pc);
530 } 528 }
531 529
532 /* 530 /*
@@ -800,129 +798,11 @@ static void ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
800 */ 798 */
801static ide_startstop_t idetape_pc_intr(ide_drive_t *drive) 799static ide_startstop_t idetape_pc_intr(ide_drive_t *drive)
802{ 800{
803 ide_hwif_t *hwif = drive->hwif;
804 idetape_tape_t *tape = drive->driver_data; 801 idetape_tape_t *tape = drive->driver_data;
805 struct ide_atapi_pc *pc = tape->pc;
806 xfer_func_t *xferfunc;
807 unsigned int temp;
808 u16 bcount;
809 u8 stat, ireason;
810
811 debug_log(DBG_PC_INTR, "Enter %s - interrupt handler\n", __func__);
812
813 /* Clear the interrupt */
814 stat = ide_read_status(drive);
815
816 if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
817 if (hwif->dma_ops->dma_end(drive) || (stat & ERR_STAT)) {
818 pc->flags |= PC_FLAG_DMA_ERROR;
819 } else {
820 pc->xferred = pc->req_xfer;
821 idetape_update_buffers(pc);
822 }
823 debug_log(DBG_PC_INTR, "%s: DMA finished\n", drive->name);
824 }
825
826 /* No more interrupts */
827 if ((stat & DRQ_STAT) == 0) {
828 debug_log(DBG_PC_INTR, "Packet command completed, %d bytes"
829 " transferred\n", pc->xferred);
830
831 pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
832 local_irq_enable_in_hardirq();
833
834 if ((stat & ERR_STAT) && pc->c[0] == REQUEST_SENSE)
835 stat &= ~ERR_STAT;
836 if ((stat & ERR_STAT) || (pc->flags & PC_FLAG_DMA_ERROR)) {
837 /* Error detected */
838 debug_log(DBG_PC_INTR, "%s: I/O error\n", drive->name);
839
840 if (pc->c[0] == REQUEST_SENSE) {
841 printk(KERN_ERR "%s: I/O error in request sense"
842 " command\n", drive->name);
843 return ide_do_reset(drive);
844 }
845 debug_log(DBG_PC_INTR, "[cmd %x]: check condition\n",
846 pc->c[0]);
847
848 /* Retry operation */
849 idetape_retry_pc(drive);
850 return ide_stopped;
851 }
852 pc->error = 0;
853 if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) &&
854 (stat & SEEK_STAT) == 0) {
855 ide_tape_handle_dsc(drive);
856 return ide_stopped;
857 }
858 /* Command finished - Call the callback function */
859 pc->callback(drive);
860 return ide_stopped;
861 }
862
863 if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
864 pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
865 printk(KERN_ERR "%s: The device wants to issue more interrupts "
866 "in DMA mode\n", drive->name);
867 ide_dma_off(drive);
868 return ide_do_reset(drive);
869 }
870 /* Get the number of bytes to transfer on this interrupt. */
871 bcount = (hwif->INB(hwif->io_ports.lbah_addr) << 8) |
872 hwif->INB(hwif->io_ports.lbam_addr);
873
874 ireason = hwif->INB(hwif->io_ports.nsect_addr);
875
876 if (ireason & CD) {
877 printk(KERN_ERR "%s: CoD != 0 in %s\n", drive->name, __func__);
878 return ide_do_reset(drive);
879 }
880 if (((ireason & IO) == IO) == !!(pc->flags & PC_FLAG_WRITING)) {
881 /* Hopefully, we will never get here */
882 printk(KERN_ERR "%s: We wanted to %s, but the device wants us "
883 "to %s!\n", drive->name,
884 (ireason & IO) ? "Write" : "Read",
885 (ireason & IO) ? "Read" : "Write");
886 return ide_do_reset(drive);
887 }
888 if (!(pc->flags & PC_FLAG_WRITING)) {
889 /* Reading - Check that we have enough space */
890 temp = pc->xferred + bcount;
891 if (temp > pc->req_xfer) {
892 if (temp > pc->buf_size) {
893 printk(KERN_ERR "%s: The device wants to send "
894 "us more data than expected - "
895 "discarding data\n",
896 drive->name);
897 ide_pad_transfer(drive, 0, bcount);
898 ide_set_handler(drive, &idetape_pc_intr,
899 IDETAPE_WAIT_CMD, NULL);
900 return ide_started;
901 }
902 debug_log(DBG_PC_INTR, "The device wants to send us more "
903 "data than expected - allowing transfer\n");
904 }
905 xferfunc = hwif->input_data;
906 } else {
907 xferfunc = hwif->output_data;
908 }
909
910 if (pc->bh)
911 ide_tape_io_buffers(drive, pc, bcount,
912 !!(pc->flags & PC_FLAG_WRITING));
913 else
914 xferfunc(drive, NULL, pc->cur_pos, bcount);
915
916 /* Update the current position */
917 pc->xferred += bcount;
918 pc->cur_pos += bcount;
919
920 debug_log(DBG_PC_INTR, "[cmd %x] transferred %d bytes on that intr.\n",
921 pc->c[0], bcount);
922 802
923 /* And set the interrupt handler again */ 803 return ide_pc_intr(drive, tape->pc, idetape_pc_intr, IDETAPE_WAIT_CMD,
924 ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); 804 NULL, idetape_update_buffers, idetape_retry_pc,
925 return ide_started; 805 ide_tape_handle_dsc, ide_tape_io_buffers);
926} 806}
927 807
928/* 808/*