X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fide%2Fide-lib.c;h=9b44fbdfe41fc503d085b6a0f08c1d3a9775d8fe;hb=444ad82bc3eaa554be40d22dc248e58aeefd54d9;hp=6b2e810cb9e099382bf27ea1d75c82a78cf99ece;hpb=a501633c7d44087e806597d3a213d735346edd51;p=linux-2.6 diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index 6b2e810cb9..9b44fbdfe4 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) * case could happen iff the transfer mode has already been set on * the device by ide-proc.c::set_xfer_rate()). */ + if (rate < XFER_PIO_0) { + if (hwif->host_flags & IDE_HFLAG_ABUSE_SET_DMA_MODE) + return ide_set_dma_mode(drive, rate); + else + return ide_config_drive_speed(drive, rate); + } return ide_set_dma_mode(drive, rate); } @@ -448,8 +454,7 @@ int ide_set_xfer_rate(ide_drive_t *drive, u8 rate) static void ide_dump_opcode(ide_drive_t *drive) { struct request *rq; - u8 opcode = 0; - int found = 0; + ide_task_t *task = NULL; spin_lock(&ide_lock); rq = NULL; @@ -458,25 +463,15 @@ static void ide_dump_opcode(ide_drive_t *drive) spin_unlock(&ide_lock); if (!rq) return; - if (rq->cmd_type == REQ_TYPE_ATA_CMD) { - char *args = rq->buffer; - if (args) { - opcode = args[0]; - found = 1; - } - } else if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { - ide_task_t *args = rq->special; - if (args) { - opcode = args->tf.command; - found = 1; - } - } + + if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) + task = rq->special; printk("ide: failed opcode was: "); - if (!found) - printk("unknown\n"); + if (task == NULL) + printk(KERN_CONT "unknown\n"); else - printk("0x%02x\n", opcode); + printk(KERN_CONT "0x%02x\n", task->tf.command); } u64 ide_get_lba_addr(struct ide_taskfile *tf, int lba48) @@ -517,61 +512,51 @@ static void ide_dump_sector(ide_drive_t *drive) tf->device & 0xf, tf->lbal); } -static u8 ide_dump_ata_status(ide_drive_t *drive, const char *msg, u8 stat) +static void ide_dump_ata_error(ide_drive_t *drive, u8 err) { - ide_hwif_t *hwif = HWIF(drive); - unsigned long flags; - u8 err = 0; - - local_irq_save(flags); - printk("%s: %s: status=0x%02x { ", drive->name, msg, stat); - if (stat & BUSY_STAT) - printk("Busy "); - else { - if (stat & READY_STAT) printk("DriveReady "); - if (stat & WRERR_STAT) printk("DeviceFault "); - if (stat & SEEK_STAT) printk("SeekComplete "); - if (stat & DRQ_STAT) printk("DataRequest "); - if (stat & ECC_STAT) printk("CorrectedError "); - if (stat & INDEX_STAT) printk("Index "); - if (stat & ERR_STAT) printk("Error "); + printk("{ "); + if (err & ABRT_ERR) printk("DriveStatusError "); + if (err & ICRC_ERR) + printk((err & ABRT_ERR) ? "BadCRC " : "BadSector "); + if (err & ECC_ERR) printk("UncorrectableError "); + if (err & ID_ERR) printk("SectorIdNotFound "); + if (err & TRK0_ERR) printk("TrackZeroNotFound "); + if (err & MARK_ERR) printk("AddrMarkNotFound "); + printk("}"); + if ((err & (BBD_ERR | ABRT_ERR)) == BBD_ERR || + (err & (ECC_ERR|ID_ERR|MARK_ERR))) { + ide_dump_sector(drive); + if (HWGROUP(drive) && HWGROUP(drive)->rq) + printk(", sector=%llu", + (unsigned long long)HWGROUP(drive)->rq->sector); } + printk("\n"); +} + +static void ide_dump_atapi_error(ide_drive_t *drive, u8 err) +{ + printk("{ "); + if (err & ILI_ERR) printk("IllegalLengthIndication "); + if (err & EOM_ERR) printk("EndOfMedia "); + if (err & ABRT_ERR) printk("AbortedCommand "); + if (err & MCR_ERR) printk("MediaChangeRequested "); + if (err & LFS_ERR) printk("LastFailedSense=0x%02x ", + (err & LFS_ERR) >> 4); printk("}\n"); - if ((stat & (BUSY_STAT|ERR_STAT)) == ERR_STAT) { - err = hwif->INB(IDE_ERROR_REG); - printk("%s: %s: error=0x%02x { ", drive->name, msg, err); - if (err & ABRT_ERR) printk("DriveStatusError "); - if (err & ICRC_ERR) - printk((err & ABRT_ERR) ? "BadCRC " : "BadSector "); - if (err & ECC_ERR) printk("UncorrectableError "); - if (err & ID_ERR) printk("SectorIdNotFound "); - if (err & TRK0_ERR) printk("TrackZeroNotFound "); - if (err & MARK_ERR) printk("AddrMarkNotFound "); - printk("}"); - if ((err & (BBD_ERR | ABRT_ERR)) == BBD_ERR || - (err & (ECC_ERR|ID_ERR|MARK_ERR))) { - ide_dump_sector(drive); - if (HWGROUP(drive) && HWGROUP(drive)->rq) - printk(", sector=%llu", - (unsigned long long)HWGROUP(drive)->rq->sector); - } - printk("\n"); - } - ide_dump_opcode(drive); - local_irq_restore(flags); - return err; } /** - * ide_dump_atapi_status - print human readable atapi status + * ide_dump_status - translate ATA/ATAPI error * @drive: drive that status applies to * @msg: text message to print * @stat: status byte to decode * * Error reporting, in human readable form (luxurious, but a memory hog). + * Combines the drive name, message and status byte to provide a + * user understandable explanation of the device error. */ -static u8 ide_dump_atapi_status(ide_drive_t *drive, const char *msg, u8 stat) +u8 ide_dump_status(ide_drive_t *drive, const char *msg, u8 stat) { unsigned long flags; u8 err = 0; @@ -592,36 +577,15 @@ static u8 ide_dump_atapi_status(ide_drive_t *drive, const char *msg, u8 stat) printk("}\n"); if ((stat & (BUSY_STAT|ERR_STAT)) == ERR_STAT) { err = drive->hwif->INB(IDE_ERROR_REG); - printk("%s: %s: error=0x%02x { ", drive->name, msg, err); - if (err & ILI_ERR) printk("IllegalLengthIndication "); - if (err & EOM_ERR) printk("EndOfMedia "); - if (err & ABRT_ERR) printk("AbortedCommand "); - if (err & MCR_ERR) printk("MediaChangeRequested "); - if (err & LFS_ERR) printk("LastFailedSense=0x%02x ", - (err & LFS_ERR) >> 4); - printk("}\n"); + printk("%s: %s: error=0x%02x ", drive->name, msg, err); + if (drive->media == ide_disk) + ide_dump_ata_error(drive, err); + else + ide_dump_atapi_error(drive, err); } ide_dump_opcode(drive); local_irq_restore(flags); return err; } -/** - * ide_dump_status - translate ATA/ATAPI error - * @drive: drive the error occured on - * @msg: information string - * @stat: status byte - * - * Error reporting, in human readable form (luxurious, but a memory hog). - * Combines the drive name, message and status byte to provide a - * user understandable explanation of the device error. - */ - -u8 ide_dump_status(ide_drive_t *drive, const char *msg, u8 stat) -{ - if (drive->media == ide_disk) - return ide_dump_ata_status(drive, msg, stat); - return ide_dump_atapi_status(drive, msg, stat); -} - EXPORT_SYMBOL(ide_dump_status);