From 9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00 Mon Sep 17 00:00:00 2001 From: Yunhong Jiang Date: Tue, 4 Aug 2015 12:17:53 -0700 Subject: Add the rt linux 4.1.3-rt3 as base Import the rt linux 4.1.3-rt3 as OPNFV kvm base. It's from git://git.kernel.org/pub/scm/linux/kernel/git/rt/linux-rt-devel.git linux-4.1.y-rt and the base is: commit 0917f823c59692d751951bf5ea699a2d1e2f26a2 Author: Sebastian Andrzej Siewior Date: Sat Jul 25 12:13:34 2015 +0200 Prepare v4.1.3-rt3 Signed-off-by: Sebastian Andrzej Siewior We lose all the git history this way and it's not good. We should apply another opnfv project repo in future. Change-Id: I87543d81c9df70d99c5001fbdf646b202c19f423 Signed-off-by: Yunhong Jiang --- kernel/drivers/ide/ide-lib.c | 171 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 kernel/drivers/ide/ide-lib.c (limited to 'kernel/drivers/ide/ide-lib.c') diff --git a/kernel/drivers/ide/ide-lib.c b/kernel/drivers/ide/ide-lib.c new file mode 100644 index 000000000..e1180fa46 --- /dev/null +++ b/kernel/drivers/ide/ide-lib.c @@ -0,0 +1,171 @@ +#include +#include +#include +#include +#include +#include +#include + +/** + * ide_toggle_bounce - handle bounce buffering + * @drive: drive to update + * @on: on/off boolean + * + * Enable or disable bounce buffering for the device. Drives move + * between PIO and DMA and that changes the rules we need. + */ + +void ide_toggle_bounce(ide_drive_t *drive, int on) +{ + u64 addr = BLK_BOUNCE_HIGH; /* dma64_addr_t */ + + if (!PCI_DMA_BUS_IS_PHYS) { + addr = BLK_BOUNCE_ANY; + } else if (on && drive->media == ide_disk) { + struct device *dev = drive->hwif->dev; + + if (dev && dev->dma_mask) + addr = *dev->dma_mask; + } + + if (drive->queue) + blk_queue_bounce_limit(drive->queue, addr); +} + +u64 ide_get_lba_addr(struct ide_cmd *cmd, int lba48) +{ + struct ide_taskfile *tf = &cmd->tf; + u32 high, low; + + low = (tf->lbah << 16) | (tf->lbam << 8) | tf->lbal; + if (lba48) { + tf = &cmd->hob; + high = (tf->lbah << 16) | (tf->lbam << 8) | tf->lbal; + } else + high = tf->device & 0xf; + + return ((u64)high << 24) | low; +} +EXPORT_SYMBOL_GPL(ide_get_lba_addr); + +static void ide_dump_sector(ide_drive_t *drive) +{ + struct ide_cmd cmd; + struct ide_taskfile *tf = &cmd.tf; + u8 lba48 = !!(drive->dev_flags & IDE_DFLAG_LBA48); + + memset(&cmd, 0, sizeof(cmd)); + if (lba48) { + cmd.valid.in.tf = IDE_VALID_LBA; + cmd.valid.in.hob = IDE_VALID_LBA; + cmd.tf_flags = IDE_TFLAG_LBA48; + } else + cmd.valid.in.tf = IDE_VALID_LBA | IDE_VALID_DEVICE; + + ide_tf_readback(drive, &cmd); + + if (lba48 || (tf->device & ATA_LBA)) + printk(KERN_CONT ", LBAsect=%llu", + (unsigned long long)ide_get_lba_addr(&cmd, lba48)); + else + printk(KERN_CONT ", CHS=%d/%d/%d", (tf->lbah << 8) + tf->lbam, + tf->device & 0xf, tf->lbal); +} + +static void ide_dump_ata_error(ide_drive_t *drive, u8 err) +{ + printk(KERN_CONT "{ "); + if (err & ATA_ABORTED) + printk(KERN_CONT "DriveStatusError "); + if (err & ATA_ICRC) + printk(KERN_CONT "%s", + (err & ATA_ABORTED) ? "BadCRC " : "BadSector "); + if (err & ATA_UNC) + printk(KERN_CONT "UncorrectableError "); + if (err & ATA_IDNF) + printk(KERN_CONT "SectorIdNotFound "); + if (err & ATA_TRK0NF) + printk(KERN_CONT "TrackZeroNotFound "); + if (err & ATA_AMNF) + printk(KERN_CONT "AddrMarkNotFound "); + printk(KERN_CONT "}"); + if ((err & (ATA_BBK | ATA_ABORTED)) == ATA_BBK || + (err & (ATA_UNC | ATA_IDNF | ATA_AMNF))) { + struct request *rq = drive->hwif->rq; + + ide_dump_sector(drive); + + if (rq) + printk(KERN_CONT ", sector=%llu", + (unsigned long long)blk_rq_pos(rq)); + } + printk(KERN_CONT "\n"); +} + +static void ide_dump_atapi_error(ide_drive_t *drive, u8 err) +{ + printk(KERN_CONT "{ "); + if (err & ATAPI_ILI) + printk(KERN_CONT "IllegalLengthIndication "); + if (err & ATAPI_EOM) + printk(KERN_CONT "EndOfMedia "); + if (err & ATA_ABORTED) + printk(KERN_CONT "AbortedCommand "); + if (err & ATA_MCR) + printk(KERN_CONT "MediaChangeRequested "); + if (err & ATAPI_LFS) + printk(KERN_CONT "LastFailedSense=0x%02x ", + (err & ATAPI_LFS) >> 4); + printk(KERN_CONT "}\n"); +} + +/** + * 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. + */ + +u8 ide_dump_status(ide_drive_t *drive, const char *msg, u8 stat) +{ + u8 err = 0; + + printk(KERN_ERR "%s: %s: status=0x%02x { ", drive->name, msg, stat); + if (stat & ATA_BUSY) + printk(KERN_CONT "Busy "); + else { + if (stat & ATA_DRDY) + printk(KERN_CONT "DriveReady "); + if (stat & ATA_DF) + printk(KERN_CONT "DeviceFault "); + if (stat & ATA_DSC) + printk(KERN_CONT "SeekComplete "); + if (stat & ATA_DRQ) + printk(KERN_CONT "DataRequest "); + if (stat & ATA_CORR) + printk(KERN_CONT "CorrectedError "); + if (stat & ATA_SENSE) + printk(KERN_CONT "Sense "); + if (stat & ATA_ERR) + printk(KERN_CONT "Error "); + } + printk(KERN_CONT "}\n"); + if ((stat & (ATA_BUSY | ATA_ERR)) == ATA_ERR) { + err = ide_read_error(drive); + printk(KERN_ERR "%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); + } + + printk(KERN_ERR "%s: possibly failed opcode: 0x%02x\n", + drive->name, drive->hwif->cmd.tf.command); + + return err; +} +EXPORT_SYMBOL(ide_dump_status); -- cgit 1.2.3-korg