/* $Id: isdnloop.c,v 1.11.6.7 2001/11/11 19:54:31 kai Exp $
*
* ISDN low-level module implementing a dummy loop driver.
*
* Copyright 1997 by Fritz Elfert (fritz@isdn4linux.de)
*
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
*
*/
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/sched.h>
#include "isdnloop.h"
static char *revision = "$Revision: 1.11.6.7 $";
static char *isdnloop_id = "loop0";
MODULE_DESCRIPTION("ISDN4Linux: Pseudo Driver that simulates an ISDN card");
MODULE_AUTHOR("Fritz Elfert");
MODULE_LICENSE("GPL");
module_param(isdnloop_id, charp, 0);
MODULE_PARM_DESC(isdnloop_id, "ID-String of first card");
static int isdnloop_addcard(char *);
/*
* Free queue completely.
*
* Parameter:
* card = pointer to card struct
* channel = channel number
*/
static void
isdnloop_free_queue(isdnloop_card *card, int channel)
{
struct sk_buff_head *queue = &card->bqueue[channel];
skb_queue_purge(queue);
card->sndcount[channel] = 0;
}
/*
* Send B-Channel data to another virtual card.
* This routine is called via timer-callback from isdnloop_pollbchan().
*
* Parameter:
* card = pointer to card struct.
* ch = channel number (0-based)
*/
static void
isdnloop_bchan_send(isdnloop_card *card, int ch)
{
isdnloop_card *rcard = card->rcard[ch];
int rch = card->rch[ch], len, ack;
struct sk_buff *skb;
isdn_ctrl cmd;
while (card->sndcount[ch]) {
if ((skb = skb_dequeue(&card->bqueue[ch]))) {
len = skb->len;
card->sndcount[ch] -= len;
ack = *(skb->head); /* used as scratch area */
cmd.driver = card->myid;
cmd.arg = ch;
if (rcard) {
rcard->interface.rcvcallb_skb(rcard->myid, rch, skb);
} else {
printk(KERN_WARNING "isdnloop: no rcard, skb dropped\n");
dev_kfree_skb(skb);
};
cmd.command = ISDN_STAT_BSENT;
cmd.
|