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

📄 hd_0.c

📁 阿基米德操作系统的源代码
💻 C
字号:
//////////////////////////////////////////////////////////////////////////////
#include "general.h"
#include "inb_outb.h"
#include "sti_cli.h"
#include "port_read_write.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"
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
int hd_op_result(void)
{
	int temp_hd_status;

	temp_hd_status = inb(HD_STATUS);
	if ((temp_hd_status & (BUSY_STAT | READY_STAT | WRERR_STAT | SEEK_STAT | ECC_STAT | ERR_STAT)) == (READY_STAT | SEEK_STAT))
		return 1;

	if (temp_hd_status & 1)
		temp_hd_status = inb(HD_ERROR);
	while(1);

	return 0;
}


int hd_if_ready_0(void)
{
	int i;

	sti();
	for (i = 0 ; i < 100000 ; i++)
		if ((inb(HD_STATUS) & (BUSY_STAT | READY_STAT)) == READY_STAT) {
			cli();
			return 1;
		}

	while (1);

	cli();
	return 0;
}

int	hd_if_ready_1(void)
{
	int i;

	sti();
	for (i = 0 ; i < 300000 ; i++)
		if (inb_p(HD_STATUS) & DRQ_STAT){
			cli();
			return 1;
		}
	
	while (1);

	cli();
	return 0;
}

int hd_if_ready_2(void)
{
	int i;

	for (i = 0 ; i < 100000 ; i++)
		if ((inb(HD_STATUS) & (BUSY_STAT | READY_STAT)) == READY_STAT)
			return 1;

	while (1);

	return 0;
}

int	hd_if_ready_3(void)
{
	int i;

	for (i = 0 ; i < 300000 ; i++)
		if (inb_p(HD_STATUS) & DRQ_STAT)
			return 1;
	
	while (1);

	return 0;
}

void do_request_0(void)
{
	int port;

	data_index = 0;

	if (!hd_if_ready_0())
		return;

	port = HD_CMD;
	outb(  hd_info[start_request_h->hd].ctl   ,   port);
	port = HD_DATA;
	outb_p(hd_info[start_request_h->hd].wpcom , ++port);
	outb_p(start_request_h->nsector           , ++port);
	outb_p(start_request_h->sector            , ++port);
	outb_p(start_request_h->cyl               , ++port);
	outb_p(start_request_h->cyl >> 8          , ++port);
	outb_p(0xA0 | (start_request_h->hd << 4) | start_request_h->head , ++port);
	outb(start_request_h->cmd                 , ++port);
	
	if (start_request_h->cmd == WIN_WRITE) {
		if (!hd_if_ready_1())
			return;
		start_request_h->bh->b_dirt = 0;
		port_write(HD_DATA , start_request_h->bh->b_data + 512 * data_index , 256);
		data_index++;
	} 
	return;
}

void do_request_1(void)
{
	int port;

	data_index = 0;

	if (!hd_if_ready_2())
		return;

	port = HD_CMD;
	outb(  hd_info[start_request_h->hd].ctl   ,   port);
	port = HD_DATA;
	outb_p(hd_info[start_request_h->hd].wpcom , ++port);
	outb_p(start_request_h->nsector           , ++port);
	outb_p(start_request_h->sector            , ++port);
	outb_p(start_request_h->cyl               , ++port);
	outb_p(start_request_h->cyl >> 8          , ++port);
	outb_p(0xA0 | (start_request_h->hd << 4) | start_request_h->head , ++port);
	outb(start_request_h->cmd                 , ++port);
	
	if (start_request_h->cmd == WIN_WRITE) {
		if (!hd_if_ready_3())
			return;
		start_request_h->bh->b_dirt = 0;
		port_write(HD_DATA , start_request_h->bh->b_data + 512 * data_index , 256);
		data_index++;
	} 
	return;
}


void do_hd(void)
{
	struct buffer_head * temp_bh;
	
	if (!hd_op_result())
		return;

	start_request_h->errors = 0;
	if (start_request_h->cmd == WIN_WRITE) {
		if (--start_request_h->nsector) {
			port_write(HD_DATA,start_request_h->bh->b_data + 512 * data_index,256);
			data_index++;
			return;
		}
	}
	else {
		port_read(HD_DATA,start_request_h->bh->b_data + 512 * data_index,256);
		data_index++;
		if (--start_request_h->nsector)
			return;
		start_request_h->bh->b_uptodate = 1;
	}
	temp_bh	= start_request_h->bh;
	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;
		}
	}
	temp_bh->b_lock = 0;

	start_request_h->hd	= -1;
	start_request_h     = start_request_h->next;
	if (!start_request_h)
		end_request_h = NULL;
	else
		do_request_0();
	return;
}

//////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

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