⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fl_drver.c

📁 移植Nuclues_RTC到coldfire5307在diab下编译通过
💻 C
📖 第 1 页 / 共 5 页
字号:
VOID fl_init_HISR();
NU_HISR     FL_HISR_Control;
CHAR        FL_HISR_Stack[500];

#else
void enable();
#endif  /*  PLUS  */

void fl_isr();

#endif /* NOT POLLED */

//Daniel Start
//int inp(unsigned portid);
//int outp(unsigned portid, int value);
#define XinBaseAddr    0x33900000          //DP8800   Liao Yibai 2002-10-15

#define fl_inp(portid)		*((UTINY *)(XinBaseAddr + portid))
#define fl_outp(portid, value)		*(UTINY *)(XinBaseAddr + portid) = value
//static void delay_1us();
//static void delay_25us();
static BOOL fl_configure();
BOOL ReportError(UCOUNT error_code);
/*static */BOOL fl_change_line(UCOUNT driveno);
UTINY		g_current_cyl; //两个磁头同时转
UCOUNT		g_Error_Info[REPORT_ERROR_NUM];
/*
UTINY   g_cyl[120]; Test
UTINY   g_Count = 0; */
//Daniel End here

BOOL floppy_ioctl(UCOUNT driveno, UCOUNT command, VOID *buffer);
BOOL floppy_raw_open(UCOUNT driveno);
BOOL floppy_open(UCOUNT driveno);
BOOL floppy_close(UCOUNT driveno);
BOOL floppy_io(UCOUNT driveno, ULONG l_sector, VOID *in_buffer, UCOUNT count, BOOL reading);
BOOL floppy_format(UCOUNT driveno, COUNT drivesize, COUNT interleave, void (*callback)(COUNT, COUNT));
static BOOL fl_controller_init();
static BOOL fl_reset_controller();
static BOOL fl_claim(UCOUNT driveno);
static BOOL fl_establish_media(UCOUNT driveno);
static BOOL fl_sense_interrupt(COMMAND_BLOCK *p);
static BOOL fl_read_id(UCOUNT driveno, COMMAND_BLOCK *p);
static BOOL fl_seek(UCOUNT driveno, UCOUNT cyl, UCOUNT head);
static BOOL fl_recalibrate(UCOUNT driveno);
static BOOL fl_specify(UCOUNT driveno);
VOID fl_motor_off(UCOUNT arg);
static VOID fl_motor_on(UCOUNT driveno);
static BOOL fl_command_phase(COMMAND_BLOCK *p);
static BOOL fl_results_phase(COMMAND_BLOCK *p);
static COUNT fl_ready();

static VOID fl_cp_parms(UCOUNT driveno, COUNT parmindex);
static VOID fl_int_enable(BOOL on);
void real_fl_isr();
static BOOL fl_waitint(COUNT millis);
static BOOL fl_report_error(COUNT error, BOOL return_me);
static BOOL fl_waitdma(COUNT millis);
/* static BOOL fl_dma_init(UTINY *in_address, UCOUNT length, BOOL reading); */
static BOOL fl_dma_init(UTINY *in_address, UCOUNT length, BOOL reading);
/* static UCOUNT fl_dma_chk(UTINY *in_address); */
static VOID  fl_write_drr(UTINY value);
static UTINY fl_read_drr();
static VOID  fl_write_dor(UTINY value);
static VOID  fl_write_data(UTINY value);
static UTINY fl_read_data();
static UTINY fl_read_msr();

int  puts(const char *p);

/* IOCTL Call. Does nothing  (in bdevsw[] table.)*/
BOOL floppy_ioctl(UCOUNT driveno, UCOUNT command, VOID *buffer)     /*__fn__*/
{
    driveno = driveno;
    command = command;
    buffer = buffer;
    return(YES);
}

/* Raw Open Function. Open Device as raw block device. No partitions
   Floppies have no partitions so this routine does nothing
   (in bdevsw[] table.) */
BOOL floppy_raw_open(UCOUNT driveno)                             /*__fn__*/
{     driveno = driveno;   return(NO);  }

/* Open function. This is pointed to by the bdevsw[] table */
COUNT		fl_controller_open_count = 0;

BOOL floppy_open(UCOUNT driveno)                                 /*__fn__*/
{
    /* Supports only A: and B: drives */
    if (driveno > 1)
		return(NO);
    /* Initialize the controller */
    if (!fl_controller_open_count)
    {
		if (!fl_controller_init())
		{
			return(NO);
		}
    }
    fl_controller_open_count += 1;
    return(YES);
}

/* Close function. This is pointed to by the bdevsw[] table */
BOOL floppy_close(UCOUNT driveno)                                   /*__fn__*/
{
    driveno = driveno;
   if (fl_controller_open_count)
   {
	if (!(--fl_controller_open_count))
	{
	    selected_floppy = 0;
    	Stop_gTimer();			//no floppy is selected, close the gTimer. Liuxudeong on 2002-3-29
	}
   }
   return(YES);
}

#ifndef POLLED

static void NEAR_copybuff(UTINY *to, UTINY *from, INT size)
{
    while (size--)
	*to++ = *from++;
}

#endif /* NOT POLLED */


/* floppy_io - Floppy disk read write routine (in bdevsw[] table.)
* 
* Summary:
*
* BOOL floppy_io(driveno, l_sector, in_buffer,  count, reading)
*
*
* Inputs:
*   UCOUNT driveno      - 0 or 1 = a: b:
*   ULONG l_sector      - absolute sector to read/write
*   VOID *in_buffer     - address of data buffer
*   UCOUNT count        - sectors to transfer
*   BOOL reading        - YES if a read NO if a write
*
* Returns:
*   YES on success else NO.
*   
* This routine performs read and writes from to the floppy disk. It calculates
* head:sector:track from the physical sector number, then it reads/write of 
* track or count, whichever is less. If more data needs to be transfered it
* adjusts the current sector number, recalculates head:sector:track and repeats
* the IO procedure. This occurs until the process is completed.
*
* Note: On a PC AT the dma controller is a 16 BIT device. A 4 bit bank
*       switch register is used to address the lower 1 MEG. A segment 
*       wrap occurs when a transfer spans two banks. When this routine
*       senses this condition it breaks the request into two or 
*       more operations so the wrap does not occur.
*
* Note: This routine is basically portable except for the the DMA wrap 
*       calculation. Also in protected mode 386/486 systems a double
*       buffering scheme needs to be added since we can only dma to the
*       first 1 meg. This double buffer logic will be identical to the
*       logic used for double buffering in the DMA segment wrap situation, 
*       the only exception being the transfer should be larger than 1.
*       
*/

BOOL floppy_io(UCOUNT driveno, ULONG l_sector, VOID *in_buffer, UCOUNT count, BOOL reading)   /*__fn__*/
{
    COMMAND_BLOCK b;
    UCOUNT cyl;
    UCOUNT head;
    UCOUNT sec;
    UCOUNT final_sec;
    UCOUNT final_cyl;
    UCOUNT final_head;
    UCOUNT utemp;
    UCOUNT sector;
    UCOUNT nleft_track;
    UCOUNT n_todo;
	
#ifndef POLLED
	
    BOOL   use_dma_buff;
	
#endif /* NOT POLLED */
	
    UTINY  *buffer = (UTINY *) in_buffer;    
	
    if (driveno > 1)
		return(NO);
    if (!count)                         /* Must have a count */
		return(NO);
	
    /* Establish media if the drive is different from before */
    /* fl_claim has its own error reporting */
    if (!fl_claim(driveno))
		return(NO);
    sector = (UCOUNT) l_sector;
	
    /* cylinder == sector / sectors/cylinder */
    cyl =   (UCOUNT) (sector/floppy[driveno].sectors_per_cyl);
    utemp = (UCOUNT) (sector%floppy[driveno].sectors_per_cyl);
    head =  (UCOUNT) (utemp/floppy[driveno].sectors_per_track);
    sec =   (UCOUNT) (utemp%floppy[driveno].sectors_per_track);
	
    nleft_track = (UCOUNT) (floppy[driveno].sectors_per_track - sec);
    if (count > nleft_track)
		n_todo =  nleft_track;
    else 
		n_todo = count;
	
    while (count)
    {
		if (fl_change_line(driveno))
		{
			/* establish media. It has a hack in here to clear change line */
			/* establish media has its own error reporting */
			 //只调用fl_establish_media会导致将上一张磁盘FAT表的信息写进新的磁盘
			if (!fl_establish_media(driveno))
				return(NO);
		}
		
#if (1)
		/* For protected mode ports where the user address is in extended
		memory but the dma circuit requires the memory in the lowest 
		one meg do the following */
		
#ifndef POLLED
		
		use_dma_buff = YES;
		
		if (n_todo > DMA_BUF_SIZE)
			n_todo = DMA_BUF_SIZE;
		
#endif /* POLLED */
		
			/* Where DMA_BUF_SIZE is the size in blocks of the memory at
			dma_buffer[], which you have allocated in low memory, the
			buffer should not wrap a segment. As determined by fl_dma_chk().
			DMA_BUF_SIZE does not have to huge, 18 blocks (9 k) is plenty.
			Note: dma_buffer[] is declared above in this file, you should
		change it. */
#else
		/* see how many blocks are left in the dma page containing buffer */
		utemp = fl_dma_chk((UTINY *) buffer);
		if (!utemp)
		{
			/* None left in this page. use a local buffer for 1 block */
			n_todo = 1;
			use_dma_buff = YES;
		}
		else
		{
			/* Dma right to user space. Don't wrap the segment */
			use_dma_buff = NO;
			if (utemp < n_todo)
				n_todo = utemp;
		}
#endif
		utemp = cyl;
		/* Double step on 360 K disks in 1.2M drives */
		if (floppy[driveno].double_step)
			utemp <<= 1;
		fl_motor_on(driveno);
		if (!fl_seek(driveno, utemp, head))
		{
//			return(fl_report_error(FLERR_SEEK, NO));
			Stop_gTimer();
			fl_controller_init();			//Daniel
			return ReportError(ERR_SEEK);
		}
		
#ifndef POLLED
		
		/* Set up the dma controller */
		if (use_dma_buff)
		{
			if (!reading)       /* copy to a local buf before writing */
				NEAR_copybuff(dma_buffer, buffer, (n_todo << 9));
			if (!fl_dma_init((UTINY *)dma_buffer, (UCOUNT) (n_todo << 9), reading))
				return(fl_report_error(FLERR_DMA, NO));
		}
		else
		{
			
#endif /* NOT POLLED */
			
			if (!fl_dma_init((UTINY *)buffer,(UCOUNT) (n_todo << 9), reading))
				return(fl_report_error(FLERR_DMA, NO));
			
#ifndef POLLED
			
		}
		
#endif /* NOT POLLED */
		
		/* Send the command to the 765 floppy controller */
		b.n_to_send = 9;       
		b.n_to_get = 7;
		if (reading)
			
#ifdef POLLED
			
			b.commands[0] = MFMBIT|FL_READ;  /* Don't set the Multitrack bit */
		
#else /* POLLED */
		
			b.commands[0] = MTBIT|MFMBIT|FL_READ;
		
#endif /* POLLED */
		
		else
			
#ifdef POLLED
			
			b.commands[0] = MFMBIT|FL_WRITE; /* Don't set the Multitrack bit */
		
#else /*  POLLED */
		
			b.commands[0] = MTBIT|MFMBIT|FL_WRITE;
		
#endif /*  POLLED */
		
		b.commands[1] = (UTINY) ((head << 2)|driveno);
		b.commands[2] = (UTINY) cyl;
		b.commands[3] = (UTINY) head;
		b.commands[4] = (UTINY) (sec+1);
		b.commands[5] = (UTINY) 2;                          /* byte length 512 */ 
		
#ifdef POLLED
		b.commands[6] = (UTINY) (sec+n_todo); /* Maximum sector # to access */
		
#else /* POLLED */
		
		b.commands[6] = (UTINY) (floppy[driveno].sectors_per_track); /*  EOT */
		
#endif /* POLLED */
		
		b.commands[7] = (UTINY) floppy[driveno].gpl_read;   /*  GPL */
		b.commands[8] = (UTINY) 0xff;                       /*  DTL = ff since N == 512 */
		
		fl_motor_on(driveno);
		fl_int_enable(NO);
		if (!fl_command_phase(&b))
		{
			fl_int_enable(YES);

			Stop_gTimer();
			fl_controller_init();			//Daniel
			return ReportError(ERR_CHIP_HUNG);			
//			return(fl_report_error(FLERR_CHIP_HUNG, NO));
		}
		
		/* Wait for the transfer to complete. (In programmed IO situations
		do the actual transfer) */
		if (!fl_waitdma(FLTMO_IO))
		{
			fl_results_phase(&b);          //By Daniel, 2001/03/13
			if(b.results[1] & BIT1)
				ReportError(ERR_WRITE_PROTECT);
			else if(b.results[1] & BIT4)
				ReportError(ERR_TIMEOUT);
			else if(b.results[1] & BIT2)
				ReportError(ERR_IO_SECTOR);
			else
				ReportError(ERR_UNKNOWN);
			Stop_gTimer();
			fl_controller_init();
			return NO;						//End here, Daniel
//			return(fl_report_error(FLERR_IO_TMO, NO));
		}
		
#ifndef POLLED
		
		/* If we read into a local buffer we need to copy it now to user space */
		if (use_dma_buff && reading)
			NEAR_copybuff(buffer, dma_buffer, (n_todo << 9));
		
#endif /* NOT POLLED */
		
		if (!fl_results_phase(&b))
		{
			Stop_gTimer();
			fl_controller_init();				//Daniel
			return ReportError(ERR_CHIP_HUNG);			
//			return(fl_report_error(FLERR_CHIP_HUNG, NO));
		}
		
		/* Check status registers. We will elaborate on this later */
		if (b.results[0] & (BIT7|BIT6))
			return(fl_report_error(FLERR_ABN_TERM, NO));
		
		/* Check the head/sector/track against what it should be */
		final_sec = (UCOUNT) (sec + n_todo);
		final_cyl = cyl;
		final_head = head;
		
#ifndef POLLED
		
		if (final_sec > floppy[driveno].sectors_per_track)
		{
			final_head = 1;
			final_sec = (UCOUNT) (final_sec - floppy[driveno].sectors_per_track);
		}
		
		if (final_sec < floppy[driveno].sectors_per_track)
			final_sec += 1;
		else if (final_sec == floppy[driveno].sectors_per_track)
		{
			final_sec = 1;
			if (final_head == 1)
			{
				final_cyl += 1;
				final_head = 0;
			}
			else
				final_head = 1;
		}
		
#endif /* NOT POLLED */
		
		if ( (b.results[3] != (UTINY) final_cyl)  ||
			(b.results[4] != (UTINY) final_head) ||
			(b.results[5] != (UTINY) final_sec) )
		{
//			return(fl_report_error(FLERR_IO_SECTOR, NO));
			Stop_gTimer();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -