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

📄 tpam_main.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
字号:
/* $Id: tpam_main.c,v 1.1.2.2 2001/12/09 18:45:14 kai Exp $ * * Turbo PAM ISDN driver for Linux. (Kernel Driver - main routines) * * Copyright 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alc魐e * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. * * For all support questions please contact: <support@auvertech.fr> * */#include <linux/module.h>#include <linux/pci.h>#include <linux/sched.h>#include <linux/tqueue.h>#include <linux/interrupt.h>#include <linux/init.h>#include <asm/io.h>#include "tpam.h"/* Local functions prototypes */static int __devinit tpam_probe(struct pci_dev *, const struct pci_device_id *);static void __devexit tpam_unregister_card(tpam_card *);static void __devexit tpam_remove(struct pci_dev *);static int __init tpam_init(void);static void __exit tpam_exit(void);/* List of boards */static tpam_card *cards; /* = NULL; *//* Number of cards */static int cards_num;/* Configurable id of the driver */static char *id = "tpam\0\0\0\0\0\0\0\0\0\0\0\0";MODULE_DESCRIPTION("ISDN4Linux: Driver for TurboPAM ISDN cards");MODULE_AUTHOR("Stelian Pop");MODULE_LICENSE("GPL");MODULE_PARM_DESC(id,"ID-String of the driver");MODULE_PARM(id,"s");/* * Finds a board by its driver ID. * * 	driverId: driver ID (as referenced by the IDSN link layer) * * Return: the tpam_card structure if found, NULL on error. */tpam_card *tpam_findcard(int driverid) {	tpam_card *p = cards;	while (p) {		if (p->id == driverid)			return p;		p = p->next;	}	return NULL;}/* * Finds a channel number by its ncoid. * * 	card: the board * 	ncoid: the NCO id * * Return: the channel number if found, TPAM_CHANNEL_INVALID if not. */u32 tpam_findchannel(tpam_card *card, u32 ncoid) {	int i;	for (i = 0; i < TPAM_NBCHANNEL; ++i)		if (card->channels[i].ncoid == ncoid)			return card->channels[i].num;	return TPAM_CHANNEL_INVALID;}/* * Initializes and registers a new TurboPAM card. * * 	dev: the PCI device * 	num: the board number * * Return: 0 if OK, <0 if error */static int __devinit tpam_probe(struct pci_dev *dev, const struct pci_device_id *pci_id) {	tpam_card *card, *c;	int i;	/* allocate memory for the board structure */	if (!(card = (tpam_card *)kmalloc(sizeof(tpam_card), GFP_KERNEL))) {		printk(KERN_ERR "TurboPAM: tpam_register_card: "		       "kmalloc failed!\n");		return -ENOMEM;	}	memset((char *)card, 0, sizeof(tpam_card));	card->irq = dev->irq;	card->lock = SPIN_LOCK_UNLOCKED;	sprintf(card->interface.id, "%s%d", id, cards_num);	/* request interrupt */	if (request_irq(card->irq, &tpam_irq, SA_INTERRUPT | SA_SHIRQ, 			card->interface.id, card)) {		printk(KERN_ERR "TurboPAM: tpam_register_card: "		       "could not request irq %d\n", card->irq);		kfree(card);		return -EIO;	}	/* remap board memory */	if (!(card->bar0 = (unsigned long) ioremap(pci_resource_start(dev, 0),						   0x800000))) {		printk(KERN_ERR "TurboPAM: tpam_register_card: "		       "unable to remap bar0\n");		free_irq(card->irq, card);		kfree(card);		return -EIO;	}	/* reset the board */	readl(card->bar0 + TPAM_RESETPAM_REGISTER);	/* initialisation magic :-( */	copy_to_pam_dword(card, (void *)0x01800008, 0x00000030);	copy_to_pam_dword(card, (void *)0x01800010, 0x00000030);	copy_to_pam_dword(card, (void *)0x01800014, 0x42240822);	copy_to_pam_dword(card, (void *)0x01800018, 0x07114000);	copy_to_pam_dword(card, (void *)0x0180001c, 0x00000400);	copy_to_pam_dword(card, (void *)0x01840070, 0x00000010);	/* fill the ISDN link layer structure */	card->interface.channels = TPAM_NBCHANNEL;	card->interface.maxbufsize = TPAM_MAXBUFSIZE;	card->interface.features = 		ISDN_FEATURE_P_EURO |		ISDN_FEATURE_L2_HDLC |		ISDN_FEATURE_L2_MODEM |		ISDN_FEATURE_L3_TRANS;	card->interface.hl_hdrlen = 0;	card->interface.command = tpam_command;	card->interface.writebuf_skb = tpam_writebuf_skb;	card->interface.writecmd = NULL;	card->interface.readstat = NULL;	/* register wrt the ISDN link layer */	if (!register_isdn(&card->interface)) {		printk(KERN_ERR "TurboPAM: tpam_register_card: "		       "unable to register %s\n", card->interface.id);		free_irq(card->irq, card);		iounmap((void *)card->bar0);		kfree(card);		return -EIO;	}	card->id = card->interface.channels;	/* initialize all channels */	for (i = 0; i < TPAM_NBCHANNEL; ++i) {		card->channels[i].num = i;		card->channels[i].card = card;		card->channels[i].ncoid = TPAM_NCOID_INVALID;		card->channels[i].hdlc = 0;		card->channels[i].realhdlc = 0;		card->channels[i].hdlcshift = 0;		skb_queue_head_init(&card->channels[i].sendq);	}	/* initialize the rest of board structure */	card->channels_used = 0;	card->channels_tested = 0;	card->running = 0;	card->busy = 0;	card->roundrobin = 0;	card->loopmode = 0;	skb_queue_head_init(&card->sendq);	skb_queue_head_init(&card->recvq);	card->recv_tq.routine = (void *) (void *) tpam_recv_tq;	card->recv_tq.data = card;	card->send_tq.routine = (void *) (void *) tpam_send_tq;	card->send_tq.data = card;	/* add the board at the end of the list of boards */	card->next = NULL;	if (cards) {		c = cards;		while (c->next)			c = c->next;		c->next = card;	}	else		cards = card;	++cards_num;	pci_set_drvdata(dev, card);	return 0;}/* * Unregisters a TurboPAM board by releasing all its ressources (irq, mem etc). * * 	card: the board. */static void __devexit tpam_unregister_card(tpam_card *card) {	isdn_ctrl cmd;	/* prevent the ISDN link layer that the driver will be unloaded */	cmd.command = ISDN_STAT_UNLOAD;	cmd.driver = card->id;	(* card->interface.statcallb)(&cmd);	/* release interrupt */	free_irq(card->irq, card);	/* release mapped memory */	iounmap((void *)card->bar0);}/* * Stops the driver. */static void __devexit tpam_remove(struct pci_dev *pcidev) {	tpam_card *card = pci_get_drvdata(pcidev);	tpam_card *c;	/* remove from the list of cards */	if (card == cards)		cards = cards->next;	else {		c = cards;		while (c->next != card) 			c = c->next;		c->next = c->next->next;	}		/* unregister each board */	tpam_unregister_card(card);		/* and free the board structure itself */	kfree(card);}static struct pci_device_id tpam_pci_tbl[] __devinitdata = {	{ PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_TURBOPAM,	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },	{ }};MODULE_DEVICE_TABLE(pci, tpam_pci_tbl);static struct pci_driver tpam_driver = {	name:		"tpam",	id_table:	tpam_pci_tbl,	probe:		tpam_probe,	remove:		__devexit_p(tpam_remove),};static int __init tpam_init(void) {	int ret;		ret = pci_module_init(&tpam_driver);	if (ret)		return ret;	printk(KERN_INFO "TurboPAM: %d card%s found, driver loaded.\n", 	       cards_num, (cards_num > 1) ? "s" : "");	return 0;}static void __exit tpam_exit(void) {	pci_unregister_driver(&tpam_driver);	printk(KERN_INFO "TurboPAM: driver unloaded\n");}/* Module entry points */module_init(tpam_init);module_exit(tpam_exit);

⌨️ 快捷键说明

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