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

📄 zip_usb.c

📁 一个linux下的usb接口源代码
💻 C
字号:

#include "DataType.h"

#define COUNT_RETRY 5
#define COUNT_LOOP 400000

UCHAR Packet(void)
{
    UCHAR status, errno	= 0,c=0x80;
    ULONG i=0;
    long cnt;
    static int ii=0;
    
    ii++;
    
    cnt = 0;
    while ((status = Read_ATA_Reg(STATUS_REG)) & ATA_STATUS_BSY)
	{
		cnt ++;
		if (cnt >= COUNT_LOOP)
		{
			Write_ATA_Reg(COMMAND_REG, 0x08);
			printk("busy1\n");
			return 1;
		}
	//	printk("ii=%d zip busy1!\n", ii);
	}

    cnt = 0;
    while(((status = Read_ATA_Reg(STATUS_REG)) & ATA_STATUS_DRQ))
    {
		cnt ++;
		if (cnt >= COUNT_LOOP)
		{
			Write_ATA_Reg(COMMAND_REG, 0x08);
			printk("drq1\n");
			return 1;
		}
	//	printk("ii=%d zip DRQ1!\n", ii);
    }
    
    Write_ATA_Reg(DRIVE_HEAD_REG, 0xa0);
    
    cnt = 0;
    while ((status = Read_ATA_Reg(STATUS_REG)) & ATA_STATUS_BSY)
	{
		cnt ++;
		if (cnt >= COUNT_LOOP)
		{
			Write_ATA_Reg(COMMAND_REG, 0x08);
			printk("busy2\n");
			return 1;
		}
	//	printk("ii=%d zip busy2!\n", ii);
	}

    cnt = 0;
    while(((status = Read_ATA_Reg(STATUS_REG)) & ATA_STATUS_DRQ))
    {
		cnt ++;
		if (cnt >= COUNT_LOOP)
		{
			Write_ATA_Reg(COMMAND_REG, 0x08);
			printk("drq2\n");
			return 1;
		}
	//	printk("req=%d zip DRQ2!\n", ii);
    }

    Write_ATA_Reg(FEATURE_REG, 0x0);
    Write_ATA_Reg(BYTE_COUNT_LOW_REG, 0xf0);
    Write_ATA_Reg(BYTE_COUNT_HIGH_REG, 0x00);
    Write_ATA_Reg(COMMAND_REG, 0xa0);
    
    cnt = 0;
    while ((status = Read_ATA_Reg(STATUS_REG)) & ATA_STATUS_BSY)
    {
		cnt ++;
		if (cnt >= COUNT_LOOP)
		{
			Write_ATA_Reg(COMMAND_REG, 0x08);
			printk("busy3\n");
			return 1;
		}
    	//	printk("ii=%d zip busy3!\n", ii);
    }
    
    cnt = 0;
    while(!((status = Read_ATA_Reg(STATUS_REG)) & ATA_STATUS_DRQ))
    {
		cnt ++;
		if (cnt >= COUNT_LOOP)
		{
			Write_ATA_Reg(COMMAND_REG, 0x08);
			printk("drq3\n");
			return 1;
		}
	//	printk("ii=%d zip DRQ3!\n", ii);
    }

    if (status & ATA_STATUS_ERR)
    {
	errno =	Read_ATA_Reg(ERROR_REG);    
	printk("packet error = %x\n", errno);
    }
    return errno;
}



void Send_Packet(unsigned short *command)
{
	unsigned char	i;
	for(i=0;i<6;i++)
	{
		Write_ATA_Data_Reg(command[i]);
	}
}

unsigned short Exec_ATAPI_Command()	//MAJOR	SUBROUTINE
{
	UCHAR Retry = 0;
   	ULONG cnt;
	UCHAR tmpbuf[16];
	unsigned char status,errno=0;
	unsigned long i,j,n,k;			//Modified by Mike Chan from UWORD to ULONG
	unsigned short * buf;

AGAIN:
	Retry++;
	cnt = 0;
	buf = (unsigned short *)(Buffer_Pointer);
	
	if (Packet())
	{
		if (Retry >= COUNT_RETRY)
		{
			return 1;
		}
		else
		{
			goto AGAIN;
		}
	}
	
	for (i=0; i<16; i++)
	{
		tmpbuf[i] = CBWBuf[15+i];
	}
	
	Send_Packet((unsigned short*)&tmpbuf[0]);
	
    if ( Id == ID_WR )					//If write operation
    {
		if ( (TPBulk_CommandBlock_bAtapi_CommandPackage0 == 0x0a) && (Buffer_Length == 0) )
		{
			Buffer_Length=256;
		}
	
		//n = Buffer_Length/512;	//Modified by Mike Chan(ChenXiaotian)
		n = Buffer_Length>>9;
		
		for (i = 0; i <	n; i++)
		{
    			while((status = Read_ATA_Reg(STATUS_REG)) & ATA_STATUS_BSY)
    			{
				cnt ++;
				if (cnt >= COUNT_LOOP*2)
				{
					Write_ATA_Reg(COMMAND_REG, 0x08);
					if (Retry >= COUNT_RETRY)
					{
						printk("busy wr\n");
						return 1;
					}
					else
					{
						goto AGAIN;
					}
				}
				//printk("Busy wr\n");
			}
			if (status & ATA_STATUS_ERR)
			{
				errno =	Read_ATA_Reg(ERROR_REG);
				printk("Write error = %x\n", errno);

				Write_ATA_Reg(COMMAND_REG, 0x08);
				if (Retry >= COUNT_RETRY)
				{
					printk("wr error\n");
					return 1;
				}
				else
				{
					goto AGAIN;
				}
			}										//check	the status
		
			for (j = 0; j <	256; j++)
			{
			    Write_ATA_Data_Reg( buf[j] );
			}
			buf += 256;
		}
    }
    else if ( Id == ID_RD )				//If read operation
    {
		if ( (TPBulk_CommandBlock_bAtapi_CommandPackage0 == 0x08) && (Buffer_Length == 0) )
		{
			Buffer_Length=256;
		}

		//n = Buffer_Length/512;	//Modified by Mike Chan(ChenXiaotian)
		n = Buffer_Length>>9;
	
		for (i = 0; i <	n; i++)
		{
			while ((status = Read_ATA_Reg(STATUS_REG)) & ATA_STATUS_BSY) 
    			{
				cnt ++;
				if (cnt >= COUNT_LOOP*2)
				{
					Write_ATA_Reg(COMMAND_REG, 0x08);
					if (Retry >= COUNT_RETRY)
					{
						printk("busy rd\n");
						return 1;
					}
					else
					{
						goto AGAIN;
					}
				}
				//printk("Busy wr\n");
			}

			if (status & ATA_STATUS_ERR)
			{
				errno =	Read_ATA_Reg(ERROR_REG);
				printk("Read error = %x\n", errno);

				Write_ATA_Reg(COMMAND_REG, 0x08);
				if (Retry >= COUNT_RETRY)
				{
					printk("rd error\n");
					return	1;
				}
				else
				{
					goto AGAIN;
				}
			}
			for (j = 0; j <	256; j++)
			{
				buf[j] = Read_ATA_Data_Reg();
			}
			//Read512Bytes(buf);
			buf	+= 256;
		}
	}
	else if	( Id == ID_SET )
	{
		while ((status = Read_ATA_Reg(STATUS_REG)) & ATA_STATUS_BSY)
    		{
			cnt ++;
			if (cnt >= COUNT_LOOP*2)
			{
				Write_ATA_Reg(COMMAND_REG, 0x08);
				if (Retry >= COUNT_RETRY)
				{
					printk("busy set\n");
					return 1;
				}
				else
				{
					goto AGAIN;
				}
			}
		}

		if (status & ATA_STATUS_ERR)
		{
			for (i=0; i<12; i++)
			{
				printk("%x\t", CBWBuf[15+i]);
			} 
			printk("\n");
			errno =	Read_ATA_Reg(ERROR_REG);
			printk("Set error = %x\n", errno);
			
			Write_ATA_Reg(COMMAND_REG, 0x08);
			if (Retry >= 2)
			{
				//printk("set error\n");
				return	1;
			}
			else
			{
				goto AGAIN;
			}
		}

		for (j = 0; j <	(unsigned short)( Buffer_Length / 2 );	j++)
		{
			Write_ATA_Data_Reg(buf[j]);
		}
	}
	else											//If other operation
	{
		while ((status = Read_ATA_Reg(STATUS_REG)) & ATA_STATUS_BSY)
    		{
			cnt ++;
			if (cnt >= COUNT_LOOP*2)
			{
				Write_ATA_Reg(COMMAND_REG, 0x08);
				if (Retry >= COUNT_RETRY)
				{
					printk("busy other\n");
					return 1;
				}
				else
				{
					goto AGAIN;
				}
			}
		}

		if (status & ATA_STATUS_ERR)
		{
			for (i=0; i<12; i++)
			{
				printk("%x\t", CBWBuf[15+i]);
			}
			printk("\n"); 
			errno =	Read_ATA_Reg(ERROR_REG);
			printk("Other error = %x\n", errno);

			Write_ATA_Reg(COMMAND_REG, 0x08);
			if (Retry >= 2)
			{
				//printk("other error\n");
				return	1;
			}
			else
			{
				goto AGAIN;
			}
		}											
		for (j = 0; j <	(unsigned short)( Buffer_Length / 2 );	j++)
		{
			buf[j] = Read_ATA_Data_Reg();
		}
	}
	return 0;
}

⌨️ 快捷键说明

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