summaryrefslogtreecommitdiff
path: root/drivers/scsi/ide-scsi.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/scsi/ide-scsi.c
parent55d82bfa6763d6761670d740ab3bac2f1c042d87 (diff)
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/scsi/ide-scsi.c')
-rw-r--r--drivers/scsi/ide-scsi.c115
1 files changed, 3 insertions, 112 deletions
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index ada733ca672..683bce375c7 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -356,120 +356,11 @@ static int idescsi_expiry(ide_drive_t *drive)
static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
{
idescsi_scsi_t *scsi = drive_to_idescsi(drive);
- ide_hwif_t *hwif = drive->hwif;
struct ide_atapi_pc *pc = scsi->pc;
- struct request *rq = pc->rq;
- xfer_func_t *xferfunc;
- unsigned int temp;
- u16 bcount;
- u8 stat, ireason;
-
- debug_log("Enter %s - interrupt handler\n", __func__);
-
- if (pc->flags & PC_FLAG_TIMEDOUT) {
- pc->callback(drive);
- return ide_stopped;
- }
-
- /* Clear the interrupt */
- stat = ide_read_status(drive);
-
- if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
- if (hwif->dma_ops->dma_end(drive))
- pc->flags |= PC_FLAG_DMA_ERROR;
- else
- pc->xferred = pc->req_xfer;
- debug_log("%s: DMA finished\n", drive->name);
- }
-
- if ((stat & DRQ_STAT) == 0) {
- /* No more interrupts */
- debug_log("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->flags & PC_FLAG_DMA_ERROR)) {
- /* Error detected */
- debug_log("%s: I/O error\n", drive->name);
-
- rq->errors++;
- }
- 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);
- }
- 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)) {
- 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);
- temp = pc->buf_size - pc->xferred;
- if (temp) {
- if (pc->sg)
- ide_scsi_io_buffers(drive, pc,
- temp, 0);
- else
- hwif->input_data(drive, NULL,
- pc->cur_pos, temp);
- printk(KERN_ERR "%s: transferred %d of "
- "%d bytes\n",
- drive->name,
- temp, bcount);
- }
- pc->xferred += temp;
- pc->cur_pos += temp;
- ide_pad_transfer(drive, 0, bcount - temp);
- ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry);
- return ide_started;
- }
- debug_log("The device wants to send us more data than "
- "expected - allowing transfer\n");
- }
- xferfunc = hwif->input_data;
- } else
- xferfunc = hwif->output_data;
-
- if (pc->sg)
- ide_scsi_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("[cmd %x] transferred %d bytes on that intr.\n",
- pc->c[0], bcount);
- /* And set the interrupt handler again */
- ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry);
- return ide_started;
+ return ide_pc_intr(drive, pc, idescsi_pc_intr, get_timeout(pc),
+ idescsi_expiry, NULL, NULL, NULL,
+ ide_scsi_io_buffers);
}
static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive)