/*
 * 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].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;
}
