/*
 * (C) Copyright 2001
 * Denis Peter, MPL AG, d.peter@mpl.ch.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * 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
 *
 */
/*
 * Floppy Disk support
 */

#include <common.h>
#include <config.h>
#include <command.h>
#include <image.h>


#undef	FDC_DEBUG

#ifdef	FDC_DEBUG
#define	PRINTF(fmt,args...)	printf (fmt ,##args)
#else
#define PRINTF(fmt,args...)
#endif

#ifndef	TRUE
#define TRUE            1
#endif
#ifndef FALSE
#define FALSE           0
#endif


#if (CONFIG_COMMANDS & CFG_CMD_DATE)
#include <rtc.h>
#endif

#if (CONFIG_COMMANDS & CFG_CMD_FDC)


typedef struct {
	int						flags;		/* connected drives ect */
	unsigned long blnr;			/* Logical block nr */
	uchar					drive; 		/* drive no */
	uchar					cmdlen; 	/* cmd length */
	uchar					cmd[16]; 	/* cmd desc */
	uchar					dma;			/* if > 0 dma enabled */
	uchar					result[11];/* status information */
	uchar					resultlen; /* lenght of result */
} FDC_COMMAND_STRUCT;
/* flags: only the lower 8bit used:
 * bit 0 if set drive 0 is present
 * bit 1 if set drive 1 is present
 * bit 2 if set drive 2 is present
 * bit 3 if set drive 3 is present
 * bit 4 if set disk in drive 0 is inserted
 * bit 5 if set disk in drive 1 is inserted
 * bit 6 if set disk in drive 2 is inserted
 * bit 7 if set disk in drive 4 is inserted
 */


/* cmd indexes */
#define COMMAND 		0
#define DRIVE 			1
#define CONFIG0			1
#define SPEC_HUTSRT	1
#define TRACK 			2
#define CONFIG1			2
#define SPEC_HLT		2
#define HEAD				3
#define CONFIG2			3
#define SECTOR 			4
#define SECTOR_SIZE	5
#define LAST_TRACK	6
#define GAP					7
#define DTL					8
/* result indexes */
#define STATUS_0						0
#define STATUS_PCN					1
#define STATUS_1						1
#define STATUS_2						2
#define STATUS_TRACK				3
#define STATUS_HEAD					4
#define STATUS_SECT					5
#define STATUS_SECT_SIZE		6


/* Register addresses */
#define FDC_BASE	0x3F0
#define FDC_SRA		FDC_BASE + 0	/* Status Register A */
#define FDC_SRB		FDC_BASE + 1	/* Status Register B */
#define FDC_DOR		FDC_BASE + 2	/* Digital Output Register */
#define FDC_TDR		FDC_BASE + 3	/* Tape Drive Register */
#define FDC_DSR		FDC_BASE + 4	/* Data rate Register */
#define FDC_MSR		FDC_BASE + 4	/* Main Status Register */
#define FDC_FIFO	FDC_BASE + 5	/* FIFO */
#define FDC_DIR		FDC_BASE + 6	/* Digital Input Register */
#define FDC_CCR		FDC_BASE + 7	/* Configuration Control */
/* Commands */
#define FDC_CMD_SENSE_INT 		0x08
#define FDC_CMD_CONFIGURE 		0x13
#define FDC_CMD_SPECIFY	 			0x03
#define FDC_CMD_RECALIBRATE 	0x07
#define FDC_CMD_READ				 	0x06
#define FDC_CMD_READ_TRACK	 	0x02
#define FDC_CMD_READ_ID			 	0x0A
#define FDC_CMD_DUMP_REG		 	0x0E
#define FDC_CMD_SEEK				 	0x0F

#define FDC_CMD_SENSE_INT_LEN 		0x01
#define FDC_CMD_CONFIGURE_LEN 		0x04
#define FDC_CMD_SPECIFY_LEN	 			0x03
#define FDC_CMD_RECALIBRATE_LEN 	0x02
#define FDC_CMD_READ_LEN				 	0x09
#define FDC_CMD_READ_TRACK_LEN	 	0x09
#define FDC_CMD_READ_ID_LEN			 	0x02
#define FDC_CMD_DUMP_REG_LEN		 	0x01
#define FDC_CMD_SEEK_LEN				 	0x03

#define FDC_FIFO_THR			0x0C
#define FDC_FIFO_DIS			0x00
#define FDC_IMPLIED_SEEK	0x01
#define FDC_POLL_DIS			0x00
#define FDC_PRE_TRK				0x00
#define FDC_CONFIGURE			FDC_FIFO_THR | (FDC_POLL_DIS<<4) | (FDC_FIFO_DIS<<5) | (FDC_IMPLIED_SEEK << 6)
#define FDC_MFM_MODE			0x01 /* MFM enable */
#define FDC_SKIP_MODE			0x00 /* skip enable */

#define FDC_TIME_OUT 100000 /* time out */
#define	FDC_RW_RETRIES		3 /* read write retries */
#define FDC_CAL_RETRIES		3 /* calibration and seek retries */


/* Disk structure */
typedef struct  {
	unsigned int size;			/* nr of sectors total */
	unsigned int sect;			/* sectors per track */
	unsigned int head;			/* nr of heads */
	unsigned int track;			/* nr of tracks */
	unsigned int stretch;		/* !=0 means double track steps */
	unsigned char	gap;			/* gap1 size */
	unsigned char	rate;			/* data rate. |= 0x40 for perpendicular */
	unsigned char	spec1;		/* stepping rate, head unload time */
	unsigned char	fmt_gap;	/* gap2 size */
	unsigned char hlt;			/* head load time */
	unsigned char sect_code; /* Sector Size code */
	const char	* name; 		/* used only for predefined formats */
} FD_GEO_STRUCT;


/* supported Floppy types (currently only one) */
const static FD_GEO_STRUCT floppy_type[2] = {
	{ 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,16,2,"H1440" },	/*  7 1.44MB 3.5"   */
	{    0, 0,0, 0,0,0x00,0x00,0x00,0x00, 0,0,NULL    },	/*  end of table    */
};

static FDC_COMMAND_STRUCT cmd; /* global command struct */

/* If the boot drive number is undefined, we assume it's drive 0             */
#ifndef CFG_FDC_DRIVE_NUMBER
#define CFG_FDC_DRIVE_NUMBER 0
#endif

/* Hardware access */
#ifndef CFG_ISA_IO_STRIDE
#define CFG_ISA_IO_STRIDE 1
#endif

#ifndef CFG_ISA_IO_OFFSET
#define CFG_ISA_IO_OFFSET 0
#endif


/* Supporting Functions */
/* reads a Register of the FDC */
unsigned char read_fdc_reg(unsigned int addr)
{
	volatile unsigned char *val = (volatile unsigned char *)(CFG_ISA_IO_BASE_ADDRESS + (addr * CFG_ISA_IO_STRIDE) + CFG_ISA_IO_OFFSET);
        
	return val [0];
}

/* writes a Register of the FDC */
void write_fdc_reg(unsigned int addr, unsigned char val)
{
        volatile unsigned char *tmp = (volatile unsigned char *)(CFG_ISA_IO_BASE_ADDRESS + (addr * CFG_ISA_IO_STRIDE) + CFG_ISA_IO_OFFSET);
	tmp[0]=val;
}

/* waits for an interrupt (polling) */
int wait_for_fdc_int(void)
{
	unsigned long timeout;
	timeout = FDC_TIME_OUT;
	while((read_fdc_reg(FDC_SRA)&0x80)==0) {
		timeout--;
		udelay(10);
		if(timeout==0) /* timeout occured */
			return FALSE;
	}
	return TRUE;
}


/* reads a byte from the FIFO of the FDC and checks direction and RQM bit
   of the MSR. returns -1 if timeout, or byte if ok */
int read_fdc_byte(void)
{
	unsigned long timeout;
	timeout = FDC_TIME_OUT;
	while((read_fdc_reg(FDC_MSR)&0xC0)!=0xC0) {
		/* direction out and ready */
		udelay(10);
		timeout--;
		if(timeout==0) /* timeout occured */
			return -1;
	}
	return read_fdc_reg(FDC_FIFO);
}

/* if the direction of the FIFO is wrong, this routine is used to
   empty the FIFO. Should _not_ be used */
int fdc_need_more_output(void)
{
	unsigned char c;
	while((read_fdc_reg(FDC_MSR)&0xC0)==0xC0)	{
			c=(unsigned char)read_fdc_byte();
			printf("Error: more output: %x\n",c);
	}
	return TRUE;
}


/* writes a byte to the FIFO of the FDC and checks direction and RQM bit
   of the MSR */
int write_fdc_byte(unsigned char val)
{
	unsigned long timeout;
	timeout = FDC_TIME_OUT;
	while((read_fdc_reg(FDC_MSR)&0xC0)!=0x80) {
		/* direction in and ready for byte */
		timeout--;
		udelay(10);
		fdc_need_more_output();
		if(timeout==0) /* timeout occured */
			return FALSE;
	}
	write_fdc_reg(FDC_FIFO,val);
	return TRUE;
}

/* sets up all FDC commands and issues it to the FDC. If
   the command causes direct results (no Execution Phase)
   the result is be read as well. */

int fdc_issue_cmd(FDC_COMMAND_STRUCT *pCMD,FD_GEO_STRUCT *pFG)
{
	int i;
	unsigned long head,track,sect,timeout;
	track = pCMD->blnr / (pFG->sect * pFG->head); /* track nr */
	sect =  pCMD->blnr % (pFG->sect * pFG->head); /* remaining blocks */
	head = sect / pFG->sect; /* head nr */
	sect =  sect % pFG->sect; /* remaining blocks */
	sect++; /* sectors are 1 based */
	PRINTF("Cmd 0x%02x Track %ld, Head %ld, Sector %ld, Drive %d (blnr %ld)\n",pCMD->cmd[0],track,head,sect,pCMD->drive,pCMD->blnr);

	if(head|=0) { /* max heads = 2 */
		pCMD->cmd[DRIVE]=pCMD->drive | 0x04; /* head 1 */
		pCMD->cmd[HEAD]=(unsigned char) head; /* head register */
	}
	else {
		pCMD->cmd[DRIVE]=pCMD->drive; /* head 0 */
		pCMD->cmd[HEAD]=(unsigned char) head; /* head register */
	}
	pCMD->cmd[TRACK]=(unsigned char) track; /* track */
	switch (pCMD->cmd[COMMAND]) {
		case FDC_CMD_READ:
			pCMD->cmd[SECTOR]=(unsigned char) sect; /* sector */
			pCMD->cmd[SECTOR_SIZE]=pFG->sect_code; /* sector size code */
			pCMD->cmd[LAST_TRACK]=pFG->sect; /* End of track */
			pCMD->cmd[GAP]=pFG->gap; /* gap */
			pCMD->cmd[DTL]=0xFF; /* DTL */
			pCMD->cmdlen=FDC_CMD_READ_LEN;
			pCMD->cmd[COMMAND]|=(FDC_MFM_MODE<<6); /* set MFM bit */
			pCMD->cmd[COMMAND]|=(FDC_SKIP_MODE<<5); /* set Skip bit */
			pCMD->resultlen=0;  /* result only after execution */
			break;
		case FDC_CMD_SEEK:
			pCMD->cmdlen=FDC_CMD_SEEK_LEN;
			pCMD->resultlen=0;  /* no result */
			break;
		case FDC_CMD_CONFIGURE:
			pCMD->cmd[CONFIG0]=0;
			pCMD->cmd[CONFIG1]=FDC_CONFIGURE; /* FIFO Threshold, Poll, Enable FIFO */
			pCMD->cmd[CONFIG2]=FDC_PRE_TRK; 	/* Precompensation Track */
			pCMD->cmdlen=FDC_CMD_CONFIGURE_LEN;
			pCMD->resultlen=0;  /* no result */
			break;
		case FDC_CMD_SPECIFY:
			pCMD->cmd[SPEC_HUTSRT]=pFG->spec1;
			pCMD->cmd[SPEC_HLT]=(pFG->hlt)<<1; /* head load time */
			if(pCMD->dma==0)
				pCMD->cmd[SPEC_HLT]|=0x1; /* no dma */
			pCMD->cmdlen=FDC_CMD_SPECIFY_LEN;
			pCMD->resultlen=0;  /* no result */
			break;
		case FDC_CMD_DUMP_REG:
			pCMD->cmdlen=FDC_CMD_DUMP_REG_LEN;
			pCMD->resultlen=10;  /* 10 byte result */
			break;
		case FDC_CMD_READ_ID:
			pCMD->cmd[COMMAND]|=(FDC_MFM_MODE<<6); /* set MFM bit */
			pCMD->cmdlen=FDC_CMD_READ_ID_LEN;
			pCMD->resultlen=7;  /* 7 byte result */
			break;
		case FDC_CMD_RECALIBRATE:
			pCMD->cmd[DRIVE]&=0x03; /* don't set the head bit */
			pCMD->cmdlen=FDC_CMD_RECALIBRATE_LEN;
			pCMD->resultlen=0;  /* no result */
			break;
			break;
		case FDC_CMD_SENSE_INT:
			pCMD->cmdlen=FDC_CMD_SENSE_INT_LEN;
			pCMD->resultlen=2;
			break;
	}
	for(i=0;i<pCMD->cmdlen;i++) {
		/* PRINTF("write cmd%d = 0x%02X\n",i,pCMD->cmd[i]); */
		if(write_fdc_byte(pCMD->cmd[i])==FALSE) {
			PRINTF("Error: timeout while issue cmd%d\n",i);
			return FALSE;
		}
	}
	timeout=FDC_TIME_OUT;
	for(i=0;i<pCMD->resultlen;i++) {
		while((read_fdc_reg(FDC_MSR)&0xC0)!=0xC0) {
			timeout--;
			if(timeout==0) {
				PRINTF(" timeout while reading result%d MSR=0x%02X\n",i,read_fdc_reg(FDC_MSR));
				return FALSE;
			}
		}
		pCMD->result[i]=(unsigned char)read_fdc_byte();
	}
	return TRUE;
}

/* selects the drive assigned in the cmd structur and
   switches on the Motor */
void select_fdc_drive(FDC_COMMAND_STRUCT *pCMD)
{
	unsigned char val;

	val=(1<<(4+pCMD->drive))|pCMD->drive|0xC; /* set reset, dma gate and motor bits */
	if((read_fdc_reg(FDC_DOR)&val)!=val) {
		write_fdc_reg(FDC_DOR,val);
		for(val=0;val<255;val++)
			udelay(500); /* wait some time to start motor */
	}
}

/* switches off the Motor of the specified drive */
void stop_fdc_drive(FDC_COMMAND_STRUCT *pCMD)
{
	unsigned char val;

	val=(1<<(4+pCMD->drive))|pCMD->drive; /* sets motor bits */
	write_fdc_reg(FDC_DOR,(read_fdc_reg(FDC_DOR)&~val));
}

/* issues a recalibrate command, waits for interrupt and
 * issues a sense_interrupt */
int fdc_recalibrate(FDC_COMMAND_STRUCT *pCMD,FD_GEO_STRUCT *pFG)
{
	pCMD->cmd[COMMAND]=FDC_CMD_RECALIBRATE;
	if(fdc_issue_cmd(pCMD,pFG)==FALSE)
		return FALSE;
	while(wait_for_fdc_int()!=TRUE);
	pCMD->cmd[COMMAND]=FDC_CMD_SENSE_INT;
	return(fdc_issue_cmd(pCMD,pFG));
}

/* issues a recalibrate command, waits for interrupt and
 * issues a sense_interrupt */
int fdc_seek(FDC_COMMAND_STRUCT *pCMD,FD_GEO_STRUCT *pFG)
{
	pCMD->cmd[COMMAND]=FDC_CMD_SEEK;
	if(fdc_issue_cmd(pCMD,pFG)==FALSE)
		return FALSE;
	while(wait_for_fdc_int()!=TRUE);
	pCMD->cmd[COMMAND]=FDC_CMD_SENSE_INT;
	return(fdc_issue_cmd(pCMD,pFG));
}


/* terminates current command, by not servicing the FIFO
 * waits for interrupt and fills in the result bytes */
int fdc_terminate(FDC_COMMAND_STRUCT *pCMD)
{
	int i;
	for(i=0;i<100;i++)
		udelay(500); /* wait 500usec for fifo overrun */
	while((read_fdc_reg(FDC_SRA)&0x80)==0x00); /* wait as long as no int has occured */
	for(i=0;i<7;i++) {
		pCMD->result[i]=(unsigned char)read_fdc_byte();
	}
	return TRUE;
}

/* reads data from FDC, seek commands are issued automatic */
int fdc_read_data(unsigned char *buffer, unsigned long blocks,FDC_COMMAND_STRUCT *pCMD, FD_GEO_STRUCT *pFG)
{
  /* first seek to start address */
	unsigned long len,lastblk,readblk,i,timeout,ii,offset;
	unsigned char pcn,c,retriesrw,retriescal;
	unsigned char *bufferw; /* working buffer */
	int sect_size;
	int flags;

	flags=disable_interrupts(); /* switch off all Interrupts */
	select_fdc_drive(pCMD); /* switch on drive */
	sect_size=0x080<<pFG->sect_code;
	retriesrw=0;
	retriescal=0;
	offset=0;
	if(fdc_seek(pCMD,pFG)==FALSE) {
		stop_fdc_drive(pCMD);
		enable_interrupts();
		return FALSE;
	}
	if((pCMD->result[STATUS_0]&0x20)!=0x20) {
		printf("Seek error Status: %02X\n",pCMD->result[STATUS_0]);
		stop_fdc_drive(pCMD);
		enable_interrupts();
		return FALSE;
	}
	pcn=pCMD->result[STATUS_PCN]; /* current track */
	/* now determine the next seek point */
	lastblk=pCMD->blnr + blocks;
	/*	readblk=(pFG->head*pFG->sect)-(pCMD->blnr%(pFG->head*pFG->sect)); */
	readblk=pFG->sect-(pCMD->blnr%pFG->sect);
	PRINTF("1st nr of block possible read %ld start %ld\n",readblk,pCMD->blnr);
	if(readblk>blocks) /* is end within 1st track */
		readblk=blocks; /* yes, correct it */
	PRINTF("we read %ld blocks start %ld\n",readblk,pCMD->blnr);
	bufferw=&buffer[0]; /* setup working buffer */
	do {
retryrw:
		len=sect_size * readblk;
		pCMD->cmd[COMMAND]=FDC_CMD_READ;
		if(fdc_issue_cmd(pCMD,pFG)==FALSE) {
			stop_fdc_drive(pCMD);
			enable_interrupts();
			return FALSE;
		}
		for (i=0;i<len;i++) {
			timeout=FDC_TIME_OUT;
			do {
				c=read_fdc_reg(FDC_MSR);
				if((c&0xC0)==0xC0) {
					bufferw[i]=read_fdc_reg(FDC_FIFO);
					break;
				}
				if((c&0xC0)==0x80) { /* output */
					PRINTF("Transfer error transfered: at %ld, MSR=%02X\n",i,c);
					if(i>6) {
						for(ii=0;ii<7;ii++) {
							pCMD->result[ii]=bufferw[(i-7+ii)];
						} /* for */
					}
					if(retriesrw++>FDC_RW_RETRIES) {
						if (retriescal++>FDC_CAL_RETRIES) {
							stop_fdc_drive(pCMD);
							enable_interrupts();
							return FALSE;
						}
						else {
							PRINTF(" trying to recalibrate Try %d\n",retriescal);
							if(fdc_recalibrate(pCMD,pFG)==FALSE) {
								stop_fdc_drive(pCMD);
								enable_interrupts();
								return FALSE;
							}
							retriesrw=0;
							goto retrycal;
						} /* else >FDC_CAL_RETRIES */
					}
					else {
						PRINTF("Read retry %d\n",retriesrw);
						goto retryrw;
					} /* else >FDC_RW_RETRIES */
				}/* if output */
				timeout--;
			}while(TRUE);
		} /* for len */
		/* the last sector of a track or all data has been read,
		 * we need to get the results */
		fdc_terminate(pCMD);
		offset+=(sect_size*readblk); /* set up buffer pointer */
		bufferw=&buffer[offset];
		pCMD->blnr+=readblk; /* update current block nr */
		blocks-=readblk; /* update blocks */
		if(blocks==0)
			break; /* we are finish */
		/* setup new read blocks */
		/*	readblk=pFG->head*pFG->sect; */
		readblk=pFG->sect;
		if(readblk>blocks)
			readblk=blocks;
retrycal:
		/* a seek is necessary */
		if(fdc_seek(pCMD,pFG)==FALSE) {
			stop_fdc_drive(pCMD);
			enable_interrupts();
			return FALSE;
		}
		if((pCMD->result[STATUS_0]&0x20)!=0x20) {
			PRINTF("Seek error Status: %02X\n",pCMD->result[STATUS_0]);
			stop_fdc_drive(pCMD);
			return FALSE;
		}
		pcn=pCMD->result[STATUS_PCN]; /* current track */
	}while(TRUE); /* start over */
	stop_fdc_drive(pCMD); /* switch off drive */
	enable_interrupts();
	return TRUE;
}

/* Scan all drives and check if drive is present and disk is inserted */
int fdc_check_drive(FDC_COMMAND_STRUCT *pCMD, FD_GEO_STRUCT *pFG)
{
	int i,drives,state;
  /* OK procedure of data book is satisfied.
	 * trying to get some information over the drives */
	state=0; /* no drives, no disks */
	for(drives=0;drives<4;drives++) {
		pCMD->drive=drives;
		select_fdc_drive(pCMD);
		pCMD->blnr=0; /* set to the 1st block */
		if(fdc_recalibrate(pCMD,pFG)==FALSE)
			continue;
		if((pCMD->result[STATUS_0]&0x10)==0x10)
			continue;
		/* ok drive connected check for disk */
		state|=(1<<drives);
		pCMD->blnr=pFG->size; /* set to the last block */
		if(fdc_seek(pCMD,pFG)==FALSE)
			continue;
		pCMD->blnr=0; /* set to the 1st block */
		if(fdc_recalibrate(pCMD,pFG)==FALSE)
			continue;
		pCMD->cmd[COMMAND]=FDC_CMD_READ_ID;
		if(fdc_issue_cmd(pCMD,pFG)==FALSE)
			continue;
		state|=(0x10<<drives);
	}
	stop_fdc_drive(pCMD);
	for(i=0;i<4;i++) {
		PRINTF("Floppy Drive %d %sconnected %sDisk inserted %s\n",i,
			((state&(1<<i))==(1<<i)) ? "":"not ",
			((state&(0x10<<i))==(0x10<<i)) ? "":"no ",
			((state&(0x10<<i))==(0x10<<i)) ? pFG->name : "");
	}
	pCMD->flags=state;
	return TRUE;
}


/**************************************************************************
* int fdc_setup
* setup the fdc according the datasheet
* assuming in PS2 Mode
*/
int fdc_setup(FDC_COMMAND_STRUCT *pCMD,	FD_GEO_STRUCT *pFG)
{

	int i;

#ifdef CFG_FDC_HW_INIT
        fdc_hw_init ();
#endif
	/* first, we reset the FDC via the DOR */
	write_fdc_reg(FDC_DOR,0x00);
	for(i=0; i<255; i++) /* then we wait some time */
		udelay(500);
	/* then, we clear the reset in the DOR */
	pCMD->drive=CFG_FDC_DRIVE_NUMBER;
	select_fdc_drive(pCMD);
	/* initialize the CCR */
	write_fdc_reg(FDC_CCR,pFG->rate);
	/* then initialize the DSR */
	write_fdc_reg(FDC_DSR,pFG->rate);
	if(wait_for_fdc_int()==FALSE) {
			PRINTF("Time Out after writing CCR\n");
			return FALSE;
	}
	/* now issue sense Interrupt and status command
	 * assuming only one drive present (drive 0) */
	pCMD->dma=0; /* we don't use any dma at all */
	for(i=0;i<4;i++) {
		/* issue sense interrupt for all 4 possible drives */
		pCMD->cmd[COMMAND]=FDC_CMD_SENSE_INT;
		if(fdc_issue_cmd(pCMD,pFG)==FALSE) {
			PRINTF("Sense Interrupt for drive %d failed\n",i);
		}
	}
	/* assuming drive 0 for rest of configuration
	 * issue the configure command */
	pCMD->drive=CFG_FDC_DRIVE_NUMBER;
	select_fdc_drive(pCMD);
	pCMD->cmd[COMMAND]=FDC_CMD_CONFIGURE;
	if(fdc_issue_cmd(pCMD,pFG)==FALSE) {
		PRINTF(" configure timeout\n");
		stop_fdc_drive(pCMD);
		return FALSE;
	}
	/* issue specify command */
	pCMD->cmd[COMMAND]=FDC_CMD_SPECIFY;
	if(fdc_issue_cmd(pCMD,pFG)==FALSE) {
		PRINTF(" specify timeout\n");
		stop_fdc_drive(pCMD);
		return FALSE;

	}
	/* then, we clear the reset in the DOR */
	/* fdc_check_drive(pCMD,pFG);	*/
	/*	write_fdc_reg(FDC_DOR,0x04); */
	return TRUE;
}

/****************************************************************************
 * main routine do_fdcboot
 */
int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	FD_GEO_STRUCT *pFG = (FD_GEO_STRUCT *)floppy_type;
	FDC_COMMAND_STRUCT *pCMD = &cmd;
 	unsigned long addr,imsize;
	image_header_t *hdr;  /* used for fdc boot */
	unsigned char boot_drive;
	int i,nrofblk;
	char *ep;
	int rcode = 0;

	switch (argc) {
	case 1:
		addr = CFG_LOAD_ADDR;
		boot_drive=CFG_FDC_DRIVE_NUMBER; 
		break;
	case 2:
		addr = simple_strtoul(argv[1], NULL, 16);
		boot_drive=CFG_FDC_DRIVE_NUMBER;
		break;
	case 3:
		addr = simple_strtoul(argv[1], NULL, 16);
		boot_drive=simple_strtoul(argv[2], NULL, 10);
		break;
	default:
		printf ("Usage:\n%s\n", cmdtp->usage);
		return 1;
	}
	/* setup FDC and scan for drives  */
	if(fdc_setup(pCMD,pFG)==FALSE) {
		printf("\n** Error in setup FDC **\n");
		return 1;
	}
	if(fdc_check_drive(pCMD,pFG)==FALSE) {
		printf("\n** Error in check_drives **\n");
		return 1;
	}
	if((pCMD->flags&(1<<boot_drive))==0) {
		/* drive not available */
		printf("\n** Drive %d not availabe **\n",boot_drive);
		return 1;
	}
	if((pCMD->flags&(0x10<<boot_drive))==0) {
		/* no disk inserted */
		printf("\n** No disk inserted in drive %d **\n",boot_drive);
		return 1;
	}
	/* ok, we have a valid source */
	pCMD->drive=boot_drive;
	/* read first block */
	pCMD->blnr=0;
	if(fdc_read_data((unsigned char *)addr,1,pCMD,pFG)==FALSE) {
		printf("\nRead error:");
		for(i=0;i<7;i++)
			printf("result%d: 0x%02X\n",i,pCMD->result[i]);
		return 1;
	}
	hdr = (image_header_t *)addr;
	if (hdr->ih_magic  != IH_MAGIC) {
		printf ("Bad Magic Number\n");
		return 1;
	}
	print_image_hdr(hdr);

	imsize= hdr->ih_size+sizeof(image_header_t);
	nrofblk=imsize/512;
	if((imsize%512)>0)
		nrofblk++;
	printf("Loading %ld Bytes (%d blocks) at 0x%08lx..\n",imsize,nrofblk,addr);
	pCMD->blnr=0;
	if(fdc_read_data((unsigned char *)addr,nrofblk,pCMD,pFG)==FALSE) {
		/* read image block */
		printf("\nRead error:");
		for(i=0;i<7;i++)
			printf("result%d: 0x%02X\n",i,pCMD->result[i]);
		return 1;
	}
	printf("OK %ld Bytes loaded.\n",imsize);

	flush_cache (addr, imsize);
	/* Loading ok, update default load address */

	load_addr = addr;
	if(hdr->ih_type  == IH_TYPE_KERNEL) {
		/* 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 ++;
		}
	}
	return rcode;
}



#endif /* CONFIG_COMMANDS & CFG_CMD_FDC */


