summaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-tape.c
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-07-15 21:22:03 +0200
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-07-15 21:22:03 +0200
commit646c0cb6c430f8d3ad3769dd1518fe664ff0ce27 (patch)
tree4e02a6ffe70aceeb36093534845f3308c81a11b5 /drivers/ide/ide-tape.c
parent55d82bfa6763d6761670d740ab3bac2f1c042d87 (diff)
downloadlinux-646c0cb6c430f8d3ad3769dd1518fe664ff0ce27.tar.bz2
ide: add ide_pc_intr() helper
* ide-tape.c: add 'drive' argument to idetape_update_buffers(). * Add generic ide_pc_intr() helper to ide-atapi.c and then convert ide-{floppy,tape,scsi} device drivers to use it. * ide-tape.c: remove no longer needed DBG_PC_INTR. There should be no functional changes caused by this patch (unless the debugging is explicitely compiled in). Cc: Borislav Petkov <petkovbb@gmail.com> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
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 {
DBG_PROCS = (1 << 3),
/* buffer alloc info (pc_stack & rq_stack) */
DBG_PCRQ_STACK = (1 << 4),
- /* IRQ handler (always log debug info if debugging is on) */
- DBG_PC_INTR = (1 << 5),
};
/* define to see debug info */
@@ -66,7 +64,7 @@ enum {
#if IDETAPE_DEBUG_LOG
#define debug_log(lvl, fmt, args...) \
{ \
- if ((lvl & DBG_PC_INTR) || (tape->debug_mask & lvl)) \
+ if (tape->debug_mask & lvl) \
printk(KERN_INFO "ide-tape: " fmt, ## args); \
}
#else
@@ -441,7 +439,7 @@ static void idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
}
}
-static void idetape_update_buffers(struct ide_atapi_pc *pc)
+static void idetape_update_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc)
{
struct idetape_bh *bh = pc->bh;
int count;
@@ -526,7 +524,7 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense)
pc->xferred = pc->req_xfer -
tape->blk_size *
get_unaligned_be32(&sense[3]);
- idetape_update_buffers(pc);
+ idetape_update_buffers(drive, pc);
}
/*
@@ -800,129 +798,11 @@ static void ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
*/
static ide_startstop_t idetape_pc_intr(ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
idetape_tape_t *tape = drive->driver_data;
- struct ide_atapi_pc *pc = tape->pc;
- xfer_func_t *xferfunc;
- unsigned int temp;
- u16 bcount;
- u8 stat, ireason;
-
- debug_log(DBG_PC_INTR, "Enter %s - interrupt handler\n", __func__);
-
- /* Clear the interrupt */
- stat = ide_read_status(drive);
-
- if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
- if (hwif->dma_ops->dma_end(drive) || (stat & ERR_STAT)) {
- pc->flags |= PC_FLAG_DMA_ERROR;
- } else {
- pc->xferred = pc->req_xfer;
- idetape_update_buffers(pc);
- }
- debug_log(DBG_PC_INTR, "%s: DMA finished\n", drive->name);
- }
-
- /* No more interrupts */
- if ((stat & DRQ_STAT) == 0) {
- debug_log(DBG_PC_INTR, "Packet command completed, %d bytes"
- " transferred\n", pc->xferred);
-
- pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
- local_irq_enable_in_hardirq();
-
- if ((stat & ERR_STAT) && pc->c[0] == REQUEST_SENSE)
- stat &= ~ERR_STAT;
- if ((stat & ERR_STAT) || (pc->flags & PC_FLAG_DMA_ERROR)) {
- /* Error detected */
- debug_log(DBG_PC_INTR, "%s: I/O error\n", drive->name);
-
- if (pc->c[0] == REQUEST_SENSE) {
- printk(KERN_ERR "%s: I/O error in request sense"
- " command\n", drive->name);
- return ide_do_reset(drive);
- }
- debug_log(DBG_PC_INTR, "[cmd %x]: check condition\n",
- pc->c[0]);
-
- /* Retry operation */
- idetape_retry_pc(drive);
- return ide_stopped;
- }
- pc->error = 0;
- if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) &&
- (stat & SEEK_STAT) == 0) {
- ide_tape_handle_dsc(drive);
- return ide_stopped;
- }
- /* Command finished - Call the callback function */
- pc->callback(drive);
- return ide_stopped;
- }
-
- if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
- pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
- printk(KERN_ERR "%s: The device wants to issue more interrupts "
- "in DMA mode\n", drive->name);
- ide_dma_off(drive);
- return ide_do_reset(drive);
- }
- /* Get the number of bytes to transfer on this interrupt. */
- bcount = (hwif->INB(hwif->io_ports.lbah_addr) << 8) |
- hwif->INB(hwif->io_ports.lbam_addr);
-
- ireason = hwif->INB(hwif->io_ports.nsect_addr);
-
- if (ireason & CD) {
- printk(KERN_ERR "%s: CoD != 0 in %s\n", drive->name, __func__);
- return ide_do_reset(drive);
- }
- if (((ireason & IO) == IO) == !!(pc->flags & PC_FLAG_WRITING)) {
- /* Hopefully, we will never get here */
- printk(KERN_ERR "%s: We wanted to %s, but the device wants us "
- "to %s!\n", drive->name,
- (ireason & IO) ? "Write" : "Read",
- (ireason & IO) ? "Read" : "Write");
- return ide_do_reset(drive);
- }
- if (!(pc->flags & PC_FLAG_WRITING)) {
- /* Reading - Check that we have enough space */
- temp = pc->xferred + bcount;
- if (temp > pc->req_xfer) {
- if (temp > pc->buf_size) {
- printk(KERN_ERR "%s: The device wants to send "
- "us more data than expected - "
- "discarding data\n",
- drive->name);
- ide_pad_transfer(drive, 0, bcount);
- ide_set_handler(drive, &idetape_pc_intr,
- IDETAPE_WAIT_CMD, NULL);
- return ide_started;
- }
- debug_log(DBG_PC_INTR, "The device wants to send us more "
- "data than expected - allowing transfer\n");
- }
- xferfunc = hwif->input_data;
- } else {
- xferfunc = hwif->output_data;
- }
-
- if (pc->bh)
- ide_tape_io_buffers(drive, pc, bcount,
- !!(pc->flags & PC_FLAG_WRITING));
- else
- xferfunc(drive, NULL, pc->cur_pos, bcount);
-
- /* Update the current position */
- pc->xferred += bcount;
- pc->cur_pos += bcount;
-
- debug_log(DBG_PC_INTR, "[cmd %x] transferred %d bytes on that intr.\n",
- pc->c[0], bcount);
- /* And set the interrupt handler again */
- ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL);
- return ide_started;
+ return ide_pc_intr(drive, tape->pc, idetape_pc_intr, IDETAPE_WAIT_CMD,
+ NULL, idetape_update_buffers, idetape_retry_pc,
+ ide_tape_handle_dsc, ide_tape_io_buffers);
}
/*