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

📄 linio.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
字号:
/* * Copyright (C) Eicon Technology Corporation, 2000. * * Eicon File Revision :    1.16   * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. * */#define N_DATA#include <asm/io.h>#include <asm/system.h>#include <linux/slab.h>#include <linux/pci.h>#include <linux/delay.h>#undef N_DATA#include "uxio.h"staticint log_on=0;int		Divasdevflag = 0;//spinlock_t diva_lock = SPIN_LOCK_UNLOCKED;staticux_diva_card_t card_pool[MAX_CARDS];void UxPause(long int ms){	int timeout = jiffies + ((ms * HZ) / 1000);	while (time_before(jiffies, timeout));}int UxCardHandleGet(ux_diva_card_t **card, dia_card_t *cfg){	int 		i;	ux_diva_card_t	*c;	if (cfg->bus_type != DIA_BUS_TYPE_PCI)	{		DPRINTF(("divas hw: type not PCI (%d)", cfg->bus_type));		return -1;	}	for (i = 0; (i < DIM(card_pool)) && (card_pool[i].in_use); i++)	{		;	}	if (i == DIM(card_pool))	{		DPRINTF(("divas hw: card_pool exhausted"));		return -1;	}	c = *card = &card_pool[i];	switch (cfg->bus_type)	{	case DIA_BUS_TYPE_PCI:		c->bus_num = cfg->bus_num;		c->func_num = cfg->func_num;		c->io_base = cfg->io_base;		c->reset_base = cfg->reset_base;		c->card_type    = cfg->card_type;		c->mapped = NULL;		c->slot 	= cfg->slot;		c->irq 		= (int) cfg->irq;		c->pDRAM    	= cfg->memory[DIVAS_RAM_MEMORY];		c->pDEVICES 	= cfg->memory[DIVAS_REG_MEMORY];		c->pCONFIG  	= cfg->memory[DIVAS_CFG_MEMORY];		c->pSHARED  	= cfg->memory[DIVAS_SHARED_MEMORY];		c->pCONTROL  	= cfg->memory[DIVAS_CTL_MEMORY];	/*		c->bus_type 	= DIA_BUS_TYPE_PCI;		c->bus_num 	= cfg->bus_num & 0x3f;		c->slot 	= cfg->slot;		c->irq 		= (int) cfg->irq;		c->int_priority = (int) cfg->int_priority;		c->card_type    = cfg->card_type;		c->io_base      = cfg->io_base;		c->reset_base   = cfg->reset_base;		c->pDRAM    	= cfg->memory[DIVAS_RAM_MEMORY];		c->pDEVICES 	= cfg->memory[DIVAS_REG_MEMORY];		c->pCONFIG  	= cfg->memory[DIVAS_CFG_MEMORY];		c->pSHARED  	= cfg->memory[DIVAS_SHARED_MEMORY];		DPRINTF(("divas hw: pDRAM is 0x%x", c->pDRAM));		DPRINTF(("divas hw: pSHARED is 0x%x", c->pSHARED));		DPRINTF(("divas hw: pCONFIG is 0x%x", c->pCONFIG));		c->cm_key		= cm_getbrdkey("Divas", cfg->card_id);*/		break;	default:		break;	}	c->in_use = TRUE;	return 0;}void UxCardHandleFree(ux_diva_card_t *card){	card->in_use = FALSE;}#define PLX_IOBASE 0#define DIVAS_IOBASE 1void *UxCardMemAttach(ux_diva_card_t *card, int id){	if (card->card_type == DIA_CARD_TYPE_DIVA_SERVER)	{		switch (id)		{		case DIVAS_SHARED_MEMORY:			card->mapped = card->pSHARED;			return card->pSHARED;			break;		case DIVAS_RAM_MEMORY:			card->mapped = card->pDRAM;			return card->pDRAM;			break;		case DIVAS_REG_MEMORY:			card->mapped = card->pDEVICES;			return card->pDEVICES;			break;		case DIVAS_CFG_MEMORY:			card->mapped = card->pCONFIG;			return card->pCONFIG;			break;		default:			ASSERT(FALSE);			card->mapped = NULL;			return (void *) 0;		}	}	else if (card->card_type == DIA_CARD_TYPE_DIVA_SERVER_B)	{		switch (id)		{		case PLX_IOBASE:			return (void *) card->reset_base;			break;		case DIVAS_IOBASE:			return (void *) card->io_base;			break;		default:			ASSERT(FALSE);			return 0;		}	}		else if (card->card_type == DIA_CARD_TYPE_DIVA_SERVER_Q)	{		switch (id)		{		case DIVAS_SHARED_MEMORY:			card->mapped = card->pSHARED;			return card->pSHARED;			break;		case DIVAS_RAM_MEMORY:			card->mapped = card->pDRAM;			return card->pDRAM;			break;		case DIVAS_REG_MEMORY:			card->mapped = (void *) card->io_base;			return (void *) card->io_base;			break;		case DIVAS_CTL_MEMORY:			card->mapped = card->pCONTROL;			return card->pCONTROL;			break;		default:			// ASSERT(FALSE);			DPRINTF(("divas: Trying to attach to mem %d", id));			card->mapped = NULL;			return (void *) 0;		}	} else		DPRINTF(("divas: Tried to attach to unknown card"));	/* Unknown card type */	return NULL;}void UxCardMemDetach(ux_diva_card_t *card, void *address){	return; // Just a place holder. No un-mapping done.}void UxCardLog(int turn_on){	log_on = turn_on;}/* * Control Register I/O Routines to be performed on Attached I/O ports */void UxCardPortIoOut(ux_diva_card_t *card, void *AttachedBase, int offset, byte the_byte){	word base = (word) (dword) AttachedBase;	base += offset;	outb(the_byte, base);}void UxCardPortIoOutW(ux_diva_card_t *card, void *AttachedBase, int offset, word the_word){	word base = (word) (dword) AttachedBase;	base += offset;	outw(the_word, base);}void UxCardPortIoOutD(ux_diva_card_t *card, void *AttachedBase, int offset, dword the_dword){	word base = (word) (dword) AttachedBase;	base += offset;	outl(the_dword, base);}byte UxCardPortIoIn(ux_diva_card_t *card, void *AttachedBase, int offset){	word base = (word) (dword) AttachedBase;	base += offset;	return inb(base);}word UxCardPortIoInW(ux_diva_card_t *card, void *AttachedBase, int offset){	word base = (word) (dword) AttachedBase;	base += offset;	return inw(base);}/* * Memory mapped card I/O functions */byte UxCardMemIn(ux_diva_card_t *card, void *address){	byte	b;	volatile byte* t = (byte*)address;	b = *t;	if (log_on)	{		byte *a = address;		a -= (int) card->mapped;		DPRINTF(("divas hw: read 0x%02x from 0x%x (memory mapped)", b & 0xff, a));    	}    return(b); }word UxCardMemInW(ux_diva_card_t *card, void *address){	word	w;	volatile word* t = (word*)address;    w = *t;	if (log_on)    {		byte *a = address;		a -= (int) card->mapped;		DPRINTF(("divas hw: read 0x%04x from 0x%x (memory mapped)", w & 0xffff, a));    }    return (w);}dword UxCardMemInD(ux_diva_card_t *card, void *address){	dword	dw;	volatile dword* t = (dword*)address;    dw = *t;	if (log_on)    {		byte *a = address;		a -= (int) card->mapped;		DPRINTF(("divas hw: read 0x%08x from 0x%x (memory mapped)", dw, a));    }    return (dw);}void UxCardMemInBuffer(ux_diva_card_t *card, void *address, void *buffer, int length){	volatile byte *pSource = address;	byte *pDest = buffer;	while (length--)	{		*pDest++ = *pSource++;	}	if (log_on)    {		byte *a = address;		a -= (int) card->mapped;		pDest = buffer;		DPRINTF(("divas hw: read %02x %02x %02x %02x %02x %02x %02x %02x from 0x%x (memory mapped)", 		pDest[0] & 0xff, pDest[1] & 0xff, pDest[2] & 0xff, pDest[3] & 0xff,		pDest[4] & 0xff, pDest[5] & 0xff, pDest[6] & 0xff, pDest[7] & 0xff,		a));    }    return;}void UxCardMemOut(ux_diva_card_t *card, void *address, byte data){	volatile byte* t = (byte*)address;	if (log_on)	{		byte *a = address;		a -= (int) card->mapped;		DPRINTF(("divas hw: wrote 0x%02x to 0x%x (memory mapped)", data & 0xff, a));	}	*t = data;    	return;}void UxCardMemOutW(ux_diva_card_t *card, void *address, word data){	volatile word* t = (word*)address;	if (log_on)	{		byte *a = address;		a -= (int) card->mapped;		DPRINTF(("divas hw: wrote 0x%04x to 0x%x (memory mapped)", data & 0xffff, a));	}	*t = data;    return;}void UxCardMemOutD(ux_diva_card_t *card, void *address, dword data){	volatile dword* t = (dword*)address;	if (log_on)	{		byte *a = address;		a -= (int) card->mapped;		DPRINTF(("divas hw: wrote 0x%08x to 0x%x (memory mapped)", data, a));	}	*t = data;    return;}void UxCardMemOutBuffer(ux_diva_card_t *card, void *address, void *buffer, int length){	byte 	*pSource = buffer;	byte	*pDest = address;	while (length--)	{		*pDest++ = *pSource++;	}	if (log_on)    {		byte *a = address;		a -= (int) card->mapped;		pDest = buffer;		DPRINTF(("divas hw: wrote %02x %02x %02x %02x %02x %02x %02x %02x to 0x%x (memory mapped)", 		pDest[0] & 0xff, pDest[1] & 0xff, pDest[2] & 0xff, pDest[3] & 0xff,		pDest[4] & 0xff, pDest[5] & 0xff, pDest[6] & 0xff, pDest[7] & 0xff,		a));    }    return;}/* * Memory mapped card I/O functions */byte UxCardIoIn(ux_diva_card_t *card, void *AttachedDivasIOBase, void *address){	byte the_byte;    outb(0xFF, card->io_base + 0xC);	outw((word) (dword) address, card->io_base + 4);	the_byte = inb(card->io_base);	if (log_on)    {		DPRINTF(("divas hw: read 0x%02x from 0x%x (I/O mapped)", 					the_byte & 0xff, address));    }    	return the_byte;}word UxCardIoInW(ux_diva_card_t *card, void *AttachedDivasIOBase, void *address){	word the_word;	outb(0xFF, card->io_base + 0xC);	outw((word) (dword) address, card->io_base + 4);	the_word = inw(card->io_base);	if (log_on)    {		DPRINTF(("divas hw: read 0x%04x from 0x%x (I/O mapped)", 					the_word & 0xffff, address));    }	return the_word;}dword UxCardIoInD(ux_diva_card_t *card, void *AttachedDivasIOBase, void *address){	dword the_dword;	outb(0xFF, card->io_base + 0xC);	outw((word) (dword) address, card->io_base + 4);	the_dword = inl(card->io_base);	if (log_on)    {		DPRINTF(("divas hw: read 0x%08x from 0x%x (I/O mapped)", 					the_dword, address));    }    return the_dword;}void UxCardIoInBuffer(ux_diva_card_t *card, void *AttachedDivasIOBase, void *address, void *buffer, int length){	byte *pSource = address;	byte *pDest = buffer;	if ((word) (dword) address & 0x1)	{		outb(0xFF, card->io_base + 0xC);		outw((word) (dword) pSource, card->io_base + 4);		*pDest = (byte) inb(card->io_base);		pDest++;		pSource++;		length--;		if (!length)        {            return;        }    }	outb(0xFF, card->io_base + 0xC);	outw((word) (dword) pSource, card->io_base + 4);	insw(card->io_base, (word *)pDest,length%2 ? (length+1)>>1 : length>>1);	if (log_on)    {		pDest = buffer;		DPRINTF(("divas hw: read %02x %02x %02x %02x %02x %02x %02x %02x from 0x%x (I/O mapped)", 		pDest[0] & 0xff, pDest[1] & 0xff, pDest[2] & 0xff, pDest[3] & 0xff,		pDest[4] & 0xff, pDest[5] & 0xff, pDest[6] & 0xff, pDest[7] & 0xff,		address));    }    return;}/* Output */void UxCardIoOut(ux_diva_card_t *card, void *AttachedDivasIOBase, void *address, byte data){	if (log_on)    {		DPRINTF(("divas hw: wrote 0x%02x to 0x%x (I/O mapped)", 					data & 0xff, address));    }	outb(0xFF, card->io_base + 0xC);	outw((word) (dword) address, card->io_base + 4);	outb((byte) data & 0xFF, card->io_base);    return;}void UxCardIoOutW(ux_diva_card_t *card, void *AttachedDivasIOBase, void *address, word data){	if (log_on)    {		DPRINTF(("divas hw: wrote 0x%04x to 0x%x (I/O mapped)", 					data & 0xffff, address));    }	outb(0xFF, card->io_base + 0xC);	outw((word) (dword) address, card->io_base + 4);	outw((word) data & 0xFFFF, card->io_base);    return;}void UxCardIoOutD(ux_diva_card_t *card, void *AttachedDivasIOBase, void *address, dword data){	if (log_on)    {		DPRINTF(("divas hw: wrote 0x%08x to 0x%x (I/O mapped)", data, address));    }	outb(0xFF, card->io_base + 0xC);	outw((word) (dword) address, card->io_base + 4);	outl((dword) data & 0xFFFFFFFF, card->io_base);    return;}void UxCardIoOutBuffer(ux_diva_card_t *card, void *AttachedDivasIOBase, void *address, void *buffer, int length){	byte 	*pSource = buffer;	byte	*pDest = address;	if ((word) (dword) address & 1)	{		outb(0xFF, card->io_base + 0xC);		outw((word) (dword) pDest, card->io_base + 4);		outb(*pSource, card->io_base);		pSource++;		pDest++;		length--;		if (!length)        {			return;        }	}    outb(0xFF, card->io_base + 0xC);	outw((word) (dword) pDest, card->io_base + 4);	outsw(card->io_base, (word *)pSource, length%2 ? (length+1)>>1 : length>>1);	if (log_on)    {		pDest = buffer;		DPRINTF(("divas hw: wrote %02x %02x %02x %02x %02x %02x %02x %02x to 0x%x (I/O mapped)", 		pDest[0] & 0xff, pDest[1] & 0xff, pDest[2] & 0xff, pDest[3] & 0xff,		pDest[4] & 0xff, pDest[5] & 0xff, pDest[6] & 0xff, pDest[7] & 0xff,		address));    }    return;}void 	Divasintr(int arg, void *unused, struct pt_regs *unused_regs){	int i;	card_t *card = NULL;	ux_diva_card_t *ux_ref = NULL;	for (i = 0; i < DivasCardNext; i++)	{		if (arg == DivasCards[i].cfg.irq)		{			card = &DivasCards[i];			ux_ref = card->hw;				if ((ux_ref) && (card->is_live))			{				(*ux_ref->user_isr)(ux_ref->user_isr_arg);				}			else 			{				DPRINTF(("divas: ISR couldn't locate card"));			}		}	}	return;}int UxIsrInstall(ux_diva_card_t *card, isr_fn_t *isr_fn, void *isr_arg){	int result;        card->user_isr = isr_fn;        card->user_isr_arg = isr_arg;	result = request_irq(card->irq, Divasintr, SA_INTERRUPT | SA_SHIRQ, "Divas", (void *) isr_arg);	return result;}void UxIsrRemove(ux_diva_card_t *card, void *dev_id){	free_irq(card->irq, card->user_isr_arg);}void UxPciConfigWrite(ux_diva_card_t *card, int size, int offset, void *value){	switch (size)	{	case sizeof(byte):		pcibios_write_config_byte(card->bus_num, card->func_num, offset, * (byte *) value);		break;	case sizeof(word):		pcibios_write_config_word(card->bus_num, card->func_num, offset, * (word *) value);		break;	case sizeof(dword):		pcibios_write_config_dword(card->bus_num, card->func_num, offset, * (dword *) value);		break;	default:		printk(KERN_WARNING "Divas: Invalid size in UxPciConfigWrite\n");	}}void UxPciConfigRead(ux_diva_card_t *card, int size, int offset, void *value){	switch (size)	{	case sizeof(byte):		pcibios_read_config_byte(card->bus_num, card->func_num, offset, (byte *) value);		break;	case sizeof(word):		pcibios_read_config_word(card->bus_num, card->func_num, offset, (word *) value);		break;	case sizeof(dword):		pcibios_read_config_dword(card->bus_num, card->func_num, offset, (unsigned int *) value);		break;	default:		printk(KERN_WARNING "Divas: Invalid size in UxPciConfigRead\n");	}}void *UxAlloc(unsigned int size){	void *m;	m = kmalloc(size, GFP_ATOMIC);	return m;}void UxFree(void *ptr){	kfree(ptr);}long UxCardLock(ux_diva_card_t *card){	unsigned long flags; 	//spin_lock_irqsave(&diva_lock, flags);		save_flags(flags);	cli();	return flags;	}void UxCardUnlock(ux_diva_card_t *card, long ipl){	//spin_unlock_irqrestore(&diva_lock, ipl);	restore_flags(ipl);}dword UxTimeGet(void){	return jiffies;}long UxInterlockedIncrement(ux_diva_card_t *card, long *dst){	register volatile long *p;	register long ret;	int ipl;	p =dst;		ipl = UxCardLock(card);	*p += 1;	ret = *p;	UxCardUnlock(card,ipl);	return(ret);}long UxInterlockedDecrement(ux_diva_card_t *card, long *dst){	register volatile long *p;	register long ret;	int ipl;	p =dst;		ipl = UxCardLock(card);	*p -= 1;	ret = *p;	UxCardUnlock(card,ipl);	return(ret);}

⌨️ 快捷键说明

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