aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ide-scsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/ide-scsi.c')
-rw-r--r--drivers/scsi/ide-scsi.c75
1 files changed, 36 insertions, 39 deletions
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index 9706de9d98d5..02e91893064d 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -395,14 +395,12 @@ static int idescsi_expiry(ide_drive_t *drive)
395static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) 395static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
396{ 396{
397 idescsi_scsi_t *scsi = drive_to_idescsi(drive); 397 idescsi_scsi_t *scsi = drive_to_idescsi(drive);
398 idescsi_pc_t *pc=scsi->pc; 398 ide_hwif_t *hwif = drive->hwif;
399 idescsi_pc_t *pc = scsi->pc;
399 struct request *rq = pc->rq; 400 struct request *rq = pc->rq;
400 atapi_bcount_t bcount;
401 atapi_status_t status;
402 atapi_ireason_t ireason;
403 atapi_feature_t feature;
404
405 unsigned int temp; 401 unsigned int temp;
402 u16 bcount;
403 u8 stat, ireason;
406 404
407#if IDESCSI_DEBUG_LOG 405#if IDESCSI_DEBUG_LOG
408 printk (KERN_INFO "ide-scsi: Reached idescsi_pc_intr interrupt handler\n"); 406 printk (KERN_INFO "ide-scsi: Reached idescsi_pc_intr interrupt handler\n");
@@ -425,30 +423,29 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
425 (void) HWIF(drive)->ide_dma_end(drive); 423 (void) HWIF(drive)->ide_dma_end(drive);
426 } 424 }
427 425
428 feature.all = 0;
429 /* Clear the interrupt */ 426 /* Clear the interrupt */
430 status.all = HWIF(drive)->INB(IDE_STATUS_REG); 427 stat = drive->hwif->INB(IDE_STATUS_REG);
431 428
432 if (!status.b.drq) { 429 if ((stat & DRQ_STAT) == 0) {
433 /* No more interrupts */ 430 /* No more interrupts */
434 if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) 431 if (test_bit(IDESCSI_LOG_CMD, &scsi->log))
435 printk (KERN_INFO "Packet command completed, %d bytes transferred\n", pc->actually_transferred); 432 printk (KERN_INFO "Packet command completed, %d bytes transferred\n", pc->actually_transferred);
436 local_irq_enable_in_hardirq(); 433 local_irq_enable_in_hardirq();
437 if (status.b.check) 434 if (stat & ERR_STAT)
438 rq->errors++; 435 rq->errors++;
439 idescsi_end_request (drive, 1, 0); 436 idescsi_end_request (drive, 1, 0);
440 return ide_stopped; 437 return ide_stopped;
441 } 438 }
442 bcount.b.low = HWIF(drive)->INB(IDE_BCOUNTL_REG); 439 bcount = (hwif->INB(IDE_BCOUNTH_REG) << 8) |
443 bcount.b.high = HWIF(drive)->INB(IDE_BCOUNTH_REG); 440 hwif->INB(IDE_BCOUNTL_REG);
444 ireason.all = HWIF(drive)->INB(IDE_IREASON_REG); 441 ireason = hwif->INB(IDE_IREASON_REG);
445 442
446 if (ireason.b.cod) { 443 if (ireason & CD) {
447 printk(KERN_ERR "ide-scsi: CoD != 0 in idescsi_pc_intr\n"); 444 printk(KERN_ERR "ide-scsi: CoD != 0 in idescsi_pc_intr\n");
448 return ide_do_reset (drive); 445 return ide_do_reset (drive);
449 } 446 }
450 if (ireason.b.io) { 447 if (ireason & IO) {
451 temp = pc->actually_transferred + bcount.all; 448 temp = pc->actually_transferred + bcount;
452 if (temp > pc->request_transfer) { 449 if (temp > pc->request_transfer) {
453 if (temp > pc->buffer_size) { 450 if (temp > pc->buffer_size) {
454 printk(KERN_ERR "ide-scsi: The scsi wants to " 451 printk(KERN_ERR "ide-scsi: The scsi wants to "
@@ -461,11 +458,13 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
461 idescsi_input_buffers(drive, pc, temp); 458 idescsi_input_buffers(drive, pc, temp);
462 else 459 else
463 drive->hwif->atapi_input_bytes(drive, pc->current_position, temp); 460 drive->hwif->atapi_input_bytes(drive, pc->current_position, temp);
464 printk(KERN_ERR "ide-scsi: transferred %d of %d bytes\n", temp, bcount.all); 461 printk(KERN_ERR "ide-scsi: transferred"
462 " %d of %d bytes\n",
463 temp, bcount);
465 } 464 }
466 pc->actually_transferred += temp; 465 pc->actually_transferred += temp;
467 pc->current_position += temp; 466 pc->current_position += temp;
468 idescsi_discard_data(drive, bcount.all - temp); 467 idescsi_discard_data(drive, bcount - temp);
469 ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry); 468 ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry);
470 return ide_started; 469 return ide_started;
471 } 470 }
@@ -474,22 +473,24 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
474#endif /* IDESCSI_DEBUG_LOG */ 473#endif /* IDESCSI_DEBUG_LOG */
475 } 474 }
476 } 475 }
477 if (ireason.b.io) { 476 if (ireason & IO) {
478 clear_bit(PC_WRITING, &pc->flags); 477 clear_bit(PC_WRITING, &pc->flags);
479 if (pc->sg) 478 if (pc->sg)
480 idescsi_input_buffers(drive, pc, bcount.all); 479 idescsi_input_buffers(drive, pc, bcount);
481 else 480 else
482 HWIF(drive)->atapi_input_bytes(drive, pc->current_position, bcount.all); 481 hwif->atapi_input_bytes(drive, pc->current_position,
482 bcount);
483 } else { 483 } else {
484 set_bit(PC_WRITING, &pc->flags); 484 set_bit(PC_WRITING, &pc->flags);
485 if (pc->sg) 485 if (pc->sg)
486 idescsi_output_buffers (drive, pc, bcount.all); 486 idescsi_output_buffers(drive, pc, bcount);
487 else 487 else
488 HWIF(drive)->atapi_output_bytes(drive, pc->current_position, bcount.all); 488 hwif->atapi_output_bytes(drive, pc->current_position,
489 bcount);
489 } 490 }
490 /* Update the current position */ 491 /* Update the current position */
491 pc->actually_transferred += bcount.all; 492 pc->actually_transferred += bcount;
492 pc->current_position += bcount.all; 493 pc->current_position += bcount;
493 494
494 /* And set the interrupt handler again */ 495 /* And set the interrupt handler again */
495 ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry); 496 ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry);
@@ -501,16 +502,16 @@ static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive)
501 ide_hwif_t *hwif = drive->hwif; 502 ide_hwif_t *hwif = drive->hwif;
502 idescsi_scsi_t *scsi = drive_to_idescsi(drive); 503 idescsi_scsi_t *scsi = drive_to_idescsi(drive);
503 idescsi_pc_t *pc = scsi->pc; 504 idescsi_pc_t *pc = scsi->pc;
504 atapi_ireason_t ireason;
505 ide_startstop_t startstop; 505 ide_startstop_t startstop;
506 u8 ireason;
506 507
507 if (ide_wait_stat(&startstop,drive,DRQ_STAT,BUSY_STAT,WAIT_READY)) { 508 if (ide_wait_stat(&startstop,drive,DRQ_STAT,BUSY_STAT,WAIT_READY)) {
508 printk(KERN_ERR "ide-scsi: Strange, packet command " 509 printk(KERN_ERR "ide-scsi: Strange, packet command "
509 "initiated yet DRQ isn't asserted\n"); 510 "initiated yet DRQ isn't asserted\n");
510 return startstop; 511 return startstop;
511 } 512 }
512 ireason.all = HWIF(drive)->INB(IDE_IREASON_REG); 513 ireason = hwif->INB(IDE_IREASON_REG);
513 if (!ireason.b.cod || ireason.b.io) { 514 if ((ireason & CD) == 0 || (ireason & IO)) {
514 printk(KERN_ERR "ide-scsi: (IO,CoD) != (0,1) while " 515 printk(KERN_ERR "ide-scsi: (IO,CoD) != (0,1) while "
515 "issuing a packet command\n"); 516 "issuing a packet command\n");
516 return ide_do_reset (drive); 517 return ide_do_reset (drive);
@@ -573,30 +574,26 @@ static ide_startstop_t idescsi_issue_pc (ide_drive_t *drive, idescsi_pc_t *pc)
573{ 574{
574 idescsi_scsi_t *scsi = drive_to_idescsi(drive); 575 idescsi_scsi_t *scsi = drive_to_idescsi(drive);
575 ide_hwif_t *hwif = drive->hwif; 576 ide_hwif_t *hwif = drive->hwif;
576 atapi_feature_t feature; 577 u16 bcount;
577 atapi_bcount_t bcount; 578 u8 dma = 0;
578 579
579 scsi->pc=pc; /* Set the current packet command */ 580 scsi->pc=pc; /* Set the current packet command */
580 pc->actually_transferred=0; /* We haven't transferred any data yet */ 581 pc->actually_transferred=0; /* We haven't transferred any data yet */
581 pc->current_position=pc->buffer; 582 pc->current_position=pc->buffer;
582 bcount.all = min(pc->request_transfer, 63 * 1024); /* Request to transfer the entire buffer at once */ 583 /* Request to transfer the entire buffer at once */
584 bcount = min(pc->request_transfer, 63 * 1024);
583 585
584 feature.all = 0;
585 if (drive->using_dma && !idescsi_map_sg(drive, pc)) { 586 if (drive->using_dma && !idescsi_map_sg(drive, pc)) {
586 hwif->sg_mapped = 1; 587 hwif->sg_mapped = 1;
587 feature.b.dma = !hwif->dma_setup(drive); 588 dma = !hwif->dma_setup(drive);
588 hwif->sg_mapped = 0; 589 hwif->sg_mapped = 0;
589 } 590 }
590 591
591 SELECT_DRIVE(drive); 592 SELECT_DRIVE(drive);
592 if (IDE_CONTROL_REG)
593 HWIF(drive)->OUTB(drive->ctl, IDE_CONTROL_REG);
594 593
595 HWIF(drive)->OUTB(feature.all, IDE_FEATURE_REG); 594 ide_pktcmd_tf_load(drive, IDE_TFLAG_NO_SELECT_MASK, bcount, dma);
596 HWIF(drive)->OUTB(bcount.b.high, IDE_BCOUNTH_REG);
597 HWIF(drive)->OUTB(bcount.b.low, IDE_BCOUNTL_REG);
598 595
599 if (feature.b.dma) 596 if (dma)
600 set_bit(PC_DMA_OK, &pc->flags); 597 set_bit(PC_DMA_OK, &pc->flags);
601 598
602 if (test_bit(IDESCSI_DRQ_INTERRUPT, &scsi->flags)) { 599 if (test_bit(IDESCSI_DRQ_INTERRUPT, &scsi->flags)) {