/*
 * (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) || (CONFIG_COMMANDS & CFG_CMD_FDOS))


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(int drive, 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=drive;
	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);
		}
	}
	/* issue the configure command */
	pCMD->drive=drive;
	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;
}
#endif /* ((CONFIG_COMMANDS & CFG_CMD_FDC)||(CONFIG_COMMANDS & CFG_CMD_FDOS))*/

#if (CONFIG_COMMANDS & CFG_CMD_FDOS)

/* Low level functions for the Floppy-DOS layer                              */

/**************************************************************************
* int fdc_fdos_init
* initialize the FDC layer 
* 
*/
int fdc_fdos_init (int drive)
{
	FD_GEO_STRUCT *pFG = (FD_GEO_STRUCT *)floppy_type;
	FDC_COMMAND_STRUCT *pCMD = &cmd;
    
	/* setup FDC and scan for drives  */
	if(fdc_setup(drive,pCMD,pFG)==FALSE) {
		printf("\n** Error in setup FDC **\n");
		return FALSE;
	}
	if(fdc_check_drive(pCMD,pFG)==FALSE) {
		printf("\n** Error in check_drives **\n");
		return FALSE;
	}
	if((pCMD->flags&(1<<drive))==0) {
		/* drive not available */
		printf("\n** Drive %d not available **\n",drive);
		return FALSE;
	}
	if((pCMD->flags&(0x10<<drive))==0) {
		/* no disk inserted */
		printf("\n** No disk inserted in drive %d **\n",drive);
		return FALSE;
	}
	/* ok, we have a valid source */
	pCMD->drive=drive;

	/* read first block */
	pCMD->blnr=0;
        return TRUE;
}
/**************************************************************************
* int fdc_fdos_seek
* parameter is a block number 
*/
int fdc_fdos_seek (int where)
{
	FD_GEO_STRUCT *pFG = (FD_GEO_STRUCT *)floppy_type;
	FDC_COMMAND_STRUCT *pCMD = &cmd;

        pCMD -> blnr = where ;
        return (fdc_seek (pCMD, pFG));
}
/**************************************************************************
* int fdc_fdos_read
*  the length is in block number
*/
int fdc_fdos_read (void *buffer, int len)
{
	FD_GEO_STRUCT *pFG = (FD_GEO_STRUCT *)floppy_type;
	FDC_COMMAND_STRUCT *pCMD = &cmd;

        return (fdc_read_data (buffer, len, pCMD, pFG));
}
#endif  /* (CONFIG_COMMANDS & CFG_CMD_FDOS)                                  */

#if (CONFIG_COMMANDS & CFG_CMD_FDC)
/****************************************************************************
 * 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(boot_drive,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 */


