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

📄 pci_ide_bus.c

📁 newos is new operation system
💻 C
📖 第 1 页 / 共 2 页
字号:
					int_set_io_interrupt_handler(14,&ide_interrupt_handler, current_cookie);					break;				}				i++;			}		}		return 0;	}	return -1;}static	int	read_block(void *cookie,int drive,long block,void *buffer,size_t size){	pci_bus_cookie	*bus_cookie;	ide_drive	*thedrive;	if(drive<0 || drive>1)		return -1;	bus_cookie = cookie;	thedrive = bus_cookie->drives[drive];	if(thedrive==NULL)		return -1;	return thedrive->read_block(bus_cookie,bus_cookie->drive_cookie[drive],block,buffer,size);}static	int	write_block(void *cookie,int drive,long block,void *buffer,size_t size){	pci_bus_cookie	*bus_cookie;	ide_drive	*thedrive;	if(drive<0 || drive>1)		return -1;	bus_cookie = cookie;	thedrive = bus_cookie->drives[drive];	if(thedrive==NULL)		return -1;	return thedrive->write_block(bus_cookie,bus_cookie->drive_cookie[drive],block,buffer,size);}static	int	setup_dma(void *cookie,int dir, long size, uint8 *buffer ){	TRACE(("entering setup_dma %x %d %d,%p\n",cookie,dir,size,buffer));	pci_bus_cookie	*bus_cookie = cookie;	prd_entry 	*table = (prd_entry*)bus_cookie->prd_buf_address;	uint32		count = 0;	uint32		physical_address;	uint32		position = 0;	uint32		bufaddr;	uint8		*logical_address;	out8( BM_CR_MASK_STOP,bus_cookie->io_port + BM_COMMAND_REG); // disable dma_channel	out8( bus_cookie->stat_reg | BM_SR_MASK_INT | BM_SR_MASK_ERR,bus_cookie->io_port+ BM_STATUS_REG); // clear dma channel                              )	bus_cookie->current_dma = buffer;	bus_cookie->current_dma_length = size;#define	PRD_ENTRIES	8	while (size)	{		if (count++ >= PRD_ENTRIES)		{     			panic("DMA table too small\n");		}		else		{			physical_address = (uint32)(bus_cookie->raw_buffer + position);			count = min (size, 0x10000);			if ((physical_address & ~(0x10000-1)) != ((physical_address+count-1) & ~(0x10000-1)))				count = 0x10000 - (physical_address & (0x10000-1));			table->address = physical_address;			table->count = count & 0xFFFFE;			table->eot = 0;			table++;			size -= count;			position += count;		}	}	table--;	table->eot = 1;	uint32		reserved;	reserved = in32(bus_cookie->io_port+BM_PRD_ADDR_LOW) & 0x03;	out32(bus_cookie->prd_phy_address | reserved,bus_cookie->io_port+BM_PRD_ADDR_LOW);	if ( dir )	{		bus_cookie->rw_control = BM_CR_MASK_READ;     // ATA Write DMA	}	else	{		bus_cookie->rw_control = BM_CR_MASK_WRITE;    // ATA Read DMA	}	out8( bus_cookie->rw_control,bus_cookie->io_port + BM_COMMAND_REG);	return 0;   }static	int	start_dma(void *cookie){	pci_bus_cookie	*bus_cookie = cookie;	TRACE(("DMA about to start cookie=%p\n",bus_cookie));	out8( bus_cookie->rw_control | BM_CR_MASK_START,bus_cookie->io_port + BM_COMMAND_REG );	TRACE(("DMA should have started\n"));	return 0;}static	int	finish_dma(void *cookie){	pci_bus_cookie	*bus_cookie = cookie;	uint8		status;	TRACE(("waiting for DMA to finish\n"));	out8( BM_CR_MASK_STOP,bus_cookie->io_port + BM_COMMAND_REG); // disable dma_channel	status = read_register( cookie,CB_STAT );	TRACE(("first status = %d\n",status));	if ( status & ( CB_STAT_BSY | CB_STAT_DF | CB_STAT_DRQ | CB_STAT_ERR ) )		return -1;	status = in8( bus_cookie->io_port + BM_STATUS_REG );	TRACE(("second status = %d %d\n",status,status & BM_SR_MASK_INT));	TRACE(("pci_ide will copy %d bytes\n",bus_cookie->current_dma_length));	bcopy(bus_cookie->mapped_address,bus_cookie->current_dma,bus_cookie->current_dma_length);	switch(status & 0x5) {		case 0:				TRACE(("IDE -- finish_dma: DMA transfer failed\n"));			return -1;		case 1:				TRACE(("IDE -- finish_dma: DMA transfer aborted\n"));			return -1;		case 4:			return 0;	    	case 5:				TRACE(("IDE -- finish_dma: PRD size > device transfer size!\n"));			return -1;	}	return 0;}static	int	write_register(void *cookie,int reg,uint8 value){	pci_bus_cookie	*bus_cookie = cookie;	uint16	reg_addr = bus_cookie->pio_reg_addrs[reg];	out8(value,reg_addr);	return 0;}static	int	write_register16(void *cookie,int reg,uint16 value){	pci_bus_cookie	*bus_cookie = cookie;	uint16	reg_addr = bus_cookie->pio_reg_addrs[reg];	out16(value,reg_addr);	return 0;}static	uint8	read_register(void *cookie,int reg){	pci_bus_cookie	*bus_cookie = cookie;  	uint16	reg_addr = bus_cookie->pio_reg_addrs[reg];  	return in8(reg_addr);}static	uint16	read_register16(void *cookie,int reg){	pci_bus_cookie	*bus_cookie = cookie;  	uint16	reg_addr = bus_cookie->pio_reg_addrs[reg];  	return in16(reg_addr);}static	uint8	get_alt_value(void *cookie){	return read_register( cookie,CB_ASTAT );}static	int	transfer_buffer(void *cookie,int reg,void *buffer,size_t size,bool fromMemory){	pci_bus_cookie	*bus_cookie = cookie;  	uint16		reg_addr = bus_cookie->pio_reg_addrs[reg];  	if(fromMemory==false)  	{  		__asm__ __volatile__    		(     			"rep ; outsw" : "=S" (buffer), "=c" (size) : "d" (reg_addr),"0" (buffer),"1" (size)     		);	} 	else 	{  		__asm__ __volatile__    		(     			"rep ; insw" : "=D" (buffer), "=c" (size) : "d" (reg_addr),"0" (buffer),"1" (size)     		);	}	return 0;}static	int	select_drive(void *cookie,int drive){	if(drive==0)		pci_bus.write_register( cookie,CB_DH, CB_DH_DEV0 );	else		pci_bus.write_register( cookie,CB_DH, CB_DH_DEV1 );	return 0;}static	int	delay_on_bus(void *cookie){	pci_bus.get_alt_status(cookie); pci_bus.get_alt_status(cookie);	pci_bus.get_alt_status(cookie); pci_bus.get_alt_status(cookie);	return 0;}static	int	reset_bus(void *cookie,int default_drive){  unsigned char	status;  unsigned char devCtrl;  devCtrl = CB_DC_HD15 | ( CB_DC_NIEN );  pci_bus.write_register(cookie,CB_DC, devCtrl | CB_DC_SRST );  pci_bus.delay_on_bus(cookie);  pci_bus.write_register(cookie,CB_DC, devCtrl );  pci_bus.delay_on_bus(cookie);  if(pci_bus.wait_busy(cookie)==-1)    return -1;  pci_bus.select_drive( cookie,default_drive );  pci_bus.delay_on_bus(cookie);  return 0;}static	int	wait_busy(void *cookie){	int		iterations = 0;	uint8	status; 	while ( 1 )  	{      		status = pci_bus.get_alt_status(cookie);      		if ( ( status & CB_STAT_BSY ) == 0 )         		return 0;      		if ( iterations>10000 )      		{         		return -1;      		}     		iterations++;  	}  	return 0;}static	void	*get_nth_cookie(int channel){	return	bus_cookies[channel];}static	bool	support_dma(void *cookie){	pci_bus_cookie	*bus_cookie = cookie;	return bus_cookie->dma_supported;}static	int	lock(void *cookie){	pci_bus_cookie	*bus_cookie = cookie;	return sem_acquire(bus_cookie->bus_semaphore,1);}static	int	unlock(void *cookie){	pci_bus_cookie	*bus_cookie = cookie;	return sem_release(bus_cookie->bus_semaphore,1);}static	void *get_attached_drive(void *cookie,int drive){	pci_bus_cookie	*bus_cookie = cookie;	return	bus_cookie->drives[drive];}static	void 	*get_attached_drive_cookie(void *cookie,int drive){	pci_bus_cookie	*bus_cookie = cookie;	return	bus_cookie->drive_cookie[drive];}ide_bus	pci_bus ={	"PCI_BUS",	&init,	&read_block,	&write_block,	&setup_dma,	&start_dma,	&finish_dma,	&write_register16,	&write_register,	&read_register16,	&read_register,	&get_alt_value,	&transfer_buffer,	&select_drive,	&reset_bus,	&delay_on_bus,	&wait_busy,	&get_nth_cookie,	&get_attached_drive,	&get_attached_drive_cookie,	&support_dma,	&lock,	&unlock};

⌨️ 快捷键说明

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