#include <common.h>
#if defined (CONFIG_SAM440EP)
#include <configs/Sam440ep.h>
#elif defined (CONFIG_SAM440EP_FLEX)
#include <configs/Sam440ep_flex.h>
#elif defined (CONFIG_SAM460EX)
#include <configs/Sam460ex.h>
#endif

#include <part.h>
#include <ide.h>
#include <ata.h>
#include <pci.h> //We need the PCI primitives.
#include <malloc.h>

#include "sys_dep.h" //Il marchio di fabbrica.
#include "sam_ide.h"
#include "misc_utils.h"

#ifdef CONFIG_SAM460EX
DECLARE_GLOBAL_DATA_PTR;

#define BOARD_CANYONLANDS_PCIE	1
#define BOARD_CANYONLANDS_SATA	2

block_dev_desc_t sata_dev_desc[CONFIG_SYS_SATA_MAX_DEVICE];
extern ulong sata_read(int device, ulong blknr, lbaint_t blkcnt, void *buffer);
#endif

/*
How to add new IDE boards to this module.
This note explains how to add new controller cards to those supported by 
a1ide.c/UBoot.

To add support for a new IDE controller you need to:
- add a new entry in the controllers[] array.
- write a couple of functions to read from the controllers, one for ATA and 
one for ATAPI.
These are very simple and usually don't need special care, they simply 
forward the call to the generic reading routines.
- write a small function to fetch a unit from those present on the controller;
much like the point above.
- write a function to initialize the controller card.
- add some bits and pieces here and there (all explained below).

Let's start with the big chunk: the controllers[] array. 
It's an array of struct controller_context.
There must be one for every supported controller/chip.
But first, a word from our spon.... no: a word about UBoot!
In "controllers" and elsewhere, it's quite often to find function pointers.
Due to the fact that UBoot gets relocated early during the initialization 
phases, NO function pointer can be used in a static structure
or a static variable of a module!!! So if you plan to use function pointers 
like in controllers, you MUST initialize them at RUN TIME, _NOT COMPILE TIME_!!!

The controller_context sturcture:
BOOL	cc_present: 		
	set this to TRUE during the initialization routine if
	the card was found and it's working.
UBYTE	cc_maxunit: 		
	total number of units that can exists on this controller
UBYTE	cc_maxbus: 			
	total number of different bus that are handled by this 
	controller. Usually 2.
char *cc_maxbus_var: 
	pointer to a string with the environment variable used
	to limit the buses being used/scanned.
BOOL *cc_bus_ok:
	an array of BOOLs, allocated at runtime, length is 
	cc_maxbus: tells which bus have real units.
base_io_address *cc_base_io: 
	array of io_address, allocated at runtime, length is 
	cc_maxbus: base IO addresses for each bus.
block_dev_desc_t * cc_units: 
	array of device descriptors, allocated at runtime, length is cc_maxunit.
char *cc_description: 
	a string defining the controller itself.
unsigned long (* cc_block_read)(): 
	function pointer to the ATA block read routine, see the warning above.
unsigned long (* cc_atapi_read)(): 
	function pointer to the ATAPI block read routine, see the warning above.

Some of these fields will be filled in by the generic part, so you don't have 
to care for them.
What must be supplied by you are:
STATIC (compile-time): cc_maxunit, cc_maxbus, cc_maxbus_var, cc_description.
DYNAMIC (run-time): cc_present, cc_base_io, cc_block_read, cc_atapi_read
DYNAMIC (run-time), simply allocated and cleared: cc_bus_ok, cc_units.

The last two entries refer to the two reading routines, one for ATA and the
second for ATAPI.
They use common code but, because of compatibility reasons, they cannot have
the controller_context structure in their prototipes. But they call upon it, 
so all you need to do is forward the call to local_ide_read and local_atapi_read,
using the appropriate cc_base_io. 
Have a look at p_sii_block_read and p_sii_atapi_read for an example.
The same kind of reasoning is applied to the "get_dev" function: you must write
one function like via_get_dev that returns a (block_dev_desc_t *) of your 
controller. This function is the hook used by cmd_boota to use units on your 
controller. You decide the name.

The initialization function: this is the main part of adding a new controller. 
This function must:
- check if the controller is really present in your system. If not present, 
	quit immediately. Otherwise:
- allocate and clear cc_units, cc_base_io and cc_bus_ok.
- really initialize the controller HW. You should know what to do here.
- fill in with sensible values cc_base_io.
- if you want to let the user swap the primary and secondary bus, call ide_swap().
- fill in cc_block_read and cc_atapi_read, linking them with the callbacks for
	your controller.
- set cc_present to TRUE.

Ok, that's it.
One more step is required: add a call to the above initialization function 
from init_controllers.

Done!
*/

#undef	IDE_DEBUG
#ifdef	IDE_DEBUG
#define	PRINTF(fmt,args...)		printf (fmt ,##args)
#define	PRINTF2(fmt,args...)    
#else
#define PRINTF(fmt,args...)
#define PRINTF2(fmt,args...)
#endif

#undef	ATAPI_DEBUG
#ifdef	ATAPI_DEBUG
#define	AT_PRINTF(fmt,args...)	printf (fmt ,##args)
#else
#define AT_PRINTF(fmt,args...)
#endif

#define EIEIO	__asm__ volatile ("eieio")

static inline base_io_address IDE_BUS_ADV(const struct controller_context * const cc, const unsigned dev)
{
	return cc->cc_base_io[dev/cc->cc_units_per_bus];
}

//#define ATA_DEVICE_ADV(cc, dev) ((dev & 1)<<4)
static int ATA_DEVICE_ADV(const struct controller_context * const cc, const unsigned dev)
{
    if (strcmp(cc->cc_description,"Sii0680") == 0) return((dev & 1)<<4);
    else return 0;
}

#define ATA_CURR_BASE_ADV(cc, dev)	(CONFIG_SYS_ATA_BASE_ADDR+IDE_BUS_ADV(cc,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 */

#ifdef CONFIG_SHOW_BOOT_PROGRESS
#include <status_led.h>
#define SHOW_BOOT_PROGRESS(arg)	show_boot_progress(arg)
#else
#define SHOW_BOOT_PROGRESS(arg)
#endif

struct controller_context controllers[]=
{
	{ FALSE, MAX_S_SII_UNITS,		MAX_S_SII_BUS,		0, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
	{ FALSE, MAX_S_4_SII_UNITS,		MAX_S_4_SII_BUS,	0, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
#ifdef CONFIG_SAM460EX
	{ FALSE, MAX_SATA2_460_UNITS,	MAX_SATA2_460_BUS,	0, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
#endif
	{ FALSE, MAX_P_SII_UNITS,		MAX_P_SII_BUS,		0, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
};

enum
{
	S_SII_POS = 0,
	S4_SII_POS,
#ifdef CONFIG_SAM460EX	
	SATA2_460_POS,
#endif
	P_SII_POS		
};

//Forward declarations.
static unsigned long s_sii_block_read(int dev, unsigned long start, lbaint_t blkcnt, unsigned long *buffer);
static ulong s_sii_atapi_read (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer);

static unsigned long s_4_sii_block_read(int dev, unsigned long start, lbaint_t blkcnt, unsigned long *buffer);
static ulong s_4_sii_atapi_read (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer);

static unsigned long p_sii_block_read(int dev, unsigned long start, lbaint_t blkcnt, unsigned long *buffer);
static ulong p_sii_atapi_read (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer);

static ulong local_ide_read (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer, const struct controller_context * const cc);
static void local_input_swap_data(int dev, ulong *sect_buf, int words, const struct controller_context * const cc);
static void local_input_data(int dev, ulong *sect_buf, int words, const struct controller_context * const cc);
static void local_ide_ident (block_dev_desc_t *dev_desc, struct controller_context * const ctx);
static uchar local_ide_wait (int dev, ulong t, const struct controller_context * const cc);
static void local_ident_cpy (unsigned char *dst, unsigned char *src, unsigned int len);

//This should between an ifdef ATAPI /endif pair
static void local_atapi_inquiry(block_dev_desc_t * dev_desc, struct controller_context * const ctx);
static uchar local_atapi_wait_mask (int dev, ulong t,uchar mask, uchar res, const struct controller_context * const cc);
static unsigned char local_atapi_issue(int device,unsigned char* ccb,int ccblen, unsigned char * buffer,int buflen, const struct controller_context * const cc);

static _Bool local_ide_set_pio(const int device, const unsigned char mode, const struct controller_context * const cc);

static void local_ide_outb(int dev, int port, unsigned char val, const struct controller_context * const cc)
{
	PRINTF2 ("a1_ide_outb (dev= %d, port= 0x%x, val= 0x%02x) : @ 0x%08lx\n",
		dev, port, val, (ATA_CURR_BASE_ADV(cc, dev)+port));
	/* Ensure I/O operations complete */
	EIEIO;
	*((uchar *)(ATA_CURR_BASE_ADV(cc, dev)+port)) = val;
}

static unsigned char local_ide_inb(int dev, int port, const struct controller_context * const cc)
{
	uchar val;
	/* Ensure I/O operations complete */
	EIEIO;
	val = *((uchar *)(ATA_CURR_BASE_ADV(cc, dev)+port));
	
	PRINTF2 ("a1_ide_inb (dev= %d, port= 0x%x) : @ 0x%08lx -> 0x%02x\n",
		dev, port, (ATA_CURR_BASE_ADV(cc, dev)+port), val);
	
	return (val);
}

//--------------

static void s_sii_early_init(struct controller_context * const ctx)
{
	unsigned int bdf;
	unsigned int addr;
	uint32_t class_rev;
	
	PRINTF ("s_sii_init: START\n");

	//Creates the devices description array.
	
	ctx->cc_units = calloc(sizeof(block_dev_desc_t),  ctx->cc_maxunit);
	ctx->cc_base_io = calloc(sizeof(base_io_address), ctx->cc_maxbus);
	ctx->cc_bus_ok = calloc(sizeof(BOOL), ctx->cc_maxbus);
	ctx->cc_maxbus_var = "ssii_maxbus";
	ctx->cc_description = "Sii3112";
		
	/* get IDE Controller Device ID */

	if ((bdf = pci_find_device(PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_3112, 0)) == -1)
	{
		if ((bdf = pci_find_device(PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_3512, 0)) == -1)
	    {
	        return;
	    }
	}

	pci_write_config_dword(bdf, PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
	
	// Reset chip registers to safe values
	pci_read_config_dword(bdf, PCI_CLASS_REVISION, &class_rev);
	class_rev &= 0xFF;
	pci_write_config_byte(bdf, PCI_CACHE_LINE_SIZE, (class_rev) ? 1 : 255); 

	pci_read_config_dword (bdf, PCI_BASE_ADDRESS_0, &addr);
	ctx->cc_base_io[0] = (void *)(addr & PCI_BASE_ADDRESS_IO_MASK);
	pci_read_config_dword (bdf, PCI_BASE_ADDRESS_2, &addr);
	ctx->cc_base_io[1] = (void *)(addr & PCI_BASE_ADDRESS_IO_MASK);

	ctx->cc_present = TRUE;
	ctx->cc_block_read = s_sii_block_read;
	ctx->cc_atapi_read = s_sii_atapi_read;
	
	PRINTF("Done s_sii initialization, base IO addresses at %08lx, %08lx\n",
		ctx->cc_base_io[0], ctx->cc_base_io[1]);
}

static void s_4_sii_early_init(struct controller_context * const ctx)
{
	unsigned int bdf;
	unsigned int addr;
	uint32_t class_rev;
	
	PRINTF ("s_4_sii_init: START\n");

	//Creates the devices description array.
	
	ctx->cc_units = calloc(sizeof(block_dev_desc_t),  ctx->cc_maxunit);
	ctx->cc_base_io = calloc(sizeof(base_io_address), ctx->cc_maxbus);
	ctx->cc_bus_ok = calloc(sizeof(BOOL), ctx->cc_maxbus);
	ctx->cc_maxbus_var = "s4sii_maxbus";
	ctx->cc_description = "Sii3114";
		
	/* get IDE Controller Device ID */

	if ((bdf = pci_find_device(PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_3114, 0)) == -1)
	{
		return;
	}

	pci_write_config_dword(bdf, PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
	
	// Reset chip registers to safe values
	pci_read_config_dword(bdf, PCI_CLASS_REVISION, &class_rev);
	class_rev &= 0xFF;
	pci_write_config_byte(bdf, PCI_CACHE_LINE_SIZE, (class_rev) ? 1 : 255); 
	//I really don't know what the above code is all about.....
	
	
	pci_read_config_dword (bdf, PCI_BASE_ADDRESS_0, &addr);
	ctx->cc_base_io[0] = (void *)(addr & PCI_BASE_ADDRESS_IO_MASK);
	pci_read_config_dword (bdf, PCI_BASE_ADDRESS_2, &addr);
	ctx->cc_base_io[1] = (void *)(addr & PCI_BASE_ADDRESS_IO_MASK);
	
/*
	Here we got a problem: since the "autoconfiguration" (ahemm...) of PCI is done via
	BAR registers, it's very likely that other cards I/O space overlap with the
	3114 "hole" after which the 2 upper buses are placed.
	This really happens if a 680 is used at the same time.
	So for the time being the two upper buses are disabled.
	
	ctx->cc_base_io[2] = ctx->cc_base_io[0] + SILLY_SIL_4_PORTS_OFFSET;
	ctx->cc_base_io[3] = ctx->cc_base_io[1] + SILLY_SIL_4_PORTS_OFFSET;
*/
//	ctx->cc_maxunit = ctx->cc_maxbus = 2; //See the comment above.

	ctx->cc_base_io[2] = ctx->cc_base_io[0] + SILLY_SIL_4_PORTS_OFFSET;
	ctx->cc_base_io[3] = ctx->cc_base_io[1] + SILLY_SIL_4_PORTS_OFFSET;
		ctx->cc_maxunit = ctx->cc_maxbus = 4;
	
	ctx->cc_present = TRUE;
	ctx->cc_block_read = s_4_sii_block_read;
	ctx->cc_atapi_read = s_4_sii_atapi_read;
	
	PRINTF("Done s_4_sii initialization, base IO addresses at %08lx, %08lx, %08lx, %08lx\n",
		ctx->cc_base_io[0], ctx->cc_base_io[1], ctx->cc_base_io[2], ctx->cc_base_io[3]);
}

#ifdef CONFIG_SAM460EX
static void sata2_460_early_init(struct controller_context * const ctx)
{
	PRINTF ("sata2_460_init: START\n");

	//Creates the devices description array.
	
	ctx->cc_units = NULL;						// later... 
	ctx->cc_base_io = NULL;						// not used
	ctx->cc_bus_ok = calloc(sizeof(BOOL), ctx->cc_maxbus);
	ctx->cc_maxbus_var = "sata2_maxbus";
	ctx->cc_description = "SATA2-460";
		
	/* get IDE Controller Device ID */
	
	if (gd->board_type != BOARD_CANYONLANDS_SATA) return;

	ctx->cc_present = TRUE;
	ctx->cc_block_read = sata_read;
	ctx->cc_atapi_read = sata_read;
	
	PRINTF("Done sata2_460 initialization\n");
}
#endif

static void p_sii_early_init(struct controller_context * const ctx)
{
	unsigned int cmd, bdf;
	unsigned int addr;
	unsigned char tmpbyte = 0;

	PRINTF ("p_sii_init: START\n");

	//Creates the devices description array.
	
	ctx->cc_units = calloc(sizeof(block_dev_desc_t),  ctx->cc_maxunit);
	ctx->cc_base_io = calloc(sizeof(base_io_address), ctx->cc_maxbus);
	ctx->cc_bus_ok = calloc(sizeof(BOOL), ctx->cc_maxbus);
	ctx->cc_maxbus_var = "psii_maxbus";
	ctx->cc_description = "Sii0680";
	
	/* get IDE Controller Device ID */

	if ((bdf = pci_find_device(PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_680, 0)) == -1)
	{
		return;
	}

	pci_read_config_dword (bdf, PCI_BASE_ADDRESS_0, &addr);
	ctx->cc_base_io[0] = (void *)(addr & PCI_BASE_ADDRESS_IO_MASK);
	pci_read_config_dword (bdf, PCI_BASE_ADDRESS_2, &addr);
	ctx->cc_base_io[1] = (void *)(addr & PCI_BASE_ADDRESS_IO_MASK);

	PRINTF("p_sii base addresses at %08lx and %08lx\n", ctx->cc_base_io[0], ctx->cc_base_io[1]);
	
	/* Enable bus mastering in case this has not been done, yet. */

	pci_read_config_dword (bdf, PCI_COMMAND, &cmd);
	cmd |= PCI_COMMAND_MASTER;
	pci_write_config_dword (bdf, PCI_COMMAND, cmd);

  	/* initialize registers */

	pci_write_config_byte (bdf, 0x80, 0x00);
	pci_write_config_byte (bdf, 0x84, 0x00);
	pci_read_config_byte (bdf, 0x8A, &tmpbyte);
	pci_write_config_byte (bdf, 0x8A, tmpbyte | 0x01);

	pci_write_config_word (bdf, 0xA2, 0x328A);
	pci_write_config_dword (bdf, 0xA4, 0x328A328A);
	pci_write_config_dword (bdf, 0xA8, 0x43924392);
	pci_write_config_dword (bdf, 0xAC, 0x40094009);
	pci_write_config_word (bdf, 0xB2, 0x328A);
	pci_write_config_dword (bdf, 0xB4, 0x328A328A);
	pci_write_config_dword (bdf, 0xB8, 0x43924392);
	pci_write_config_dword (bdf, 0xBC, 0x40094009);
	
	ctx->cc_present = TRUE;
	ctx->cc_block_read = p_sii_block_read;
	ctx->cc_atapi_read = p_sii_atapi_read;
	
	PRINTF("Done p_sii initialization\n");
}

static void init_controllers(void) //Will fill in controllers[] with the appropriate values.
{
	unsigned cnt;
	s_sii_early_init(&controllers[S_SII_POS]);
	s_4_sii_early_init(&controllers[S4_SII_POS]);
#ifdef CONFIG_SAM460EX
	sata2_460_early_init(&controllers[SATA2_460_POS]);
#endif
	p_sii_early_init(&controllers[P_SII_POS]);	

	PRINTF("Looping in early init for a total of %lu controllers to compute units per bus\n", 
		((sizeof controllers)/(sizeof (struct controller_context))));

	for(cnt=0; cnt < ((sizeof controllers)/(sizeof (struct controller_context))); cnt++)
	{
		controllers[cnt].cc_units_per_bus = controllers[cnt].cc_maxunit/controllers[cnt].cc_maxbus;
		PRINTF("Units per bus for bus %u: %u\n", cnt, controllers[cnt].cc_units_per_bus);
	}

	PRINTF("Done init controllers\n");
}

static void internal_ide_unit_scan(struct controller_context * ctx) //Taken from cmd_ide.c/ide_init, but sort of preprocessed.
{
	unsigned char c;
	int i, bus;
	
	unsigned int max_bus_scan;
	unsigned int ata_reset_time;
	char *s;
		
	/*
	 * Wait for IDE to get ready.
	 * According to spec, this can take up to 31 seconds!
	 */
	PRINTF("Checking for %s\n",ctx->cc_maxbus_var);
	s = getenv(ctx->cc_maxbus_var);
	if (s) 
	    max_bus_scan = simple_strtol(s, NULL, 10);
	else 
	    max_bus_scan = ctx->cc_maxbus;

	PRINTF("Now looping for a total of %u bus\n", max_bus_scan);

	for (bus=0; bus<max_bus_scan; ++bus) 
	{
		int dev = bus * (ctx->cc_maxunit / max_bus_scan);
        printf ("SATA Device %d: ",dev);
        
		ctx->cc_bus_ok[bus] = 0;

		/* Select device
		 */
		udelay (100000);		/* 100 ms */
		local_ide_outb (dev, ATA_DEV_HD, ATA_LBA | ATA_DEVICE_ADV(ctx,dev), ctx);
		udelay (100000);		/* 100 ms */
		
		ata_reset_time = ATA_RESET_TIME;
		s = getenv("ide_reset_timeout");
		if (s) ata_reset_time = simple_strtol(s, NULL, 10);
		
		i = 0;
		do {
			udelay (10000);		/* 10 ms */

			c = local_ide_inb (dev, ATA_STATUS, ctx);
			i++;
			
			if (i > (ata_reset_time * 100)) 
			{
				puts ("* Timeout *\n");
				
				/* If this is the second bus, the first one was OK */
				if (bus != 0) 
				{
				    ctx->cc_bus_ok[bus] = FALSE;
				    goto skip_bus;
				}
				return;
			}
			if ((i >= 100) && ((i%100)==0)) 
			{
				putc ('.');
				PRINTF ("%x",c);
			}
		} while (c & ATA_STAT_BUSY);

		if (c & (ATA_STAT_BUSY | ATA_STAT_FAULT)) 
		{
			puts ("not available ");
			PRINTF ("Status = 0x%02X ", c);
#ifndef CONFIG_ATAPI /* ATAPI Devices do not set DRDY */
		} else  if ((c & ATA_STAT_READY) == 0) {
			puts ("not available ");
			PRINTF ("Status = 0x%02X ", c);
#endif
		} else {
			puts ("OK ");
			ctx->cc_bus_ok[bus] = TRUE;
		}
	}

skip_bus:
	putc ('\n');

	for (i=0; i<ctx->cc_maxunit; i++) 
	{
		ctx->cc_units[i].type=DEV_TYPE_UNKNOWN;
		ctx->cc_units[i].if_type=IF_TYPE_IDE;
		ctx->cc_units[i].dev=i;
		ctx->cc_units[i].part_type=PART_TYPE_UNKNOWN;
		ctx->cc_units[i].blksz=0;
		ctx->cc_units[i].lba=0;
		ctx->cc_units[i].block_read=ctx->cc_block_read;
		
		if (!ctx->cc_bus_ok[IDE_BUS(i)])
			continue;

		local_ide_ident(&ctx->cc_units[i], ctx);

		dev_print(&ctx->cc_units[i]);

		if ((ctx->cc_units[i].lba > 0) && (ctx->cc_units[i].blksz > 0)) 
		{
			/* initialize partition type */
			init_part (&ctx->cc_units[i]);			
		}
	}
}

#ifdef CONFIG_SAM460EX
void sata_460_initialize(struct controller_context *curr)
{
	PRINTF("CALLING init_sata\n");

	int rc, i;

	for (i = 0; i < CONFIG_SYS_SATA_MAX_DEVICE; i++) 
	{
		memset(&sata_dev_desc[i], 0, sizeof(struct block_dev_desc));
		sata_dev_desc[i].if_type = IF_TYPE_SATA;
		sata_dev_desc[i].dev = i;
		sata_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
		sata_dev_desc[i].type = DEV_TYPE_HARDDISK;
		sata_dev_desc[i].lba = 0;
		sata_dev_desc[i].blksz = 512;
		sata_dev_desc[i].block_read = sata_read;
		//sata_dev_desc[i].block_write = sata_write;

		rc = init_sata(i);
		rc = scan_sata(i);
		if ((sata_dev_desc[i].lba > 0) && (sata_dev_desc[i].blksz > 0))
			init_part(&sata_dev_desc[i]);
	}
	
	curr->cc_units = &sata_dev_desc;
	
	if (rc == 0)
	{				
		for (i = 0; i < CONFIG_SYS_SATA_MAX_DEVICE; ++i) 
		{
			if (sata_dev_desc[i].type == DEV_TYPE_UNKNOWN)
				continue;
			printf ("SATA device %d:\n", i);
			dev_print(&curr->cc_units[i]);
		}
	}
}
#endif

void ide_controllers_init(void)
{
	unsigned cnt;
	
	//Activates all the controllers	
	init_controllers(); 

	//Ok, now tries to scan the various HDD buses.
	for(cnt=0; cnt < sizeof(controllers)/sizeof(struct controller_context); cnt++)
	{
		struct controller_context *curr = &controllers[cnt];

		if(curr->cc_present)
		{
			unsigned unit_index;
			PRINTF("doing unit scan for controller n. %u\n", cnt);

#ifdef CONFIG_SAM460EX			
			if (strcmp(curr->cc_description,"SATA2-460") == 0)
			{
				sata_460_initialize(curr);
			}			
			else
#endif			
			{				
			    internal_ide_unit_scan(curr);

				//For each unit tries to enable PIO4
			
				for(unit_index = 0; unit_index < curr->cc_maxunit; unit_index++) 
				{
					block_dev_desc_t * dev = &curr->cc_units[unit_index];
					if(dev->blksz)
					{
						local_ide_set_pio(unit_index, 4, curr);
					}
				}
			}
		}
	}
}

static block_dev_desc_t * generic_get_dev(const unsigned unit, const struct controller_context * const cc)
{
	if(unit < cc->cc_maxunit)
	{
		if(cc->cc_units[unit].block_read)
		{
			return &cc->cc_units[unit];
		}
	}
	return NULL;
}

block_dev_desc_t *s_sii_get_dev(const unsigned unit)
{
	return generic_get_dev(unit, &controllers[S_SII_POS]);
}

static unsigned long s_sii_block_read(int dev, unsigned long start, lbaint_t blkcnt, unsigned long *buffer)
{
	return local_ide_read(dev, start, blkcnt, buffer, &controllers[S_SII_POS]);
}

block_dev_desc_t *s_4_sii_get_dev(const unsigned unit)
{
	return generic_get_dev(unit, &controllers[S4_SII_POS]);
}

static unsigned long s_4_sii_block_read(int dev, unsigned long start, lbaint_t blkcnt, unsigned long *buffer)
{
	return local_ide_read(dev, start, blkcnt, buffer, &controllers[S4_SII_POS]);
}

#ifdef CONFIG_SAM460EX
block_dev_desc_t * sata2_460_get_dev(const unsigned unit)
{
	return generic_get_dev(unit, &controllers[SATA2_460_POS]);
}
#endif

block_dev_desc_t *p_sii_get_dev(const unsigned unit)
{
	return generic_get_dev(unit, &controllers[P_SII_POS]);
}

static unsigned long p_sii_block_read(int dev, unsigned long start, lbaint_t blkcnt, unsigned long *buffer)
{
	return local_ide_read(dev, start, blkcnt, buffer, &controllers[P_SII_POS]);
}

static ulong local_ide_read (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer, const struct controller_context * const cc)
{
	ulong n = 0;
	unsigned char c;
	unsigned char pwrsave=0; /* power save */
#ifdef CONFIG_LBA48
	unsigned char lba48 = 0;

	if (blknr & (uint64_t)0x0000fffff0000000) {
		/* more than 28 bits used, use 48bit mode */
		lba48 = 1;
	}
#endif
	PRINTF ("ide_read dev %d start %p, blocks %lX buffer at %p\n",
		device, blknr, blkcnt, (ulong)buffer);

	/* Select device
	 */
	local_ide_outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE_ADV(cc,device), cc);
	c = local_ide_wait (device, IDE_TIME_OUT, cc);

	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 */
	local_ide_outb (device, ATA_COMMAND,  ATA_CMD_CHK_PWR, cc);
	udelay (50);

	c = local_ide_wait (device, IDE_TIME_OUT, cc);	/* 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 = local_ide_inb(device,ATA_SECT_CNT, cc);
		PRINTF("Powersaving %02X\n",c);
		if(c==0)
			pwrsave=1;
	}

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

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

#ifdef CONFIG_LBA48
		if (lba48) 
		{
			local_ide_outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE_ADV(cc,device) , cc);
			local_ide_outb (device, ATA_COMMAND, ATA_CMD_READ_EXT, cc);

		} else
#endif
		{
			local_ide_outb (device, ATA_DEV_HD,   ATA_LBA		|
						    ATA_DEVICE_ADV(cc, device)	|
						    ((blknr >> 24) & 0xF) , cc);
			local_ide_outb (device, ATA_COMMAND,  ATA_CMD_READ, cc);
		}

		udelay (50);

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

		if ((c&(ATA_STAT_DRQ|ATA_STAT_BUSY|ATA_STAT_ERR)) != ATA_STAT_DRQ) {
#if defined(CONFIG_SYS_64BIT_LBA) && defined(CONFIG_SYS_64BIT_VSPRINTF)
			printf ("Error (no IRQ) dev %d blk %qd: status 0x%02x\n",
				device, blknr, c);
#else
			printf ("Error (no IRQ) dev %d blk %ld: status 0x%02x\n",
				device, (ulong)blknr, c);
#endif
			break;
		}

		local_input_data (device, buffer, ATA_SECTORWORDS, cc);
		(void) local_ide_inb (device, ATA_STATUS, cc);	/* clear IRQ */

		++n;
		++blknr;
		buffer += ATA_SECTORWORDS;
	}
	
IDE_READ_E:
	return (n);
}

static void local_input_swap_data(int dev, ulong *sect_buf, int words, const struct controller_context * const cc)
{
	volatile ushort	*pbuf = (ushort *)(ATA_CURR_BASE_ADV(cc, dev)+ATA_DATA_REG);
	ushort	*dbuf = (ushort *)sect_buf;

	PRINTF("in input swap data base for read is %lx\n", (unsigned long) pbuf);

	while (words--) {
		EIEIO;
		*dbuf++ = ld_le16(pbuf);
		EIEIO;		
		*dbuf++ = ld_le16(pbuf);
	}
}

static void local_input_data(int dev, ulong *sect_buf, int words, const struct controller_context * const cc)
{
	ushort	*dbuf;
	volatile ushort	*pbuf;

	pbuf = (ushort *)(ATA_CURR_BASE_ADV(cc, dev)+ATA_DATA_REG);
	dbuf = (ushort *)sect_buf;

	PRINTF("in input data base for read is %lx\n", (unsigned long) pbuf);

	while (words--) {
		EIEIO;
		*dbuf++ = *pbuf;
		EIEIO;
		*dbuf++ = *pbuf;
	}
}

static void local_ide_ident(block_dev_desc_t *dev_desc, struct controller_context * const ctx)
{
	ulong iobuf[ATA_SECTORWORDS] = { 0 };
	hd_driveid_t *iop = (hd_driveid_t *)iobuf;

	int ii;
	int device;
	int max_bus_scan;
	int retries = 0;
	int do_retry = 0;
	char *s;
	unsigned char c;
			
	device=dev_desc->dev;
	PRINTF("ENTERED local_ide_ident %p %d %p\n",dev_desc,device,ctx);

 	s = getenv(ctx->cc_maxbus_var);
	if (s) {
		max_bus_scan = simple_strtol(s, NULL, 10);
	} else {
		max_bus_scan = CONFIG_SYS_IDE_MAXBUS;
	}

	if (device >= max_bus_scan*2) {
		dev_desc->type=DEV_TYPE_UNKNOWN;
		return;
	}

	// issue a device reset, since it could happen the device is in an unkwown state
	//local_ide_outb (device, ATA_COMMAND, 0x08, ctx);
	/* wait 750 ms */
	//for (ii=0; ii<750; ++ii) 
	//{
	//	udelay (1000);
	//}
	
	/* Select device
	 */
	 
	local_ide_outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE_ADV(ctx,device), ctx);
	udelay (100000);		/* 100 ms */
	
	// issue a device reset, since it could happen the device is in an unkwown state
	local_ide_outb (device, ATA_COMMAND, 0x08, ctx);
	udelay (100000);		/* 100 ms */
		
	dev_desc->if_type=IF_TYPE_IDE;
    
	do_retry = 0;
	retries = 0;

	/* Warning: This will be tricky to read */
	while (retries <= 2) 
	{
		/* check signature */
		u8 tmp = local_ide_inb(device,ATA_SECT_NUM, ctx);
		
		if (/*(tmp == 0x00) ||*/
			((tmp == 0x01) &&
			 (local_ide_inb(device,ATA_CYL_LOW, ctx)  == 0x14) &&
			 (local_ide_inb(device,ATA_CYL_HIGH, ctx) == 0xEB)))
		{
			/* ATAPI Signature found */
			PRINTF("ATAPI\n");
			dev_desc->if_type=IF_TYPE_ATAPI;
			/* Start Ident Command
			 */
			local_ide_outb (device, ATA_COMMAND, ATAPI_CMD_IDENT, ctx);
			/*
			 * Wait for completion - ATAPI devices need more time
			 * to become ready
			 */
			c = local_ide_wait (device, ATAPI_TIME_OUT, ctx);
		} 
		else
		{
			/* Start Ident Command
			 */
			PRINTF("ATA\n");
			local_ide_outb (device, ATA_COMMAND, ATA_CMD_IDENT, ctx);
	
			/* Wait for completion
			 */
			c = local_ide_wait (device, IDE_TIME_OUT, ctx);
		}

		if (((c & ATA_STAT_DRQ) == 0) ||
		    ((c & (ATA_STAT_FAULT|ATA_STAT_ERR)) != 0) ) 
		{
			if (retries <=1) //== 0) 
			{
				do_retry = 1;
			} 
			else 
			{
				return;
			}
		}

		s = getenv("ide_doreset");
		if (s && strcmp(s, "on") == 0 && 1 == do_retry) 
		{
			/* Need to soft reset the device in case it's an ATAPI...  */
			PRINTF("Retrying...\n");
			local_ide_outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE_ADV(ctx,device), ctx);
			udelay(100000);
			local_ide_outb (device, ATA_COMMAND, 0x08, ctx);
			udelay (100000);	/* 100 ms */
			retries++;
		} 
		else 
		{
			retries = 100;
		}
	}	/* see above - ugly to read */

	local_input_swap_data (device, iobuf, ATA_SECTORWORDS, ctx);

	local_ident_cpy (dev_desc->revision, iop->fw_rev, sizeof(dev_desc->revision));
	local_ident_cpy (dev_desc->vendor, iop->model, sizeof(dev_desc->vendor));
	local_ident_cpy (dev_desc->product, iop->serial_no, sizeof(dev_desc->product));
	
	if ((iop->config & 0x0080)==0x0080)
		dev_desc->removable = 1;
	else
		dev_desc->removable = 0;

#ifdef CONFIG_ATAPI
	if (dev_desc->if_type==IF_TYPE_ATAPI) 
	{
		local_atapi_inquiry(dev_desc, ctx);
		return;
	}
#endif /* CONFIG_ATAPI */

	/* swap shorts */
	dev_desc->lba = (iop->lba_capacity << 16) | (iop->lba_capacity >> 16);

#ifdef CONFIG_LBA48
	if (iop->command_set_2 & 0x0400) { /* LBA 48 support */
		dev_desc->lba48 = 1;
		dev_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 {
		dev_desc->lba48 = 0;
	}
#endif /* CONFIG_LBA48 */
	/* assuming HD */
	dev_desc->type=DEV_TYPE_HARDDISK;
	dev_desc->blksz=ATA_BLOCKSIZE;
	dev_desc->lun=0; /* just to fill something in... */
}

static uchar local_ide_wait (int dev, ulong t, const struct controller_context * const cc)
{
	ulong delay = 10 * t;		/* poll every 100 us */
	uchar c;

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

static void local_ident_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';
}

#ifdef CONFIG_ATAPI
/****************************************************************************
 * ATAPI Support
 */

/* since ATAPI may use commands with not 4 bytes alligned length
 * we have our own transfer functions, 2 bytes aligned */
static void local_output_data_shorts(int dev, ushort *sect_buf, int shorts, const struct controller_context * const cc)
{
	ushort	*dbuf;
	volatile ushort	*pbuf;

	pbuf = (ushort *)(ATA_CURR_BASE_ADV(cc, dev)+ATA_DATA_REG);
	dbuf = (ushort *)sect_buf;

	AT_PRINTF("in output data shorts base for read is %lx\n", (unsigned long) pbuf);

	while (shorts--) 
	{
		EIEIO;
		*pbuf = *dbuf++;
	}
}

static void local_input_data_shorts(int dev, ushort *sect_buf, int shorts, const struct controller_context * const cc)
{
	ushort	*dbuf;
	volatile ushort	*pbuf;

	pbuf = (ushort *)(ATA_CURR_BASE_ADV(cc, dev)+ATA_DATA_REG);
	dbuf = (ushort *)sect_buf;

	AT_PRINTF("in input data shorts base for read is %lx\n", (unsigned long) pbuf);

	while (shorts--) 
	{
		EIEIO;
		*dbuf++ = *pbuf;
	}
}

/*
 * 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 local_atapi_wait_mask (int dev, ulong t,uchar mask, uchar res, const struct controller_context * const cc)
{
	ulong delay = 10 * t;		/* poll every 100 us */
	uchar c;

	c = local_ide_inb(dev,ATA_DEV_CTL, cc); /* prevents to read the status before valid */
	while (((c = local_ide_inb(dev, ATA_STATUS, cc)) & mask) != 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-- == 0) 
		{
			break;
		}
	}
	return (c);
}

/*
 * issue an atapi command
 */
static unsigned char local_atapi_issue(int device,unsigned char* ccb,int ccblen, unsigned char * buffer,int buflen, const struct controller_context * const cc)
{
	unsigned char c,err,mask,res;
	int n;

	/* Select device
	 */
	mask = ATA_STAT_BUSY|ATA_STAT_DRQ;
	res = 0;
/*
#ifdef	CONFIG_AMIGAONEG3SE
# warning THF: Removed LBA mode ???
#endif
*/
	local_ide_outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE_ADV(cc,device), cc);
	c = local_atapi_wait_mask(device,ATAPI_TIME_OUT,mask,res, cc);
	if ((c & mask) != res) 
	{
		printf ("ATAPI_ISSUE: device %d not ready status %X\n", device,c);
		err=0xFF;
		goto AI_OUT;
	}
	/* write taskfile */
	local_ide_outb (device, ATA_ERROR_REG, 0, cc); /* no DMA, no overlaped */
	local_ide_outb (device, ATA_SECT_CNT, 0, cc);
	local_ide_outb (device, ATA_SECT_NUM, 0, cc);
	local_ide_outb (device, ATA_CYL_LOW,  (unsigned char)(buflen & 0xFF), cc);
	local_ide_outb (device, ATA_CYL_HIGH, (unsigned char)((buflen>>8) & 0xFF), cc);

/*
#ifdef	CONFIG_AMIGAONEG3SE
# warning THF: Removed LBA mode ???
#endif
*/
	local_ide_outb (device, ATA_DEV_HD,   ATA_LBA | ATA_DEVICE_ADV(cc,device), cc);

	local_ide_outb (device, ATA_COMMAND,  ATAPI_CMD_PACKET, cc);
	udelay (50);

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

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

	local_output_data_shorts (device, (unsigned short *)ccb,ccblen/2, cc); /* write command block */
 	/* ATAPI Command written wait for completition */
	udelay (5000); /* 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 = local_atapi_wait_mask(device,ATAPI_TIME_OUT,mask,res, cc);
	if ((c & mask) != res ) 
	{
		if (c & ATA_STAT_ERR) 
		{
			err=(local_ide_inb(device,ATA_ERROR_REG, cc))>>4;
			AT_PRINTF("atapi_issue 1 returned sense key %X status %02X\n",err,c);
		} 
		else 
		{
			printf ("ATAPI_ISSUE: (no DRQ) after sending ccb (%x) status 0x%02x\n", ccb[0],c);
			err=0xFF;
		}
		goto AI_OUT;
	}
	n=local_ide_inb(device, ATA_CYL_HIGH, cc);
	n<<=8;
	n+=local_ide_inb(device, ATA_CYL_LOW, cc);
	if(n>buflen) 
	{
		printf("ERROR, transfer bytes %d requested only %d\n",n,buflen);
		err=0xff;
		goto AI_OUT;
	}
	if((n==0)&&(buflen<0)) 
	{
		printf("ERROR, transfer bytes %d requested %d\n",n,buflen);
		err=0xff;
		goto AI_OUT;
	}
	if(n!=buflen) 
	{
		AT_PRINTF("WARNING, transfer bytes %d not equal with requested %d\n",n,buflen);
	}
	if(n!=0) { /* data transfer */
		AT_PRINTF("ATAPI_ISSUE: %d Bytes to transfer\n",n);
		 /* we transfer shorts */
		n>>=1;
		/* ok now decide if it is an in or output */
		if ((local_ide_inb(device, ATA_SECT_CNT, cc)&0x02)==0) 
		{
			AT_PRINTF("Write to device\n");
			local_output_data_shorts(device,(unsigned short *)buffer,n, cc);
		} 
		else 
		{
			AT_PRINTF("Read from device @ %p shorts %d\n",buffer,n);
			local_input_data_shorts(device,(unsigned short *)buffer,n, cc);
		}
	}
	udelay(5000); /* seems that some CD ROMs need this... */
	mask = ATA_STAT_BUSY|ATA_STAT_ERR;
	res=0;
	c = local_atapi_wait_mask(device,ATAPI_TIME_OUT,mask,res, cc);
	if ((c & ATA_STAT_ERR) == ATA_STAT_ERR) 
	{
		err=(local_ide_inb(device,ATA_ERROR_REG, cc) >> 4);
		AT_PRINTF("atapi_issue 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

unsigned char local_atapi_issue_autoreq (int device,
				   unsigned char* ccb,
				   int ccblen,
				   unsigned char *buffer,
				   int buflen,
				   const struct controller_context * const cc)
{
	unsigned char sense_data[18],sense_ccb[12];
	unsigned char res,key,asc,ascq;
	int notready,unitattn;

	char *s;
	unsigned int timeout, retrycnt;

	s = getenv("ide_cd_timeout");
	timeout = s ? (simple_strtol(s, NULL, 10)*1000000)/5 : 0;

	retrycnt = 0;

	unitattn=ATAPI_UNIT_ATTN;
	notready=ATAPI_DRIVE_NOT_READY;

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

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

	AT_PRINTF("(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=local_atapi_issue(device,sense_ccb,12,sense_data,18, cc);
	key=(sense_data[2]&0xF);
	asc=(sense_data[12]);
	ascq=(sense_data[13]);

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

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

	if((key==5) && (asc==0x24) && (ascq==00)) 
	{
		// this patch is required by some slim DVD/CD 
		AT_PRINTF("CDB in UFI command contains illegal value\n");
		return 0; /* ok device ready */
	}
			
	if((key==6)|| (asc==0x29) || (asc==0x28)) { /* Unit Attention */
		if(unitattn-->0) 
		{
			udelay(200*1000);
			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) 
		{
			udelay(200*1000);
			goto retry;
		}
		printf("Drive not ready, tried %d times\n",ATAPI_DRIVE_NOT_READY);
		goto error;
	}
	
	if(asc==0x3a) 
	{
		AT_PRINTF("Media not present\n");
		goto error;
	}

	if ((sense_data[2]&0xF)==0x0B) 
	{
		AT_PRINTF("ABORTED COMMAND...retry\n");
		if (retrycnt++ < 4)
			goto retry;
		return (0xFF);
	}

	if ((sense_data[2]&0xf) == 0x02 &&
	    sense_data[12] == 0x04	&&
	    sense_data[13] == 0x01	) 
	{
		AT_PRINTF("Waiting for unit to become active\n");
		udelay(timeout);
		if (retrycnt++ < 4)
			goto retry;
		return 0xFF;
	}

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


static void local_atapi_inquiry(block_dev_desc_t * dev_desc, struct controller_context * const ctx)
{
	unsigned char ccb[12]; /* Command descriptor block */
	unsigned char iobuf[64]; /* temp buf */
	unsigned char c;
	int device;
	
	device=dev_desc->dev;
	dev_desc->type=DEV_TYPE_UNKNOWN; /* not yet valid */
	dev_desc->block_read=ctx->cc_atapi_read;

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

	ccb[0]=ATAPI_CMD_INQUIRY;
	ccb[4]=40; /* allocation Legnth */
	c=local_atapi_issue_autoreq(device,ccb,12,(unsigned char *)iobuf,40, ctx);

	AT_PRINTF("ATAPI_CMD_INQUIRY returned %x\n",c);
	if (c!=0)
		return;

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

	dev_desc->lun=0;
	dev_desc->lba=0;
	dev_desc->blksz=0;
	dev_desc->type=iobuf[0] & 0x1f;

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

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

	c=local_atapi_issue_autoreq(device,ccb,12,(unsigned char *)iobuf,0, ctx);

	AT_PRINTF("ATAPI_CMD_START_STOP returned %x\n",c);
	if (c!=0)
		return;

	memset(ccb,0,sizeof(ccb));
	memset(iobuf,0,sizeof(iobuf));
	c=local_atapi_issue_autoreq(device,ccb,12,(unsigned char *)iobuf,0, ctx);

	AT_PRINTF("ATAPI_CMD_UNIT_TEST_READY returned %x\n",c);
	if (c!=0)
		return;

	memset(ccb,0,sizeof(ccb));
	memset(iobuf,0,sizeof(iobuf));
	ccb[0]=ATAPI_CMD_READ_CAP;
	c=local_atapi_issue_autoreq(device,ccb,12,(unsigned char *)iobuf,8, ctx);
	AT_PRINTF("ATAPI_CMD_READ_CAP returned %x\n",c);
	if (c!=0)
		return;

	AT_PRINTF("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]);

	dev_desc->lba  =((unsigned long)iobuf[0]<<24) +
			((unsigned long)iobuf[1]<<16) +
			((unsigned long)iobuf[2]<< 8) +
			((unsigned long)iobuf[3]);
	dev_desc->blksz=((unsigned long)iobuf[4]<<24) +
			((unsigned long)iobuf[5]<<16) +
			((unsigned long)iobuf[6]<< 8) +
			((unsigned long)iobuf[7]);
#ifdef CONFIG_LBA48
	dev_desc->lba48 = 0; /* ATAPI devices cannot use 48bit addressing (ATA/ATAPI v7) */
#endif
	return;
}

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

static ulong local_atapi_read (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer,
				const struct controller_context * const cc)
{
	ulong n = 0;
	unsigned char ccb[12]; /* Command descriptor block */
	ulong cnt;

	AT_PRINTF("atapi_read dev %d start %lX, blocks %lX 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]=(unsigned char) (blknr>>24) & 0xFF; /* MSB Block */
		ccb[3]=(unsigned char) (blknr>>16) & 0xFF; /*  */
		ccb[4]=(unsigned char) (blknr>> 8) & 0xFF;
		ccb[5]=(unsigned char)  blknr      & 0xFF; /* LSB Block */
		ccb[6]=(unsigned char) (cnt  >>24) & 0xFF; /* MSB Block count */
		ccb[7]=(unsigned char) (cnt  >>16) & 0xFF;
		ccb[8]=(unsigned char) (cnt  >> 8) & 0xFF;
		ccb[9]=(unsigned char)  cnt	   & 0xFF; /* LSB Block */
		ccb[10]=0; /* reserved */
		ccb[11]=0; /* reserved */

		if (local_atapi_issue_autoreq(device,ccb,12,
					(unsigned char *)buffer,
					cnt*ATAPI_READ_BLOCK_SIZE, cc) == 0xFF) 
		{
			return (n);
		}
		n+=cnt;
		blkcnt-=cnt;
		blknr+=cnt;
		buffer+=cnt*(ATAPI_READ_BLOCK_SIZE/4); /* ulong blocksize in ulong */
	} 
	while (blkcnt > 0);
	
	return (n);
}

static ulong s_sii_atapi_read (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer)
{
	return local_atapi_read(device, blknr, blkcnt, buffer, &controllers[S_SII_POS]);//Note that uboot is broken if lbaint_t is 64 bit!
}

static ulong s_4_sii_atapi_read (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer)
{
	return local_atapi_read(device, blknr, blkcnt, buffer, &controllers[S4_SII_POS]);//Note that uboot is broken if lbaint_t is 64 bit!
}

static ulong p_sii_atapi_read (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer)
{
	return local_atapi_read(device, blknr, blkcnt, buffer, &controllers[P_SII_POS]);//Note that uboot is broken if lbaint_t is 64 bit!
}

/* ------------------------------------------------------------------------- */

#endif /* CONFIG_ATAPI */

static _Bool local_ide_set_pio(const int device, const unsigned char mode, const struct controller_context * const cc)
{
	_Bool ret = 0;
	unsigned char pwrsave=0, c; // power save
	
	PRINTF ("Trying to set PIO mode %u for device %d \n", mode, device);

	//Select device
	
	local_ide_outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE_ADV(cc,device), cc);
	c = local_ide_wait (device, IDE_TIME_OUT, cc);

	if (c & ATA_STAT_BUSY)
	{
		goto IDE_EXIT;
	}

	// first check if the drive is in Powersaving mode, if yes, increase the timeout value
	local_ide_outb (device, ATA_COMMAND,  ATA_CMD_CHK_PWR, cc);
	udelay (50);

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

	if (c & ATA_STAT_BUSY)
	{
		goto IDE_EXIT;
	}
		
	if ((c & ATA_STAT_ERR) == ATA_STAT_ERR)
	{
	}
	else	{
		c = local_ide_inb(device,ATA_SECT_CNT, cc);
		PRINTF("Powersaving %02X\n",c);
		if(c==0)
			pwrsave=1;
	}

	//Ok, the real game starts here.

	c = local_ide_wait (device, IDE_TIME_OUT, cc);
		
	if (c & ATA_STAT_BUSY)
	{
		goto IDE_EXIT;
	}
		
	local_ide_outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE_ADV(cc,device), cc);
	local_ide_outb (device, ATA_SECT_NUM, 0x00, cc);
	local_ide_outb (device, ATA_CYL_LOW,  0x00, cc);
	local_ide_outb (device, ATA_CYL_HIGH, 0x00, cc);
	
	local_ide_outb (device, ATA_ERROR_REG, 0x03, cc); //Set tramsfer mode; this is the "feature" register when writing.
	local_ide_outb (device, ATA_SECT_CNT, 8|mode, cc); //Sets selected PIO mode
	
	//This one must be the last one, and it actually starts the command.
	local_ide_outb (device, ATA_COMMAND,  ATA_CMD_SETF, cc);

	udelay (50);

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

	if(!(c & ATA_STAT_ERR))
	{
		PRINTF("Done!\n");
		ret = 1; //Done!
	}
	else PRINTF("Status is 0x%02x\n", c);
	(void) local_ide_inb (device, ATA_STATUS, cc);	// clear IRQ
	
IDE_EXIT:
	return ret;
}

int local_do_ide (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
//int local_do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);

U_BOOT_CMD(
	sata,  5,  1,  local_do_ide,
	"SATA sub-system",
	"sata reset [x] - init SATA controller 'x'\n"
	"sata info [x] - show available SATA devices on controller 'x'\n"
	"sata device [x] [dev] - select device 'dev' on controller 'x'\n"
	"sata part [x] [dev] - print partition table of device 'dev' on controller 'x'\n"

);

/*
U_BOOT_CMD(
	diskboot,	4,	1,	local_do_diskboot,
	"boot from IDE device",
	"loadAddr dev:part [x] - boot from IDE device 'dev' on controller 'x'\n"
);
*/
//This one should be inlined, but it's not because of code size concerns.
static BOOL valid_controller_num(WORD pos, WORD * old)
{ 
	int last;
	
//#ifdef CONFIG_SAM460EX	
	last = SATA2_460_POS;
//#else
	last = S4_SII_POS;
//#endif
    
    last = P_SII_POS;
    
	//if(pos >= 0 && pos <= ((sizeof(controllers) / sizeof(struct controller_context))))
	if ((pos >= 0) && (pos <= last))	
	{
		if(controllers[pos].cc_present)
		{
			*old = pos;
			return TRUE;
		}
	}
	
	//if(*old >= 0 && *old <= ((sizeof(controllers) / sizeof(struct controller_context))))
	//if ((*old >= 0) && (*old <= last))	
	//	return TRUE;
	
	return FALSE;
}

//WARNING: prerequisite is that valid_controller_num was successfull!!
static BOOL valid_unit_num(const WORD c_controller, WORD devoffset, WORD * old_dev)
{
	struct controller_context * curr_cont = &controllers[c_controller];

	if(devoffset >= 0 && devoffset <= curr_cont->cc_maxunit)
	{
		if(curr_cont->cc_units[devoffset].type != DEV_TYPE_UNKNOWN && curr_cont->cc_units[devoffset].blksz)
		{
			if(old_dev) *old_dev = devoffset;
			return TRUE;
		}
	}

	if(old_dev)
	{
		devoffset = *old_dev;

		if(devoffset >= 0 && devoffset <= curr_cont->cc_maxunit)
		{
			if(curr_cont->cc_units[devoffset].type != DEV_TYPE_UNKNOWN && curr_cont->cc_units[devoffset].blksz)
				return TRUE;
		}
	}
	
	return FALSE;
}

struct match_opt {
	char *	mo_string;
	WORD	mo_value;
	UWORD	mo_minlen;
};

enum do_ide_vals {
	UNDEFINED = -1,
	VAL_RESET=0,
	VAL_INFO,
	VAL_DEVICE,
	VAL_PART,
};

struct match_opt do_ide_opts[] ={
	{ "reset",	VAL_RESET,	3},
	{ "info",	VAL_INFO,	3},
	{ "device",	VAL_DEVICE,	3},
	{ "part",	VAL_PART,	4},
	{ "",		UNDEFINED,	1}
};

static WORD find_opt(char * const str, const struct match_opt * const mo, const UWORD len)
{
	UWORD cnt;
	for(cnt=0; cnt < len; cnt++)
	{
		if(!strncmp(str, mo[cnt].mo_string, mo[cnt].mo_minlen))
			return mo[cnt].mo_value;
	}
	return UNDEFINED;
}

static void print_no_controller(void)
{
	puts("Selected controller doesn't exist\n");
}

static void print_controller(const unsigned index)
{
	UWORD i;
	struct controller_context * cc = &controllers[index];

	printf("Units on controller %s\n", cc->cc_description);

	for (i=0; i< controllers[index].cc_maxunit; ++i)
	{
		if (controllers[index].cc_units[i].type==DEV_TYPE_UNKNOWN)
			continue; // list only known devices
		printf ("SATA device %d: ", i);
		dev_print(&controllers[index].cc_units[i]);
	}
	puts("\n");
}

static WORD curr_controller = UNDEFINED;
//The variable above holds the currently selected controller. 
//It's used by both local_do_ide and local_do_diskboot.

int local_do_ide (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
    WORD scanres, val1=0, val2=0;
    static WORD curr_device=UNDEFINED;
    
    if(argc == 0 || argc == 1)
	{
		printf ("Usage:\n%s\n", cmdtp->usage);
		return 1;
	}
		
	scanres = find_opt(argv[1], do_ide_opts, sizeof(do_ide_opts)/sizeof(struct match_opt));
	if(argc>2)
  	{
		val1 = atoi(argv[2]);
		if(argc>=3)
			val2 = atoi(argv[3]);
	}
		
	switch(scanres)
  	{
	case -1:
		printf ("Usage:\n%s\n", cmdtp->usage);
		return 1;
	
	case VAL_RESET:
		if(valid_controller_num(val1, &curr_controller))
		{
#ifdef CONFIG_SAM460EX		
			if (curr_controller == 2) 
				sata_460_initialize(&controllers[curr_controller]);
			else
#endif			
				internal_ide_unit_scan(&controllers[curr_controller]);
		}
		else 
		{
			print_no_controller();
		}
		break;
		
	case VAL_INFO:
		if(valid_controller_num(val1, &curr_controller))
		{
			print_controller(curr_controller);
		}
		else print_no_controller();
		break;
		
	case VAL_DEVICE:
		if(valid_controller_num(val1, &curr_controller) && valid_unit_num(curr_controller, val2, &curr_device))
		{
			printf("Device %d on %s selected.\n", curr_device, controllers[curr_controller].cc_description);
		}
		break;
		
	case VAL_PART:
		if(valid_controller_num(val1, &curr_controller) && valid_unit_num(curr_controller, val2, &curr_device))
		{
			block_dev_desc_t * currdev = &controllers[curr_controller].cc_units[curr_device];
			if(currdev->part_type!=PART_TYPE_UNKNOWN)
			{
				print_part(currdev);
			}
		}
		break;
	default:
		printf("Unknown option.\n");
	}
	
	return 1;
}
/*
int local_do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	char *boot_device = NULL;
	char *ep;
	int dev, part = 0;
	ulong cnt;
	ulong addr;
	disk_partition_t info;
	image_header_t *hdr;
	int rcode = 0;
	block_dev_desc_t * target_unit;

	switch (argc) {
	case 1:
		addr = CONFIG_SYS_LOAD_ADDR;
		boot_device = getenv ("bootdevice");
		break;
	case 2:
		addr = simple_strtoul(argv[1], NULL, 16);
		boot_device = getenv ("bootdevice");
		break;
	case 3:
		addr = simple_strtoul(argv[1], NULL, 16);
		boot_device = argv[2];
		break;
	case 4:
		{
		WORD tentative_controller = atoi(argv[3]);
		if(valid_controller_num(tentative_controller, &curr_controller))
		{
			addr = simple_strtoul(argv[1], NULL, 16);
			boot_device = argv[2];
			break;
		}
		//If the controller entry is not valid, code will fall through to the default entry.
		}
	default:
		printf ("Usage:\n%s\n", cmdtp->usage);
		SHOW_BOOT_PROGRESS (-1);
		return 1;
	}

	if(curr_controller == UNDEFINED)
	{
		printf ("\n* No valid controller specified *\n", cmdtp->usage);
		SHOW_BOOT_PROGRESS (-1);
		return 1;		
	}
	
	if (!boot_device) {
		puts ("\n* No boot device *\n");
		SHOW_BOOT_PROGRESS (-1);
		return 1;
	}

	dev = simple_strtoul(boot_device, &ep, 16);

	if (!valid_unit_num(curr_controller, dev, NULL))
	{
		printf ("\n* Device %d not available\n", dev);
		SHOW_BOOT_PROGRESS (-1);
		return 1;
	}

	//Now tries to find the partition to boot from, by moving the cursor upto where
	//the end of the boot_device number was.
	if (*ep) {
		if (*ep != ':') {
			puts ("\n* Invalid boot device, use `dev[:part]' *\n");
			SHOW_BOOT_PROGRESS (-1);
			return 1;
		}
		part = simple_strtoul(++ep, NULL, 16);
	}
	
	target_unit = &controllers[curr_controller].cc_units[dev];
	
	if (get_partition_info (target_unit, part, &info)) {
		SHOW_BOOT_PROGRESS (-1);
		return 1;
	}
	
	if ((strncmp(info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) &&
	    (strncmp(info.type, BOOT_PART_COMP, sizeof(info.type)) != 0)) {
		printf ("\n* Invalid partition type \"%.32s\""
			" (expect \"" BOOT_PART_TYPE "\")\n",
			info.type);
		SHOW_BOOT_PROGRESS (-1);
		return 1;
	}

	printf ("\nLoading from IDE device %d, partition %d: "
		"Name: %.32s  Type: %.32s\n",
		dev, part, info.name, info.type);

	PRINTF ("First Block: %ld,  # of blocks: %ld, Block Size: %ld\n",
		info.start, info.size, info.blksz);

	if (target_unit->block_read (dev, info.start, 1, (ulong *)addr) != 1)
	{
		printf ("* Read error on %d:%d\n", dev, part);
		SHOW_BOOT_PROGRESS (-1);
		return 1;
	}

	hdr = (image_header_t *)addr;

	if (ntohl(hdr->ih_magic) == IH_MAGIC) {

		//print_image_hdr (hdr);

		cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t));
		cnt += info.blksz - 1;
		cnt /= info.blksz;
		cnt -= 1;
	} else {
		printf("\n* Bad Magic Number *\n");
		SHOW_BOOT_PROGRESS (-1);
		return 1;
	}

	if (target_unit->block_read (dev, info.start+1, cnt,
		      (ulong *)(addr+info.blksz)) != cnt) {
		printf ("* Read error on %d:%d\n", dev, part);
		SHOW_BOOT_PROGRESS (-1);
		return 1;
	}

	// Loading ok, update default load address

	load_addr = addr;

	// Check if we should attempt an auto-start
	if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) {
		char *local_args[2];
		extern int do_bootm (cmd_tbl_t *, int, int, char *[]);

		local_args[0] = argv[0];
		local_args[1] = NULL;

		printf ("Automatic boot of image at addr 0x%08lX ...\n", addr);

		do_bootm (cmdtp, 0, 1, local_args);
		rcode = 1;
	}
	return rcode;;
}
*/
