📄 fd_0.c
字号:
////////////////////////////////////////////////////////////////////////
#include "general.h"
#include "inb_outb.h"
#include "sti_cli.h"
#include "copy_block.h"
#include "hd_info_struct.h"
#include "dir_entry.h"
#include "msdos_dir_entry.h"
#include "d_inode.h"
#include "m_inode.h"
#include "buffer_head.h"
#include "fat_cache.h"
#include "file.h"
#include "hd_request_struct.h"
#include "super_block.h"
#include "common_head.h"
///////////////////////////////////////////////////////////////////////////////
void setup_DMA(int temp_rwflag)
{
unsigned long temp_uLong;
unsigned char temp_uChar;
outb_p(0x06,DMA_MASK_REG);
if (temp_rwflag)
outb_p(DMA_MODE_READ,DMA_MODE_REG);
else
outb_p(DMA_MODE_WRITE,DMA_MODE_REG);
outb_p(0x00,DMA_CLEAR_FF_REG);
temp_uLong = (unsigned long)floppy_buffer;
temp_uChar = temp_uLong & 0xff;
outb_p(temp_uChar,DMA_ADDR_2);
temp_uChar = (temp_uLong >> 8) & 0xff;
outb_p(temp_uChar,DMA_ADDR_2);
temp_uChar = (temp_uLong >> 16) & 0xff;
outb_p(temp_uChar,DMA_PAGE_2);
outb_p(0xff,DMA_CNT_2);
outb_p(0x03,DMA_CNT_2);
outb_p(0x02,DMA_MASK_REG);
return;
}
int output_byte(unsigned char Command)
{
int i;
sti();
for (i = 0; i < 50000; i++)
{
if ((inb(FD_STATUS) & (STATUS_READY | STATUS_DIR)) == STATUS_READY)
{
outb(Command,FD_DATA);
cli();
return 0;
}
}
cli();
return -1;
}
int get_result(void)
{
unsigned char Status;
int ret_val = 0;
int i;
sti();
for (i = 0; i < 50000; i++)
{
Status = inb(FD_STATUS) & (STATUS_DIR | STATUS_READY | STATUS_BUSY);
if (Status == STATUS_READY)
{
cli();
return ret_val;
}
if (Status == (STATUS_DIR | STATUS_READY | STATUS_BUSY))
{
reply_buffer[ret_val++] = inb(FD_DATA);
if (ret_val >= 8)
{
cli();
return -1;
}
}
}
cli();
return -1;
}
int output0_byte(unsigned char Command)
{
int i;
for (i = 0; i < 50000; i++)
{
if ((inb(FD_STATUS) & (STATUS_READY | STATUS_DIR)) == STATUS_READY)
{
outb(Command,FD_DATA);
return 0;
}
}
return -1;
}
int get0_result(void)
{
unsigned char Status;
int ret_val = 0;
int i;
for (i = 0; i < 50000; i++)
{
Status = inb(FD_STATUS) & (STATUS_DIR | STATUS_READY | STATUS_BUSY);
if (Status == STATUS_READY)
return ret_val;
if (Status == (STATUS_DIR | STATUS_READY | STATUS_BUSY))
{
reply_buffer[ret_val++] = inb(FD_DATA);
if (ret_val >= 8)
return -1;
}
}
return -1;
}
//////////////////////////////////////////////////////////////////////////////
void fd_rwblock_0(void)
{
floppy_temp_track = start_request_f->cyl;
floppy_temp_head = start_request_f->head;
floppy_temp_sector = start_request_f->sector;
floppy_temp_rwflag = start_request_f->cmd;
start_request_f->bh->b_dirt = 0;
floppy_timerval = FD_DRIVER_DOWN;
floppy_finishedflag = 0;
switch (floppy_state)
{
case 4:
floppy_state = 5;
output_byte(FD_RECALIBRATE);
output_byte(0x00);
break;
case 8:
if ((floppy_temp_track != floppy_current_track) ||
(floppy_temp_head != floppy_current_head))
{
floppy_state = 7;
output_byte(FD_SEEK);
output_byte(floppy_temp_head << 2);
output_byte(floppy_temp_track);
}
else
{
setup_DMA(floppy_temp_rwflag);
if (floppy_temp_rwflag)
{
floppy_state = 9;
output_byte(FD_READ);
}
else
{
copy_block(start_request_f->bh->b_data,floppy_buffer);
floppy_state = 11;
output_byte(FD_WRITE);
}
output_byte(floppy_temp_head << 2);
output_byte(floppy_temp_track);
output_byte(floppy_temp_head);
output_byte(floppy_temp_sector);
output_byte(0x02);
output_byte(0x12);
output_byte(0x1b);
output_byte(0xff);
}
break;
}
return;
}
void fd_rwblock_1(void)
{
floppy_temp_track = start_request_f->cyl;
floppy_temp_head = start_request_f->head;
floppy_temp_sector = start_request_f->sector;
floppy_temp_rwflag = start_request_f->cmd;
start_request_f->bh->b_dirt = 0;
floppy_timerval = FD_DRIVER_DOWN;
floppy_finishedflag = 0;
switch (floppy_state)
{
case 2:
floppy_state = 3;
floppy_timerval = FD_DRIVER_UP;
outb_p(0x1c,FD_DOR);
break;
case 4:
floppy_state = 5;
output0_byte(FD_RECALIBRATE);
output0_byte(0x00);
break;
case 8:
if ((floppy_temp_track != floppy_current_track) ||
(floppy_temp_head != floppy_current_head))
{
floppy_state = 7;
output0_byte(FD_SEEK);
output0_byte(floppy_temp_head << 2);
output0_byte(floppy_temp_track);
}
else
{
setup_DMA(floppy_temp_rwflag);
if (floppy_temp_rwflag)
{
floppy_state = 9;
output0_byte(FD_READ);
}
else
{
copy_block(start_request_f->bh->b_data,floppy_buffer);
floppy_state = 11;
output0_byte(FD_WRITE);
}
output0_byte(floppy_temp_head << 2);
output0_byte(floppy_temp_track);
output0_byte(floppy_temp_head);
output0_byte(floppy_temp_sector);
output0_byte(0x02);
output0_byte(0x12);
output0_byte(0x1b);
output0_byte(0xff);
}
break;
}
return;
}
//////////////////////////////////////////////////////////////////////////////
void do_fd(void)
{
struct buffer_head * temp_bh;
floppy_timerval = FD_DRIVER_DOWN;
switch (floppy_state)
{
case 1:
output_byte(FD_SPECIFY);
output_byte(0xcf);
output_byte(0x06);
floppy_state = 2;
floppy_timerval = 0;
floppy_finishedflag = 1;
return;
case 5:
output_byte(FD_SENSEI);
reply_length = get_result();
if (reply_length != 2)
while (1);
if (reply_buffer[0] & 0xc0)
{
floppy_errors++;
if (floppy_errors <= 5)
{
output_byte(FD_RECALIBRATE);
output_byte(0x00);
return;
}
floppy_state = floppy_state + 100;
floppy_rwerrors = 0;
}
else
{
floppy_state = 6;
floppy_current_track= 0;
}
floppy_errors= 0;
break;
case 7:
output_byte(FD_SENSEI);
reply_length = get_result();
if (reply_length != 2)
while (1);
if (reply_buffer[0] & 0xc0)
{
floppy_errors++;
if (floppy_errors <= 5)
{
output_byte(FD_SEEK);
output_byte(floppy_temp_head << 2);
output_byte(floppy_temp_track);
return;
}
floppy_state = floppy_state + 100;
floppy_rwerrors = 0;
}
else
{
floppy_state = 8;
floppy_current_track= floppy_temp_track;
floppy_current_head = floppy_temp_head;
}
floppy_errors= 0;
break;
case 9:
reply_length = get_result();
if (reply_length != 7)
while (1);
if ((reply_buffer[0] & 0xc0) || reply_buffer[1] || reply_buffer[2])
{
floppy_rwerrors++;
if (floppy_rwerrors <= 5)
{
floppy_state = 5;
output_byte(FD_RECALIBRATE);
output_byte(0x00);
return;
}
floppy_state = floppy_state + 100;
}
else
{
floppy_state = 10;
floppy_current_track = reply_buffer[3];
floppy_current_head = reply_buffer[4];
floppy_current_sector = reply_buffer[5];
}
floppy_rwerrors= 0;
break;
case 11:
reply_length = get_result();
if (reply_length != 7)
while (1);
if ((reply_buffer[0] & 0xc0) || reply_buffer[1] || reply_buffer[2])
{
if (reply_buffer[1] & 0x02)
{
floppy_state = floppy_state + 100;
floppy_rwerrors = 0;
break;
}
floppy_rwerrors++;
if (floppy_rwerrors <= 5)
{
floppy_state = 5;
output_byte(FD_RECALIBRATE);
output_byte(0x00);
return;
}
floppy_state = floppy_state + 100;
}
else
{
floppy_state = 12;
floppy_current_track = reply_buffer[3];
floppy_current_head = reply_buffer[4];
floppy_current_sector = reply_buffer[5];
}
floppy_rwerrors= 0;
break;
}
temp_bh = start_request_f->bh;
switch (floppy_state)
{
case 6:
floppy_state = 7;
output_byte(FD_SEEK);
output_byte(floppy_temp_head << 2);
output_byte(floppy_temp_track);
return;
case 8:
setup_DMA(floppy_temp_rwflag);
if (floppy_temp_rwflag)
{
floppy_state = 9;
output_byte(FD_READ);
}
else
{
copy_block(temp_bh->b_data,floppy_buffer);
floppy_state = 11;
output_byte(FD_WRITE);
}
output_byte(floppy_temp_head << 2);
output_byte(floppy_temp_track);
output_byte(floppy_temp_head);
output_byte(floppy_temp_sector);
output_byte(0x02);
output_byte(0x12);
output_byte(0x1b);
output_byte(0xff);
return;
case 10:
case 12:
floppy_state = 8;
floppy_finishedflag = 1;
break;
case 105:
case 107:
case 109:
case 111:
floppy_state = 4;
floppy_finishedflag = -1;
break;
}
/////////////////////////////////////////////
if ((temp_bh->b_count == 0) && (temp_bh->b_dirt == 0)){
if (free_list == NULL)
free_list = temp_bh;
else {
temp_bh->b_next_free = free_list;
temp_bh->b_prev_free = free_list->b_prev_free;
free_list->b_prev_free->b_next_free = temp_bh;
free_list->b_prev_free = temp_bh;
if (floppy_finishedflag == -1)
free_list = temp_bh;
}
}
if (floppy_finishedflag == 1)
{
temp_bh->b_uptodate = temp_bh->b_uptodate | 0x01;
if (floppy_temp_rwflag)
copy_block(floppy_buffer,temp_bh->b_data);
}
else
{
temp_bh->b_uptodate = temp_bh->b_uptodate & 0xfe;
if (temp_bh->b_uptodate & 0x80)
floppy_workstate = -1;
}
temp_bh->b_lock = 0;
start_request_f->hd = -1;
start_request_f = start_request_f->next;
if (!start_request_f)
end_request_f = NULL;
else
fd_rwblock_0();
return;
/////////////////////////////////////////////
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -