?? fl_drver.c
字號:
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 + -