aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ide-scsi.c
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-07-15 15:22:03 -0400
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-07-15 15:22:03 -0400
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 ada733ca6725..683bce375c74 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)
356static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) 356static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
357{ 357{
358 idescsi_scsi_t *scsi = drive_to_idescsi(drive); 358 idescsi_scsi_t *scsi = drive_to_idescsi(drive);
359 ide_hwif_t *hwif = drive->hwif;
360 struct ide_atapi_pc *pc = scsi->pc; 359 struct ide_atapi_pc *pc = scsi->pc;
361 struct request *rq = pc->rq;
362 xfer_func_t *xferfunc;
363 unsigned int temp;
364 u16 bcount;
365 u8 stat, ireason;
366
367 debug_log("Enter %s - interrupt handler\n", __func__);
368
369 if (pc->flags & PC_FLAG_TIMEDOUT) {
370 pc->callback(drive);
371 return ide_stopped;
372 }
373
374 /* Clear the interrupt */
375 stat = ide_read_status(drive);
376
377 if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
378 if (hwif->dma_ops->dma_end(drive))
379 pc->flags |= PC_FLAG_DMA_ERROR;
380 else
381 pc->xferred = pc->req_xfer;
382 debug_log("%s: DMA finished\n", drive->name);
383 }
384
385 if ((stat & DRQ_STAT) == 0) {
386 /* No more interrupts */
387 debug_log("Packet command completed, %d bytes transferred\n",
388 pc->xferred);
389 pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
390 local_irq_enable_in_hardirq();
391 if ((stat & ERR_STAT) || (pc->flags & PC_FLAG_DMA_ERROR)) {
392 /* Error detected */
393 debug_log("%s: I/O error\n", drive->name);
394
395 rq->errors++;
396 }
397 pc->callback(drive);
398 return ide_stopped;
399 }
400 if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
401 pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
402 printk(KERN_ERR "%s: The device wants to issue more interrupts "
403 "in DMA mode\n", drive->name);
404 ide_dma_off(drive);
405 return ide_do_reset(drive);
406 }
407 bcount = (hwif->INB(hwif->io_ports.lbah_addr) << 8) |
408 hwif->INB(hwif->io_ports.lbam_addr);
409 ireason = hwif->INB(hwif->io_ports.nsect_addr);
410
411 if (ireason & CD) {
412 printk(KERN_ERR "%s: CoD != 0 in %s\n", drive->name, __func__);
413 return ide_do_reset (drive);
414 }
415 if (((ireason & IO) == IO) == !!(pc->flags & PC_FLAG_WRITING)) {
416 /* Hopefully, we will never get here */
417 printk(KERN_ERR "%s: We wanted to %s, but the device wants us "
418 "to %s!\n", drive->name,
419 (ireason & IO) ? "Write" : "Read",
420 (ireason & IO) ? "Read" : "Write");
421 return ide_do_reset(drive);
422 }
423 if (!(pc->flags & PC_FLAG_WRITING)) {
424 temp = pc->xferred + bcount;
425 if (temp > pc->req_xfer) {
426 if (temp > pc->buf_size) {
427 printk(KERN_ERR "%s: The device wants to send "
428 "us more data than expected - "
429 "discarding data\n",
430 drive->name);
431 temp = pc->buf_size - pc->xferred;
432 if (temp) {
433 if (pc->sg)
434 ide_scsi_io_buffers(drive, pc,
435 temp, 0);
436 else
437 hwif->input_data(drive, NULL,
438 pc->cur_pos, temp);
439 printk(KERN_ERR "%s: transferred %d of "
440 "%d bytes\n",
441 drive->name,
442 temp, bcount);
443 }
444 pc->xferred += temp;
445 pc->cur_pos += temp;
446 ide_pad_transfer(drive, 0, bcount - temp);
447 ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry);
448 return ide_started;
449 }
450 debug_log("The device wants to send us more data than "
451 "expected - allowing transfer\n");
452 }
453 xferfunc = hwif->input_data;
454 } else
455 xferfunc = hwif->output_data;
456
457 if (pc->sg)
458 ide_scsi_io_buffers(drive, pc, bcount,
459 !!(pc->flags & PC_FLAG_WRITING));
460 else
461 xferfunc(drive, NULL, pc->cur_pos, bcount);
462
463 /* Update the current position */
464 pc->xferred += bcount;
465 pc->cur_pos += bcount;
466
467 debug_log("[cmd %x] transferred %d bytes on that intr.\n",
468 pc->c[0], bcount);
469 360
470 /* And set the interrupt handler again */ 361 return ide_pc_intr(drive, pc, idescsi_pc_intr, get_timeout(pc),
471 ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry); 362 idescsi_expiry, NULL, NULL, NULL,
472 return ide_started; 363 ide_scsi_io_buffers);
473} 364}
474 365
475static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive) 366static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive)