linio.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:14k
- /*
- * 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"
- static
- int log_on=0;
- int Divasdevflag = 0;
- //spinlock_t diva_lock = SPIN_LOCK_UNLOCKED;
- static
- ux_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 1
- void *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 UxPciConfigWriten");
- }
- }
- 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 UxPciConfigReadn");
- }
- }
- 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);
- }