patch-2.2.19 linux/drivers/isdn/avmb1/c4.c
Next file: linux/drivers/isdn/avmb1/capi.c
Previous file: linux/drivers/isdn/avmb1/b1pcmcia.c
Back to the patch index
Back to the overall index
- Lines: 474
- Date:
Sun Mar 25 11:37:31 2001
- Orig file:
v2.2.18/drivers/isdn/avmb1/c4.c
- Orig date:
Sun Mar 25 11:28:24 2001
diff -u --new-file --recursive --exclude-from /usr/src/exclude v2.2.18/drivers/isdn/avmb1/c4.c linux/drivers/isdn/avmb1/c4.c
@@ -1,11 +1,75 @@
/*
- * $Id: c4.c,v 1.5 2000/03/16 15:21:03 calle Exp $
+ * $Id: c4.c,v 1.20.6.2 2001/02/13 11:43:29 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.2 2001/02/13 11:43:29 kai
+ * more compatility changes for 2.2.19
+ *
+ * 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 :-(
*
@@ -35,7 +99,9 @@
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/pci.h>
+#include <linux/isdn_compat.h>
#include <linux/capi.h>
+#include <linux/init.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include "capicmd.h"
@@ -43,35 +109,16 @@
#include "capilli.h"
#include "avmcard.h"
-static char *revision = "$Revision: 1.5 $";
+static char *revision = "$Revision: 1.20.6.2 $";
#undef CONFIG_C4_DEBUG
#undef CONFIG_C4_POLLDEBUG
/* ------------------------------------------------------------- */
-#ifndef PCI_VENDOR_ID_DEC
-#define PCI_VENDOR_ID_DEC 0x1011
-#endif
-
-#ifndef PCI_DEVICE_ID_DEC_21285
-#define PCI_DEVICE_ID_DEC_21285 0x1065
-#endif
-
-#ifndef PCI_VENDOR_ID_AVM
-#define PCI_VENDOR_ID_AVM 0x1244
-#endif
-
-#ifndef PCI_DEVICE_ID_AVM_C4
-#define PCI_DEVICE_ID_AVM_C4 0x0800
-#endif
-
-/* ------------------------------------------------------------- */
-
-static int suppress_pollack = 0;
+static int suppress_pollack;
MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>");
-
MODULE_PARM(suppress_pollack, "0-1i");
/* ------------------------------------------------------------- */
@@ -535,8 +582,7 @@
avmctrl_info *cinfo;
struct sk_buff *skb;
void *p = dma->recvbuf;
- __u32 ApplId, DataB3Len, NCCI, WindowSize;
- __s32 MsgLen;
+ __u32 ApplId, MsgLen, DataB3Len, NCCI, WindowSize;
__u8 b1cmd = _get_byte(&p);
__u32 cidx;
@@ -655,22 +701,26 @@
case RECEIVE_TASK_READY:
ApplId = (unsigned) _get_word(&p);
MsgLen = _get_slice(&p, card->msgbuf);
- card->msgbuf[MsgLen--] = 0;
- while ( MsgLen >= 0
- && ( card->msgbuf[MsgLen] == '\n'
- || card->msgbuf[MsgLen] == '\r'))
- card->msgbuf[MsgLen--] = 0;
+ card->msgbuf[MsgLen] = 0;
+ while ( MsgLen > 0
+ && ( card->msgbuf[MsgLen-1] == '\n'
+ || card->msgbuf[MsgLen-1] == '\r')) {
+ card->msgbuf[MsgLen-1] = 0;
+ MsgLen--;
+ }
printk(KERN_INFO "%s: task %d \"%s\" ready.\n",
card->name, ApplId, card->msgbuf);
break;
case RECEIVE_DEBUGMSG:
MsgLen = _get_slice(&p, card->msgbuf);
- card->msgbuf[MsgLen--] = 0;
- while ( MsgLen >= 0
- && ( card->msgbuf[MsgLen] == '\n'
- || card->msgbuf[MsgLen] == '\r'))
- card->msgbuf[MsgLen--] = 0;
+ card->msgbuf[MsgLen] = 0;
+ while ( MsgLen > 0
+ && ( card->msgbuf[MsgLen-1] == '\n'
+ || card->msgbuf[MsgLen-1] == '\r')) {
+ card->msgbuf[MsgLen-1] = 0;
+ MsgLen--;
+ }
printk(KERN_INFO "%s: DEBUG: %s\n", card->name, card->msgbuf);
break;
@@ -774,45 +824,78 @@
c4_dispatch_tx(card);
}
-static int c4_send_config(avmcard *card, capiloaddatapart * config)
+static int queue_sendconfigword(avmcard *card, __u32 val)
{
struct sk_buff *skb;
- __u8 val[sizeof(__u32)];
void *p;
- unsigned char *dp;
- int left, retval;
-
- skb = alloc_skb(12 + ((config->len+3)/4)*5, GFP_ATOMIC);
+
+ skb = alloc_skb(3+4, GFP_ATOMIC);
if (!skb) {
- printk(KERN_CRIT "%s: no memory, can't send config.\n",
+ printk(KERN_CRIT "%s: no memory, send config\n",
card->name);
- return -ENOMEM;
+ return -ENOMEM;
}
p = skb->data;
_put_byte(&p, 0);
_put_byte(&p, 0);
_put_byte(&p, SEND_CONFIG);
- _put_word(&p, 1);
+ _put_word(&p, val);
+ skb_put(skb, (__u8 *)p - (__u8 *)skb->data);
+
+ skb_queue_tail(&card->dma->send_queue, skb);
+ c4_dispatch_tx(card);
+ return 0;
+}
+
+static int queue_sendconfig(avmcard *card, char cval[4])
+{
+ struct sk_buff *skb;
+ void *p;
+
+ skb = alloc_skb(3+4, GFP_ATOMIC);
+ if (!skb) {
+ printk(KERN_CRIT "%s: no memory, send config\n",
+ card->name);
+ return -ENOMEM;
+ }
+ p = skb->data;
+ _put_byte(&p, 0);
+ _put_byte(&p, 0);
_put_byte(&p, SEND_CONFIG);
- _put_word(&p, config->len); /* 12 */
+ _put_byte(&p, cval[0]);
+ _put_byte(&p, cval[1]);
+ _put_byte(&p, cval[2]);
+ _put_byte(&p, cval[3]);
+ skb_put(skb, (__u8 *)p - (__u8 *)skb->data);
+
+ skb_queue_tail(&card->dma->send_queue, skb);
+ c4_dispatch_tx(card);
+ return 0;
+}
+
+static int c4_send_config(avmcard *card, capiloaddatapart * config)
+{
+ __u8 val[4];
+ unsigned char *dp;
+ int left, retval;
+
+ if ((retval = queue_sendconfigword(card, 1)) != 0)
+ return retval;
+ if ((retval = queue_sendconfigword(card, config->len)) != 0)
+ return retval;
dp = config->data;
left = config->len;
while (left >= sizeof(__u32)) {
if (config->user) {
retval = copy_from_user(val, dp, sizeof(val));
- if (retval) {
- dev_kfree_skb(skb);
+ if (retval)
return -EFAULT;
- }
} else {
memcpy(val, dp, sizeof(val));
}
- _put_byte(&p, SEND_CONFIG);
- _put_byte(&p, val[0]);
- _put_byte(&p, val[1]);
- _put_byte(&p, val[2]);
- _put_byte(&p, val[3]);
+ if ((retval = queue_sendconfig(card, val)) != 0)
+ return retval;
left -= sizeof(val);
dp += sizeof(val);
}
@@ -820,25 +903,15 @@
memset(val, 0, sizeof(val));
if (config->user) {
retval = copy_from_user(&val, dp, left);
- if (retval) {
- dev_kfree_skb(skb);
+ if (retval)
return -EFAULT;
- }
} else {
memcpy(&val, dp, left);
}
- _put_byte(&p, SEND_CONFIG);
- _put_byte(&p, val[0]);
- _put_byte(&p, val[1]);
- _put_byte(&p, val[2]);
- _put_byte(&p, val[3]);
+ if ((retval = queue_sendconfig(card, val)) != 0)
+ return retval;
}
- skb_put(skb, (__u8 *)p - (__u8 *)skb->data);
-
- skb_queue_tail(&card->dma->send_queue, skb);
- c4_dispatch_tx(card);
-
return 0;
}
@@ -875,8 +948,15 @@
c4outmeml(card->mbase+DOORBELL, DBELL_UP_ARM);
restore_flags(flags);
- if (data->configuration.len > 0 && data->configuration.data)
- c4_send_config(card, &data->configuration);
+ if (data->configuration.len > 0 && data->configuration.data) {
+ retval = c4_send_config(card, &data->configuration);
+ if (retval) {
+ printk(KERN_ERR "%s: failed to set config!!\n",
+ card->name);
+ c4_reset(card);
+ return retval;
+ }
+ }
c4_send_init(card);
@@ -910,8 +990,10 @@
for (i=0; i < 4; i++) {
cinfo = &card->ctrlinfo[i];
- if (cinfo->capi_ctrl)
+ if (cinfo->capi_ctrl) {
di->detach_ctr(cinfo->capi_ctrl);
+ cinfo->capi_ctrl = NULL;
+ }
}
free_irq(card->irq, card);
@@ -1124,7 +1206,6 @@
cinfo = (avmctrl_info *) kmalloc(sizeof(avmctrl_info)*4, GFP_ATOMIC);
if (!cinfo) {
printk(KERN_WARNING "%s: no memory.\n", driver->name);
- kfree(card->ctrlinfo);
kfree(card->dma);
kfree(card);
MOD_DEC_USE_COUNT;
@@ -1231,57 +1312,33 @@
/* ------------------------------------------------------------- */
static struct capi_driver c4_driver = {
- "c4",
- "0.0",
- c4_load_firmware,
- c4_reset_ctr,
- c4_remove_ctr,
- c4_register_appl,
- c4_release_appl,
- c4_send_message,
-
- c4_procinfo,
- c4_read_proc,
- 0, /* use standard driver_read_proc */
+ name: "c4",
+ revision: "0.0",
+ load_firmware: c4_load_firmware,
+ reset_ctr: c4_reset_ctr,
+ remove_ctr: c4_remove_ctr,
+ register_appl: c4_register_appl,
+ release_appl: c4_release_appl,
+ send_message: c4_send_message,
+
+ procinfo: c4_procinfo,
+ ctr_read_proc: c4_read_proc,
+ driver_read_proc: 0, /* use standard driver_read_proc */
- 0, /* no add_card function */
+ add_card: 0, /* no add_card function */
};
-#ifdef MODULE
-#define c4_init init_module
-void cleanup_module(void);
-#endif
-
-#ifndef PCI_ANY_ID
-#define PCI_ANY_ID (~0)
-#endif
-
-static struct pci_dev *
-pci_find_subsys(unsigned int vendor, unsigned int device,
- unsigned int ss_vendor, unsigned int ss_device,
- struct pci_dev *from)
-{
- unsigned short subsystem_vendor, subsystem_device;
-
- while ((from = pci_find_device(vendor, device, from))) {
- pci_read_config_word(from, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor);
- pci_read_config_word(from, PCI_SUBSYSTEM_ID, &subsystem_device);
- if ((ss_vendor == PCI_ANY_ID || subsystem_vendor == ss_vendor) &&
- (ss_device == PCI_ANY_ID || subsystem_device == ss_device))
- return from;
- }
- return NULL;
-}
-
static int ncards = 0;
-int c4_init(void)
+static int __init c4_init(void)
{
struct capi_driver *driver = &c4_driver;
struct pci_dev *dev = NULL;
char *p;
int retval;
+ MOD_INC_USE_COUNT;
+
if ((p = strchr(revision, ':'))) {
strncpy(driver->revision, p + 1, sizeof(driver->revision));
p = strchr(driver->revision, '$');
@@ -1295,6 +1352,7 @@
if (!di) {
printk(KERN_ERR "%s: failed to attach capi_driver\n",
driver->name);
+ MOD_DEC_USE_COUNT;
return -EIO;
}
@@ -1302,6 +1360,7 @@
if (!pci_present()) {
printk(KERN_ERR "%s: no PCI bus present\n", driver->name);
detach_capi_driver(driver);
+ MOD_DEC_USE_COUNT;
return -EIO;
}
@@ -1314,6 +1373,7 @@
param.irq = dev->irq;
param.membase = dev->base_address[ 0] & PCI_BASE_ADDRESS_MEM_MASK;
+
printk(KERN_INFO
"%s: PCI BIOS reports AVM-C4 at i/o %#x, irq %d, mem %#x\n",
driver->name, param.port, param.irq, param.membase);
@@ -1322,9 +1382,8 @@
printk(KERN_ERR
"%s: no AVM-C4 at i/o %#x, irq %d detected, mem %#x\n",
driver->name, param.port, param.irq, param.membase);
-#ifdef MODULE
- cleanup_module();
-#endif
+ detach_capi_driver(driver);
+ MOD_DEC_USE_COUNT;
return retval;
}
ncards++;
@@ -1332,19 +1391,24 @@
if (ncards) {
printk(KERN_INFO "%s: %d C4 card(s) detected\n",
driver->name, ncards);
+ MOD_DEC_USE_COUNT;
return 0;
}
printk(KERN_ERR "%s: NO C4 card detected\n", driver->name);
+ detach_capi_driver(driver);
+ MOD_DEC_USE_COUNT;
return -ESRCH;
#else
printk(KERN_ERR "%s: kernel not compiled with PCI.\n", driver->name);
+ MOD_DEC_USE_COUNT;
return -EIO;
#endif
}
-#ifdef MODULE
-void cleanup_module(void)
+static void c4_exit(void)
{
detach_capi_driver(&c4_driver);
}
-#endif
+
+module_init(c4_init);
+module_exit(c4_exit);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)