aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/ide-lib.c')
-rw-r--r--drivers/ide/ide-lib.c207
1 files changed, 94 insertions, 113 deletions
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c
index 062d3bcb2471..a3bd8e8ed6b0 100644
--- a/drivers/ide/ide-lib.c
+++ b/drivers/ide/ide-lib.c
@@ -441,6 +441,12 @@ int ide_set_xfer_rate(ide_drive_t *drive, u8 rate)
441 * case could happen iff the transfer mode has already been set on 441 * case could happen iff the transfer mode has already been set on
442 * the device by ide-proc.c::set_xfer_rate()). 442 * the device by ide-proc.c::set_xfer_rate()).
443 */ 443 */
444 if (rate < XFER_PIO_0) {
445 if (hwif->host_flags & IDE_HFLAG_ABUSE_SET_DMA_MODE)
446 return ide_set_dma_mode(drive, rate);
447 else
448 return ide_config_drive_speed(drive, rate);
449 }
444 450
445 return ide_set_dma_mode(drive, rate); 451 return ide_set_dma_mode(drive, rate);
446} 452}
@@ -458,8 +464,7 @@ static void ide_dump_opcode(ide_drive_t *drive)
458 spin_unlock(&ide_lock); 464 spin_unlock(&ide_lock);
459 if (!rq) 465 if (!rq)
460 return; 466 return;
461 if (rq->cmd_type == REQ_TYPE_ATA_CMD || 467 if (rq->cmd_type == REQ_TYPE_ATA_CMD) {
462 rq->cmd_type == REQ_TYPE_ATA_TASK) {
463 char *args = rq->buffer; 468 char *args = rq->buffer;
464 if (args) { 469 if (args) {
465 opcode = args[0]; 470 opcode = args[0];
@@ -468,8 +473,7 @@ static void ide_dump_opcode(ide_drive_t *drive)
468 } else if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { 473 } else if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
469 ide_task_t *args = rq->special; 474 ide_task_t *args = rq->special;
470 if (args) { 475 if (args) {
471 task_struct_t *tf = (task_struct_t *) args->tfRegister; 476 opcode = args->tf.command;
472 opcode = tf->command;
473 found = 1; 477 found = 1;
474 } 478 }
475 } 479 }
@@ -481,141 +485,118 @@ static void ide_dump_opcode(ide_drive_t *drive)
481 printk("0x%02x\n", opcode); 485 printk("0x%02x\n", opcode);
482} 486}
483 487
484static u8 ide_dump_ata_status(ide_drive_t *drive, const char *msg, u8 stat) 488u64 ide_get_lba_addr(struct ide_taskfile *tf, int lba48)
485{ 489{
486 ide_hwif_t *hwif = HWIF(drive); 490 u32 high, low;
487 unsigned long flags;
488 u8 err = 0;
489 491
490 local_irq_save(flags); 492 if (lba48)
491 printk("%s: %s: status=0x%02x { ", drive->name, msg, stat); 493 high = (tf->hob_lbah << 16) | (tf->hob_lbam << 8) |
492 if (stat & BUSY_STAT) 494 tf->hob_lbal;
493 printk("Busy "); 495 else
494 else { 496 high = tf->device & 0xf;
495 if (stat & READY_STAT) printk("DriveReady "); 497 low = (tf->lbah << 16) | (tf->lbam << 8) | tf->lbal;
496 if (stat & WRERR_STAT) printk("DeviceFault "); 498
497 if (stat & SEEK_STAT) printk("SeekComplete "); 499 return ((u64)high << 24) | low;
498 if (stat & DRQ_STAT) printk("DataRequest "); 500}
499 if (stat & ECC_STAT) printk("CorrectedError "); 501EXPORT_SYMBOL_GPL(ide_get_lba_addr);
500 if (stat & INDEX_STAT) printk("Index "); 502
501 if (stat & ERR_STAT) printk("Error "); 503static void ide_dump_sector(ide_drive_t *drive)
504{
505 ide_task_t task;
506 struct ide_taskfile *tf = &task.tf;
507 int lba48 = (drive->addressing == 1) ? 1 : 0;
508
509 memset(&task, 0, sizeof(task));
510 if (lba48)
511 task.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_HOB_LBA |
512 IDE_TFLAG_LBA48;
513 else
514 task.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_DEVICE;
515
516 ide_tf_read(drive, &task);
517
518 if (lba48 || (tf->device & ATA_LBA))
519 printk(", LBAsect=%llu",
520 (unsigned long long)ide_get_lba_addr(tf, lba48));
521 else
522 printk(", CHS=%d/%d/%d", (tf->lbah << 8) + tf->lbam,
523 tf->device & 0xf, tf->lbal);
524}
525
526static void ide_dump_ata_error(ide_drive_t *drive, u8 err)
527{
528 printk("{ ");
529 if (err & ABRT_ERR) printk("DriveStatusError ");
530 if (err & ICRC_ERR)
531 printk((err & ABRT_ERR) ? "BadCRC " : "BadSector ");
532 if (err & ECC_ERR) printk("UncorrectableError ");
533 if (err & ID_ERR) printk("SectorIdNotFound ");
534 if (err & TRK0_ERR) printk("TrackZeroNotFound ");
535 if (err & MARK_ERR) printk("AddrMarkNotFound ");
536 printk("}");
537 if ((err & (BBD_ERR | ABRT_ERR)) == BBD_ERR ||
538 (err & (ECC_ERR|ID_ERR|MARK_ERR))) {
539 ide_dump_sector(drive);
540 if (HWGROUP(drive) && HWGROUP(drive)->rq)
541 printk(", sector=%llu",
542 (unsigned long long)HWGROUP(drive)->rq->sector);
502 } 543 }
544 printk("\n");
545}
546
547static void ide_dump_atapi_error(ide_drive_t *drive, u8 err)
548{
549 printk("{ ");
550 if (err & ILI_ERR) printk("IllegalLengthIndication ");
551 if (err & EOM_ERR) printk("EndOfMedia ");
552 if (err & ABRT_ERR) printk("AbortedCommand ");
553 if (err & MCR_ERR) printk("MediaChangeRequested ");
554 if (err & LFS_ERR) printk("LastFailedSense=0x%02x ",
555 (err & LFS_ERR) >> 4);
503 printk("}\n"); 556 printk("}\n");
504 if ((stat & (BUSY_STAT|ERR_STAT)) == ERR_STAT) {
505 err = hwif->INB(IDE_ERROR_REG);
506 printk("%s: %s: error=0x%02x { ", drive->name, msg, err);
507 if (err & ABRT_ERR) printk("DriveStatusError ");
508 if (err & ICRC_ERR)
509 printk((err & ABRT_ERR) ? "BadCRC " : "BadSector ");
510 if (err & ECC_ERR) printk("UncorrectableError ");
511 if (err & ID_ERR) printk("SectorIdNotFound ");
512 if (err & TRK0_ERR) printk("TrackZeroNotFound ");
513 if (err & MARK_ERR) printk("AddrMarkNotFound ");
514 printk("}");
515 if ((err & (BBD_ERR | ABRT_ERR)) == BBD_ERR ||
516 (err & (ECC_ERR|ID_ERR|MARK_ERR))) {
517 if (drive->addressing == 1) {
518 __u64 sectors = 0;
519 u32 low = 0, high = 0;
520 hwif->OUTB(drive->ctl&~0x80, IDE_CONTROL_REG);
521 low = ide_read_24(drive);
522 hwif->OUTB(drive->ctl|0x80, IDE_CONTROL_REG);
523 high = ide_read_24(drive);
524 sectors = ((__u64)high << 24) | low;
525 printk(", LBAsect=%llu, high=%d, low=%d",
526 (unsigned long long) sectors,
527 high, low);
528 } else {
529 u8 cur = hwif->INB(IDE_SELECT_REG);
530 if (cur & 0x40) { /* using LBA? */
531 printk(", LBAsect=%ld", (unsigned long)
532 ((cur&0xf)<<24)
533 |(hwif->INB(IDE_HCYL_REG)<<16)
534 |(hwif->INB(IDE_LCYL_REG)<<8)
535 | hwif->INB(IDE_SECTOR_REG));
536 } else {
537 printk(", CHS=%d/%d/%d",
538 (hwif->INB(IDE_HCYL_REG)<<8) +
539 hwif->INB(IDE_LCYL_REG),
540 cur & 0xf,
541 hwif->INB(IDE_SECTOR_REG));
542 }
543 }
544 if (HWGROUP(drive) && HWGROUP(drive)->rq)
545 printk(", sector=%llu",
546 (unsigned long long)HWGROUP(drive)->rq->sector);
547 }
548 printk("\n");
549 }
550 ide_dump_opcode(drive);
551 local_irq_restore(flags);
552 return err;
553} 557}
554 558
555/** 559/**
556 * ide_dump_atapi_status - print human readable atapi status 560 * ide_dump_status - translate ATA/ATAPI error
557 * @drive: drive that status applies to 561 * @drive: drive that status applies to
558 * @msg: text message to print 562 * @msg: text message to print
559 * @stat: status byte to decode 563 * @stat: status byte to decode
560 * 564 *
561 * Error reporting, in human readable form (luxurious, but a memory hog). 565 * Error reporting, in human readable form (luxurious, but a memory hog).
566 * Combines the drive name, message and status byte to provide a
567 * user understandable explanation of the device error.
562 */ 568 */
563 569
564static u8 ide_dump_atapi_status(ide_drive_t *drive, const char *msg, u8 stat) 570u8 ide_dump_status(ide_drive_t *drive, const char *msg, u8 stat)
565{ 571{
566 unsigned long flags; 572 unsigned long flags;
573 u8 err = 0;
567 574
568 atapi_status_t status;
569 atapi_error_t error;
570
571 status.all = stat;
572 error.all = 0;
573 local_irq_save(flags); 575 local_irq_save(flags);
574 printk("%s: %s: status=0x%02x { ", drive->name, msg, stat); 576 printk("%s: %s: status=0x%02x { ", drive->name, msg, stat);
575 if (status.b.bsy) 577 if (stat & BUSY_STAT)
576 printk("Busy "); 578 printk("Busy ");
577 else { 579 else {
578 if (status.b.drdy) printk("DriveReady "); 580 if (stat & READY_STAT) printk("DriveReady ");
579 if (status.b.df) printk("DeviceFault "); 581 if (stat & WRERR_STAT) printk("DeviceFault ");
580 if (status.b.dsc) printk("SeekComplete "); 582 if (stat & SEEK_STAT) printk("SeekComplete ");
581 if (status.b.drq) printk("DataRequest "); 583 if (stat & DRQ_STAT) printk("DataRequest ");
582 if (status.b.corr) printk("CorrectedError "); 584 if (stat & ECC_STAT) printk("CorrectedError ");
583 if (status.b.idx) printk("Index "); 585 if (stat & INDEX_STAT) printk("Index ");
584 if (status.b.check) printk("Error "); 586 if (stat & ERR_STAT) printk("Error ");
585 } 587 }
586 printk("}\n"); 588 printk("}\n");
587 if (status.b.check && !status.b.bsy) { 589 if ((stat & (BUSY_STAT|ERR_STAT)) == ERR_STAT) {
588 error.all = HWIF(drive)->INB(IDE_ERROR_REG); 590 err = drive->hwif->INB(IDE_ERROR_REG);
589 printk("%s: %s: error=0x%02x { ", drive->name, msg, error.all); 591 printk("%s: %s: error=0x%02x ", drive->name, msg, err);
590 if (error.b.ili) printk("IllegalLengthIndication "); 592 if (drive->media == ide_disk)
591 if (error.b.eom) printk("EndOfMedia "); 593 ide_dump_ata_error(drive, err);
592 if (error.b.abrt) printk("AbortedCommand "); 594 else
593 if (error.b.mcr) printk("MediaChangeRequested "); 595 ide_dump_atapi_error(drive, err);
594 if (error.b.sense_key) printk("LastFailedSense=0x%02x ",
595 error.b.sense_key);
596 printk("}\n");
597 } 596 }
598 ide_dump_opcode(drive); 597 ide_dump_opcode(drive);
599 local_irq_restore(flags); 598 local_irq_restore(flags);
600 return error.all; 599 return err;
601}
602
603/**
604 * ide_dump_status - translate ATA/ATAPI error
605 * @drive: drive the error occured on
606 * @msg: information string
607 * @stat: status byte
608 *
609 * Error reporting, in human readable form (luxurious, but a memory hog).
610 * Combines the drive name, message and status byte to provide a
611 * user understandable explanation of the device error.
612 */
613
614u8 ide_dump_status(ide_drive_t *drive, const char *msg, u8 stat)
615{
616 if (drive->media == ide_disk)
617 return ide_dump_ata_status(drive, msg, stat);
618 return ide_dump_atapi_status(drive, msg, stat);
619} 600}
620 601
621EXPORT_SYMBOL(ide_dump_status); 602EXPORT_SYMBOL(ide_dump_status);