/*
 * 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>

extern block_dev_desc_t sata_dev_desc[CONFIG_SYS_SATA_MAX_DEVICE];
extern int sata_curr_device;

#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 = 0;		/*Primary cmd block */
u32 iobase2 = 0;		/*Primary ctl block */
u32 iobase3 = 0;		/*Sec cmd block */
u32 iobase4 = 0;		/*sec ctl block */
u32 iobase5 = 0;		/*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)) {
		printf ("error no base addr for SATA controller\n");
		return 1;
	 /*ERROR*/}

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

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

	pci_read_config_byte (bdf, PCI_PI, &pi);
	if ((pi & 0x05) != 0x05) {
		printf ("Sata is in Legacy mode\n");
		return 1;
	} else {
		printf ("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 = 0;
	u8 i, rv = 0;

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

	rv = pci_sata_init ();
	if (rv == 1) {
		printf ("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]);
				if (sata_curr_device < 0)
					sata_curr_device =
					    i * CONFIG_SYS_SATA_DEVS_PER_BUS + j;
			}
		}
	}
	return 0;
}

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

static void __inline__
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))) {
			PRINTF ("dev_chk failed for dev#%d\n", i);
		} else {
			port[num].dev_mask |= (1 << i);
			PRINTF ("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.
	 */
	msleep (150);
	status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 300);
	while ((status & ATA_BUSY)) {
		msleep (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", port);

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

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

void
sata_identify (int num, int dev)
{
	u8 cmd = 0, status = 0, 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) {
		printf ("\ndevice not responding\n");
		port[num].dev_mask &= ~mask;
		return;
	}

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

	PRINTF ("\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)) {
		PRINTF ("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);
	}
	PRINTF ("no. of sectors %u\n", ata_id_u64 (iobuf, 100));
	PRINTF ("no. of sectors %u\n", ata_id_u32 (iobuf, 60));

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

	sata_cpy (sata_dev_desc[devno].revision, iop->fw_rev,
		  sizeof (sata_dev_desc[devno].revision));
	sata_cpy (sata_dev_desc[devno].vendor, iop->model,
		  sizeof (sata_dev_desc[devno].vendor));
	sata_cpy (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;
	PRINTF ("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)) {
		PRINTF ("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);
	msleep (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);
}

void
msleep (int count)
{
	int i;

	for (i = 0; i < count; i++)
		udelay (1000);
}

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);
		}

		msleep (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, 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);
		}

		msleep (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;
}
