📄 comempci.c
字号:
volatile unsigned long *rp; volatile unsigned short *sp; unsigned long r; unsigned short val;#ifdef DEBUGIO printk(KERN_DEBUG "pci_inw(addr=%x)", addr);#endif rp = (volatile unsigned long *) COMEM_BASE; r = COMEM_DA_IORD | COMEM_DA_ADDR(addr) | pci_bwmask[(addr & 0x3)]; rp[LREG(COMEM_DAHBASE)] = r; sp = (volatile unsigned short *) COMEM_BASE; addr = (addr & ~0x3) + (~addr & 0x02); val = sp[WREG(COMEM_PCIBUS + COMEM_DA_OFFSET(addr))]; if (pci_byteswap) val = ((val & 0xff) << 8) | ((val >> 8) & 0xff);#ifdef DEBUGIO printk(KERN_DEBUG "=%04x\n", val);#endif return(val);}/*****************************************************************************/unsigned int pci_inl(unsigned int addr){ volatile unsigned long *rp; volatile unsigned int *lp; unsigned int val;#ifdef DEBUGIO printk(KERN_DEBUG "pci_inl(addr=%x)", addr);#endif rp = (volatile unsigned long *) COMEM_BASE; lp = (volatile unsigned int *) COMEM_BASE; rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IORD | COMEM_DA_ADDR(addr); val = lp[LREG(COMEM_PCIBUS + COMEM_DA_OFFSET(addr))]; if (pci_byteswap) val = (val << 24) | ((val & 0x0000ff00) << 8) | ((val & 0x00ff0000) >> 8) | (val >> 24);#ifdef DEBUGIO printk(KERN_DEBUG "=%08x\n", val);#endif return(val);}/*****************************************************************************/void pci_outsb(void *addr, void *buf, int len){ volatile unsigned long *rp; volatile unsigned char *bp; unsigned char *dp = (unsigned char *) buf; unsigned int a = (unsigned int) addr;#ifdef DEBUGIO printk(KERN_DEBUG "pci_outsb(addr=%x,buf=%x,len=%d)\n", (int)addr, (int)buf, len);#endif rp = (volatile unsigned long *) COMEM_BASE; rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IOWR | COMEM_DA_ADDR(a); a = (a & ~0x3) + (~a & 0x03); bp = (volatile unsigned char *) (COMEM_BASE + COMEM_PCIBUS + COMEM_DA_OFFSET(a)); while (len--) *bp = *dp++;}/*****************************************************************************/void pci_outsw(void *addr, void *buf, int len){ volatile unsigned long *rp; volatile unsigned short *wp; unsigned short w, *dp = (unsigned short *) buf; unsigned int a = (unsigned int) addr;#ifdef DEBUGIO printk(KERN_DEBUG "pci_outsw(addr=%x,buf=%x,len=%d)\n", (int)addr, (int)buf, len);#endif rp = (volatile unsigned long *) COMEM_BASE; rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IOWR | COMEM_DA_ADDR(a); a = (a & ~0x3) + (~a & 0x2); wp = (volatile unsigned short *) (COMEM_BASE + COMEM_PCIBUS + COMEM_DA_OFFSET(a)); while (len--) { w = *dp++; if (pci_byteswap) w = ((w & 0xff) << 8) | ((w >> 8) & 0xff); *wp = w; }}/*****************************************************************************/void pci_outsl(void *addr, void *buf, int len){ volatile unsigned long *rp; volatile unsigned long *lp; unsigned long l, *dp = (unsigned long *) buf; unsigned int a = (unsigned int) addr;#ifdef DEBUGIO printk(KERN_DEBUG "pci_outsl(addr=%x,buf=%x,len=%d)\n", (int)addr, (int)buf, len);#endif rp = (volatile unsigned long *) COMEM_BASE; rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IOWR | COMEM_DA_ADDR(a); lp = (volatile unsigned long *) (COMEM_BASE + COMEM_PCIBUS + COMEM_DA_OFFSET(a)); while (len--) { l = *dp++; if (pci_byteswap) l = (l << 24) | ((l & 0x0000ff00) << 8) | ((l & 0x00ff0000) >> 8) | (l >> 24); *lp = l; }}/*****************************************************************************/void pci_insb(void *addr, void *buf, int len){ volatile unsigned long *rp; volatile unsigned char *bp; unsigned char *dp = (unsigned char *) buf; unsigned int a = (unsigned int) addr;#ifdef DEBUGIO printk(KERN_DEBUG "pci_insb(addr=%x,buf=%x,len=%d)\n", (int)addr, (int)buf, len);#endif rp = (volatile unsigned long *) COMEM_BASE; rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IORD | COMEM_DA_ADDR(a); a = (a & ~0x3) + (~a & 0x03); bp = (volatile unsigned char *) (COMEM_BASE + COMEM_PCIBUS + COMEM_DA_OFFSET(a)); while (len--) *dp++ = *bp;}/*****************************************************************************/void pci_insw(void *addr, void *buf, int len){ volatile unsigned long *rp; volatile unsigned short *wp; unsigned short w, *dp = (unsigned short *) buf; unsigned int a = (unsigned int) addr;#ifdef DEBUGIO printk(KERN_DEBUG "pci_insw(addr=%x,buf=%x,len=%d)\n", (int)addr, (int)buf, len);#endif rp = (volatile unsigned long *) COMEM_BASE; rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IORD | COMEM_DA_ADDR(a); a = (a & ~0x3) + (~a & 0x2); wp = (volatile unsigned short *) (COMEM_BASE + COMEM_PCIBUS + COMEM_DA_OFFSET(a)); while (len--) { w = *wp; if (pci_byteswap) w = ((w & 0xff) << 8) | ((w >> 8) & 0xff); *dp++ = w; }}/*****************************************************************************/void pci_insl(void *addr, void *buf, int len){ volatile unsigned long *rp; volatile unsigned long *lp; unsigned long l, *dp = (unsigned long *) buf; unsigned int a = (unsigned int) addr;#ifdef DEBUGIO printk(KERN_DEBUG "pci_insl(addr=%x,buf=%x,len=%d)\n", (int)addr, (int)buf, len);#endif rp = (volatile unsigned long *) COMEM_BASE; rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IORD | COMEM_DA_ADDR(a); lp = (volatile unsigned long *) (COMEM_BASE + COMEM_PCIBUS + COMEM_DA_OFFSET(a)); while (len--) { l = *lp; if (pci_byteswap) l = (l << 24) | ((l & 0x0000ff00) << 8) | ((l & 0x00ff0000) >> 8) | (l >> 24); *dp++ = l; }}/*****************************************************************************/struct pci_localirqlist { void (*handler)(int, void *, struct pt_regs *); const char *device; void *dev_id;};struct pci_localirqlist pci_irqlist[COMEM_MAXPCI];/*****************************************************************************/int pci_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *device, void *dev_id){ int i;#ifdef DEBUGIO printk(KERN_DEBUG "pci_request_irq(irq=%d,handler=%x,flags=%x,device=%s," "dev_id=%x)\n", irq, (int) handler, (int) flags, device, (int) dev_id);#endif /* Check if this interrupt handler is already lodged */ for (i = 0; (i < COMEM_MAXPCI); i++) { if (pci_irqlist[i].handler == handler) return(0); } /* Find a free spot to put this handler */ for (i = 0; (i < COMEM_MAXPCI); i++) { if (pci_irqlist[i].handler == 0) { pci_irqlist[i].handler = handler; pci_irqlist[i].device = device; pci_irqlist[i].dev_id = dev_id; return(0); } } /* Couldn't fit?? */ return(1);}/*****************************************************************************/void pci_free_irq(unsigned int irq, void *dev_id){ int i;#ifdef DEBUGIO printk(KERN_DEBUG "pci_free_irq(irq=%d,dev_id=%x)\n", irq, (int) dev_id);#endif if (dev_id == (void *) NULL) return; /* Check if this interrupt handler is lodged */ for (i = 0; (i < COMEM_MAXPCI); i++) { if (pci_irqlist[i].dev_id == dev_id) { pci_irqlist[i].handler = NULL; pci_irqlist[i].device = NULL; pci_irqlist[i].dev_id = NULL; break; } }}/*****************************************************************************/void pci_interrupt(int irq, void *id, struct pt_regs *fp){ int i;#ifdef DEBUGIO printk(KERN_DEBUG "pci_interrupt(irq=%d,id=%x,fp=%x)\n", irq, (int) id, (int) fp);#endif for (i = 0; (i < COMEM_MAXPCI); i++) { if (pci_irqlist[i].handler) (*pci_irqlist[i].handler)(irq,pci_irqlist[i].dev_id,fp); }}/*****************************************************************************//* * The shared memory region is broken up into contiguous 512 byte * regions for easy allocation... This is not an optimal solution * but it makes allocation and freeing regions really easy. */#define PCI_MEMSLOTSIZE 512#define PCI_MEMSLOTS (COMEM_SHMEMSIZE / PCI_MEMSLOTSIZE)char pci_shmemmap[PCI_MEMSLOTS];void *pci_bmalloc(int size){ int i, j, nrslots;#ifdef DEBUGIO printk(KERN_DEBUG "pci_bmalloc(size=%d)\n", size);#endif if (size <= 0) return((void *) NULL); nrslots = (size - 1) / PCI_MEMSLOTSIZE; for (i = 0; (i < (PCI_MEMSLOTS-nrslots)); i++) { if (pci_shmemmap[i] == 0) { for (j = i+1; (j < (i+nrslots)); j++) { if (pci_shmemmap[j]) goto restart; } for (j = i; (j <= i+nrslots); j++) pci_shmemmap[j] = 1; break; }restart: } return((void *) (COMEM_BASE + COMEM_SHMEM + (i * PCI_MEMSLOTSIZE)));}/*****************************************************************************/void pci_bmfree(void *mp, int size){ int i, j, nrslots;#ifdef DEBUGIO printk(KERN_DEBUG "pci_bmfree(mp=%x,size=%d)\n", (int) mp, size);#endif nrslots = size / PCI_MEMSLOTSIZE; i = (((unsigned long) mp) - (COMEM_BASE + COMEM_SHMEM)) / PCI_MEMSLOTSIZE; for (j = i; (j < (i+nrslots)); j++) pci_shmemmap[j] = 0;}/*****************************************************************************/unsigned long pci_virt_to_bus(volatile void *address){ unsigned long l;#ifdef DEBUGIO printk(KERN_DEBUG "pci_virt_to_bus(address=%x)", (int) address);#endif l = ((unsigned long) address) - COMEM_BASE;#ifdef DEBUGIO printk(KERN_DEBUG "=%x\n", (int) (l+pci_shmemaddr));#endif return(l + pci_shmemaddr);}/*****************************************************************************/void *pci_bus_to_virt(unsigned long address){ unsigned long l;#ifdef DEBUGIO printk(KERN_DEBUG "pci_bus_to_virt(address=%x)", (int) address);#endif l = address - pci_shmemaddr;#ifdef DEBUGIO printk(KERN_DEBUG "=%x\n", (int) (address + COMEM_BASE));#endif return((void *) (address + COMEM_BASE));}/*****************************************************************************/void pci_bmcpyto(void *dst, void *src, int len){ unsigned long *dp, *sp, val; unsigned char *dcp, *scp; int i, j;#ifdef DEBUGIO printk(KERN_DEBUG "pci_bmcpyto(dst=%x,src=%x,len=%d)\n", (int)dst, (int)src, len);#endif dp = (unsigned long *) dst; sp = (unsigned long *) src; i = len >> 2;#if 0 printk(KERN_INFO "DATA:"); scp = (unsigned char *) sp; for (i = 0; (i < len); i++) { if ((i % 16) == 0) printk(KERN_INFO "\n%04x: ", i); printk(KERN_INFO "%02x ", *scp++); } printk(KERN_INFO "\n");#endif for (j = 0; (i >= 0); i--, j++) { val = *sp++; val = (val << 24) | ((val & 0x0000ff00) << 8) | ((val & 0x00ff0000) >> 8) | (val >> 24); *dp++ = val; } if (len & 0x3) { dcp = (unsigned char *) dp; scp = ((unsigned char *) sp) + 3; for (i = 0; (i < (len & 0x3)); i++) *dcp++ = *scp--; }}/*****************************************************************************/void pci_bmcpyfrom(void *dst, void *src, int len){ unsigned long *dp, *sp, val; unsigned char *dcp, *scp; int i;#ifdef DEBUGIO printk(KERN_DEBUG "pci_bmcpyfrom(dst=%x,src=%x,len=%d)\n",(int)dst,(int)src,len);#endif dp = (unsigned long *) dst; sp = (unsigned long *) src; i = len >> 2; for (; (i >= 0); i--) { val = *sp++; val = (val << 24) | ((val & 0x0000ff00) << 8) | ((val & 0x00ff0000) >> 8) | (val >> 24); *dp++ = val; } if (len & 0x3) { dcp = ((unsigned char *) dp) + 3; scp = (unsigned char *) sp; for (i = 0; (i < (len & 0x3)); i++) *dcp++ = *scp--; }#if 0 printk(KERN_INFO "DATA:"); dcp = (unsigned char *) dst; for (i = 0; (i < len); i++) { if ((i % 16) == 0) printk(KERN_INFO "\n%04x: ", i); printk(KERN_INFO "%02x ", *dcp++); } printk(KERN_INFO "\n");#endif}/*****************************************************************************/void *pci_alloc_consistent(struct pci_dev *dev, size_t size, dma_addr_t *dma_addr){ void *mp; if ((mp = pci_bmalloc(size)) != NULL) { dma_addr = mp - (COMEM_BASE + COMEM_SHMEM); return(mp); } *dma_addr = (dma_addr_t) NULL; return(NULL);}/*****************************************************************************/void pci_free_consistent(struct pci_dev *dev, size_t size, void *cpu_addr, dma_addr_t dma_addr){ pci_bmfree(cpu_addr, size);}/*****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -