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

📄 c4.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * $Id: c4.c,v 1.20.6.1 2000/11/28 12:02:45 kai Exp $ *  * Module for AVM C4 card. *  * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de) *  * $Log: c4.c,v $ * Revision 1.20.6.1  2000/11/28 12:02:45  kai * MODULE_DEVICE_TABLE for 2.4 * * Revision 1.20.2.2  2000/11/26 17:47:53  kai * added PCI_DEV_TABLE for 2.4 * * Revision 1.20.2.1  2000/11/26 17:14:19  kai * fix device ids * also needs patches to include/linux/pci_ids.h * * Revision 1.20  2000/11/23 20:45:14  kai * fixed module_init/exit stuff * Note: compiled-in kernel doesn't work pre 2.2.18 anymore. * * Revision 1.19  2000/11/19 17:02:47  kai * compatibility cleanup - part 3 * * Revision 1.18  2000/11/01 14:05:02  calle * - use module_init/module_exit from linux/init.h. * - all static struct variables are initialized with "membername:" now. * - avm_cs.c, let it work with newer pcmcia-cs. * * Revision 1.17  2000/10/10 17:44:19  kai * changes from/for 2.2.18 * * Revision 1.16  2000/08/20 07:30:13  keil * changes for 2.4 * * Revision 1.15  2000/08/08 09:24:19  calle * calls to pci_enable_device surounded by #ifndef COMPAT_HAS_2_2_PCI * * Revision 1.14  2000/08/04 12:20:08  calle * - Fix unsigned/signed warning in the right way ... * * Revision 1.13  2000/07/20 10:21:21  calle * Bugfix: driver will not be unregistered, if not cards were detected. *         this result in an oops in kcapi.c * * Revision 1.12  2000/06/19 16:51:53  keil * don't free skb in irq context * * Revision 1.11  2000/06/19 15:11:24  keil * avoid use of freed structs * changes from 2.4.0-ac21 * * Revision 1.10  2000/05/29 12:29:18  keil * make pci_enable_dev compatible to 2.2 kernel versions * * Revision 1.9  2000/05/19 15:43:22  calle * added calls to pci_device_start(). * * Revision 1.8  2000/04/03 16:38:05  calle * made suppress_pollack static. * * Revision 1.7  2000/04/03 13:29:24  calle * make Tim Waugh happy (module unload races in 2.3.99-pre3). * no real problem there, but now it is much cleaner ... * * Revision 1.6  2000/03/17 12:21:08  calle * send patchvalues now working. * * Revision 1.5  2000/03/16 15:21:03  calle * Bugfix in c4_remove: loop 5 times instead of 4 :-( * * Revision 1.4  2000/02/02 18:36:03  calle * - Modules are now locked while init_module is running * - fixed problem with memory mapping if address is not aligned * * Revision 1.3  2000/01/25 14:37:39  calle * new message after successfull detection including card revision and * used resources. * * Revision 1.2  2000/01/21 20:52:58  keil * pci_find_subsys as local function for 2.2.X kernel * * Revision 1.1  2000/01/20 10:51:37  calle * Added driver for C4. * * */#include <linux/config.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/skbuff.h>#include <linux/delay.h>#include <linux/mm.h>#include <linux/interrupt.h>#include <linux/ioport.h>#include <linux/pci.h>#include <linux/capi.h>#include <linux/init.h>#include <asm/io.h>#include <asm/uaccess.h>#include <linux/netdevice.h>#include "capicmd.h"#include "capiutil.h"#include "capilli.h"#include "avmcard.h"static char *revision = "$Revision: 1.20.6.1 $";#undef CONFIG_C4_DEBUG#undef CONFIG_C4_POLLDEBUG/* ------------------------------------------------------------- */static int suppress_pollack;static struct pci_device_id c4_pci_tbl[] __initdata = {	{ PCI_VENDOR_ID_DEC,PCI_DEVICE_ID_DEC_21285, PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_C4 },	{ }			/* Terminating entry */};MODULE_DEVICE_TABLE(pci, c4_pci_tbl);MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>");MODULE_PARM(suppress_pollack, "0-1i");/* ------------------------------------------------------------- */static struct capi_driver_interface *di;/* ------------------------------------------------------------- */static void c4_dispatch_tx(avmcard *card);/* ------------------------------------------------------------- */#define DC21285_DRAM_A0MR	0x40000000#define DC21285_DRAM_A1MR	0x40004000#define DC21285_DRAM_A2MR	0x40008000#define DC21285_DRAM_A3MR	0x4000C000#define	CAS_OFFSET	0x88#define DC21285_ARMCSR_BASE	0x42000000#define	PCI_OUT_INT_STATUS	0x30#define	PCI_OUT_INT_MASK	0x34#define	MAILBOX_0		0x50#define	MAILBOX_1		0x54#define	MAILBOX_2		0x58#define	MAILBOX_3		0x5C#define	DOORBELL		0x60#define	DOORBELL_SETUP		0x64#define CHAN_1_CONTROL		0x90#define CHAN_2_CONTROL		0xB0#define DRAM_TIMING		0x10C#define DRAM_ADDR_SIZE_0	0x110#define DRAM_ADDR_SIZE_1	0x114#define DRAM_ADDR_SIZE_2	0x118#define DRAM_ADDR_SIZE_3	0x11C#define	SA_CONTROL		0x13C#define	XBUS_CYCLE		0x148#define	XBUS_STROBE		0x14C#define	DBELL_PCI_MASK		0x150#define DBELL_SA_MASK		0x154#define SDRAM_SIZE		0x1000000/* ------------------------------------------------------------- */#define	MBOX_PEEK_POKE		MAILBOX_0#define DBELL_ADDR		0x01#define DBELL_DATA		0x02#define DBELL_RNWR		0x40#define DBELL_INIT		0x80/* ------------------------------------------------------------- */#define	MBOX_UP_ADDR		MAILBOX_0#define	MBOX_UP_LEN		MAILBOX_1#define	MBOX_DOWN_ADDR		MAILBOX_2#define	MBOX_DOWN_LEN		MAILBOX_3#define	DBELL_UP_HOST		0x00000100#define	DBELL_UP_ARM		0x00000200#define	DBELL_DOWN_HOST		0x00000400#define	DBELL_DOWN_ARM		0x00000800#define	DBELL_RESET_HOST	0x40000000#define	DBELL_RESET_ARM		0x80000000/* ------------------------------------------------------------- */#define	DRAM_TIMING_DEF		0x001A01A5#define DRAM_AD_SZ_DEF0		0x00000045#define DRAM_AD_SZ_NULL		0x00000000#define SA_CTL_ALLRIGHT		0x64AA0271#define	INIT_XBUS_CYCLE		0x100016DB#define	INIT_XBUS_STROBE	0xF1F1F1F1/* ------------------------------------------------------------- */#define	RESET_TIMEOUT		(15*HZ)	/* 15 sec */#define	PEEK_POKE_TIMEOUT	(HZ/10)	/* 0.1 sec *//* ------------------------------------------------------------- */#define c4outmeml(addr, value)	writel(value, addr)#define c4inmeml(addr)	readl(addr)#define c4outmemw(addr, value)	writew(value, addr)#define c4inmemw(addr)	readw(addr)#define c4outmemb(addr, value)	writeb(value, addr)#define c4inmemb(addr)	readb(addr)/* ------------------------------------------------------------- */static inline int wait_for_doorbell(avmcard *card, unsigned long t){	unsigned long stop;	stop = jiffies + t;	while (c4inmeml(card->mbase+DOORBELL) != 0xffffffff) {		if (!time_before(jiffies, stop))			return -1;	}	return 0;}static int c4_poke(avmcard *card,  unsigned long off, unsigned long value){	if (wait_for_doorbell(card, HZ/10) < 0)		return -1;		c4outmeml(card->mbase+MBOX_PEEK_POKE, off);	c4outmeml(card->mbase+DOORBELL, DBELL_ADDR);	if (wait_for_doorbell(card, HZ/10) < 0)		return -1;	c4outmeml(card->mbase+MBOX_PEEK_POKE, value);	c4outmeml(card->mbase+DOORBELL, DBELL_DATA | DBELL_ADDR);	return 0;}static int c4_peek(avmcard *card,  unsigned long off, unsigned long *valuep){	if (wait_for_doorbell(card, HZ/10) < 0)		return -1;	c4outmeml(card->mbase+MBOX_PEEK_POKE, off);	c4outmeml(card->mbase+DOORBELL, DBELL_RNWR | DBELL_ADDR);	if (wait_for_doorbell(card, HZ/10) < 0)		return -1;	*valuep = c4inmeml(card->mbase+MBOX_PEEK_POKE);	return 0;}/* ------------------------------------------------------------- */static int c4_load_t4file(avmcard *card, capiloaddatapart * t4file){	__u32 val;	unsigned char *dp;	int left, retval;	__u32 loadoff = 0;	dp = t4file->data;	left = t4file->len;	while (left >= sizeof(__u32)) {	        if (t4file->user) {			retval = copy_from_user(&val, dp, sizeof(val));			if (retval)				return -EFAULT;		} else {			memcpy(&val, dp, sizeof(val));		}		if (c4_poke(card, loadoff, val)) {			printk(KERN_ERR "%s: corrupted firmware file ?\n",					card->name);			return -EIO;		}		left -= sizeof(__u32);		dp += sizeof(__u32);		loadoff += sizeof(__u32);	}	if (left) {		val = 0;		if (t4file->user) {			retval = copy_from_user(&val, dp, left);			if (retval)				return -EFAULT;		} else {			memcpy(&val, dp, left);		}		if (c4_poke(card, loadoff, val)) {			printk(KERN_ERR "%s: corrupted firmware file ?\n",					card->name);			return -EIO;		}	}	return 0;}/* ------------------------------------------------------------- */static inline void _put_byte(void **pp, __u8 val){	__u8 *s = *pp;	*s++ = val;	*pp = s;}static inline void _put_word(void **pp, __u32 val){	__u8 *s = *pp;	*s++ = val & 0xff;	*s++ = (val >> 8) & 0xff;	*s++ = (val >> 16) & 0xff;	*s++ = (val >> 24) & 0xff;	*pp = s;}static inline void _put_slice(void **pp, unsigned char *dp, unsigned int len){	unsigned i = len;	_put_word(pp, i);	while (i-- > 0)		_put_byte(pp, *dp++);}static inline __u8 _get_byte(void **pp){	__u8 *s = *pp;	__u8 val;	val = *s++;	*pp = s;	return val;}static inline __u32 _get_word(void **pp){	__u8 *s = *pp;	__u32 val;	val = *s++;	val |= (*s++ << 8);	val |= (*s++ << 16);	val |= (*s++ << 24);	*pp = s;	return val;}static inline __u32 _get_slice(void **pp, unsigned char *dp){	unsigned int len, i;	len = i = _get_word(pp);	while (i-- > 0) *dp++ = _get_byte(pp);	return len;}/* ------------------------------------------------------------- */static void c4_reset(avmcard *card){	unsigned long stop;	c4outmeml(card->mbase+DOORBELL, DBELL_RESET_ARM);	stop = jiffies + HZ*10;	while (c4inmeml(card->mbase+DOORBELL) != 0xffffffff) {		if (!time_before(jiffies, stop))			return;		c4outmeml(card->mbase+DOORBELL, DBELL_ADDR);	}	c4_poke(card, DC21285_ARMCSR_BASE + CHAN_1_CONTROL, 0);	c4_poke(card, DC21285_ARMCSR_BASE + CHAN_2_CONTROL, 0);}/* ------------------------------------------------------------- */static int c4_detect(avmcard *card){	unsigned long stop, dummy;	c4outmeml(card->mbase+PCI_OUT_INT_MASK, 0x0c);	if (c4inmeml(card->mbase+PCI_OUT_INT_MASK) != 0x0c)		return	1;	c4outmeml(card->mbase+DOORBELL, DBELL_RESET_ARM);	stop = jiffies + HZ*10;	while (c4inmeml(card->mbase+DOORBELL) != 0xffffffff) {		if (!time_before(jiffies, stop))			return 2;		c4outmeml(card->mbase+DOORBELL, DBELL_ADDR);	}	c4_poke(card, DC21285_ARMCSR_BASE + CHAN_1_CONTROL, 0);	c4_poke(card, DC21285_ARMCSR_BASE + CHAN_2_CONTROL, 0);	c4outmeml(card->mbase+MAILBOX_0, 0x55aa55aa);	if (c4inmeml(card->mbase+MAILBOX_0) != 0x55aa55aa) return 3;	c4outmeml(card->mbase+MAILBOX_0, 0xaa55aa55);	if (c4inmeml(card->mbase+MAILBOX_0) != 0xaa55aa55) return 4;	if (c4_poke(card, DC21285_ARMCSR_BASE+DBELL_SA_MASK, 0)) return 5;	if (c4_poke(card, DC21285_ARMCSR_BASE+DBELL_PCI_MASK, 0)) return 6;	if (c4_poke(card, DC21285_ARMCSR_BASE+SA_CONTROL, SA_CTL_ALLRIGHT))		return 7;	if (c4_poke(card, DC21285_ARMCSR_BASE+XBUS_CYCLE, INIT_XBUS_CYCLE))		return 8;	if (c4_poke(card, DC21285_ARMCSR_BASE+XBUS_STROBE, INIT_XBUS_STROBE))		return 8;	if (c4_poke(card, DC21285_ARMCSR_BASE+DRAM_TIMING, 0)) return 9;        mdelay(1);	if (c4_peek(card, DC21285_DRAM_A0MR, &dummy)) return 10;	if (c4_peek(card, DC21285_DRAM_A1MR, &dummy)) return 11;	if (c4_peek(card, DC21285_DRAM_A2MR, &dummy)) return 12;	if (c4_peek(card, DC21285_DRAM_A3MR, &dummy)) return 13;	if (c4_poke(card, DC21285_DRAM_A0MR+CAS_OFFSET, 0)) return 14;	if (c4_poke(card, DC21285_DRAM_A1MR+CAS_OFFSET, 0)) return 15;	if (c4_poke(card, DC21285_DRAM_A2MR+CAS_OFFSET, 0)) return 16;	if (c4_poke(card, DC21285_DRAM_A3MR+CAS_OFFSET, 0)) return 17;        mdelay(1);	if (c4_poke(card, DC21285_ARMCSR_BASE+DRAM_TIMING, DRAM_TIMING_DEF))		return 18;	if (c4_poke(card, DC21285_ARMCSR_BASE+DRAM_ADDR_SIZE_0,DRAM_AD_SZ_DEF0))		return 19;	if (c4_poke(card, DC21285_ARMCSR_BASE+DRAM_ADDR_SIZE_1,DRAM_AD_SZ_NULL))		return 20;	if (c4_poke(card, DC21285_ARMCSR_BASE+DRAM_ADDR_SIZE_2,DRAM_AD_SZ_NULL))		return 21;	if (c4_poke(card, DC21285_ARMCSR_BASE+DRAM_ADDR_SIZE_3,DRAM_AD_SZ_NULL))		return 22;	/* Transputer test */		if (   c4_poke(card, 0x000000, 0x11111111)	    || c4_poke(card, 0x400000, 0x22222222)	    || c4_poke(card, 0x800000, 0x33333333)	    || c4_poke(card, 0xC00000, 0x44444444))		return 23;	if (   c4_peek(card, 0x000000, &dummy) || dummy != 0x11111111	    || c4_peek(card, 0x400000, &dummy) || dummy != 0x22222222	    || c4_peek(card, 0x800000, &dummy) || dummy != 0x33333333	    || c4_peek(card, 0xC00000, &dummy) || dummy != 0x44444444)		return 24;	if (   c4_poke(card, 0x000000, 0x55555555)	    || c4_poke(card, 0x400000, 0x66666666)	    || c4_poke(card, 0x800000, 0x77777777)	    || c4_poke(card, 0xC00000, 0x88888888))		return 25;	if (   c4_peek(card, 0x000000, &dummy) || dummy != 0x55555555	    || c4_peek(card, 0x400000, &dummy) || dummy != 0x66666666	    || c4_peek(card, 0x800000, &dummy) || dummy != 0x77777777	    || c4_peek(card, 0xC00000, &dummy) || dummy != 0x88888888)		return 26;

⌨️ 快捷键说明

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