int capi_major = 68; /* allocated */
#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
+#define CAPINC_NR_PORTS 32
+#define CAPINC_MAX_PORTS 256
int capi_ttymajor = 191;
+int capi_ttyminors = CAPINC_NR_PORTS;
#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
MODULE_PARM(capi_major, "i");
#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
MODULE_PARM(capi_ttymajor, "i");
+MODULE_PARM(capi_ttyminors, "i");
#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
/* -------- defines ------------------------------------------------- */
return 0;
}
-#define CAPINC_NR_PORTS 256
static struct tty_driver *capinc_tty_driver;
static struct tty_operations capinc_ops = {
static int capinc_tty_init(void)
{
- struct tty_driver *drv = alloc_tty_driver(CAPINC_NR_PORTS);
+ struct tty_driver *drv;
+
+ if (capi_ttyminors > CAPINC_MAX_PORTS)
+ capi_ttyminors = CAPINC_MAX_PORTS;
+ if (capi_ttyminors <= 0)
+ capi_ttyminors = CAPINC_NR_PORTS;
+ drv = alloc_tty_driver(capi_ttyminors);
if (!drv)
return -ENOMEM;
char *p;
char *compileinfo;
-
if ((p = strchr(revision, ':')) != 0 && p[1]) {
strlcpy(rev, p + 2, sizeof(rev));
if ((p = strchr(rev, '$')) != 0 && p > rev)
devfs_mk_cdev(MKDEV(capi_major, 0), S_IFCHR | S_IRUSR | S_IWUSR,
"isdn/capi20");
- printk(KERN_NOTICE "capi20: started up with major %d\n", capi_major);
-
#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
if (capinc_tty_init() < 0) {
unregister_chrdev(capi_major, "capi20");
int i;
sprintf(id, "capidrv-%d", contr);
+ if (!try_module_get(THIS_MODULE)) {
+ printk(KERN_WARNING "capidrv: (%s) Could not reserve module\n", id);
+ return -1;
+ }
if (!(card = (capidrv_contr *) kmalloc(sizeof(capidrv_contr), GFP_ATOMIC))) {
printk(KERN_WARNING
"capidrv: (%s) Could not allocate contr-struct.\n", id);
}
memset(card, 0, sizeof(capidrv_contr));
card->owner = THIS_MODULE;
- if (!try_module_get(card->owner)) {
- printk(KERN_WARNING "capidrv: (%s) Could not reserve module\n", id);
- kfree(card);
- return -1;
- }
init_timer(&card->listentimer);
strcpy(card->name, id);
card->contrnr = contr;
printk(KERN_ERR "capidrv: delcontr: no contr %u\n", contr);
return -1;
}
+ #warning FIXME: maybe a race condition the card should be removed here from global list /kkeil
spin_unlock_irqrestore(&global_lock, flags);
del_timer(&card->listentimer);
static inline struct capi_ctr *
capi_ctr_get(struct capi_ctr *card)
{
- if (try_module_get(card->owner))
- return card;
- return NULL;
+ if (!try_module_get(card->owner))
+ return NULL;
+ DBG("Reserve module: %s", card->owner->name);
+ return card;
}
static inline void
capi_ctr_put(struct capi_ctr *card)
{
module_put(card->owner);
- DBG("MOD_COUNT DEC");
-}
-
-/* -------- own ref counting -------------------------------------- */
-
-static inline void
-kcapi_get_ref(void)
-{
- if (!try_module_get(THIS_MODULE))
- printk(KERN_WARNING "%s: cannot reserve module\n", __FUNCTION__);
-}
-
-static inline void
-kcapi_put_ref(void)
-{
- module_put(THIS_MODULE);
+ DBG("Release module: %s", card->owner->name);
}
/* ------------------------------------------------------------- */
{
struct capi_notifier *np;
- kcapi_get_ref();
+ if (!try_module_get(THIS_MODULE)) {
+ printk(KERN_WARNING "%s: cannot reserve module\n", __FUNCTION__);
+ return -1;
+ }
np = (struct capi_notifier *)kmalloc(sizeof(struct capi_notifier), GFP_ATOMIC);
if (!np) {
- kcapi_put_ref();
+ module_put(THIS_MODULE);
return -1;
}
memset(np, 0, sizeof(struct capi_notifier));
* of devices. Devices can only removed in
* user process, not in bh.
*/
- kcapi_get_ref();
+ __module_get(THIS_MODULE);
if (schedule_work(&tq_state_notify) == 0)
- kcapi_put_ref();
+ module_put(THIS_MODULE);
return 0;
}
while ((np = notify_dequeue()) != 0) {
notify_doit(np);
kfree(np);
- kcapi_put_ref();
+ module_put(THIS_MODULE);
}
- kcapi_put_ref();
+ module_put(THIS_MODULE);
}
/* -------- Receiver ------------------------------------------ */
static int suppress_pollack;
static struct pci_device_id c4_pci_tbl[] = {
- { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285, PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_C4, 4 },
- { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285, PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_C2, 2 },
+ { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285, PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_C4, 0, 0, (unsigned long)4 },
+ { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285, PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_C2, 0, 0, (unsigned long)2 },
{ } /* Terminating entry */
};
while (c4inmeml(card->mbase+DOORBELL) != 0xffffffff) {
if (!time_before(jiffies, stop))
return -1;
+ mb();
}
return 0;
}
if (!time_before(jiffies, stop))
return;
c4outmeml(card->mbase+DOORBELL, DBELL_ADDR);
+ mb();
}
c4_poke(card, DC21285_ARMCSR_BASE + CHAN_1_CONTROL, 0);
if (!time_before(jiffies, stop))
return 2;
c4outmeml(card->mbase+DOORBELL, DBELL_ADDR);
+ mb();
}
c4_poke(card, DC21285_ARMCSR_BASE + CHAN_1_CONTROL, 0);
avmctrl_info *cinfo;
u_int i;
+ if (!card)
+ return;
+
c4_reset(card);
for (i=0; i < card->nr_controllers; i++) {
iounmap(card->mbase);
release_region(card->port, AVMB1_PORTLEN);
avmcard_dma_free(card->dma);
+ pci_set_drvdata(pdev, NULL);
b1_free_card(card);
}
retval = c4_detect(card);
if (retval != 0) {
- printk(KERN_NOTICE "c4: NO card at 0x%x (%d)\n",
+ printk(KERN_NOTICE "c4: NO card at 0x%x error(%d)\n",
card->port, retval);
retval = -EIO;
goto err_unmap;
printk(KERN_INFO "c4: AVM C%d at i/o %#x, irq %d, mem %#lx\n",
nr_controllers, card->port, card->irq,
card->membase);
-
+ pci_set_drvdata(dev, card);
return 0;
err_free_irq:
ISDN_AUDIO_SKB_DLECOUNT(skb) = 0;
ISDN_AUDIO_SKB_LOCK(skb) = 0;
isdn_tty_queue_tail(info, skb, 2);
- if ((dev->modempoll) && (info->rcvsched))
+ if (((get_isdn_dev())->modempoll) && (info->rcvsched))
mod_timer(&info->read_timer, jiffies + 4);
} else
kfree_skb(skb);
ISDN_AUDIO_SKB_LOCK(skb) = 0;
isdn_tty_queue_tail(info, skb, 2);
/* Schedule dequeuing */
- if ((dev->modempoll) && (info->rcvsched))
+ if (((get_isdn_dev())->modempoll) && (info->rcvsched))
mod_timer(&info->read_timer, jiffies + 4);
}
MODULE_AUTHOR("Fritz Elfert");
MODULE_LICENSE("GPL");
-isdn_dev *dev;
+static isdn_dev_t *isdndev;
-static void isdn_lock_driver(struct isdn_driver *drv);
-static void isdn_unlock_driver(struct isdn_driver *drv);
-
-/* ====================================================================== */
+isdn_dev_t *
+get_isdn_dev(void) {
+ return(isdndev);
+}
/* Description of hardware-level-driver */
-struct isdn_driver {
+typedef struct isdn_driver {
int di;
char id[20];
atomic_t refcnt;
spinlock_t lock;
struct isdn_slot *slots;
struct fsm_inst fi;
-} driver;
+} isdn_driver_t;
+
+static spinlock_t drivers_lock = SPIN_LOCK_UNLOCKED;
+static isdn_driver_t *drivers[ISDN_MAX_DRIVERS];
+
+static void isdn_lock_driver(struct isdn_driver *drv);
+static void isdn_unlock_driver(struct isdn_driver *drv);
+
+/* ====================================================================== */
static void drv_destroy(struct isdn_driver *drv);
isdn_lock_driver(slot->drv);
fsm_change_state(fi, ST_SLOT_IN);
slot_debug(fi, "ICALL: %s\n", ctrl->parm.num);
- if (dev->global_flags & ISDN_GLOBAL_STOPPED)
+ if (isdndev->global_flags & ISDN_GLOBAL_STOPPED)
return 0;
strcpy(slot->num, ctrl->parm.setup.phone);
static int __drv_command(struct isdn_driver *drv, isdn_ctrl *cmd);
-static spinlock_t drivers_lock = SPIN_LOCK_UNLOCKED;
-static struct isdn_driver *drivers[ISDN_MAX_DRIVERS];
-
static int
isdn_writebuf_skb(struct isdn_slot *slot, struct sk_buff *skb)
{
unsigned long flags;
int drvidx;
- dev->global_features = 0;
+ isdndev->global_features = 0;
spin_lock_irqsave(&drivers_lock, flags);
for (drvidx = 0; drvidx < ISDN_MAX_DRIVERS; drvidx++) {
if (!drivers[drvidx])
continue;
if (drivers[drvidx]->fi.state != ST_DRV_RUNNING)
continue;
- dev->global_features |= drivers[drvidx]->features;
+ isdndev->global_features |= drivers[drvidx]->features;
}
spin_unlock_irqrestore(&drivers_lock, flags);
}
spin_unlock_irqrestore(&drivers_lock, flags);
put_drv(drv);
- dev->channels -= drv->channels;
+ isdndev->channels -= drv->channels;
isdn_info_update();
return 0;
case ISDN_STAT_AUDIO:
rc = fsm_event(&drv->fi, EV_STAT_AUDIO, c);
break;
+#warning FIXME divert interface
#if 0
case ISDN_STAT_ICALL:
/* Find any ttyI, waiting for D-channel setup */
if (divert_if)
divert_if->stat_callback(c);
break;
- case ISDN_STAT_BCONN:
- break;
- case ISDN_STAT_BHUP:
- break;
-#endif
-#if 0 // FIXME
case ISDN_STAT_DISCH:
save_flags(flags);
cli();
unsigned long flags;
int drvidx;
- drv = kmalloc(sizeof(*drv), GFP_KERNEL);
+ drv = kmalloc(sizeof(*drv), GFP_ATOMIC);
if (!drv) {
printk(KERN_WARNING "register_isdn: out of mem\n");
goto fail;
void
isdn_info_update(void)
{
- infostruct *p = dev->infochain;
+ infostruct *p = isdndev->infochain;
while (p) {
*(p->private) = 1;
p = (infostruct *) p->next;
}
- wake_up_interruptible(&(dev->info_waitq));
+ wake_up_interruptible(&(isdndev->info_waitq));
}
static int
if (!p)
return -ENOMEM;
- p->next = (char *) dev->infochain;
+ p->next = (char *) isdndev->infochain;
p->private = (char *) &(filep->private_data);
- dev->infochain = p;
+ isdndev->infochain = p;
/* At opening we allow a single update */
filep->private_data = (char *) 1;
static int
isdn_status_release(struct inode *ino, struct file *filep)
{
- infostruct *p = dev->infochain;
+ infostruct *p = isdndev->infochain;
infostruct *q = NULL;
lock_kernel();
if (q)
q->next = p->next;
else
- dev->infochain = (infostruct *) (p->next);
+ isdndev->infochain = (infostruct *) (p->next);
kfree(p);
goto out;
}
if (!file->private_data) {
if (file->f_flags & O_NONBLOCK)
return -EAGAIN;
- interruptible_sleep_on(&(dev->info_waitq));
+ interruptible_sleep_on(&(isdndev->info_waitq));
}
lock_kernel();
p = isdn_statstr();
{
unsigned int mask = 0;
- poll_wait(file, &(dev->info_waitq), wait);
+ poll_wait(file, &(isdndev->info_waitq), wait);
lock_kernel();
if (file->private_data)
mask |= POLLIN | POLLRDNORM;
{
struct isdn_slot *slot = file->private_data;
- if (dev->profd == current)
- dev->profd = NULL;
+ if (isdndev->profd == current)
+ isdndev->profd = NULL;
isdn_unlock_driver(slot->drv);
put_slot(slot);
case IIOCNETHUP:
return isdn_net_ioctl(inode, file, cmd, arg);
case IIOCSETVER:
- dev->net_verbose = arg;
- printk(KERN_INFO "isdn: Verbose-Level is %d\n", dev->net_verbose);
+ isdndev->net_verbose = arg;
+ printk(KERN_INFO "isdn: Verbose-Level is %d\n", isdndev->net_verbose);
return 0;
case IIOCSETGST:
if (arg) {
- dev->global_flags |= ISDN_GLOBAL_STOPPED;
+ isdndev->global_flags |= ISDN_GLOBAL_STOPPED;
isdn_net_hangup_all();
} else {
- dev->global_flags &= ~ISDN_GLOBAL_STOPPED;
+ isdndev->global_flags &= ~ISDN_GLOBAL_STOPPED;
}
return 0;
case IIOCSETBRJ:
drivers[drvidx]->flags &= ~DRV_FLAG_REJBUS;
return 0;
case IIOCSIGPRF:
- dev->profd = current;
+ isdndev->profd = current;
return 0;
break;
case IIOCGETPRF:
return -EINVAL;
case IIOCDBGVAR:
if (arg) {
- if (copy_to_user((char *) arg, (char *) &dev, sizeof(ulong)))
+ if (copy_to_user((char *) arg, (char *) &isdndev, sizeof(ulong)))
return -EFAULT;
return 0;
} else
if (n < 1)
return 0;
- if (dev->channels + n > ISDN_MAX_CHANNELS) {
+ if (isdndev->channels + n > ISDN_MAX_CHANNELS) {
printk(KERN_WARNING "register_isdn: Max. %d channels supported\n",
ISDN_MAX_CHANNELS);
return -EBUSY;
}
- dev->channels += n;
- drv->slots = kmalloc(sizeof(struct isdn_slot) * n, GFP_KERNEL);
+ isdndev->channels += n;
+ drv->slots = kmalloc(sizeof(struct isdn_slot) * n, GFP_ATOMIC);
if (!drv->slots)
return -ENOMEM;
-
+ memset(drv->slots, 0, sizeof(struct isdn_slot) * n);
for (ch = 0; ch < n; ch++) {
slot = drv->slots + ch;
#if defined(CONFIG_ISDN_DIVERSION) || defined(CONFIG_ISDN_DIVERSION_MODULE)
+/*
+ * map_drvname
+ */
static char *map_drvname(int di)
{
- if ((di < 0) || (di >= ISDN_MAX_DRIVERS))
- return(NULL);
- return(dev->drvid[di]); /* driver name */
-} /* map_drvname */
+ if ((di < 0) || (di >= ISDN_MAX_DRIVERS))
+ return(NULL);
+ return(isdndev->drvid[di]); /* driver name */
+}
+/*
+ * map_namedrv
+ */
static int map_namedrv(char *id)
-{ int i;
+{
+ int i;
- for (i = 0; i < ISDN_MAX_DRIVERS; i++)
- { if (!strcmp(dev->drvid[i],id))
- return(i);
- }
- return(-1);
-} /* map_namedrv */
+ for (i = 0; i < ISDN_MAX_DRIVERS; i++) {
+ if (!strcmp(dev->drvid[i],id))
+ return(i);
+ }
+ return(-1);
+}
+/*
+ * DIVERT_REG_NAME
+ */
int DIVERT_REG_NAME(isdn_divert_if *i_div)
{
- if (i_div->if_magic != DIVERT_IF_MAGIC)
- return(DIVERT_VER_ERR);
- switch (i_div->cmd)
- {
- case DIVERT_CMD_REL:
- if (divert_if != i_div)
- return(DIVERT_REL_ERR);
- divert_if = NULL; /* free interface */
- MOD_DEC_USE_COUNT;
- return(DIVERT_NO_ERR);
-
- case DIVERT_CMD_REG:
- if (divert_if)
- return(DIVERT_REG_ERR);
- i_div->ll_cmd = isdn_command; /* set command function */
- i_div->drv_to_name = map_drvname;
- i_div->name_to_drv = map_namedrv;
- MOD_INC_USE_COUNT;
- divert_if = i_div; /* remember interface */
- return(DIVERT_NO_ERR);
-
- default:
- return(DIVERT_CMD_ERR);
- }
-} /* DIVERT_REG_NAME */
+ if (i_div->if_magic != DIVERT_IF_MAGIC)
+ return(DIVERT_VER_ERR);
+ switch (i_div->cmd) {
+ case DIVERT_CMD_REL:
+ if (divert_if != i_div)
+ return(DIVERT_REL_ERR);
+ divert_if = NULL; /* free interface */
+ MOD_DEC_USE_COUNT;
+ return(DIVERT_NO_ERR);
+ case DIVERT_CMD_REG:
+ if (divert_if)
+ return(DIVERT_REG_ERR);
+ i_div->ll_cmd = isdn_command; /* set command function */
+ i_div->drv_to_name = map_drvname;
+ i_div->name_to_drv = map_namedrv;
+ MOD_INC_USE_COUNT;
+ divert_if = i_div; /* remember interface */
+ return(DIVERT_NO_ERR);
+ default:
+ return(DIVERT_CMD_ERR);
+ }
+}
EXPORT_SYMBOL(DIVERT_REG_NAME);
ctrl->arg &= ~0xff; ctrl->arg |= slot->ch;
break;
case ISDN_CMD_DIAL:
- if (dev->global_flags & ISDN_GLOBAL_STOPPED)
+ if (isdndev->global_flags & ISDN_GLOBAL_STOPPED)
return -EBUSY;
/* fall through */
if (retval)
goto err_slot_fsm;
- dev = vmalloc(sizeof(*dev));
- if (!dev) {
+ isdndev = vmalloc(sizeof(*isdndev));
+ if (!isdndev) {
retval = -ENOMEM;
goto err_drv_fsm;
}
- memset(dev, 0, sizeof(*dev));
- init_MUTEX(&dev->sem);
- init_waitqueue_head(&dev->info_waitq);
+ memset(isdndev, 0, sizeof(*isdndev));
+ init_MUTEX(&isdndev->sem);
+ init_waitqueue_head(&isdndev->info_waitq);
retval = register_chrdev(ISDN_MAJOR, "isdn", &isdn_fops);
if (retval) {
isdn_cleanup_devfs();
unregister_chrdev(ISDN_MAJOR, "isdn");
err_vfree:
- vfree(dev);
+ vfree(isdndev);
err_drv_fsm:
fsm_free(&drv_fsm);
err_slot_fsm:
isdn_tty_exit();
unregister_chrdev(ISDN_MAJOR, "isdn");
isdn_cleanup_devfs();
- vfree(dev);
+ vfree(isdndev);
fsm_free(&drv_fsm);
fsm_free(&slot_fsm);
}
if (!idev)
return -ENODEV;
- if (idev->isdn_slot < 0)
+ if (idev->isdn_slot == NULL)
return -ENOTCONN;
isdn_net_hangup(idev);
{
isdn_net_local *mlp = idev->mlp;
- if (idev->isdn_slot < 0) {
+ if (idev->isdn_slot == NULL) {
isdn_BUG();
return;
}
goto discard;
/* Log packet, which triggered dialing */
- if (dev->net_verbose)
+ if ((get_isdn_dev())->net_verbose)
isdn_net_log_skb(skb, idev);
stop_queue:
int
isdn_net_find_icall(struct isdn_slot *slot, setup_parm *setup)
{
- isdn_net_local *lp;
- isdn_net_dev *idev;
- char *nr, *eaz;
- unsigned char si1, si2;
- int retval;
- unsigned long flags;
+ isdn_net_local *lp;
+ isdn_net_dev *idev;
+ char *nr, *eaz;
+ unsigned char si1, si2;
+ int retval;
+ int verbose = (get_isdn_dev())->net_verbose;
+ unsigned long flags;
/* fix up calling number */
if (!setup->phone[0]) {
}
si1 = setup->si1;
si2 = setup->si2;
- if (dev->net_verbose > 1)
+ if (verbose > 1)
printk(KERN_INFO "isdn_net: call from %s,%d,%d -> %s\n",
nr, si1, si2, eaz);
/* check service indicator */
/* Accept DATA and VOICE calls at this stage
local eaz is checked later for allowed call types */
if ((si1 != 7) && (si1 != 1)) {
- if (dev->net_verbose > 1)
+ if (verbose > 1)
printk(KERN_INFO "isdn_net: "
"Service-Indicator not 1 or 7, ignored\n");
return 0;
}
spin_unlock_irqrestore(&running_devs_lock, flags);
if (!retval) {
- if (dev->net_verbose)
+ if (verbose)
printk(KERN_INFO "isdn_net: call "
"from %s -> %s ignored\n", nr, eaz);
}
int
isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
{
- isdn_net_dev *idev;
- isdn_net_local *mlp = ndev->priv;
- unsigned long flags;
- int retval;
+ isdn_net_dev *idev;
+ isdn_net_local *mlp = ndev->priv;
+ unsigned long flags;
+ int retval;
ndev->trans_start = jiffies;
idev->last_jiffies = jiffies;
idev->transcount = 0;
}
- if (dev->net_verbose > 3)
+ if ((get_isdn_dev())->net_verbose > 3)
printk(KERN_DEBUG "%s: %d bogocps\n", idev->name, idev->cps);
if (idev->cps > mlp->triggercps) {
);
restore_flags(flags);
/* Schedule dequeuing */
- if (dev->modempoll && info->rcvsched)
+ if ((get_isdn_dev())->modempoll && info->rcvsched)
mod_timer(&info->read_timer, jiffies + 4);
return 1;
}
info = &isdn_mdm.info[line];
if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_open"))
return -ENODEV;
- if (!try_module_get(info->owner))
+ if (!try_module_get(info->owner)) {
printk(KERN_WARNING "%s: cannot reserve module\n", __FUNCTION__);
+ return -ENODEV;
+ }
#ifdef ISDN_DEBUG_MODEM_OPEN
printk(KERN_DEBUG "isdn_tty_open %s, count = %d\n", tty->name,
info->count);
#ifdef ISDN_DEBUG_MODEM_OPEN
printk(KERN_DEBUG "isdn_tty_open ttyi%d successful...\n", info->line);
#endif
- dev->modempoll++;
+ (get_isdn_dev())->modempoll++;
#ifdef ISDN_DEBUG_MODEM_OPEN
printk(KERN_DEBUG "isdn_tty_open normal exit\n");
#endif
if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_close"))
goto out;
+ #warning need fixing /kkeil
save_flags(flags);
cli();
if (tty_hung_up_p(filp)) {
break;
}
}
- dev->modempoll--;
+ (get_isdn_dev())->modempoll--;
isdn_tty_shutdown(info);
if (tty->driver->flush_buffer)
tty->driver->flush_buffer(tty);
memcpy(m->profile, m->mdmreg, ISDN_MODEM_NUMREG);
memcpy(m->pmsn, m->msn, ISDN_MSNLEN);
memcpy(m->plmsn, m->lmsn, ISDN_LMSNLEN);
- if (dev->profd)
- kill_pg_info(SIGIO, SEND_SIG_PRIV, dev->profd->pgrp);
+ if ((get_isdn_dev())->profd)
+ kill_pg_info(SIGIO, SEND_SIG_PRIV, (get_isdn_dev())->profd->pgrp);
}
static struct tty_operations modem_ops = {
printk(KERN_DEBUG "m_fi: match1 wret=%d\n", wret);
printk(KERN_DEBUG "m_fi: sl=%d flags=%08lx drv=%d ch=%d usg=%d\n", sl,
info->flags, info->isdn_driver, info->isdn_channel,
- dev->usage[idx]);
+ slot->usage);
#endif
if (
#ifndef FIX_FILE_TRANSFER
isdn_tty_queue_tail(info, skb, skb->len);
restore_flags(flags);
/* Schedule dequeuing */
- if (dev->modempoll && info->rcvsched)
+ if ((get_isdn_dev())->modempoll && info->rcvsched)
mod_timer(&info->read_timer, jiffies + 4);
} else {
restore_flags(flags);
#ifdef CONFIG_ISDN_TTY_FAX
case '1':
p[0]++;
- if (!(dev->global_features &
+ if (!((get_isdn_dev())->global_features &
ISDN_FEATURE_L3_FCLASS1))
PARSE_ERROR1;
m->mdmreg[REG_SI1] = 1;
break;
case '2':
p[0]++;
- if (!(dev->global_features &
+ if (!((get_isdn_dev())->global_features &
ISDN_FEATURE_L3_FCLASS2))
PARSE_ERROR1;
m->mdmreg[REG_SI1] = 1;
p[0]++;
strcpy(rs, "\r\n0,");
#ifdef CONFIG_ISDN_TTY_FAX
- if (dev->global_features &
+ if ((get_isdn_dev())->global_features &
ISDN_FEATURE_L3_FCLASS1)
strcat(rs, "1,");
- if (dev->global_features &
+ if ((get_isdn_dev())->global_features &
ISDN_FEATURE_L3_FCLASS2)
strcat(rs, "2,");
#endif
static char
*revision = "$Revision: 1.65.6.8 $";
-static spinlock_t icn_lock = SPIN_LOCK_UNLOCKED;
-
static int icn_addcard(int, char *, char *);
/*
{
struct sk_buff_head *queue = &card->spqueue[channel];
struct sk_buff *skb;
- unsigned long flags;
skb_queue_purge(queue);
- spin_lock_irqsave(&icn_lock, flags);
card->xlen[channel] = 0;
card->sndcount[channel] = 0;
if ((skb = card->xskb[channel])) {
card->xskb[channel] = NULL;
- spin_unlock_irqrestore(&icn_lock, flags);
dev_kfree_skb(skb);
- } else
- spin_unlock_irqrestore(&icn_lock, flags);
+ }
}
/* Put a value into a shift-register, highest bit first.
/*
* Map a cards channel0 (Bank0/Bank8) or channel1 (Bank4/Bank12)
+ *
+ * must called with holding the devlock
*/
static inline void
icn_map_channel(icn_card * card, int channel)
* Lock a cards channel.
* Return 0 if requested card/channel is unmapped (failure).
* Return 1 on success.
+ *
+ * must called with holding the devlock
*/
static inline int
icn_lock_channel(icn_card * card, int channel)
{
register int retval;
- ulong flags;
#ifdef MAP_DEBUG
printk(KERN_DEBUG "icn_lock_channel %d\n", channel);
#endif
- spin_lock_irqsave(&icn_lock, flags);
if ((dev.channel == channel) && (card == dev.mcard)) {
dev.chanlock++;
retval = 1;
printk(KERN_DEBUG "icn_lock_channel %d FAILED, dc=%d\n", channel, dev.channel);
#endif
}
- spin_unlock_irqrestore(&icn_lock, flags);
return retval;
}
/*
* Release current card/channel lock
+ *
+ * must called with holding the devlock
*/
static inline void
-icn_release_channel(void)
+__icn_release_channel(void)
{
- ulong flags;
-
#ifdef MAP_DEBUG
printk(KERN_DEBUG "icn_release_channel l=%d\n", dev.chanlock);
#endif
- spin_lock_irqsave(&icn_lock, flags);
if (dev.chanlock > 0)
dev.chanlock--;
- spin_unlock_irqrestore(&icn_lock, flags);
+}
+
+/*
+ * Release current card/channel lock
+ */
+static inline void
+icn_release_channel(void)
+{
+ ulong flags;
+
+ spin_lock_irqsave(&dev.devlock, flags);
+ __icn_release_channel();
+ spin_unlock_irqrestore(&dev.devlock, flags);
}
/*
printk(KERN_DEBUG "trymaplock c=%d dc=%d l=%d\n", channel, dev.channel,
dev.chanlock);
#endif
- spin_lock_irqsave(&icn_lock, flags);
+ spin_lock_irqsave(&dev.devlock, flags);
if ((!dev.chanlock) ||
((dev.channel == channel) && (dev.mcard == card))) {
dev.chanlock++;
icn_map_channel(card, channel);
- spin_unlock_irqrestore(&icn_lock, flags);
+ spin_unlock_irqrestore(&dev.devlock, flags);
#ifdef MAP_DEBUG
printk(KERN_DEBUG "trymaplock %d OK\n", channel);
#endif
return 1;
}
- spin_unlock_irqrestore(&icn_lock, flags);
+ spin_unlock_irqrestore(&dev.devlock, flags);
#ifdef MAP_DEBUG
printk(KERN_DEBUG "trymaplock %d FAILED\n", channel);
#endif
#ifdef MAP_DEBUG
printk(KERN_DEBUG "map_release c=%d l=%d\n", channel, dev.chanlock);
#endif
- spin_lock_irqsave(&icn_lock, flags);
+ spin_lock_irqsave(&dev.devlock, flags);
if (dev.chanlock > 0)
dev.chanlock--;
if (!dev.chanlock)
icn_map_channel(card, channel);
- spin_unlock_irqrestore(&icn_lock, flags);
+ spin_unlock_irqrestore(&dev.devlock, flags);
}
/* Get Data from the B-Channel, assemble fragmented packets and put them
(card->sndcount[channel] ||
skb_queue_len(&card->spqueue[channel]) ||
card->xskb[channel])) {
- spin_lock_irqsave(&icn_lock, flags);
+ spin_lock_irqsave(&card->lock, flags);
if (card->xmit_lock[channel]) {
- spin_unlock_irqrestore(&icn_lock, flags);
+ spin_unlock_irqrestore(&card->lock, flags);
break;
}
card->xmit_lock[channel]++;
- spin_unlock_irqrestore(&icn_lock, flags);
+ spin_unlock_irqrestore(&card->lock, flags);
skb = card->xskb[channel];
if (!skb) {
skb = skb_dequeue(&card->spqueue[channel]);
writeb(cnt, &sbuf_l);
memcpy_toio(&sbuf_d, skb->data, cnt);
skb_pull(skb, cnt);
- card->sndcount[channel] -= cnt;
sbnext; /* switch to next buffer */
icn_maprelease_channel(card, mch & 2);
+ spin_lock_irqsave(&card->lock, flags);
+ card->sndcount[channel] -= cnt;
if (!skb->len) {
- spin_lock_irqsave(&icn_lock, flags);
if (card->xskb[channel])
card->xskb[channel] = NULL;
- spin_unlock_irqrestore(&icn_lock, flags);
+ card->xmit_lock[channel] = 0;
+ spin_unlock_irqrestore(&card->lock, flags);
dev_kfree_skb(skb);
if (card->xlen[channel]) {
cmd.command = ISDN_STAT_BSENT;
card->interface.statcallb(&cmd);
}
} else {
- spin_lock_irqsave(&icn_lock, flags);
card->xskb[channel] = skb;
- spin_unlock_irqrestore(&icn_lock, flags);
+ card->xmit_lock[channel] = 0;
+ spin_unlock_irqrestore(&card->lock, flags);
}
- card->xmit_lock[channel] = 0;
if (!icn_trymaplock_channel(card, mch))
break;
}
}
if (card->flags & (ICN_FLAGS_B1ACTIVE | ICN_FLAGS_B2ACTIVE)) {
/* schedule b-channel polling again */
- spin_lock_irqsave(&icn_lock, flags);
+ spin_lock_irqsave(&card->lock, flags);
mod_timer(&card->rb_timer, jiffies+ICN_TIMER_BCREAD);
card->flags |= ICN_FLAGS_RBTIMER;
- spin_unlock_irqrestore(&icn_lock, flags);
+ spin_unlock_irqrestore(&card->lock, flags);
} else
card->flags &= ~ICN_FLAGS_RBTIMER;
}
cmd.arg = channel;
switch (action) {
case 11:
- spin_lock_irqsave(&icn_lock, flags);
+ spin_lock_irqsave(&card->lock, flags);
icn_free_queue(card,channel);
card->rcvidx[channel] = 0;
ncmd.driver = card->myid;
ncmd.arg = channel;
ncmd.command = ISDN_STAT_BHUP;
- spin_unlock_irqrestore(&icn_lock, flags);
+ spin_unlock_irqrestore(&card->lock, flags);
card->interface.statcallb(&cmd);
} else
- spin_unlock_irqrestore(&icn_lock, flags);
+ spin_unlock_irqrestore(&card->lock, flags);
break;
case 1:
+ spin_lock_irqsave(&card->lock, flags);
icn_free_queue(card,channel);
card->flags |= (channel) ?
ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE;
+ spin_unlock_irqrestore(&card->lock, flags);
break;
case 2:
+ spin_lock_irqsave(&card->lock, flags);
card->flags &= ~((channel) ?
ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE);
icn_free_queue(card, channel);
- spin_lock_irqsave(&icn_lock, flags);
card->rcvidx[channel] = 0;
- spin_unlock_irqrestore(&icn_lock, flags);
+ spin_unlock_irqrestore(&card->lock, flags);
break;
case 3:
{
strlcpy(cmd.parm.num, status + 1, sizeof(cmd.parm.num));
break;
case 8:
+ spin_lock_irqsave(&card->lock, flags);
card->flags &= ~ICN_FLAGS_B1ACTIVE;
icn_free_queue(card, 0);
- spin_lock_irqsave(&icn_lock, flags);
card->rcvidx[0] = 0;
- spin_unlock_irqrestore(&icn_lock, flags);
+ spin_unlock_irqrestore(&card->lock, flags);
cmd.arg = 0;
cmd.driver = card->myid;
card->interface.statcallb(&cmd);
cmd.driver = card->myid;
card->interface.statcallb(&cmd);
cmd.command = ISDN_STAT_BHUP;
+ spin_lock_irqsave(&card->lock, flags);
card->flags &= ~ICN_FLAGS_B2ACTIVE;
icn_free_queue(card, 1);
- spin_lock_irqsave(&icn_lock, flags);
card->rcvidx[1] = 0;
- spin_unlock_irqrestore(&icn_lock, flags);
+ spin_unlock_irqrestore(&card->lock, flags);
cmd.arg = 1;
cmd.driver = card->myid;
card->interface.statcallb(&cmd);
{
ulong flags;
- spin_lock_irqsave(&icn_lock, flags);
+ spin_lock_irqsave(&card->lock, flags);
*card->msg_buf_write++ = (c == 0xff) ? '\n' : c;
if (card->msg_buf_write == card->msg_buf_read) {
if (++card->msg_buf_read > card->msg_buf_end)
}
if (card->msg_buf_write > card->msg_buf_end)
card->msg_buf_write = card->msg_buf;
- spin_unlock_irqrestore(&icn_lock, flags);
+ spin_unlock_irqrestore(&card->lock, flags);
}
static void
cmd.arg = avail;
card->interface.statcallb(&cmd);
}
+ spin_lock_irqsave(&card->lock, flags);
if (card->flags & (ICN_FLAGS_B1ACTIVE | ICN_FLAGS_B2ACTIVE))
if (!(card->flags & ICN_FLAGS_RBTIMER)) {
/* schedule b-channel polling */
card->flags |= ICN_FLAGS_RBTIMER;
- spin_lock_irqsave(&icn_lock, flags);
del_timer(&card->rb_timer);
card->rb_timer.function = icn_pollbchan;
card->rb_timer.data = (unsigned long) card;
card->rb_timer.expires = jiffies + ICN_TIMER_BCREAD;
add_timer(&card->rb_timer);
- spin_unlock_irqrestore(&icn_lock, flags);
}
/* schedule again */
- spin_lock_irqsave(&icn_lock, flags);
mod_timer(&card->st_timer, jiffies+ICN_TIMER_DCREAD);
- spin_unlock_irqrestore(&icn_lock, flags);
+ spin_unlock_irqrestore(&card->lock, flags);
}
/* Append a packet to the transmit buffer-queue.
return 0;
if (card->sndcount[channel] > ICN_MAX_SQUEUE)
return 0;
- spin_lock_irqsave(&icn_lock, flags);
+ #warning TODO test headroom or use skb->nb to flag ACK
nskb = skb_clone(skb, GFP_ATOMIC);
if (nskb) {
/* Push ACK flag as one
dev_kfree_skb(skb);
} else
len = 0;
+ spin_lock_irqsave(&card->lock, flags);
card->sndcount[channel] += len;
- spin_unlock_irqrestore(&icn_lock, flags);
+ spin_unlock_irqrestore(&card->lock, flags);
}
return len;
}
#ifdef BOOT_DEBUG
printk(KERN_DEBUG "Map Bank 0\n");
#endif
- spin_lock_irqsave(&icn_lock, flags);
+ spin_lock_irqsave(&dev.devlock, flags);
icn_map_channel(card, 0); /* Select Bank 0 */
icn_lock_channel(card, 0); /* Lock Bank 0 */
- spin_unlock_irqrestore(&icn_lock, flags);
+ spin_unlock_irqrestore(&dev.devlock, flags);
SLEEP(1);
memcpy_toio(dev.shmem, codebuf, ICN_CODE_STAGE1); /* Copy code */
#ifdef BOOT_DEBUG
#ifdef BOOT_DEBUG
printk(KERN_DEBUG "Map Bank 8\n");
#endif
- spin_lock_irqsave(&icn_lock, flags);
- icn_release_channel();
+ spin_lock_irqsave(&dev.devlock, flags);
+ __icn_release_channel();
icn_map_channel(card, 2); /* Select Bank 8 */
icn_lock_channel(card, 2); /* Lock Bank 8 */
- spin_unlock_irqrestore(&icn_lock, flags);
+ spin_unlock_irqrestore(&dev.devlock, flags);
SLEEP(1);
memcpy_toio(dev.shmem, codebuf, ICN_CODE_STAGE1); /* Copy code */
#ifdef BOOT_DEBUG
#ifdef BOOT_DEBUG
printk(KERN_DEBUG "Map Bank 0\n");
#endif
- spin_lock_irqsave(&icn_lock, flags);
+ spin_lock_irqsave(&dev.devlock, flags);
icn_map_channel(card, 0); /* Select Bank 0 */
icn_lock_channel(card, 0); /* Lock Bank 0 */
- spin_unlock_irqrestore(&icn_lock, flags);
+ spin_unlock_irqrestore(&dev.devlock, flags);
SLEEP(1);
ret = (icn_check_loader(1));
if ((ret = verify_area(VERIFY_READ, (void *) buffer, ICN_CODE_STAGE2)))
return ret;
timer = 0;
- spin_lock_irqsave(&icn_lock, flags);
+ spin_lock_irqsave(&dev.devlock, flags);
if (card->secondhalf) {
icn_map_channel(card, 2);
icn_lock_channel(card, 2);
icn_map_channel(card, 0);
icn_lock_channel(card, 0);
}
- spin_unlock_irqrestore(&icn_lock, flags);
+ spin_unlock_irqrestore(&dev.devlock, flags);
while (left) {
if (sbfree) { /* If there is a free buffer... */
cnt = left;
printk(KERN_DEBUG "Proto loaded, install poll-timer %d\n",
card->secondhalf);
#endif
- spin_lock_irqsave(&icn_lock, flags);
+ spin_lock_irqsave(&card->lock, flags);
init_timer(&card->st_timer);
card->st_timer.expires = jiffies + ICN_TIMER_DCREAD;
card->st_timer.function = icn_polldchan;
add_timer(&card->other->st_timer);
card->other->flags |= ICN_FLAGS_RUNNING;
}
- spin_unlock_irqrestore(&icn_lock, flags);
+ spin_unlock_irqrestore(&card->lock, flags);
}
icn_maprelease_channel(card, 0);
return 0;
} else
memcpy(msg, buf, count);
- spin_lock_irqsave(&icn_lock, flags);
+ spin_lock_irqsave(&dev.devlock, flags);
lastmap_card = dev.mcard;
lastmap_channel = dev.channel;
icn_map_channel(card, mch);
writeb((readb(&cmd_i) + count) & 0xff, &cmd_i);
if (lastmap_card)
icn_map_channel(lastmap_card, lastmap_channel);
- spin_unlock_irqrestore(&icn_lock, flags);
+ spin_unlock_irqrestore(&dev.devlock, flags);
if (len) {
mdelay(1);
if (loop++ > 20)
unsigned long flags;
isdn_ctrl cmd;
- spin_lock_irqsave(&icn_lock, flags);
+ spin_lock_irqsave(&card->lock, flags);
if (card->flags & ICN_FLAGS_RUNNING) {
card->flags &= ~ICN_FLAGS_RUNNING;
del_timer(&card->st_timer);
del_timer(&card->rb_timer);
+ spin_unlock_irqrestore(&card->lock, flags);
cmd.command = ISDN_STAT_STOP;
cmd.driver = card->myid;
card->interface.statcallb(&cmd);
if (card->doubleS0)
icn_stopcard(card->other);
- }
- spin_unlock_irqrestore(&icn_lock, flags);
+ } else
+ spin_unlock_irqrestore(&card->lock, flags);
}
static void
}
release_mem_region(a & 0x0ffc000, 0x4000);
icn_stopallcards();
- spin_lock_irqsave(&icn_lock, flags);
+ spin_lock_irqsave(&card->lock, flags);
if (dev.mvalid) {
iounmap(dev.shmem);
release_mem_region(dev.memaddr, 0x4000);
}
dev.mvalid = 0;
dev.memaddr = a & 0x0ffc000;
- spin_unlock_irqrestore(&icn_lock, flags);
+ spin_unlock_irqrestore(&card->lock, flags);
printk(KERN_INFO
"icn: (%s) mmio set to 0x%08lx\n",
CID,
}
release_region((unsigned short) a, ICN_PORTLEN);
icn_stopcard(card);
- spin_lock_irqsave(&icn_lock, flags);
+ spin_lock_irqsave(&card->lock, flags);
if (card->rvalid)
release_region(card->port, ICN_PORTLEN);
card->port = (unsigned short) a;
card->other->port = (unsigned short) a;
card->other->rvalid = 0;
}
- spin_unlock_irqrestore(&icn_lock, flags);
+ spin_unlock_irqrestore(&card->lock, flags);
printk(KERN_INFO
"icn: (%s) port set to 0x%03x\n",
CID, card->port);
return (icn_card *) 0;
}
memset((char *) card, 0, sizeof(icn_card));
+ spin_lock_init(&card->lock);
card->port = port;
card->interface.owner = THIS_MODULE;
card->interface.hl_hdrlen = 1;
dev.channel = -1;
dev.mcard = NULL;
dev.firstload = 1;
+ spin_lock_init(&dev.devlock);
if ((p = strchr(revision, ':'))) {
strcpy(rev, p + 1);
icn_card *card = cards;
icn_card *last;
int i;
+ unsigned long flags;
icn_stopallcards();
while (card) {
cmd.command = ISDN_STAT_UNLOAD;
cmd.driver = card->myid;
card->interface.statcallb(&cmd);
+ spin_lock_irqsave(&card->lock, flags);
if (card->rvalid) {
OUTB_P(0, ICN_RUN); /* Reset Controller */
OUTB_P(0, ICN_MAPRAM); /* Disable RAM */
icn_free_queue(card, i);
}
card = card->next;
+ spin_unlock_irqrestore(&card->lock, flags);
}
card = cards;
+ cards = NULL;
while (card) {
last = card;
card = card->next;
int myid; /* Driver-Nr. assigned by linklevel */
int rvalid; /* IO-portregion has been requested */
int leased; /* Flag: This Adapter is connected */
- /* to a leased line */
+ /* to a leased line */
unsigned short flags; /* Statusflags */
int doubleS0; /* Flag: ICN4B */
int secondhalf; /* Flag: Second half of a doubleS0 */
int fw_rev; /* Firmware revision loaded */
int ptype; /* Protocol type (1TR6 or Euro) */
- struct timer_list st_timer; /* Timer for Status-Polls */
- struct timer_list rb_timer; /* Timer for B-Channel-Polls */
- u_char rcvbuf[ICN_BCH][4096]; /* B-Channel-Receive-Buffers */
+ struct timer_list st_timer; /* Timer for Status-Polls */
+ struct timer_list rb_timer; /* Timer for B-Channel-Polls */
+ u_char rcvbuf[ICN_BCH][4096]; /* B-Channel-Receive-Buffers */
int rcvidx[ICN_BCH]; /* Index for above buffers */
int l2_proto[ICN_BCH]; /* Current layer-2-protocol */
isdn_if interface; /* Interface to upper layer */
char *msg_buf_end; /* Pointer to end of statusbuffer */
int sndcount[ICN_BCH]; /* Byte-counters for B-Ch.-send */
int xlen[ICN_BCH]; /* Byte-counters/Flags for sent-ACK */
- struct sk_buff *xskb[ICN_BCH];
- /* Current transmitted skb */
- struct sk_buff_head
- spqueue[ICN_BCH]; /* Sendqueue */
+ struct sk_buff *xskb[ICN_BCH]; /* Current transmitted skb */
+ struct sk_buff_head spqueue[ICN_BCH]; /* Sendqueue */
char regname[35]; /* Name used for request_region */
- u_char xmit_lock[ICN_BCH]; /* Semaphore for pollbchan_send() */
+ u_char xmit_lock[ICN_BCH]; /* Semaphore for pollbchan_send()*/
+ spinlock_t lock; /* protect critical operations */
} icn_card;
/*
* Main driver data
*/
typedef struct icn_dev {
+ spinlock_t devlock; /* spinlock to protect this struct */
unsigned long memaddr; /* Address of memory mapped buffers */
icn_shmem *shmem; /* Pointer to memory-mapped-buffers */
int mvalid; /* IO-shmem has been requested */
#define ISDN_CMSGLEN 50 /* Length of CONNECT-Message to add for Modem */
#define ISDN_MSNLEN 32
-#define NET_DV 0x06 /* Data version for isdn_net_ioctl_cfg */
-#define TTY_DV 0x06 /* Data version for iprofd etc. */
+#define NET_DV 0x06 /* Data version for isdn_net_ioctl_cfg */
+#define TTY_DV 0x06 /* Data version for iprofd etc. */
-#define INF_DV 0x01 /* Data version for /dev/isdninfo */
+#define INF_DV 0x01 /* Data version for /dev/isdninfo */
typedef struct {
- char drvid[25];
- unsigned long arg;
+ char drvid[25];
+ unsigned long arg;
} isdn_ioctl_struct;
typedef struct {
- char name[10];
- char phone[ISDN_MSNLEN];
- int outgoing;
+ char name[10];
+ char phone[ISDN_MSNLEN];
+ int outgoing;
} isdn_net_ioctl_phone;
typedef struct {
- char name[10]; /* Name of interface */
- char master[10]; /* Name of Master for Bundling */
- char slave[10]; /* Name of Slave for Bundling */
- char eaz[256]; /* EAZ/MSN */
- char drvid[25]; /* DriverId for Bindings */
- int onhtime; /* Hangup-Timeout */
- int charge; /* Charge-Units */
- int l2_proto; /* Layer-2 protocol */
- int l3_proto; /* Layer-3 protocol */
- int p_encap; /* Encapsulation */
- int exclusive; /* Channel, if bound exclusive */
- int dialmax; /* Dial Retry-Counter */
- int slavedelay; /* Delay until slave starts up */
- int cbdelay; /* Delay before Callback */
- int chargehup; /* Flag: Charge-Hangup */
- int ihup; /* Flag: Hangup-Timeout on incoming line */
- int secure; /* Flag: Secure */
- int callback; /* Flag: Callback */
- int cbhup; /* Flag: Reject Call before Callback */
- int pppbind; /* ippp device for bindings */
- int chargeint; /* Use fixed charge interval length */
- int triggercps; /* BogoCPS needed for triggering slave */
- int dialtimeout; /* Dial-Timeout */
- int dialwait; /* Time to wait after failed dial */
- int dialmode; /* Flag: off / on / auto */
+ char name[10]; /* Name of interface */
+ char master[10]; /* Name of Master for Bundling */
+ char slave[10]; /* Name of Slave for Bundling */
+ char eaz[256]; /* EAZ/MSN */
+ char drvid[25]; /* DriverId for Bindings */
+ int onhtime; /* Hangup-Timeout */
+ int charge; /* Charge-Units */
+ int l2_proto; /* Layer-2 protocol */
+ int l3_proto; /* Layer-3 protocol */
+ int p_encap; /* Encapsulation */
+ int exclusive; /* Channel, if bound exclusive */
+ int dialmax; /* Dial Retry-Counter */
+ int slavedelay; /* Delay until slave starts up */
+ int cbdelay; /* Delay before Callback */
+ int chargehup; /* Flag: Charge-Hangup */
+ int ihup; /* Flag: Hangup-Timeout on incoming line */
+ int secure; /* Flag: Secure */
+ int callback; /* Flag: Callback */
+ int cbhup; /* Flag: Reject Call before Callback */
+ int pppbind; /* ippp device for bindings */
+ int chargeint; /* Use fixed charge interval length */
+ int triggercps; /* BogoCPS needed for triggering slave */
+ int dialtimeout; /* Dial-Timeout */
+ int dialwait; /* Time to wait after failed dial */
+ int dialmode; /* Flag: off / on / auto */
} isdn_net_ioctl_cfg;
#define ISDN_NET_DIALMODE_MASK 0xC0 /* bits for status */
} infostruct;
/* Main driver-data */
-typedef struct isdn_devt {
- unsigned short flags; /* Bitmapped Flags: */
- /* */
- int channels; /* Current number of channels */
- int net_verbose; /* Verbose-Flag */
- int modempoll; /* Flag: tty-read active */
- int tflags; /* Timer-Flags: */
- /* see ISDN_TIMER_..defines */
- int global_flags;
- infostruct *infochain; /* List of open info-devs. */
- wait_queue_head_t info_waitq; /* Wait-Queue for isdninfo */
- struct task_struct *profd; /* For iprofd */
- struct semaphore sem; /* serialize list access*/
- unsigned long global_features;
-} isdn_dev;
-
-extern isdn_dev *dev;
-
+typedef struct _isdn_dev_t {
+ unsigned short flags; /* Bitmapped Flags: */
+ int channels; /* Current number of channels */
+ int net_verbose; /* Verbose-Flag */
+ int modempoll; /* Flag: tty-read active */
+ int tflags; /* Timer-Flags: */
+ /* see ISDN_TIMER_..defines */
+ int global_flags;
+ infostruct *infochain; /* List of open info-devs. */
+ wait_queue_head_t info_waitq; /* Wait-Queue for isdninfo */
+ struct task_struct *profd; /* For iprofd */
+ struct semaphore sem; /* serialize list access*/
+ unsigned long global_features;
+} isdn_dev_t;
+
+extern isdn_dev_t *get_isdn_dev(void);
#endif /* __KERNEL__ */