// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2000-2011
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 */

#define LOG_CATEGORY UCLASS_IDE

#include <ata.h>
#include <blk.h>
#include <bootdev.h>
#include <dm.h>
#include <ide.h>
#include <log.h>
#include <part.h>
#include <watchdog.h>
#include <asm/io.h>
#include <linux/delay.h>

#ifdef __PPC__
# define EIEIO		__asm__ volatile ("eieio")
# define SYNC		__asm__ volatile ("sync")
#else
# define EIEIO		/* nothing */
# define SYNC		/* nothing */
#endif

/* Current offset for IDE0 / IDE1 bus access	*/
ulong ide_bus_offset[CONFIG_SYS_IDE_MAXBUS] = {
#if defined(CONFIG_SYS_ATA_IDE0_OFFSET)
	CONFIG_SYS_ATA_IDE0_OFFSET,
#endif
#if defined(CONFIG_SYS_ATA_IDE1_OFFSET) && (CONFIG_SYS_IDE_MAXBUS > 1)
	CONFIG_SYS_ATA_IDE1_OFFSET,
#endif
};

#define ATA_CURR_BASE(dev)	(CONFIG_SYS_ATA_BASE_ADDR + \
		ide_bus_offset[IDE_BUS(dev)])

#define IDE_TIME_OUT	2000	/* 2 sec timeout */

#define ATAPI_TIME_OUT	7000	/* 7 sec timeout (5 sec seems to work...) */

#define IDE_SPIN_UP_TIME_OUT 5000 /* 5 sec spin-up timeout */

static void ide_reset(void)
{
	if (IS_ENABLED(CONFIG_IDE_RESET)) {
		/* assert reset */
		ide_set_reset(1);

		/* the reset signal shall be asserted for et least 25 us */
		udelay(25);

		schedule();

		/* de-assert RESET signal */
		ide_set_reset(0);

		mdelay(250);
	}
}

static void ide_outb(int dev, int port, u8 val)
{
	log_debug("(dev= %d, port= %#x, val= 0x%02x) : @ 0x%08lx\n",
		  dev, port, val, ATA_CURR_BASE(dev) + port);

	outb(val, ATA_CURR_BASE(dev) + port);
}

static u8 ide_inb(int dev, int port)
{
	uchar val;

	val = inb(ATA_CURR_BASE(dev) + port);

	log_debug("(dev= %d, port= %#x) : @ 0x%08lx -> 0x%02x\n",
		  dev, port, ATA_CURR_BASE(dev) + port, val);
	return val;
}

static void ide_input_swap_data(int dev, ulong *sect_buf, int words)
{
	uintptr_t paddr = (ATA_CURR_BASE(dev) + ATA_DATA_REG);
	ushort *dbuf = (ushort *)sect_buf;

	log_debug("in input swap data base for read is %p\n", (void *)paddr);

	while (words--) {
		EIEIO;
		*dbuf++ = be16_to_cpu(inw(paddr));
		EIEIO;
		*dbuf++ = be16_to_cpu(inw(paddr));
	}
}

/*
 * Wait until Busy bit is off, or timeout (in ms)
 * Return last status
 */
static uchar ide_wait(int dev, ulong t)
{
	ulong delay = 10 * t;	/* poll every 100 us */
	uchar c;

	while ((c = ide_inb(dev, ATA_STATUS)) & ATA_STAT_BUSY) {
		udelay(100);
		if (!delay--)
			break;
	}
	return c;
}

/*
 * copy src to dest, skipping leading and trailing blanks and null
 * terminate the string
 * "len" is the size of available memory including the terminating '\0'
 */
static void ident_cpy(u8 *dst, u8 *src, uint len)
{
	u8 *end, *last;

	last = dst;
	end = src + len - 1;

	/* reserve space for '\0' */
	if (len < 2)
		goto OUT;

	/* skip leading white space */
	while ((*src) && (src < end) && (*src == ' '))
		++src;

	/* copy string, omitting trailing white space */
	while ((*src) && (src < end)) {
		*dst++ = *src;
		if (*src++ != ' ')
			last = dst;
	}
OUT:
	*last = '\0';
}

/****************************************************************************
 * ATAPI Support
 */

/* since ATAPI may use commands with not 4 bytes alligned length
 * we have our own transfer functions, 2 bytes alligned */
static void ide_output_data_shorts(int dev, ushort *sect_buf, int shorts)
{
	uintptr_t paddr = ATA_CURR_BASE(dev) + ATA_DATA_REG;
	ushort *dbuf;

	dbuf = (ushort *)sect_buf;

	log_debug("in output data shorts base for read is %p\n", (void *)paddr);

	while (shorts--) {
		EIEIO;
		outw(cpu_to_le16(*dbuf++), paddr);
	}
}

static void ide_input_data_shorts(int dev, ushort *sect_buf, int shorts)
{
	uintptr_t paddr = ATA_CURR_BASE(dev) + ATA_DATA_REG;
	ushort *dbuf;

	dbuf = (ushort *)sect_buf;

	log_debug("in input data shorts base for read is %p\n", (void *)paddr);

	while (shorts--) {
		EIEIO;
		*dbuf++ = le16_to_cpu(inw(paddr));
	}
}

/*
 * Wait until (Status & mask) == res, or timeout (in ms)
 * Return last status
 * This is used since some ATAPI CD ROMs clears their Busy Bit first
 * and then they set their DRQ Bit
 */
static uchar atapi_wait_mask(int dev, ulong t, uchar mask, uchar res)
{
	ulong delay = 10 * t;	/* poll every 100 us */
	uchar c;

	/* prevents to read the status before valid */
	c = ide_inb(dev, ATA_DEV_CTL);

	while (c = ide_inb(dev, ATA_STATUS) & mask, c != res) {
		/* break if error occurs (doesn't make sense to wait more) */
		if ((c & ATA_STAT_ERR) == ATA_STAT_ERR)
			break;
		udelay(100);
		if (!delay--)
			break;
	}
	return c;
}

/*
 * issue an atapi command
 */
static u8 atapi_issue(int device, u8 *ccb, int ccblen, u8 *buffer, int buflen)
{
	u8 c, err, mask, res;
	int n;

	/* Select device
	 */
	mask = ATA_STAT_BUSY | ATA_STAT_DRQ;
	res = 0;
	ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
	c = atapi_wait_mask(device, ATAPI_TIME_OUT, mask, res);
	if ((c & mask) != res) {
		printf("ATAPI_ISSUE: device %d not ready status %x\n", device,
		       c);
		err = 0xff;
		goto AI_OUT;
	}
	/* write taskfile */
	ide_outb(device, ATA_ERROR_REG, 0);	/* no DMA, no overlaped */
	ide_outb(device, ATA_SECT_CNT, 0);
	ide_outb(device, ATA_SECT_NUM, 0);
	ide_outb(device, ATA_CYL_LOW, (u8)(buflen & 0xff));
	ide_outb(device, ATA_CYL_HIGH, (u8)((buflen >> 8) & 0xff));
	ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));

	ide_outb(device, ATA_COMMAND, ATA_CMD_PACKET);
	udelay(50);

	mask = ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR;
	res = ATA_STAT_DRQ;
	c = atapi_wait_mask(device, ATAPI_TIME_OUT, mask, res);

	if ((c & mask) != res) {	/* DRQ must be 1, BSY 0 */
		printf("ATAPI_ISSUE: Error (no IRQ) before sending ccb dev %d status %#02x\n",
		       device, c);
		err = 0xff;
		goto AI_OUT;
	}

	/* write command block */
	ide_output_data_shorts(device, (ushort *)ccb, ccblen / 2);

	/* ATAPI Command written wait for completition */
	mdelay(5);		/* device must set bsy */

	mask = ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR;
	/*
	 * if no data wait for DRQ = 0 BSY = 0
	 * if data wait for DRQ = 1 BSY = 0
	 */
	res = 0;
	if (buflen)
		res = ATA_STAT_DRQ;
	c = atapi_wait_mask(device, ATAPI_TIME_OUT, mask, res);
	if ((c & mask) != res) {
		if (c & ATA_STAT_ERR) {
			err = (ide_inb(device, ATA_ERROR_REG)) >> 4;
			log_debug("1 returned sense key %x status %02x\n",
				  err, c);
		} else {
			printf("ATAPI_ISSUE: (no DRQ) after sending ccb (%x)  status %#02x\n",
			       ccb[0], c);
			err = 0xff;
		}
		goto AI_OUT;
	}
	n = ide_inb(device, ATA_CYL_HIGH);
	n <<= 8;
	n += ide_inb(device, ATA_CYL_LOW);
	if (n > buflen) {
		printf("ERROR, transfer bytes %d requested only %d\n", n,
		       buflen);
		err = 0xff;
		goto AI_OUT;
	}
	if (!n && buflen < 0) {
		printf("ERROR, transfer bytes %d requested %d\n", n, buflen);
		err = 0xff;
		goto AI_OUT;
	}
	if (n != buflen) {
		log_debug("WARNING, transfer bytes %d not equal with requested %d\n",
			  n, buflen);
	}
	if (n) {		/* data transfer */
		log_debug("ATAPI_ISSUE: %d Bytes to transfer\n", n);
		/* we transfer shorts */
		n >>= 1;
		/* ok now decide if it is an in or output */
		if (!(ide_inb(device, ATA_SECT_CNT) & 0x02)) {
			log_debug("Write to device\n");
			ide_output_data_shorts(device, (ushort *)buffer, n);
		} else {
			log_debug("Read from device @ %p shorts %d\n", buffer,
				  n);
			ide_input_data_shorts(device, (ushort *)buffer, n);
		}
	}
	mdelay(5);		/* seems that some CD ROMs need this... */
	mask = ATA_STAT_BUSY | ATA_STAT_ERR;
	res = 0;
	c = atapi_wait_mask(device, ATAPI_TIME_OUT, mask, res);
	if ((c & ATA_STAT_ERR) == ATA_STAT_ERR) {
		err = (ide_inb(device, ATA_ERROR_REG) >> 4);
		log_debug("2 returned sense key %x status %x\n", err, c);
	} else {
		err = 0;
	}
AI_OUT:
	return err;
}

/*
 * sending the command to atapi_issue. If an status other than good
 * returns, an request_sense will be issued
 */

#define ATAPI_DRIVE_NOT_READY	100
#define ATAPI_UNIT_ATTN		10

static u8 atapi_issue_autoreq(int device, u8 *ccb, int ccblen, u8 *buffer,
			      int buflen)
{
	u8 sense_data[18], sense_ccb[12];
	u8 res, key, asc, ascq;
	int notready, unitattn;

	unitattn = ATAPI_UNIT_ATTN;
	notready = ATAPI_DRIVE_NOT_READY;

retry:
	res = atapi_issue(device, ccb, ccblen, buffer, buflen);
	if (!res)
		return 0;	/* Ok */

	if (res == 0xff)
		return 0xff;	/* error */

	log_debug("(auto_req)atapi_issue returned sense key %x\n", res);

	memset(sense_ccb, 0, sizeof(sense_ccb));
	memset(sense_data, 0, sizeof(sense_data));
	sense_ccb[0] = ATAPI_CMD_REQ_SENSE;
	sense_ccb[4] = 18;	/* allocation Length */

	res = atapi_issue(device, sense_ccb, 12, sense_data, 18);
	key = (sense_data[2] & 0xf);
	asc = (sense_data[12]);
	ascq = (sense_data[13]);

	log_debug("ATAPI_CMD_REQ_SENSE returned %x\n", res);
	log_debug(" Sense page: %02X key %02X ASC %02X ASCQ %02X\n",
		  sense_data[0], key, asc, ascq);

	if (!key)
		return 0;	/* ok device ready */

	if (key == 6 || asc == 0x29 || asc == 0x28) { /* Unit Attention */
		if (unitattn-- > 0) {
			mdelay(200);
			goto retry;
		}
		printf("Unit Attention, tried %d\n", ATAPI_UNIT_ATTN);
		goto error;
	}
	if (asc == 0x4 && ascq == 0x1) {
		/* not ready, but will be ready soon */
		if (notready-- > 0) {
			mdelay(200);
			goto retry;
		}
		printf("Drive not ready, tried %d times\n",
		       ATAPI_DRIVE_NOT_READY);
		goto error;
	}
	if (asc == 0x3a) {
		log_debug("Media not present\n");
		goto error;
	}

	printf("ERROR: Unknown Sense key %02X ASC %02X ASCQ %02X\n", key, asc,
	       ascq);
error:
	log_debug("ERROR Sense key %02X ASC %02X ASCQ %02X\n", key, asc, ascq);
	return 0xff;
}

/*
 * atapi_read:
 * we transfer only one block per command, since the multiple DRQ per
 * command is not yet implemented
 */
#define ATAPI_READ_MAX_BYTES	2048	/* we read max 2kbytes */
#define ATAPI_READ_BLOCK_SIZE	2048	/* assuming CD part */
#define ATAPI_READ_MAX_BLOCK	(ATAPI_READ_MAX_BYTES/ATAPI_READ_BLOCK_SIZE)

static ulong atapi_read(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
			void *buffer)
{
	struct blk_desc *desc = dev_get_uclass_plat(dev);
	int device = desc->devnum;
	ulong n = 0;
	u8 ccb[12];	/* Command descriptor block */
	ulong cnt;

	log_debug("%d start " LBAF " blocks " LBAF " buffer at %lx\n", device,
		  blknr, blkcnt, (ulong)buffer);

	do {
		if (blkcnt > ATAPI_READ_MAX_BLOCK)
			cnt = ATAPI_READ_MAX_BLOCK;
		else
			cnt = blkcnt;

		ccb[0] = ATAPI_CMD_READ_12;
		ccb[1] = 0;	/* reserved */
		ccb[2] = (u8)(blknr >> 24) & 0xff;	/* MSB Block */
		ccb[3] = (u8)(blknr >> 16) & 0xff;	/*  */
		ccb[4] = (u8)(blknr >> 8) & 0xff;
		ccb[5] = (u8)blknr & 0xff;	/* LSB Block */
		ccb[6] = (u8)(cnt >> 24) & 0xff; /* MSB Block cnt */
		ccb[7] = (u8)(cnt >> 16) & 0xff;
		ccb[8] = (u8)(cnt >> 8) & 0xff;
		ccb[9] = (u8)cnt & 0xff;	/* LSB Block */
		ccb[10] = 0;	/* reserved */
		ccb[11] = 0;	/* reserved */

		if (atapi_issue_autoreq(device, ccb, 12,
					(u8 *)buffer,
					cnt * ATAPI_READ_BLOCK_SIZE) == 0xff)
			return n;
		n += cnt;
		blkcnt -= cnt;
		blknr += cnt;
		buffer += cnt * ATAPI_READ_BLOCK_SIZE;
	} while (blkcnt > 0);
	return n;
}

static void atapi_inquiry(struct blk_desc *desc)
{
	u8 ccb[12];	/* Command descriptor block */
	u8 iobuf[64];	/* temp buf */
	u8 c;
	int device;

	device = desc->devnum;
	desc->type = DEV_TYPE_UNKNOWN;	/* not yet valid */

	memset(ccb, 0, sizeof(ccb));
	memset(iobuf, 0, sizeof(iobuf));

	ccb[0] = ATAPI_CMD_INQUIRY;
	ccb[4] = 40;		/* allocation Legnth */
	c = atapi_issue_autoreq(device, ccb, 12, (u8 *)iobuf, 40);

	log_debug("ATAPI_CMD_INQUIRY returned %x\n", c);
	if (c)
		return;

	/* copy device ident strings */
	ident_cpy((u8 *)desc->vendor, &iobuf[8], 8);
	ident_cpy((u8 *)desc->product, &iobuf[16], 16);
	ident_cpy((u8 *)desc->revision, &iobuf[32], 5);

	desc->lun = 0;
	desc->lba = 0;
	desc->blksz = 0;
	desc->log2blksz = LOG2_INVALID(typeof(desc->log2blksz));
	desc->type = iobuf[0] & 0x1f;

	if (iobuf[1] & 0x80)
		desc->removable = 1;
	else
		desc->removable = 0;

	memset(ccb, 0, sizeof(ccb));
	memset(iobuf, 0, sizeof(iobuf));
	ccb[0] = ATAPI_CMD_START_STOP;
	ccb[4] = 0x03;		/* start */

	c = atapi_issue_autoreq(device, ccb, 12, (u8 *)iobuf, 0);

	log_debug("ATAPI_CMD_START_STOP returned %x\n", c);
	if (c)
		return;

	memset(ccb, 0, sizeof(ccb));
	memset(iobuf, 0, sizeof(iobuf));
	c = atapi_issue_autoreq(device, ccb, 12, (u8 *)iobuf, 0);

	log_debug("ATAPI_CMD_UNIT_TEST_READY returned %x\n", c);
	if (c)
		return;

	memset(ccb, 0, sizeof(ccb));
	memset(iobuf, 0, sizeof(iobuf));
	ccb[0] = ATAPI_CMD_READ_CAP;
	c = atapi_issue_autoreq(device, ccb, 12, (u8 *)iobuf, 8);
	log_debug("ATAPI_CMD_READ_CAP returned %x\n", c);
	if (c)
		return;

	log_debug("Read Cap: LBA %02X%02X%02X%02X blksize %02X%02X%02X%02X\n",
		  iobuf[0], iobuf[1], iobuf[2], iobuf[3],
		  iobuf[4], iobuf[5], iobuf[6], iobuf[7]);

	desc->lba = (ulong)iobuf[0] << 24 | (ulong)iobuf[1] << 16 |
		(ulong)iobuf[2] << 8 | (ulong)iobuf[3];
	desc->blksz = (ulong)iobuf[4] << 24 | (ulong)iobuf[5] << 16 |
		(ulong)iobuf[6] << 8 | (ulong)iobuf[7];
	desc->log2blksz = LOG2(desc->blksz);

	/* ATAPI devices cannot use 48bit addressing (ATA/ATAPI v7) */
	desc->lba48 = false;
}

/**
 * ide_ident() - Identify an IDE device
 *
 * @device: Device number to use
 * @desc: Block descriptor to fill in
 * Returns: 0 if OK, -ENOENT if no device is found
 */
static int ide_ident(int device, struct blk_desc *desc)
{
	hd_driveid_t iop;
	bool is_atapi = false;
	int tries = 1;
	u8 c;

	memset(desc, '\0', sizeof(*desc));
	desc->devnum = device;
	desc->type = DEV_TYPE_UNKNOWN;
	desc->uclass_id = UCLASS_IDE;
	desc->log2blksz = LOG2_INVALID(typeof(desc->log2blksz));
	printf("  Device %d: ", device);

	/* Select device
	 */
	ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
	if (IS_ENABLED(CONFIG_ATAPI))
		tries = 2;

	while (tries) {
		/* check signature */
		if (IS_ENABLED(CONFIG_ATAPI) &&
		    ide_inb(device, ATA_SECT_CNT) == 0x01 &&
		    ide_inb(device, ATA_SECT_NUM) == 0x01 &&
		    ide_inb(device, ATA_CYL_LOW) == 0x14 &&
		    ide_inb(device, ATA_CYL_HIGH) == 0xeb) {
			/* ATAPI Signature found */
			is_atapi = true;
			/*
			 * Start Ident Command
			 */
			ide_outb(device, ATA_COMMAND, ATA_CMD_ID_ATAPI);
			/*
			 * Wait for completion - ATAPI devices need more time
			 * to become ready
			 */
			c = ide_wait(device, ATAPI_TIME_OUT);
		} else {
			/*
			 * Start Ident Command
			 */
			ide_outb(device, ATA_COMMAND, ATA_CMD_ID_ATA);

			/*
			 * Wait for completion
			 */
			c = ide_wait(device, IDE_TIME_OUT);
		}

		if ((c & ATA_STAT_DRQ) &&
		    !(c & (ATA_STAT_FAULT | ATA_STAT_ERR))) {
			break;
		} else if (IS_ENABLED(CONFIG_ATAPI)) {
			/*
			 * Need to soft reset the device
			 * in case it's an ATAPI...
			 */
			log_debug("Retrying...\n");
			ide_outb(device, ATA_DEV_HD,
				 ATA_LBA | ATA_DEVICE(device));
			mdelay(100);
			ide_outb(device, ATA_COMMAND, 0x08);
			mdelay(500);
			/* Select device */
			ide_outb(device, ATA_DEV_HD,
				 ATA_LBA | ATA_DEVICE(device));
		}
		tries--;
	}

	if (!tries)	/* Not found */
		return -ENOENT;

	ide_input_swap_data(device, (ulong *)&iop, ATA_SECTORWORDS);

	ident_cpy((u8 *)desc->revision, iop.fw_rev, sizeof(desc->revision));
	ident_cpy((u8 *)desc->vendor, iop.model, sizeof(desc->vendor));
	ident_cpy((u8 *)desc->product, iop.serial_no, sizeof(desc->product));

	if (iop.config & 0x0080)
		desc->removable = 1;
	else
		desc->removable = 0;

	if (IS_ENABLED(CONFIG_ATAPI) && is_atapi) {
		desc->atapi = true;
		atapi_inquiry(desc);
		return 0;
	}

	iop.lba_capacity[0] = be16_to_cpu(iop.lba_capacity[0]);
	iop.lba_capacity[1] = be16_to_cpu(iop.lba_capacity[1]);
	desc->lba = (ulong)iop.lba_capacity[0] |
		(ulong)iop.lba_capacity[1] << 16;

	if (IS_ENABLED(CONFIG_LBA48) && (iop.command_set_2 & 0x0400)) {
		/* LBA 48 support */
		desc->lba48 = true;
		for (int i = 0; i < 4; i++)
			iop.lba48_capacity[i] = be16_to_cpu(iop.lba48_capacity[i]);
		desc->lba = (unsigned long long)iop.lba48_capacity[0] |
			(unsigned long long)iop.lba48_capacity[1] << 16 |
			(unsigned long long)iop.lba48_capacity[2] << 32 |
			(unsigned long long)iop.lba48_capacity[3] << 48;
	} else {
		desc->lba48 = false;
	}

	/* assuming HD */
	desc->type = DEV_TYPE_HARDDISK;
	desc->blksz = ATA_BLOCKSIZE;
	desc->log2blksz = LOG2(desc->blksz);
	desc->lun = 0;	/* just to fill something in... */

#if 0				/* only used to test the powersaving mode,
				 * if enabled, the drive goes after 5 sec
				 * in standby mode */
	ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
	c = ide_wait(device, IDE_TIME_OUT);
	ide_outb(device, ATA_SECT_CNT, 1);
	ide_outb(device, ATA_LBA_LOW, 0);
	ide_outb(device, ATA_LBA_MID, 0);
	ide_outb(device, ATA_LBA_HIGH, 0);
	ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
	ide_outb(device, ATA_COMMAND, 0xe3);
	udelay(50);
	c = ide_wait(device, IDE_TIME_OUT);	/* can't take over 500 ms */
#endif

	return 0;
}

/**
 * ide_init_one() - Init one IDE device
 *
 * @bus: Bus to use
 * Return: 0 iuf OK, -EIO if not available, -ETIMEDOUT if timed out
 */
static int ide_init_one(int bus)
{
	int dev = bus * CONFIG_SYS_IDE_MAXDEVICE / CONFIG_SYS_IDE_MAXBUS;
	int i;
	u8 c;

	printf("Bus %d: ", bus);

	/* Select device */
	mdelay(100);
	ide_outb(dev, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(dev));
	mdelay(100);
	i = 0;
	do {
		mdelay(10);

		c = ide_inb(dev, ATA_STATUS);
		i++;
		if (i > (ATA_RESET_TIME * 100)) {
			puts("** Timeout **\n");
			return -ETIMEDOUT;
		}
		if (i >= 100 && !(i % 100))
			putc('.');
	} while (c & ATA_STAT_BUSY);

	if (c & (ATA_STAT_BUSY | ATA_STAT_FAULT)) {
		puts("not available  ");
		log_debug("Status = %#02X ", c);
		return -EIO;
	} else if (IS_ENABLED(CONFIG_ATAPI) && !(c & ATA_STAT_READY)) {
		/* ATAPI Devices do not set DRDY */
		puts("not available  ");
		log_debug("Status = %#02X ", c);
		return -EIO;
	}
	puts("OK ");

	return 0;
}

static void ide_output_data(int dev, const ulong *sect_buf, int words)
{
	uintptr_t paddr = (ATA_CURR_BASE(dev) + ATA_DATA_REG);
	ushort *dbuf;

	dbuf = (ushort *)sect_buf;
	while (words--) {
		EIEIO;
		outw(cpu_to_le16(*dbuf++), paddr);
		EIEIO;
		outw(cpu_to_le16(*dbuf++), paddr);
	}
}

static void ide_input_data(int dev, ulong *sect_buf, int words)
{
	uintptr_t paddr = (ATA_CURR_BASE(dev) + ATA_DATA_REG);
	ushort *dbuf;

	dbuf = (ushort *)sect_buf;

	log_debug("in input data base for read is %p\n", (void *)paddr);

	while (words--) {
		EIEIO;
		*dbuf++ = le16_to_cpu(inw(paddr));
		EIEIO;
		*dbuf++ = le16_to_cpu(inw(paddr));
	}
}

static ulong ide_read(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
		      void *buffer)
{
	struct blk_desc *desc = dev_get_uclass_plat(dev);
	int device = desc->devnum;
	bool lba48 = false;
	ulong n = 0;
	u8 pwrsave = 0;	/* power save */
	u8 c;

	if (IS_ENABLED(CONFIG_LBA48) && (blknr & 0x0000fffff0000000ULL)) {
		/* more than 28 bits used, use 48bit mode */
		lba48 = true;
	}

	log_debug("dev %d start " LBAF ", blocks " LBAF " buffer at %lx\n",
		  device, blknr, blkcnt, (ulong)buffer);

	/* Select device
	 */
	ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
	c = ide_wait(device, IDE_TIME_OUT);

	if (c & ATA_STAT_BUSY) {
		printf("IDE read: device %d not ready\n", device);
		goto IDE_READ_E;
	}

	/* first check if the drive is in Powersaving mode, if yes,
	 * increase the timeout value */
	ide_outb(device, ATA_COMMAND, ATA_CMD_CHK_POWER);
	udelay(50);

	c = ide_wait(device, IDE_TIME_OUT);	/* can't take over 500 ms */

	if (c & ATA_STAT_BUSY) {
		printf("IDE read: device %d not ready\n", device);
		goto IDE_READ_E;
	}
	if ((c & ATA_STAT_ERR) == ATA_STAT_ERR) {
		printf("No Powersaving mode %x\n", c);
	} else {
		c = ide_inb(device, ATA_SECT_CNT);
		log_debug("Powersaving %02X\n", c);
		if (!c)
			pwrsave = 1;
	}

	while (blkcnt-- > 0) {
		c = ide_wait(device, IDE_TIME_OUT);

		if (c & ATA_STAT_BUSY) {
			printf("IDE read: device %d not ready\n", device);
			break;
		}
		if (IS_ENABLED(CONFIG_LBA48) && lba48) {
			/* write high bits */
			ide_outb(device, ATA_SECT_CNT, 0);
			ide_outb(device, ATA_LBA_LOW, (blknr >> 24) & 0xff);
#ifdef CONFIG_SYS_64BIT_LBA
			ide_outb(device, ATA_LBA_MID, (blknr >> 32) & 0xff);
			ide_outb(device, ATA_LBA_HIGH, (blknr >> 40) & 0xff);
#else
			ide_outb(device, ATA_LBA_MID, 0);
			ide_outb(device, ATA_LBA_HIGH, 0);
#endif
		}
		ide_outb(device, ATA_SECT_CNT, 1);
		ide_outb(device, ATA_LBA_LOW, (blknr >> 0) & 0xff);
		ide_outb(device, ATA_LBA_MID, (blknr >> 8) & 0xff);
		ide_outb(device, ATA_LBA_HIGH, (blknr >> 16) & 0xff);

		if (IS_ENABLED(CONFIG_LBA48) && lba48) {
			ide_outb(device, ATA_DEV_HD,
				 ATA_LBA | ATA_DEVICE(device));
			ide_outb(device, ATA_COMMAND, ATA_CMD_PIO_READ_EXT);

		} else {
			ide_outb(device, ATA_DEV_HD, ATA_LBA |
				 ATA_DEVICE(device) | ((blknr >> 24) & 0xf));
			ide_outb(device, ATA_COMMAND, ATA_CMD_PIO_READ);
		}

		udelay(50);

		if (pwrsave) {
			/* may take up to 4 sec */
			c = ide_wait(device, IDE_SPIN_UP_TIME_OUT);
			pwrsave = 0;
		} else {
			/* can't take over 500 ms */
			c = ide_wait(device, IDE_TIME_OUT);
		}

		if ((c & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR)) !=
		    ATA_STAT_DRQ) {
			printf("Error (no IRQ) dev %d blk " LBAF
			       ": status %#02x\n", device, blknr, c);
			break;
		}

		ide_input_data(device, buffer, ATA_SECTORWORDS);
		(void) ide_inb(device, ATA_STATUS);	/* clear IRQ */

		++n;
		++blknr;
		buffer += ATA_BLOCKSIZE;
	}
IDE_READ_E:
	return n;
}

static ulong ide_write(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
		       const void *buffer)
{
	struct blk_desc *desc = dev_get_uclass_plat(dev);
	int device = desc->devnum;
	ulong n = 0;
	bool lba48 = false;
	u8 c;

	if (IS_ENABLED(CONFIG_LBA48) && (blknr & 0x0000fffff0000000ULL)) {
		/* more than 28 bits used, use 48bit mode */
		lba48 = true;
	}

	/* Select device
	 */
	ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));

	while (blkcnt-- > 0) {
		c = ide_wait(device, IDE_TIME_OUT);

		if (c & ATA_STAT_BUSY) {
			printf("IDE read: device %d not ready\n", device);
			goto WR_OUT;
		}
		if (IS_ENABLED(CONFIG_LBA48) && lba48) {
			/* write high bits */
			ide_outb(device, ATA_SECT_CNT, 0);
			ide_outb(device, ATA_LBA_LOW, (blknr >> 24) & 0xff);
#ifdef CONFIG_SYS_64BIT_LBA
			ide_outb(device, ATA_LBA_MID, (blknr >> 32) & 0xff);
			ide_outb(device, ATA_LBA_HIGH, (blknr >> 40) & 0xff);
#else
			ide_outb(device, ATA_LBA_MID, 0);
			ide_outb(device, ATA_LBA_HIGH, 0);
#endif
		}
		ide_outb(device, ATA_SECT_CNT, 1);
		ide_outb(device, ATA_LBA_LOW, (blknr >> 0) & 0xff);
		ide_outb(device, ATA_LBA_MID, (blknr >> 8) & 0xff);
		ide_outb(device, ATA_LBA_HIGH, (blknr >> 16) & 0xff);

		if (IS_ENABLED(CONFIG_LBA48) && lba48) {
			ide_outb(device, ATA_DEV_HD,
				 ATA_LBA | ATA_DEVICE(device));
			ide_outb(device, ATA_COMMAND, ATA_CMD_PIO_WRITE_EXT);

		} else {
			ide_outb(device, ATA_DEV_HD, ATA_LBA |
				 ATA_DEVICE(device) | ((blknr >> 24) & 0xf));
			ide_outb(device, ATA_COMMAND, ATA_CMD_PIO_WRITE);
		}

		udelay(50);

		/* can't take over 500 ms */
		c = ide_wait(device, IDE_TIME_OUT);

		if ((c & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR)) !=
		    ATA_STAT_DRQ) {
			printf("Error (no IRQ) dev %d blk " LBAF
			       ": status %#02x\n", device, blknr, c);
			goto WR_OUT;
		}

		ide_output_data(device, buffer, ATA_SECTORWORDS);
		c = ide_inb(device, ATA_STATUS);	/* clear IRQ */
		++n;
		++blknr;
		buffer += ATA_BLOCKSIZE;
	}
WR_OUT:
	return n;
}

ulong ide_or_atapi_read(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
			void *buffer)
{
	struct blk_desc *desc = dev_get_uclass_plat(dev);

	if (IS_ENABLED(CONFIG_ATAPI) && desc->atapi)
		return atapi_read(dev, blknr, blkcnt, buffer);

	return ide_read(dev, blknr, blkcnt, buffer);
}

static const struct blk_ops ide_blk_ops = {
	.read	= ide_or_atapi_read,
	.write	= ide_write,
};

U_BOOT_DRIVER(ide_blk) = {
	.name		= "ide_blk",
	.id		= UCLASS_BLK,
	.ops		= &ide_blk_ops,
};

static int ide_bootdev_bind(struct udevice *dev)
{
	struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);

	ucp->prio = BOOTDEVP_5_SCAN_SLOW;

	return 0;
}

static int ide_bootdev_hunt(struct bootdev_hunter *info, bool show)
{
	struct udevice *dev;

	uclass_first_device(UCLASS_IDE, &dev);

	return 0;
}

struct bootdev_ops ide_bootdev_ops = {
};

static const struct udevice_id ide_bootdev_ids[] = {
	{ .compatible = "u-boot,bootdev-ide" },
	{ }
};

U_BOOT_DRIVER(ide_bootdev) = {
	.name		= "ide_bootdev",
	.id		= UCLASS_BOOTDEV,
	.ops		= &ide_bootdev_ops,
	.bind		= ide_bootdev_bind,
	.of_match	= ide_bootdev_ids,
};

BOOTDEV_HUNTER(ide_bootdev_hunter) = {
	.prio		= BOOTDEVP_5_SCAN_SLOW,
	.uclass		= UCLASS_IDE,
	.hunt		= ide_bootdev_hunt,
	.drv		= DM_DRIVER_REF(ide_bootdev),
};

static int ide_probe(struct udevice *udev)
{
	bool bus_ok[CONFIG_SYS_IDE_MAXBUS];
	int i, bus;

	schedule();

	/* ATAPI Drives seems to need a proper IDE Reset */
	ide_reset();

	/*
	 * Wait for IDE to get ready.
	 * According to spec, this can take up to 31 seconds!
	 */
	for (bus = 0; bus < CONFIG_SYS_IDE_MAXBUS; ++bus) {
		bus_ok[bus] = !ide_init_one(bus);
		schedule();
	}

	putc('\n');

	schedule();

	for (i = 0; i < CONFIG_SYS_IDE_MAXDEVICE; i++) {
		struct blk_desc *desc, pdesc;
		struct udevice *blk;
		char name[20];
		int ret;

		if (!bus_ok[IDE_BUS(i)])
			continue;

		ret = ide_ident(i, &pdesc);
		dev_print(&pdesc);

		if (ret)
			continue;

		sprintf(name, "blk#%d", i);

		/*
		 * With CDROM, if there is no CD inserted, blksz will
		 * be zero, don't bother to create IDE block device.
		 */
		if (!pdesc.blksz)
			continue;
		ret = blk_create_devicef(udev, "ide_blk", name, UCLASS_IDE, i,
					 pdesc.blksz, pdesc.lba, &blk);
		if (ret)
			return ret;

		ret = blk_probe_or_unbind(blk);
		if (ret)
			return ret;

		/* fill in device vendor/product/rev strings */
		desc = dev_get_uclass_plat(blk);
		strlcpy(desc->vendor, pdesc.vendor, BLK_VEN_SIZE);
		strlcpy(desc->product, pdesc.product, BLK_PRD_SIZE);
		strlcpy(desc->revision, pdesc.revision, BLK_REV_SIZE);
		desc->removable = pdesc.removable;
		desc->atapi = pdesc.atapi;
		desc->lba48 = pdesc.lba48;
		desc->type = pdesc.type;

		ret = bootdev_setup_for_sibling_blk(blk, "ide_bootdev");
		if (ret)
			return log_msg_ret("bd", ret);
	}

	return 0;
}

U_BOOT_DRIVER(ide) = {
	.name		= "ide",
	.id		= UCLASS_IDE,
	.probe		= ide_probe,
};

struct pci_device_id ide_supported[] = {
	{ PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_IDE << 8, 0xffff00) },
	{ }
};

U_BOOT_PCI_DEVICE(ide, ide_supported);

UCLASS_DRIVER(ide) = {
	.name		= "ide",
	.id		= UCLASS_IDE,
};
