--- zzzz-none-000/linux-2.4.17/drivers/isdn/tpam/tpam_main.c 2001-12-21 17:41:54.000000000 +0000 +++ sangam-fb-322/linux-2.4.17/drivers/isdn/tpam/tpam_main.c 2004-11-24 13:23:00.000000000 +0000 @@ -1,279 +1,279 @@ -/* $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 , Alcôve - * - * 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: - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#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); - +/* $Id: tpam_main.c,v 1.1.1.1 2003/06/23 22:18:27 jharrell Exp $ + * + * Turbo PAM ISDN driver for Linux. (Kernel Driver - main routines) + * + * Copyright 2001 Stelian Pop , Alcôve + * + * 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: + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#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); +