/*
 * Copyright (C) Procsys. All rights reserved.
 * Author: Mushtaq Khan <mushtaq_k@procsys.com>
 *			<mushtaqk_921@yahoo.co.in>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 *
 * with the reference to ata_piix driver in kernel 2.4.32
 */

/*
 * This file contains SATA controller and SATA drive initialization functions
 */

#include <common.h>
#include <asm/io.h>
#include <pci.h>
#include <command.h>
#include <config.h>
#include <asm/byteorder.h>
#include <part.h>
#include <ide.h>
#include <ata.h>
#include <sata.h>

#define DEBUG_SATA 0		/* For debug prints set DEBUG_SATA to 1 */

#define SATA_DECL
#define DRV_DECL		/* For file specific declarations */
#include "ata_piix.h"

/* Macros realted to PCI */
#define PCI_SATA_BUS	0x00
#define PCI_SATA_DEV	0x1f
#define PCI_SATA_FUNC	0x02

#define PCI_SATA_BASE1 0x10
#define PCI_SATA_BASE2 0x14
#define PCI_SATA_BASE3 0x18
#define PCI_SATA_BASE4 0x1c
#define PCI_SATA_BASE5 0x20
#define PCI_PMR         0x90
#define PCI_PI          0x09
#define PCI_PCS         0x92
#define PCI_DMA_CTL     0x48

#define PORT_PRESENT (1<<0)
#define PORT_ENABLED (1<<4)

u32 bdf;
u32 iobase1;		/* Primary cmd block */
u32 iobase2;		/* Primary ctl block */
u32 iobase3;		/* Sec cmd block */
u32 iobase4;		/* sec ctl block */
u32 iobase5;		/* BMDMA*/

int pci_sata_init(void)
{
	u32 bus = PCI_SATA_BUS;
	u32 dev = PCI_SATA_DEV;
	u32 fun = PCI_SATA_FUNC;
	u16 cmd = 0;
	u8 lat = 0, pcibios_max_latency = 0xff;
	u8 pmr; /* Port mapping reg */
	u8 pi; /* Prgming Interface reg */

	bdf = PCI_BDF(bus, dev, fun);
	pci_read_config_dword(bdf, PCI_SATA_BASE1, &iobase1);
	pci_read_config_dword(bdf, PCI_SATA_BASE2, &iobase2);
	pci_read_config_dword(bdf, PCI_SATA_BASE3, &iobase3);
	pci_read_config_dword(bdf, PCI_SATA_BASE4, &iobase4);
	pci_read_config_dword(bdf, PCI_SATA_BASE5, &iobase5);

	if ((iobase1 == 0xFFFFFFFF) || (iobase2 == 0xFFFFFFFF) ||
	    (iobase3 == 0xFFFFFFFF) || (iobase4 == 0xFFFFFFFF) ||
	    (iobase5 == 0xFFFFFFFF)) {
		/* ERROR */
		printf("error no base addr for SATA controller\n");
		return 1;
	}

	iobase1 &= 0xFFFFFFFE;
	iobase2 &= 0xFFFFFFFE;
	iobase3 &= 0xFFFFFFFE;
	iobase4 &= 0xFFFFFFFE;
	iobase5 &= 0xFFFFFFFE;

	/* check for mode */
	pci_read_config_byte(bdf, PCI_PMR, &pmr);
	if (pmr > 1) {
		puts("combined mode not supported\n");
		return 1;
	}

	pci_read_config_byte(bdf, PCI_PI, &pi);
	if ((pi & 0x05) != 0x05) {
		puts("Sata is in Legacy mode\n");
		return 1;
	} else
		puts("sata is in Native mode\n");

	/* MASTER CFG AND IO CFG */
	pci_read_config_word(bdf, PCI_COMMAND, &cmd);
	cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_IO;
	pci_write_config_word(bdf, PCI_COMMAND, cmd);
	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);

	if (lat < 16)
		lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
	else if (lat > pcibios_max_latency)
		lat = pcibios_max_latency;
	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);

	return 0;
}

int sata_bus_probe(int port_no)
{
	int orig_mask, mask;
	u16 pcs;

	mask = (PORT_PRESENT << port_no);
	pci_read_config_word(bdf, PCI_PCS, &pcs);
	orig_mask = (int) pcs & 0xff;
	if ((orig_mask & mask) != mask)
		return 0;
	else
		return 1;
}

int init_sata(int dev)
{
	static int done;
	u8 i, rv = 0;

	if (!done)
		done = 1;
	else
		return 0;

	rv = pci_sata_init();
	if (rv == 1) {
		puts("pci initialization failed\n");
		return 1;
	}

	port[0].port_no = 0;
	port[0].ioaddr.cmd_addr = iobase1;
	port[0].ioaddr.altstatus_addr = port[0].ioaddr.ctl_addr =
	    iobase2 | ATA_PCI_CTL_OFS;
	port[0].ioaddr.bmdma_addr = iobase5;

	port[1].port_no = 1;
	port[1].ioaddr.cmd_addr = iobase3;
	port[1].ioaddr.altstatus_addr = port[1].ioaddr.ctl_addr =
	    iobase4 | ATA_PCI_CTL_OFS;
	port[1].ioaddr.bmdma_addr = iobase5 + 0x8;

	for (i = 0; i < CONFIG_SYS_SATA_MAXBUS; i++)
		sata_port(&port[i].ioaddr);

	for (i = 0; i < CONFIG_SYS_SATA_MAXBUS; i++) {
		if (!(sata_bus_probe(i))) {
			port[i].port_state = 0;
			printf("SATA#%d port is not present\n", i);
		} else {
			printf("SATA#%d port is present\n", i);
			if (sata_bus_softreset(i))
				port[i].port_state = 0;
			else
				port[i].port_state = 1;
		}
	}

	for (i = 0; i < CONFIG_SYS_SATA_MAXBUS; i++) {
		u8 j, devno;

		if (port[i].port_state == 0)
			continue;
		for (j = 0; j < CONFIG_SYS_SATA_DEVS_PER_BUS; j++) {
			sata_identify(i, j);
			set_Feature_cmd(i, j);
			devno = i * CONFIG_SYS_SATA_DEVS_PER_BUS + j;
			if ((sata_dev_desc[devno].lba > 0) &&
			    (sata_dev_desc[devno].blksz > 0)) {
				dev_print(&sata_dev_desc[devno]);
				/* initialize partition type */
				init_part(&sata_dev_desc[devno]);
			}
		}
	}
	return 0;
}

static inline u8 sata_inb(unsigned long ioaddr)
{
	return inb(ioaddr);
}

static inline void sata_outb(unsigned char val, unsigned long ioaddr)
{
	outb(val, ioaddr);
}

static void output_data(struct sata_ioports *ioaddr, ulong * sect_buf,
		int words)
{
	outsw(ioaddr->data_addr, sect_buf, words << 1);
}

static int input_data(struct sata_ioports *ioaddr, ulong * sect_buf, int words)
{
	insw(ioaddr->data_addr, sect_buf, words << 1);
	return 0;
}

static void sata_cpy(unsigned char *dst, unsigned char *src, unsigned int len)
{
	unsigned char *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';
}

int sata_bus_softreset(int num)
{
	u8 dev = 0, status = 0, i;

	port[num].dev_mask = 0;

	for (i = 0; i < CONFIG_SYS_SATA_DEVS_PER_BUS; i++) {
		if (!(sata_devchk(&port[num].ioaddr, i))) {
			debug("dev_chk failed for dev#%d\n", i);
		} else {
			port[num].dev_mask |= (1 << i);
			debug("dev_chk passed for dev#%d\n", i);
		}
	}

	if (!(port[num].dev_mask)) {
		printf("no devices on port%d\n", num);
		return 1;
	}

	dev_select(&port[num].ioaddr, dev);

	port[num].ctl_reg = 0x08;	/* Default value of control reg */
	sata_outb(port[num].ctl_reg, port[num].ioaddr.ctl_addr);
	udelay(10);
	sata_outb(port[num].ctl_reg | ATA_SRST, port[num].ioaddr.ctl_addr);
	udelay(10);
	sata_outb(port[num].ctl_reg, port[num].ioaddr.ctl_addr);

	/*
	 * spec mandates ">= 2ms" before checking status.
	 * We wait 150ms, because that was the magic delay used for
	 * ATAPI devices in Hale Landis's ATADRVR, for the period of time
	 * between when the ATA command register is written, and then
	 * status is checked.  Because waiting for "a while" before
	 * checking status is fine, post SRST, we perform this magic
	 * delay here as well.
	 */
	mdelay(150);
	status = sata_busy_wait(&port[num].ioaddr, ATA_BUSY, 300);
	while ((status & ATA_BUSY)) {
		mdelay(100);
		status = sata_busy_wait(&port[num].ioaddr, ATA_BUSY, 3);
	}

	if (status & ATA_BUSY)
		printf("ata%u is slow to respond,plz be patient\n", num);

	while ((status & ATA_BUSY)) {
		mdelay(100);
		status = sata_chk_status(&port[num].ioaddr);
	}

	if (status & ATA_BUSY) {
		printf("ata%u failed to respond : bus reset failed\n", num);
		return 1;
	}
	return 0;
}

void sata_identify(int num, int dev)
{
	u8 cmd = 0, status = 0;
	u8 devno = num * CONFIG_SYS_SATA_DEVS_PER_BUS + dev;
	u16 iobuf[ATA_SECT_SIZE];
	u64 n_sectors = 0;
	u8 mask = 0;

	memset(iobuf, 0, sizeof(iobuf));
	hd_driveid_t *iop = (hd_driveid_t *) iobuf;

	if (dev == 0)
		mask = 0x01;
	else
		mask = 0x02;

	if (!(port[num].dev_mask & mask)) {
		printf("dev%d is not present on port#%d\n", dev, num);
		return;
	}

	printf("port=%d dev=%d\n", num, dev);

	dev_select(&port[num].ioaddr, dev);

	status = 0;
	cmd = ATA_CMD_IDENT;	/* Device Identify Command */
	sata_outb(cmd, port[num].ioaddr.command_addr);
	sata_inb(port[num].ioaddr.altstatus_addr);
	udelay(10);

	status = sata_busy_wait(&port[num].ioaddr, ATA_BUSY, 1000);
	if (status & ATA_ERR) {
		puts("\ndevice not responding\n");
		port[num].dev_mask &= ~mask;
		return;
	}

	input_data(&port[num].ioaddr, (ulong *) iobuf, ATA_SECTORWORDS);

	debug("\nata%u: dev %u cfg 49:%04x 82:%04x 83:%04x 84:%04x85:%04x"
		"86:%04x" "87:%04x 88:%04x\n", num, dev, iobuf[49],
		iobuf[82], iobuf[83], iobuf[84], iobuf[85], iobuf[86],
		iobuf[87], iobuf[88]);

	/* we require LBA and DMA support (bits 8 & 9 of word 49) */
	if (!ata_id_has_dma(iobuf) || !ata_id_has_lba(iobuf))
		debug("ata%u: no dma/lba\n", num);
	ata_dump_id(iobuf);

	if (ata_id_has_lba48(iobuf))
		n_sectors = ata_id_u64(iobuf, 100);
	else
		n_sectors = ata_id_u32(iobuf, 60);
	debug("no. of sectors %u\n", ata_id_u64(iobuf, 100));
	debug("no. of sectors %u\n", ata_id_u32(iobuf, 60));

	if (n_sectors == 0) {
		port[num].dev_mask &= ~mask;
		return;
	}

	sata_cpy((unsigned char *)sata_dev_desc[devno].revision, iop->fw_rev,
		  sizeof(sata_dev_desc[devno].revision));
	sata_cpy((unsigned char *)sata_dev_desc[devno].vendor, iop->model,
		  sizeof(sata_dev_desc[devno].vendor));
	sata_cpy((unsigned char *)sata_dev_desc[devno].product, iop->serial_no,
		  sizeof(sata_dev_desc[devno].product));
	strswab(sata_dev_desc[devno].revision);
	strswab(sata_dev_desc[devno].vendor);

	if ((iop->config & 0x0080) == 0x0080)
		sata_dev_desc[devno].removable = 1;
	else
		sata_dev_desc[devno].removable = 0;

	sata_dev_desc[devno].lba = iop->lba_capacity;
	debug("lba=0x%x", sata_dev_desc[devno].lba);

#ifdef CONFIG_LBA48
	if (iop->command_set_2 & 0x0400) {
		sata_dev_desc[devno].lba48 = 1;
		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 {
		sata_dev_desc[devno].lba48 = 0;
	}
#endif

	/* assuming HD */
	sata_dev_desc[devno].type = DEV_TYPE_HARDDISK;
	sata_dev_desc[devno].blksz = ATA_BLOCKSIZE;
	sata_dev_desc[devno].log2blksz = LOG2(sata_dev_desc[devno].blksz);
	sata_dev_desc[devno].lun = 0;	/* just to fill something in... */
}

void set_Feature_cmd(int num, int dev)
{
	u8 mask = 0x00, status = 0;

	if (dev == 0)
		mask = 0x01;
	else
		mask = 0x02;

	if (!(port[num].dev_mask & mask)) {
		debug("dev%d is not present on port#%d\n", dev, num);
		return;
	}

	dev_select(&port[num].ioaddr, dev);

	sata_outb(SETFEATURES_XFER, port[num].ioaddr.feature_addr);
	sata_outb(XFER_PIO_4, port[num].ioaddr.nsect_addr);
	sata_outb(0, port[num].ioaddr.lbal_addr);
	sata_outb(0, port[num].ioaddr.lbam_addr);
	sata_outb(0, port[num].ioaddr.lbah_addr);

	sata_outb(ATA_DEVICE_OBS, port[num].ioaddr.device_addr);
	sata_outb(ATA_CMD_SETF, port[num].ioaddr.command_addr);

	udelay(50);
	mdelay(150);

	status = sata_busy_wait(&port[num].ioaddr, ATA_BUSY, 5000);
	if ((status & (ATA_STAT_BUSY | ATA_STAT_ERR))) {
		printf("Error  : status 0x%02x\n", status);
		port[num].dev_mask &= ~mask;
	}
}

void sata_port(struct sata_ioports *ioport)
{
	ioport->data_addr = ioport->cmd_addr + ATA_REG_DATA;
	ioport->error_addr = ioport->cmd_addr + ATA_REG_ERR;
	ioport->feature_addr = ioport->cmd_addr + ATA_REG_FEATURE;
	ioport->nsect_addr = ioport->cmd_addr + ATA_REG_NSECT;
	ioport->lbal_addr = ioport->cmd_addr + ATA_REG_LBAL;
	ioport->lbam_addr = ioport->cmd_addr + ATA_REG_LBAM;
	ioport->lbah_addr = ioport->cmd_addr + ATA_REG_LBAH;
	ioport->device_addr = ioport->cmd_addr + ATA_REG_DEVICE;
	ioport->status_addr = ioport->cmd_addr + ATA_REG_STATUS;
	ioport->command_addr = ioport->cmd_addr + ATA_REG_CMD;
}

int sata_devchk(struct sata_ioports *ioaddr, int dev)
{
	u8 nsect, lbal;

	dev_select(ioaddr, dev);

	sata_outb(0x55, ioaddr->nsect_addr);
	sata_outb(0xaa, ioaddr->lbal_addr);

	sata_outb(0xaa, ioaddr->nsect_addr);
	sata_outb(0x55, ioaddr->lbal_addr);

	sata_outb(0x55, ioaddr->nsect_addr);
	sata_outb(0xaa, ioaddr->lbal_addr);

	nsect = sata_inb(ioaddr->nsect_addr);
	lbal = sata_inb(ioaddr->lbal_addr);

	if ((nsect == 0x55) && (lbal == 0xaa))
		return 1;	/* we found a device */
	else
		return 0;	/* nothing found */
}

void dev_select(struct sata_ioports *ioaddr, int dev)
{
	u8 tmp = 0;

	if (dev == 0)
		tmp = ATA_DEVICE_OBS;
	else
		tmp = ATA_DEVICE_OBS | ATA_DEV1;

	sata_outb(tmp, ioaddr->device_addr);
	sata_inb(ioaddr->altstatus_addr);
	udelay(5);
}

u8 sata_busy_wait(struct sata_ioports *ioaddr, int bits, unsigned int max)
{
	u8 status;

	do {
		udelay(1000);
		status = sata_chk_status(ioaddr);
		max--;
	} while ((status & bits) && (max > 0));

	return status;
}

u8 sata_chk_status(struct sata_ioports *ioaddr)
{
	return sata_inb(ioaddr->status_addr);
}


ulong sata_read(int device, ulong blknr, lbaint_t blkcnt, void *buff)
{
	ulong n = 0, *buffer = (ulong *)buff;
	u8 dev = 0, num = 0, mask = 0, status = 0;

#ifdef CONFIG_LBA48
	unsigned char lba48 = 0;

	if (blknr & 0x0000fffff0000000) {
		if (!sata_dev_desc[devno].lba48) {
			printf("Drive doesn't support 48-bit addressing\n");
			return 0;
		}
		/* more than 28 bits used, use 48bit mode */
		lba48 = 1;
	}
#endif
	/* Port Number */
	num = device / CONFIG_SYS_SATA_DEVS_PER_BUS;
	/* dev on the port */
	if (device >= CONFIG_SYS_SATA_DEVS_PER_BUS)
		dev = device - CONFIG_SYS_SATA_DEVS_PER_BUS;
	else
		dev = device;

	if (dev == 0)
		mask = 0x01;
	else
		mask = 0x02;

	if (!(port[num].dev_mask & mask)) {
		printf("dev%d is not present on port#%d\n", dev, num);
		return 0;
	}

	/* Select device */
	dev_select(&port[num].ioaddr, dev);

	status = sata_busy_wait(&port[num].ioaddr, ATA_BUSY, 500);
	if (status & ATA_BUSY) {
		printf("ata%u failed to respond\n", port[num].port_no);
		return n;
	}
	while (blkcnt-- > 0) {
		status = sata_busy_wait(&port[num].ioaddr, ATA_BUSY, 500);
		if (status & ATA_BUSY) {
			printf("ata%u failed to respond\n", 0);
			return n;
		}
#ifdef CONFIG_LBA48
		if (lba48) {
			/* write high bits */
			sata_outb(0, port[num].ioaddr.nsect_addr);
			sata_outb((blknr >> 24) & 0xFF,
				   port[num].ioaddr.lbal_addr);
			sata_outb((blknr >> 32) & 0xFF,
				   port[num].ioaddr.lbam_addr);
			sata_outb((blknr >> 40) & 0xFF,
				   port[num].ioaddr.lbah_addr);
		}
#endif
		sata_outb(1, port[num].ioaddr.nsect_addr);
		sata_outb(((blknr) >> 0) & 0xFF,
			   port[num].ioaddr.lbal_addr);
		sata_outb((blknr >> 8) & 0xFF, port[num].ioaddr.lbam_addr);
		sata_outb((blknr >> 16) & 0xFF, port[num].ioaddr.lbah_addr);

#ifdef CONFIG_LBA48
		if (lba48) {
			sata_outb(ATA_LBA, port[num].ioaddr.device_addr);
			sata_outb(ATA_CMD_READ_EXT,
				   port[num].ioaddr.command_addr);
		} else
#endif
		{
			sata_outb(ATA_LBA | ((blknr >> 24) & 0xF),
				   port[num].ioaddr.device_addr);
			sata_outb(ATA_CMD_READ,
				   port[num].ioaddr.command_addr);
		}

		mdelay(50);
		/* may take up to 4 sec */
		status = sata_busy_wait(&port[num].ioaddr, ATA_BUSY, 4000);

		if ((status & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR))
		    != ATA_STAT_DRQ) {
			u8 err = 0;

			printf("Error no DRQ dev %d blk %ld: sts 0x%02x\n",
				device, (ulong) blknr, status);
			err = sata_inb(port[num].ioaddr.error_addr);
			printf("Error reg = 0x%x\n", err);
			return n;
		}
		input_data(&port[num].ioaddr, buffer, ATA_SECTORWORDS);
		sata_inb(port[num].ioaddr.altstatus_addr);
		udelay(50);

		++n;
		++blknr;
		buffer += ATA_SECTORWORDS;
	}
	return n;
}

ulong sata_write(int device, ulong blknr, lbaint_t blkcnt, const void *buff)
{
	ulong n = 0, *buffer = (ulong *)buff;
	unsigned char status = 0, num = 0, dev = 0, mask = 0;

#ifdef CONFIG_LBA48
	unsigned char lba48 = 0;

	if (blknr & 0x0000fffff0000000) {
		if (!sata_dev_desc[devno].lba48) {
			printf("Drive doesn't support 48-bit addressing\n");
			return 0;
		}
		/* more than 28 bits used, use 48bit mode */
		lba48 = 1;
	}
#endif
	/* Port Number */
	num = device / CONFIG_SYS_SATA_DEVS_PER_BUS;
	/* dev on the Port */
	if (device >= CONFIG_SYS_SATA_DEVS_PER_BUS)
		dev = device - CONFIG_SYS_SATA_DEVS_PER_BUS;
	else
		dev = device;

	if (dev == 0)
		mask = 0x01;
	else
		mask = 0x02;

	/* Select device */
	dev_select(&port[num].ioaddr, dev);

	status = sata_busy_wait(&port[num].ioaddr, ATA_BUSY, 500);
	if (status & ATA_BUSY) {
		printf("ata%u failed to respond\n", port[num].port_no);
		return n;
	}

	while (blkcnt-- > 0) {
		status = sata_busy_wait(&port[num].ioaddr, ATA_BUSY, 500);
		if (status & ATA_BUSY) {
			printf("ata%u failed to respond\n",
				port[num].port_no);
			return n;
		}
#ifdef CONFIG_LBA48
		if (lba48) {
			/* write high bits */
			sata_outb(0, port[num].ioaddr.nsect_addr);
			sata_outb((blknr >> 24) & 0xFF,
				   port[num].ioaddr.lbal_addr);
			sata_outb((blknr >> 32) & 0xFF,
				   port[num].ioaddr.lbam_addr);
			sata_outb((blknr >> 40) & 0xFF,
				   port[num].ioaddr.lbah_addr);
		}
#endif
		sata_outb(1, port[num].ioaddr.nsect_addr);
		sata_outb((blknr >> 0) & 0xFF, port[num].ioaddr.lbal_addr);
		sata_outb((blknr >> 8) & 0xFF, port[num].ioaddr.lbam_addr);
		sata_outb((blknr >> 16) & 0xFF, port[num].ioaddr.lbah_addr);
#ifdef CONFIG_LBA48
		if (lba48) {
			sata_outb(ATA_LBA, port[num].ioaddr.device_addr);
			sata_outb(ATA_CMD_WRITE_EXT,
				   port[num].ioaddr.command_addr);
		} else
#endif
		{
			sata_outb(ATA_LBA | ((blknr >> 24) & 0xF),
				   port[num].ioaddr.device_addr);
			sata_outb(ATA_CMD_WRITE,
				   port[num].ioaddr.command_addr);
		}

		mdelay(50);
		/* may take up to 4 sec */
		status = sata_busy_wait(&port[num].ioaddr, ATA_BUSY, 4000);
		if ((status & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR))
		    != ATA_STAT_DRQ) {
			printf("Error no DRQ dev %d blk %ld: sts 0x%02x\n",
				device, (ulong) blknr, status);
			return n;
		}

		output_data(&port[num].ioaddr, buffer, ATA_SECTORWORDS);
		sata_inb(port[num].ioaddr.altstatus_addr);
		udelay(50);

		++n;
		++blknr;
		buffer += ATA_SECTORWORDS;
	}
	return n;
}

int scan_sata(int dev)
{
	return 0;
}
