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

📄 ata_ide_drive.c

📁 newos is new operation system
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "ide_bus.h"#include "ata_ide_drive.h"#include <kernel/dev/arch/i386/ide/ide_bus.h>#include <kernel/heap.h>#include <kernel/debug.h>#include <kernel/lock.h>#define CB_DC_HD15   0x08  // bit should always be set to one#define CB_DC_NIEN   0x02  // disable interrupts#define CB_DH_DEV0 0xa0    // select device 0#define CB_DH_DEV1 0xb0    // select device 1#define DH_DRV1				0x1#define DH_LBA				0x400// Most mandtory and optional ATA commands (from ATA-3),#define CMD_CFA_ERASE_SECTORS            0xC0#define CMD_CFA_REQUEST_EXT_ERR_CODE     0x03#define CMD_CFA_TRANSLATE_SECTOR         0x87#define CMD_CFA_WRITE_MULTIPLE_WO_ERASE  0xCD#define CMD_CFA_WRITE_SECTORS_WO_ERASE   0x38#define CMD_CHECK_POWER_MODE1            0xE5#define CMD_CHECK_POWER_MODE2            0x98#define CMD_DEVICE_RESET                 0x08#define CMD_EXECUTE_DEVICE_DIAGNOSTIC    0x90#define CMD_FLUSH_CACHE                  0xE7#define CMD_FORMAT_TRACK                 0x50#define CMD_IDENTIFY_DEVICE              0xEC#define CMD_IDENTIFY_DEVICE_PACKET       0xA1#define CMD_IDENTIFY_PACKET_DEVICE       0xA1#define CMD_IDLE1                        0xE3#define CMD_IDLE2                        0x97#define CMD_IDLE_IMMEDIATE1              0xE1#define CMD_IDLE_IMMEDIATE2              0x95#define CMD_INITIALIZE_DRIVE_PARAMETERS  0x91#define CMD_INITIALIZE_DEVICE_PARAMETERS 0x91#define CMD_NOP                          0x00#define CMD_PACKET                       0xA0#define CMD_READ_BUFFER                  0xE4#define CMD_READ_DMA                     0xC8#define CMD_READ_DMA_QUEUED              0xC7#define CMD_READ_MULTIPLE                0xC4#define CMD_READ_SECTORS                 0x20#define CMD_READ_VERIFY_SECTORS          0x40#define CMD_RECALIBRATE                  0x10#define CMD_SEEK                         0x70#define CMD_SET_FEATURES                 0xEF#define CMD_SET_MULTIPLE_MODE            0xC6#define CMD_SLEEP1                       0xE6#define CMD_SLEEP2                       0x99#define CMD_STANDBY1                     0xE2#define CMD_STANDBY2                     0x96#define CMD_STANDBY_IMMEDIATE1           0xE0#define CMD_STANDBY_IMMEDIATE2           0x94#define CMD_WRITE_BUFFER                 0xE8#define CMD_WRITE_DMA                    0xCA#define CMD_WRITE_DMA_QUEUED             0xCC#define CMD_WRITE_MULTIPLE               0xC5#define CMD_WRITE_SECTORS                0x30#define CMD_WRITE_VERIFY                 0x3C#define CB_STAT_BSY  0x80  // busy#define CB_STAT_RDY  0x40  // ready#define CB_STAT_DF   0x20  // device fault#define CB_STAT_WFT  0x20  // write fault (old name)#define CB_STAT_SKC  0x10  // seek complete#define CB_STAT_SERV 0x10  // service#define CB_STAT_DRQ  0x08  // data request#define CB_STAT_CORR 0x04  // corrected#define CB_STAT_IDX  0x02  // index#define CB_STAT_ERR  0x01  // error (ATA)#define CB_STAT_CHK  0x01  // check (ATAPI)#define	NO_ERR	0#define	ERR_EXPIRED_TIME_OUT	-1#define	ERR_DISK_BUSY		-2#define	ERR_HARDWARE_ERROR	-3#define	ERR_DRQ_NOT_SET		-4#define	ERR_TRANSMIT_BUFFER_NOT_EMPTY	-5#define	ERR_DEVICE_FAULT	-6#define	DRIVE_SUPPORT_LBA		0x0200#define IDE_TRACE 1#if IDE_TRACE#define TRACE(x) dprintf x#else#define TRACE(x)#endif#define	STATUS_WAITING_INTR	1#define	STATUS_IDLE		2typedef	struct	s_ata_command{	int			cmd;	int			fr;	int			sc;	int			cyl;	int			head;	int			sect;	uint8			*output;	int			numSect;	int			multiCnt;	bool			read;	bool			useInterrupt;}ata_command;typedef	struct{	ide_bus		*attached_bus;	void		*attached_bus_cookie;	int		position;	bool		lba_supported;	long		sector_count;	uint16		bytes_per_sector;	ide_drive_info	device_info;	int		status;	ata_command	*active_command;	mutex		interrupt_mutex;}ata_drive_cookie;static void	ide_reg_poll(ide_bus *bus, void *b_cookie){	uint8		status;	while(1)	{		status = bus->get_alt_status(b_cookie);       // poll for not busy		if ( ( status & CB_STAT_BSY ) == 0 )    			break;	}}static	int	convert_error(int error){	if(error & CB_STAT_BSY)		return ERR_DISK_BUSY;	if(error & CB_STAT_DF)		return ERR_DEVICE_FAULT;	if(error & CB_STAT_ERR)		return ERR_HARDWARE_ERROR;	return 0;}static	void	signal_interrupt(void *b_cookie,void *drive_cookie){	ata_drive_cookie	*cookie = drive_cookie;	TRACE(("in signal interrupt status is %d\n",cookie->status));	if(cookie->status == STATUS_WAITING_INTR)	{		TRACE(("unlock mutex\n"));		mutex_unlock(&cookie->interrupt_mutex);	}}int execute_command( ide_bus *bus, void *b_cookie,ata_drive_cookie *drive_cookie,ata_command *command){	unsigned char 		devHead;	unsigned char 		devCtrl;	unsigned char 		cylLow;	unsigned char 		cylHigh;	unsigned char 		status;	unsigned int 		wordCnt;	int			i;	uint16			*buffer = (uint16*)command->output;	int			error_code;	if(command->useInterrupt==true)		devCtrl = CB_DC_HD15;	else		devCtrl = CB_DC_HD15 | CB_DC_NIEN;	devHead = drive_cookie->position ? CB_DH_DEV1 : CB_DH_DEV0;	devHead = devHead | ( command->head & 0x4f );	cylLow = command->cyl & 0x00ff;	cylHigh = ( command->cyl & 0xff00 ) >> 8;	// these commands transfer only 1 sector	if (( command->cmd == CMD_IDENTIFY_DEVICE )|| ( command->cmd == CMD_IDENTIFY_DEVICE_PACKET )|| ( command->cmd == CMD_READ_BUFFER )|| ( command->cmd == CMD_WRITE_BUFFER))		command->numSect = 1;	// only Read Multiple uses multiCnt	if ( (command->cmd != CMD_READ_MULTIPLE ) && ( command->cmd != CMD_WRITE_MULTIPLE )   && ( command->cmd != CMD_CFA_WRITE_MULTIPLE_WO_ERASE ))		command->multiCnt = 1;	if(command->useInterrupt)	{		drive_cookie->active_command = command;		drive_cookie->status = STATUS_WAITING_INTR;	}	if ( bus->select_drive( b_cookie,drive_cookie->position) )	{		return ERR_EXPIRED_TIME_OUT;	}	bus->write_register(b_cookie, CB_DC, devCtrl );	bus->write_register(b_cookie, CB_FR, command->fr );	bus->write_register(b_cookie, CB_SC, command->sc );	bus->write_register(b_cookie, CB_SN, command->sect );	bus->write_register(b_cookie, CB_CL, cylLow );	bus->write_register(b_cookie, CB_CH, cylHigh );	bus->write_register(b_cookie, CB_DH, devHead );	bus->write_register(b_cookie, CB_CMD, command->cmd );	if(command->useInterrupt)	{		TRACE(("locking interrupt mutex\n"));		mutex_lock(&drive_cookie->interrupt_mutex);		TRACE(("entering wait loop\n"));	}	else	{		bus->delay_on_bus(b_cookie);	}	while ( 1 )	{		if(command->read)		{			if(command->useInterrupt)			{				mutex_lock(&drive_cookie->interrupt_mutex);				mutex_unlock(&drive_cookie->interrupt_mutex);			}			else				ide_reg_poll(bus,b_cookie);		}		status = bus->get_alt_status(b_cookie);		if ( ( status & ( CB_STAT_BSY | CB_STAT_DRQ ) ) == CB_STAT_DRQ )		{			wordCnt = command->multiCnt ? command->multiCnt : 1;			if ( wordCnt > command->numSect )				wordCnt = command->numSect;			wordCnt = wordCnt * 256;			bus->transfer_buffer( b_cookie,CB_DATA, buffer, wordCnt ,command->read);			bus->delay_on_bus(b_cookie);			command->numSect = command->numSect - ( command->multiCnt ? command->multiCnt : 1 );			buffer+=wordCnt;		}		if(!command->read)		{			if(command->useInterrupt)			{				mutex_lock(&drive_cookie->interrupt_mutex);				mutex_unlock(&drive_cookie->interrupt_mutex);			}			else				ide_reg_poll(bus,b_cookie);			status = bus->get_alt_status(b_cookie);		}		error_code = convert_error(status);		if(error_code!=0)			return error_code;		if ( ( status & CB_STAT_DRQ ) == 0 )		{			return ERR_DRQ_NOT_SET;		}		if ( command->numSect < 1 )		{			status = bus->get_alt_status(b_cookie);			error_code = convert_error(status);			if(error_code!=0)				return error_code;			if( status & CB_STAT_DRQ)			{				return ERR_TRANSMIT_BUFFER_NOT_EMPTY;			}			break;   // go to READ_DONE		}	}	drive_cookie->status = STATUS_IDLE;	return NO_ERR;}int execute_command_dma( ide_bus *bus, void *b_cookie,ata_drive_cookie *drive_cookie,  ata_command *command){	unsigned char 	devHead;	unsigned char 	devCtrl;	unsigned char 	cylLow;	unsigned char 	cylHigh;	unsigned char 	status;	int 		ns;	unsigned long 	lw1, lw2;	int		doTwo;	// setup register values	dprintf("entering execute_command_dma %X %X %X %X %X\n",bus,b_cookie,drive_cookie,command,command->output);	devCtrl = 0;	devHead = drive_cookie->position ? CB_DH_DEV1 : CB_DH_DEV0;

⌨️ 快捷键说明

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