?? rwdisk.c
字號:
/***************************************************************************
rwdisk.c - description
-------------------
copyright : (C) 2003
***************************************************************************/
#include "ata.h"
#include "disk.h"
#define SECTOR_SIZE 512
unsigned char intFlag = 1;
//////////////////////////////////////////////////////////////////
void init_chip_param()
{
// set transfer parameters
T2_INIT_REG = 0x44; // set chip PIO transfer mode
T2i_INIT_REG = 0x44;
}
/////////////////////////////////////////
void wait_device_int()
{
unsigned char ch;
ch = INTR_REG;
while(!(ch & 0x01)){
ch = read_ata_reg(Adr_AS);
if(ch & 0x01) break;
ch = PIO_FSM;
ch = INTR_REG;
}
read_ata_reg(Adr_ST);
ch = CHIP_STATUS;
}
/////////////////////////////////////////////////////////////
void ata_select_dev()
{
//unsigned int data i;
while(read_ata_reg(Adr_ST) & 0x88);
write_ata_reg(Adr_DH,0x00);
//for(;i<5;i++); //delay
while(read_ata_reg(Adr_ST) & 0x88);
}
////////////////////////////////////////////////////////
unsigned char read_ata_reg(unsigned char addr)
{
unsigned char ch;
PIO_CTRL_REG |= 0x80; //PIO read enable
ATA_ADDR_REG = addr;
PIO_CTRL_REG &= 0x00;
while (!(INTR_REG & 0x02)); //wait pio ready;
ATA_ADDR_REG = 0x00;
ch = PIOFIFOL_R;
return ch;
}
//////////////////////////////////////////////////////////
/* host write atapi device's register(8 bits) */
void write_ata_reg(unsigned char addr,unsigned char ch)
{
PIO_CTRL_REG |= 0x81; //PIO write enable
ATA_ADDR_REG = addr;
PIO_CTRL_REG &= 0x01;
while(!(INTR_REG & 0x02)); //wait pio ready;
PIOFIFOL_W = ch;
ATA_ADDR_REG = 0x00;
}
////////////////////////////////////////////////////////////
void wait_pio_ready()
{
unsigned char ch;
ch = CHIP_STATUS;
while (!(ch & 0x01))
ch = INTR_REG;
}
/////////////////////////////////////////////////////////////////
void set_pio_write(void)
{
PIO_CTRL_REG = 0x01;
}
////////////////////////////////////////////////////////////////
void set_pio_read(void)
{
PIO_CTRL_REG = 0x00;
}
/////////////////////////////////////////////////////////////////////////
/*
Non-data command flow, this protocol include: SET FEARTURE,READ NATIVE MAX ADDRESS,
SET MAX ADDRESS, etc.
*/
int non_data_com(device_reg_set_t *device_reg_set)
{
unsigned char ch;
ata_select_dev();
write_ata_reg(Adr_FR,device_reg_set->feature);
write_ata_reg(Adr_SC,device_reg_set->sector_count);
write_ata_reg(Adr_SN,device_reg_set->sector_number);
write_ata_reg(Adr_CH,device_reg_set->cylinder_high);
write_ata_reg(Adr_CL,device_reg_set->cylinder_low);
write_ata_reg(Adr_DH,device_reg_set->device_head);
write_ata_reg(Adr_CM,device_reg_set->command);
ch = read_ata_reg(Adr_AS);
while(ch & 0x80)
ch = read_ata_reg(Adr_AS);
if(ch & 0x01) { //some error occured
ch = read_ata_reg(Adr_ER);
if(intFlag) {
wait_device_int();
read_ata_reg(Adr_ST);
return -1;
}
else {
read_ata_reg(Adr_ST);
return -1;
}
}
if(intFlag) { // normal exit
wait_device_int();
read_ata_reg(Adr_ST);
return 0;
}
else {
read_ata_reg(Adr_ST);
return 0;
}
}
/////////////////////////////////////////////////////////////////////////
/*
PIO DATA in flow, this protocol include: identify device,indentify packet device,
read buffer,read multiple, read sectors
*/
int ata_pio_in(device_reg_set_t *p_device_reg_set)
{
unsigned char ch;
// unsigned int i;
unsigned long byte_num = 0;
write_ata_reg(Adr_FR,p_device_reg_set->feature);
write_ata_reg(Adr_SC,p_device_reg_set->sector_count);
write_ata_reg(Adr_SN,p_device_reg_set->sector_number);
write_ata_reg(Adr_CH,p_device_reg_set->cylinder_high);
write_ata_reg(Adr_CL,p_device_reg_set->cylinder_low);
write_ata_reg(Adr_DH,p_device_reg_set->device_head);
write_ata_reg(Adr_CM,p_device_reg_set->command);
do{
ch = read_ata_reg(Adr_AS);
if(ch & 0x01){
ch = read_ata_reg(Adr_ER);
if(intFlag){
wait_device_int();
read_ata_reg(Adr_ST);
}
else read_ata_reg(Adr_ST);
return -1;
}
if(intFlag){
wait_device_int();
read_ata_reg(Adr_ST);
}
else {
read_ata_reg(Adr_AS);
ch = read_ata_reg(Adr_ST);
while(!((!(ch & 0x80))&&(ch & 0x08)))
ch = read_ata_reg(Adr_ST);
}
PIO_CTRL_REG = PIO_READ; //set pio read;
for(; byte_num < SECTOR_SIZE; byte_num += 2) {
ATA_ADDR_REG = Adr_DA; //Adr_DA:PIO data register;
while(!(INTR_REG & 0x02)); //wait pio ready;
ATA_ADDR_REG = 0x00;
ch = PIOFIFOH_R;
ch = PIOFIFOL_R;
}
byte_num += SECTOR_SIZE;
ch = read_ata_reg(Adr_AS);
}while(((ch & 0x80)&&(!(ch & 0x08))) || ((!(ch & 0x80)) && (ch & 0x08)));
read_ata_reg(Adr_AS);
read_ata_reg(Adr_ST);
return 0;
}
/////////////////////////////////////////////////////////////////////////
/*
PIO DATA out flow, this protocol include: security disable password,security erase unit,
security set password, security unlock, write buffer, write multiple,
write sector
*/
int ata_pio_out(device_reg_set_t *device_reg_set,unsigned int length)
{
unsigned char ch;
unsigned int i,byte_num;
unsigned int num = 1; //the number of sectors that be writed to disc
write_ata_reg(Adr_FR,device_reg_set->feature);
write_ata_reg(Adr_SC,device_reg_set->sector_count);
write_ata_reg(Adr_SN,device_reg_set->sector_number);
write_ata_reg(Adr_CH,device_reg_set->cylinder_high);
write_ata_reg(Adr_CL,device_reg_set->cylinder_low);
write_ata_reg(Adr_DH,device_reg_set->device_head);
write_ata_reg(Adr_CM,device_reg_set->command);
ch = read_ata_reg(Adr_AS);
if(ch & 0x01) {
ch = read_ata_reg(Adr_ER);
if(intFlag) {
wait_device_int();
read_ata_reg(Adr_ST);
return -1;
}
else {
read_ata_reg(Adr_ST);
return -1;
}
}
while(!(!(ch & 0x80)&&(ch & 0x08)))
ch = read_ata_reg(Adr_AS);
do {
byte_num = num*512;
if(byte_num>length) //error: data number beyond the length of array
return -1;
for(i=(num-1)*512;i<byte_num;i+=2) {
set_pio_write();
ATA_ADDR_REG = Adr_DA;//Adr_DA:PIO data register;
wait_pio_ready();
PIOFIFOH_W = (unsigned char)(i >> 8);
PIOFIFOL_W = (unsigned char)(i);
ATA_ADDR_REG = 0x00;
}
num++;
ch = read_ata_reg(Adr_AS);
if(ch & 0x01) { //error
ch = read_ata_reg(Adr_ER);
if(intFlag) {
wait_device_int();
read_ata_reg(Adr_ST);
return -1;
}
else {
read_ata_reg(Adr_ST);
return -1;
}
}
if(!(!(ch & 0x80)&&(ch & 0x08))||((ch & 0x80)&&(!(ch & 0x08)))) {
if(intFlag) {
wait_device_int();
read_ata_reg(Adr_ST);
return 0;
}
else {
read_ata_reg(Adr_ST);
return 0;
}
}
else {
if(intFlag) {
wait_device_int();
read_ata_reg(Adr_ST);
}
else {
ch = read_ata_reg(Adr_ST);
while(!(!(ch & 0x80)&&(ch & 0x08)))
ch = read_ata_reg(Adr_ST);
}
}
} while(1);
}
/////////////////////////////////////////////////////////////////////////
int pio_block_out(volatile device_reg_set_t *p_device_reg_set)
{
unsigned char ch;
unsigned int j=0,k=0;
write_ata_reg(Adr_FR,p_device_reg_set->feature);
write_ata_reg(Adr_SC,p_device_reg_set->sector_count);
write_ata_reg(Adr_SN,p_device_reg_set->sector_number);
write_ata_reg(Adr_CH,p_device_reg_set->cylinder_high);
write_ata_reg(Adr_CL,p_device_reg_set->cylinder_low);
write_ata_reg(Adr_DH,p_device_reg_set->device_head);
write_ata_reg(Adr_CM,p_device_reg_set->command);
//for(i=0;i<1000;i++); //delay
ch = read_ata_reg(Adr_AS);
ch = read_ata_reg(Adr_ST);
if(ch == 0x51) {
ch = read_ata_reg(Adr_ER);
if(intFlag) {
wait_device_int();
return -1;
}
else {
read_ata_reg(Adr_ST);
return -1;
}
}
while(!(!(ch & 0x80)&&(ch & 0x08)&&(ch & 0x40)))
ch = read_ata_reg(Adr_AS);
do {
PIO_CTRL_REG = 0x80;
ATA_ADDR_REG = Adr_DA; //Adr_DA:PIO data register;
PIO_CTRL_REG = 0x07;
ch = INTR_REG;
while(!(ch&0x04))
ch = INTR_REG; // wait pio block finish interrupt
PIO_CTRL_REG = 0x80;
ATA_ADDR_REG = 0x00;
if(intFlag) {
wait_device_int();
ch = read_ata_reg(Adr_ST);
}
else {
//tmp = CHIP_STATUS;
read_ata_reg(Adr_AS);
ch = read_ata_reg(Adr_ST);
}
if(ch & 0x01) {
if(intFlag) {
wait_device_int();
read_ata_reg(Adr_ST);
return read_ata_reg(Adr_ER);
}
else {
//tmp = CHIP_STATUS;
read_ata_reg(Adr_ST);
return read_ata_reg(Adr_ER);
}
}
if(!(!(ch & 0x80)&&(ch & 0x08))||((ch & 0x80)&&(!(ch & 0x08)))) {
ch = read_ata_reg(Adr_ST);
return 0;
}
else {
while(!(!(ch & 0x80)&&(ch & 0x08)&&(ch & 0x40)))
ch = read_ata_reg(Adr_AS);
}
}while(1);
}
//////////////////////////////////////////////////////////////////////////////////////
int pio_block_in(device_reg_set_t *p_device_reg_set)
{
unsigned char ch;
write_ata_reg(Adr_FR,p_device_reg_set->feature);
write_ata_reg(Adr_SC,p_device_reg_set->sector_count);
write_ata_reg(Adr_SN,p_device_reg_set->sector_number);
write_ata_reg(Adr_CH,p_device_reg_set->cylinder_high);
write_ata_reg(Adr_CL,p_device_reg_set->cylinder_low);
write_ata_reg(Adr_DH,p_device_reg_set->device_head);
write_ata_reg(Adr_CM,p_device_reg_set->command);
ch = read_ata_reg(Adr_AS);
do{
if(ch & 0x01){
ch = read_ata_reg(Adr_ER);
if(intFlag){
wait_device_int();
read_ata_reg(Adr_ST);
}
else read_ata_reg(Adr_ST);
return -1;
}
if(intFlag){
wait_device_int();
}
else {
read_ata_reg(Adr_AS);
ch = read_ata_reg(Adr_ST);
while(!((!(ch & 0x80))&&(ch & 0x08)))
ch = read_ata_reg(Adr_ST);
}
PIO_CTRL_REG = 0x80;
ATA_ADDR_REG = Adr_DA; //Adr_DA:PIO data register;
PIO_CTRL_REG = 0x06;
ch = INTR_REG;
while(!(ch&0x04))
ch = INTR_REG; // wait pio block finish interrupt
ATA_ADDR_REG = 0x00;
ch = CHIP_STATUS;
ch = read_ata_reg(Adr_ST);
}while(((ch & 0x80)&&(!(ch & 0x08))) || ((!(ch & 0x80)) && (ch & 0x08)));
ch = read_ata_reg(Adr_AS);
ch = read_ata_reg(Adr_ST);
return 0;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -