diff options
Diffstat (limited to 'drivers/scsi/ide-scsi.c')
-rw-r--r-- | drivers/scsi/ide-scsi.c | 75 |
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) | |||
395 | static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) | 395 | static 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)) { |