/*
 * 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 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 (curr_device < 0)
					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;
}
