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

📄 ata_ide_drive.c

📁 newos is new operation system
💻 C
📖 第 1 页 / 共 2 页
字号:
	devHead = devHead | ( command->head & 0x4f );	cylLow = command->cyl & 0x00ff;	cylHigh = ( command->cyl & 0xff00 ) >> 8;	// Quit now if the command is incorrect.	if ( ( command->cmd != CMD_READ_DMA) && ( command->cmd != CMD_WRITE_DMA) )	{		return -1;	}	// set up the dma transfer(s)	ns = command->sc;	if ( ! ns )		ns = 256;	drive_cookie->active_command = command;	doTwo = bus->setup_dma(b_cookie,command->cmd == CMD_WRITE_DMA, ns * 512L, command->output);	if ( bus->select_drive( b_cookie,drive_cookie->position) )	{		return ERR_EXPIRED_TIME_OUT;	}	// Set up all the registers except the command register.	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 );	drive_cookie->status = STATUS_WAITING_INTR;   	bus->delay_on_bus(b_cookie);	bus->start_dma( b_cookie);   	dprintf("first lock\n");   	mutex_lock(&drive_cookie->interrupt_mutex);   	dprintf("second lock\n");   	mutex_lock(&drive_cookie->interrupt_mutex);   	mutex_unlock(&drive_cookie->interrupt_mutex);	return  bus->finish_dma(b_cookie);}static	void ide_string_conv (char *str, int len){  unsigned int i;  int	       j;  for (i = 0; i < len / sizeof (unsigned short); i++)    {      char	c = str[i*2+1];      str[i*2+1] = str[i*2];      str[i*2] = c;    }  str[len - 1] = 0;  for (j = len - 1; j >= 0 && str[j] == ' '; j--)    str[j] = 0;}int		ide_identify_device (ide_bus *bus, void *b_cookie,ata_drive_cookie *drive_cookie,int bus_pos){	int			ret;	uint8			*buffer;	ata_command		command;	buffer = (uint8*)&drive_cookie->device_info;	TRACE(("executing command\n"));	command.cmd = CMD_IDENTIFY_DEVICE;	command.fr = 1;	command.sc = 0;	command.cyl = 0;	command.head = 0;	command.sect = 0;	command.output = buffer;	command.numSect = 1;	command.multiCnt = 0;	command.read = true;	command.useInterrupt = false;	ret = execute_command(	bus,b_cookie,drive_cookie,&command);	TRACE(("executing command %d\n",ret));	if(ret<0)		return	-1;	ide_string_conv(drive_cookie->device_info.model,40);	drive_cookie->sector_count = drive_cookie->device_info.cyls*drive_cookie->device_info.heads*drive_cookie->device_info.sectors;	drive_cookie->bytes_per_sector = 512;	drive_cookie->lba_supported = drive_cookie->device_info.capabilities & DRIVE_SUPPORT_LBA;	TRACE( ("ide: disk at bus %d, device %d %s\n", bus_pos, drive_cookie->position,drive_cookie->device_info.model));	TRACE(("ide/%d/%d: %dMB; %d cyl, %d head, %d sec, %d bytes/sec  (LBA=%d)\n",bus_pos, drive_cookie->position,		drive_cookie->sector_count * drive_cookie->bytes_per_sector / 1024,		drive_cookie->device_info.cyls,		drive_cookie->device_info.heads,		drive_cookie->device_info.sectors,		drive_cookie->bytes_per_sector,		drive_cookie->lba_supported	));	return 0;}static	void	*init_drive(ide_bus *bus,void *b_cookie,int channel,int drive){	uint8			sc,sn,ch,cl,st;  	unsigned char 		devCtrl = CB_DC_HD15 | CB_DC_NIEN ;  	void			*ret = NULL;  	bus->write_register(b_cookie,CB_DC,devCtrl);	bus->select_drive(b_cookie,drive);  	bus->delay_on_bus(b_cookie);	bus->write_register( b_cookie,CB_SC, 0x55 );	bus->write_register( b_cookie,CB_SN, 0xaa );	bus->write_register( b_cookie,CB_SC, 0xaa );	bus->write_register( b_cookie,CB_SN, 0x55 );	bus->write_register( b_cookie,CB_SC, 0x55 );	bus->write_register( b_cookie,CB_SN, 0xaa );	sc = bus->read_register( b_cookie,CB_SC );	sn = bus->read_register( b_cookie,CB_SN );	if(sc!=0x55 && sn!=0xaa)	{		return NULL;	}	bus->select_drive(b_cookie,drive);	bus->delay_on_bus(b_cookie);	bus->reset_bus( b_cookie,drive);	bus->select_drive(b_cookie,drive);  	bus->delay_on_bus(b_cookie);  	sc = bus->read_register( b_cookie,CB_SC );  	sn = bus->read_register( b_cookie,CB_SN );  	if ( ( sc == 0x01 ) && ( sn == 0x01 ) )    	{    		ret = NULL;      		cl = bus->read_register( b_cookie,CB_CL );      		ch = bus->read_register( b_cookie,CB_CH );      		st = bus->read_register( b_cookie,CB_STAT );      		if ( ( cl == 0x14 ) && ( ch == 0xeb ) )			ret = NULL;      		else			if ( ( cl == 0x00 ) && ( ch == 0x00 ) && ( st != 0x00 ) )	  		{	  			ata_drive_cookie *cookie = kmalloc(sizeof(ata_drive_cookie));	  			cookie->attached_bus = bus;	  			cookie->attached_bus_cookie = b_cookie;	  			cookie->position = drive;				mutex_init(&cookie->interrupt_mutex,"test");	  			if(ide_identify_device(bus,b_cookie,cookie,channel)==0)	  				ret = cookie;	  			else	  				ret = NULL;	  		}    	}	return ret;}void ide_btochs(uint32 block, ata_drive_cookie *dev, int *cylinder, int *head, int *sect){	uint32	sav_block = block;  *sect = (block % dev->device_info.sectors) + 1;  block /= dev->device_info.sectors;  *head = (block % dev->device_info.heads) | (dev->position ? DH_DRV1 : 0);  block /= dev->device_info.heads;  *cylinder = block & 0xFFFF;  TRACE(("ide_btochs: block %d -> cyl %d head %d sect %d\n", sav_block, *cylinder, *head, *sect));}void ide_btolba(uint32 block, ata_drive_cookie *dev, int *cylinder,int *head, int *sect){	uint32	sav_block = block;  *sect = block & 0xFF;  *cylinder = (block >> 8) & 0xFFFF;  *head = ((block >> 24) & 0xF) | ( dev->position ? DH_DRV1: 0) | DH_LBA;  TRACE(("ide_btolba: block %d -> cyl %d head %d sect %d\n", sav_block, *cylinder, *head, *sect));}static	int	read_block(void *b_cookie,void *d_cookie,long block,void *buffer,size_t size){	ata_drive_cookie	*drive_cookie = d_cookie;	ide_bus			*bus = drive_cookie->attached_bus;	int 			cyl, head, sect;	ata_command		command;	TRACE(("in read_blocks %x\n",block));  	if(drive_cookie->lba_supported==1)    		ide_btolba(block, drive_cookie, &cyl, &head, &sect);  	else   		ide_btochs(block, drive_cookie, &cyl, &head, &sect);    	TRACE(("about to read from %d %d %d\n",cyl,head,sect));    	command.fr = 0;    	command.sc = size;    	command.cyl = cyl;    	command.head = head;    	command.sect = sect;    	command.output = buffer;    	command.numSect = size;    	command.multiCnt = 2;    	command.read = true;    	command.useInterrupt = true;    	if(drive_cookie->attached_bus->support_dma(b_cookie)==true)    	{    		TRACE(("Will use DMA to transfer data\n"));    		command.cmd = CMD_READ_DMA;  		return execute_command_dma( bus,b_cookie,drive_cookie,&command);	}	else	{		TRACE(("Will use PIO to transfer data\n"));		command.cmd = CMD_READ_SECTORS;  		return execute_command( bus,b_cookie,drive_cookie,&command);	}}static	int	write_block(void *b_cookie,void *d_cookie,long block,const void *buffer,size_t size){	ata_drive_cookie	*drive_cookie = d_cookie;	ide_bus			*bus = drive_cookie->attached_bus;	int 			cyl, head, sect;	ata_command		command;  	if(drive_cookie->lba_supported==1)    		ide_btolba(block, drive_cookie, &cyl, &head, &sect);  	else   		ide_btochs(block, drive_cookie, &cyl, &head, &sect);       	command.fr = 0;    	command.sc = size;    	command.cyl = cyl;    	command.head = head;    	command.sect = sect;    	command.output = buffer;    	command.numSect = size;    	command.multiCnt = 2;    	command.read = false;    	command.useInterrupt = true;    	if(drive_cookie->attached_bus->support_dma(b_cookie)==true)    	{    		command.cmd = CMD_WRITE_DMA;  		return execute_command_dma( bus,b_cookie,drive_cookie,&command);	}	else	{		command.cmd = CMD_WRITE_SECTORS;  		return execute_command( bus,b_cookie,drive_cookie,&command);	}}static	uint16		get_bytes_per_sector(void *d_cookie){	ata_drive_cookie	*cookie = d_cookie;	return	cookie->bytes_per_sector;}static	int		ioctl(void *b_cookie,void *d_cookie,int command,void *buffer,size_t size){	ata_drive_cookie	*cookie = d_cookie;	int			retCode;	switch(command)	{		case	10000:		{			/*if(size!=sizeof(device_information))			{				retCode = -1;			}			else			{				device_information	*ret = (device_information*)buffer;				ret->bytes_per_sector = cookie->bytes_per_sector;				ret->sectors = cookie->sector_count;				ret->heads = cookie->device_info.heads;				ret->cylinders = cookie->device_info.cyls;				retCode = 0;			}*/			break;		}		default:		{			retCode = -1;		}	}	return retCode;}ide_drive	ata_ide_drive ={	"ATA_DRIVE",	&init_drive,	&read_block,	&write_block,	&get_bytes_per_sector,	&ioctl,	&signal_interrupt,	NULL};

⌨️ 快捷键说明

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