summaryrefslogtreecommitdiffstats
path: root/Kbuild
AgeCommit message (Expand)Author
2020-02-04kbuild: rename hostprogs-y/always to hostprogs/always-yMasahiro Yamada
2019-08-21kbuild: do not descend to ./Kbuild when cleaningMasahiro Yamada
2019-08-15kbuild: remove meaningless 'targets' in ./KbuildMasahiro Yamada
2019-03-10Merge tag 'kbuild-v5.1' of git://git.kernel.org/pub/scm/linux/kernel/git/masa...Linus Torvalds
2019-02-27kbuild: remove unimportant comments from ./KbuildMasahiro Yamada
2019-02-27scripts/gdb: delay generation of gdb constants.pyMasahiro Yamada
2019-02-11Merge branch 'locking/atomics' into locking/core, to pick up WIP commitsIngo Molnar
2019-01-06kbuild: use assignment instead of define ... endef for filechk_* rulesMasahiro Yamada
2019-01-06kbuild: change filechk to surround the given command with { }Masahiro Yamada
2018-12-25kbuild: remove unused cmd_gentimeconstMasahiro Yamada
2018-12-23kbuild: remove $(obj)/ prefixes in ./KbuildMasahiro Yamada
2018-12-23treewide: remove explicit rules for *offsets.sMasahiro Yamada
2018-11-09locking/atomics: Fix out-of-tree buildBorislav Petkov
2018-11-01locking/atomics: Check generated headers are up-to-dateMark Rutland
2017-11-17Merge tag 'kbuild-v4.15' of git://git.kernel.org/pub/scm/linux/kernel/git/mas...Linus Torvalds
2017-11-16kbuild: remove redundant mkdir from ./KbuildMasahiro Yamada
2017-11-02License cleanup: add SPDX GPL-2.0 license identifier to files with no licenseGreg Kroah-Hartman
2017-04-13kbuild: Consolidate header generation from ASM offset informationMatthias Kaehlcke
2016-05-23scripts/gdb: provide linux constantsKieran Bingham
2015-07-01time: Remove development rules from Kbuild/MakefileThomas Gleixner
2015-05-19time: Move timeconst.h into include/generatedNicholas Mc Guire
2015-04-02kbuild: do not add $(bounds-file) and $(offsets-file) to targetsMasahiro Yamada
2015-03-24kbuild: Don't reset timestamps in include/generated if not neededMichal Marek
2015-01-05kbuild: remove redundant line from bounds.h/asm-offsets.hMasahiro Yamada
2015-01-05kbuild: merge bounds.h and asm-offsets.h rulesMasahiro Yamada
2011-11-09kbuild: Fix missing system calls check on mips.David Daney
2011-11-02Kbuild: append missing-syscalls to the default target listArnaud Lacombe
2010-10-28Merge branch 'kbuild' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek...Linus Torvalds
2010-10-27Partially revert patch that encloses asm-offset.h numbers in bracketsDavid Howells
2010-10-22x86, asm: Fix ancient-GAS workaroundAlexander van Heukelum
2010-10-19x86, asm: Fix CFI macro invocations to deal with shortcomings in gasJan Beulich
2010-03-11kbuild: Really don't clean bounds.h and asm-offsets.hMichal Marek
2009-12-12kbuild: move asm-offsets.h to include/generatedSam Ravnborg
2009-12-12kbuild: move bounds.h to include/generatedSam Ravnborg
2008-07-25kbuild: asm symlink support for arch/$ARCH/includeSam Ravnborg
2008-05-19Don't clean bounds.h and asm-offsets.hJan Blunck
2008-04-28pageflags: standardize comment inclusion in asm-offsets.h and fix MIPSChristoph Lameter
2008-04-28kbuild: create a way to create preprocessor constants from C expressionsChristoph Lameter
2007-10-11i386/x86_64: move headers to include/asm-x86Thomas Gleixner
2007-10-11Kbuild: allow arch/xxx to use a different source pathThomas Gleixner
2007-07-16kbuild: asm-offsets.h is now cleaned with O=.. buildsSam Ravnborg
2007-05-02kbuild: complain about missing system callsSam Ravnborg
2006-09-25remove RPM_BUILD_ROOT from asm-offsets.hOlaf Hering
2006-04-05kbuild: mips: fix sed regexp to generate asm-offset.hAtsushi Nemoto
2006-01-08kbuild: clean up asm-offsets.h creationBrian Gerst
2005-09-10kbuild: fix generic asm-offsets.h supportSam Ravnborg
2005-09-09kbuild: mips use generic asm-offsets.h supportSam Ravnborg
2005-09-09kbuild: full dependency check on asm-offsets.hSam Ravnborg
349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442
#include <linux/kernel.h>
#include <linux/export.h>
#include <linux/ide.h>
#include <linux/delay.h>

static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq,
				     u8 stat, u8 err)
{
	ide_hwif_t *hwif = drive->hwif;

	if ((stat & ATA_BUSY) ||
	    ((stat & ATA_DF) && (drive->dev_flags & IDE_DFLAG_NOWERR) == 0)) {
		/* other bits are useless when BUSY */
		rq->errors |= ERROR_RESET;
	} else if (stat & ATA_ERR) {
		/* err has different meaning on cdrom and tape */
		if (err == ATA_ABORTED) {
			if ((drive->dev_flags & IDE_DFLAG_LBA) &&
			    /* some newer drives don't support ATA_CMD_INIT_DEV_PARAMS */
			    hwif->tp_ops->read_status(hwif) == ATA_CMD_INIT_DEV_PARAMS)
				return ide_stopped;
		} else if ((err & BAD_CRC) == BAD_CRC) {
			/* UDMA crc error, just retry the operation */
			drive->crc_count++;
		} else if (err & (ATA_BBK | ATA_UNC)) {
			/* retries won't help these */
			rq->errors = ERROR_MAX;
		} else if (err & ATA_TRK0NF) {
			/* help it find track zero */
			rq->errors |= ERROR_RECAL;
		}
	}

	if ((stat & ATA_DRQ) && rq_data_dir(rq) == READ &&
	    (hwif->host_flags & IDE_HFLAG_ERROR_STOPS_FIFO) == 0) {
		int nsect = drive->mult_count ? drive->mult_count : 1;

		ide_pad_transfer(drive, READ, nsect * SECTOR_SIZE);
	}

	if (rq->errors >= ERROR_MAX || blk_noretry_request(rq)) {
		ide_kill_rq(drive, rq);
		return ide_stopped;
	}

	if (hwif->tp_ops->read_status(hwif) & (ATA_BUSY | ATA_DRQ))
		rq->errors |= ERROR_RESET;

	if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
		++rq->errors;
		return ide_do_reset(drive);
	}

	if ((rq->errors & ERROR_RECAL) == ERROR_RECAL)
		drive->special_flags |= IDE_SFLAG_RECALIBRATE;

	++rq->errors;

	return ide_stopped;
}

static ide_startstop_t ide_atapi_error(ide_drive_t *drive, struct request *rq,
				       u8 stat, u8 err)
{
	ide_hwif_t *hwif = drive->hwif;

	if ((stat & ATA_BUSY) ||
	    ((stat & ATA_DF) && (drive->dev_flags & IDE_DFLAG_NOWERR) == 0)) {
		/* other bits are useless when BUSY */
		rq->errors |= ERROR_RESET;
	} else {
		/* add decoding error stuff */
	}

	if (hwif->tp_ops->read_status(hwif) & (ATA_BUSY | ATA_DRQ))
		/* force an abort */
		hwif->tp_ops->exec_command(hwif, ATA_CMD_IDLEIMMEDIATE);

	if (rq->errors >= ERROR_MAX) {
		ide_kill_rq(drive, rq);
	} else {
		if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
			++rq->errors;
			return ide_do_reset(drive);
		}
		++rq->errors;
	}

	return ide_stopped;
}

static ide_startstop_t __ide_error(ide_drive_t *drive, struct request *rq,
				   u8 stat, u8 err)
{
	if (drive->media == ide_disk)
		return ide_ata_error(drive, rq, stat, err);
	return ide_atapi_error(drive, rq, stat, err);
}

/**
 *	ide_error	-	handle an error on the IDE
 *	@drive: drive the error occurred on
 *	@msg: message to report
 *	@stat: status bits
 *
 *	ide_error() takes action based on the error returned by the drive.
 *	For normal I/O that may well include retries. We deal with
 *	both new-style (taskfile) and old style command handling here.
 *	In the case of taskfile command handling there is work left to
 *	do
 */

ide_startstop_t ide_error(ide_drive_t *drive, const char *msg, u8 stat)
{
	struct request *rq;
	u8 err;

	err = ide_dump_status(drive, msg, stat);

	rq = drive->hwif->rq;
	if (rq == NULL)
		return ide_stopped;

	/* retry only "normal" I/O: */
	if (rq->cmd_type != REQ_TYPE_FS) {
		if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
			struct ide_cmd *cmd = rq->special;

			if (cmd)
				ide_complete_cmd(drive, cmd, stat, err);
		} else if (ata_pm_request(rq)) {
			rq->errors = 1;
			ide_complete_pm_rq(drive, rq);
			return ide_stopped;
		}
		rq->errors = err;
		ide_complete_rq(drive, err ? -EIO : 0, blk_rq_bytes(rq));
		return ide_stopped;
	}

	return __ide_error(drive, rq, stat, err);
}
EXPORT_SYMBOL_GPL(ide_error);

static inline void ide_complete_drive_reset(ide_drive_t *drive, int err)
{
	struct request *rq = drive->hwif->rq;

	if (rq && rq->cmd_type == REQ_TYPE_DRV_PRIV &&
	    rq->cmd[0] == REQ_DRIVE_RESET) {
		if (err <= 0 && rq->errors == 0)
			rq->errors = -EIO;
		ide_complete_rq(drive, err ? err : 0, blk_rq_bytes(rq));
	}
}

/* needed below */
static ide_startstop_t do_reset1(ide_drive_t *, int);

/*
 * atapi_reset_pollfunc() gets invoked to poll the interface for completion
 * every 50ms during an atapi drive reset operation.  If the drive has not yet
 * responded, and we have not yet hit our maximum waiting time, then the timer
 * is restarted for another 50ms.
 */
static ide_startstop_t atapi_reset_pollfunc(ide_drive_t *drive)
{
	ide_hwif_t *hwif = drive->hwif;
	const struct ide_tp_ops *tp_ops = hwif->tp_ops;
	u8 stat;

	tp_ops->dev_select(drive);
	udelay(10);
	stat = tp_ops->read_status(hwif);

	if (OK_STAT(stat, 0, ATA_BUSY))
		printk(KERN_INFO "%s: ATAPI reset complete\n", drive->name);
	else {
		if (time_before(jiffies, hwif->poll_timeout)) {
			ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20);
			/* continue polling */
			return ide_started;
		}
		/* end of polling */
		hwif->polling = 0;
		printk(KERN_ERR "%s: ATAPI reset timed-out, status=0x%02x\n",
			drive->name, stat);
		/* do it the old fashioned way */
		return do_reset1(drive, 1);
	}
	/* done polling */
	hwif->polling = 0;
	ide_complete_drive_reset(drive, 0);
	return ide_stopped;
}

static void ide_reset_report_error(ide_hwif_t *hwif, u8 err)
{
	static const char *err_master_vals[] =
		{ NULL, "passed", "formatter device error",
		  "sector buffer error", "ECC circuitry error",
		  "controlling MPU error" };

	u8 err_master = err & 0x7f;

	printk(KERN_ERR "%s: reset: master: ", hwif->name);
	if (err_master && err_master < 6)
		printk(KERN_CONT "%s", err_master_vals[err_master]);
	else
		printk(KERN_CONT "error (0x%02x?)", err);
	if (err & 0x80)
		printk(KERN_CONT "; slave: failed");
	printk(KERN_CONT "\n");
}

/*
 * reset_pollfunc() gets invoked to poll the interface for completion every 50ms
 * during an ide reset operation. If the drives have not yet responded,
 * and we have not yet hit our maximum waiting time, then the timer is restarted
 * for another 50ms.
 */
static ide_startstop_t reset_pollfunc(ide_drive_t *drive)
{
	ide_hwif_t *hwif = drive->hwif;
	const struct