Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 088ec0cc authored by Tilman Schmidt's avatar Tilman Schmidt Committed by David S. Miller
Browse files

gigaset: prepare for CAPI implementation



Reorganize the code of the Gigaset driver, moving all isdn4linux
dependencies to the source file i4l.c so that it can be replaced
by a file capi.c interfacing to Kernel CAPI instead.

Impact: refactoring, no functional change
Signed-off-by: default avatarTilman Schmidt <tilman@imap.cc>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7ecc59c1
Loading
Loading
Loading
Loading
+58 −66
Original line number Diff line number Diff line
@@ -119,10 +119,7 @@ static inline int hdlc_loop(unsigned char c, unsigned char *src, int numbytes,
	int inputstate = bcs->inputstate;
	__u16 fcs = bcs->fcs;
	struct sk_buff *skb = bcs->skb;
	unsigned char error;
	struct sk_buff *compskb;
	int startbytes = numbytes;
	int l;

	if (unlikely(inputstate & INS_byte_stuff)) {
		inputstate &= ~INS_byte_stuff;
@@ -158,8 +155,8 @@ static inline int hdlc_loop(unsigned char c, unsigned char *src, int numbytes,
#endif

				/* end of frame */
				error = 1;
				gigaset_rcv_error(NULL, cs, bcs);
				gigaset_isdn_rcv_err(bcs);
				dev_kfree_skb(skb);
			} else if (!(inputstate & INS_have_data)) { /* 7E 7E */
#ifdef CONFIG_GIGASET_DEBUG
				++bcs->emptycount;
@@ -170,55 +167,40 @@ static inline int hdlc_loop(unsigned char c, unsigned char *src, int numbytes,
					"7e----------------------------");

				/* end of frame */
				error = 0;

				if (unlikely(fcs != PPP_GOODFCS)) {
					dev_err(cs->dev,
				"Checksum failed, %u bytes corrupted!\n",
						skb->len);
					compskb = NULL;
					gigaset_rcv_error(compskb, cs, bcs);
					error = 1;
				} else {
					if (likely((l = skb->len) > 2)) {
						skb->tail -= 2;
						skb->len -= 2;
					} else {
					gigaset_isdn_rcv_err(bcs);
					dev_kfree_skb(skb);
						skb = NULL;
						inputstate |= INS_skip_frame;
						if (l == 1) {
				} else if (likely(skb->len > 2)) {
					__skb_trim(skb, skb->len - 2);
					gigaset_skb_rcvd(bcs, skb);
				} else {
					if (skb->len) {
						dev_err(cs->dev,
						  "invalid packet size (1)!\n");
							error = 1;
							gigaset_rcv_error(NULL,
								cs, bcs);
						}
					}
					if (likely(!(error ||
						     (inputstate &
						      INS_skip_frame)))) {
						gigaset_rcv_skb(skb, cs, bcs);
					"invalid packet size (%d)\n", skb->len);
						gigaset_isdn_rcv_err(bcs);
					}
					dev_kfree_skb(skb);
				}
			}

			if (unlikely(error))
				if (skb)
					dev_kfree_skb(skb);

			fcs = PPP_INITFCS;
			inputstate &= ~(INS_have_data | INS_skip_frame);
			if (unlikely(bcs->ignore)) {
				inputstate |= INS_skip_frame;
				skb = NULL;
			} else if (likely((skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL)) {
				skb_reserve(skb, HW_HDR_LEN);
			} else {
				skb = dev_alloc_skb(SBUFSIZE + cs->hw_hdr_len);
				if (skb != NULL) {
					skb_reserve(skb, cs->hw_hdr_len);
				} else {
					dev_warn(cs->dev,
						"could not allocate new skb\n");
					inputstate |= INS_skip_frame;
				}
			}

			break;
		} else if (unlikely(muststuff(c))) {
@@ -314,20 +296,23 @@ static inline int iraw_loop(unsigned char c, unsigned char *src, int numbytes,
	/* pass data up */
	if (likely(inputstate & INS_have_data)) {
		if (likely(!(inputstate & INS_skip_frame))) {
			gigaset_rcv_skb(skb, cs, bcs);
			gigaset_skb_rcvd(bcs, skb);
		}
		inputstate &= ~(INS_have_data | INS_skip_frame);
		if (unlikely(bcs->ignore)) {
			inputstate |= INS_skip_frame;
			skb = NULL;
		} else if (likely((skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN))
				  != NULL)) {
			skb_reserve(skb, HW_HDR_LEN);
		} else {
			dev_warn(cs->dev, "could not allocate new skb\n");
			skb = dev_alloc_skb(SBUFSIZE + cs->hw_hdr_len);
			if (skb != NULL) {
				skb_reserve(skb, cs->hw_hdr_len);
			} else {
				dev_warn(cs->dev,
					 "could not allocate new skb\n");
				inputstate |= INS_skip_frame;
			}
		}
	}

	bcs->inputstate = inputstate;
	bcs->skb = skb;
@@ -383,7 +368,7 @@ void gigaset_m10x_input(struct inbuf_t *inbuf)
					/* FIXME use function pointers?  */
					if (inbuf->inputstate & INS_command)
						procbytes = cmd_loop(c, src, numbytes, inbuf);
					else if (inbuf->bcs->proto2 == ISDN_PROTO_L2_HDLC)
					else if (inbuf->bcs->proto2 == L2_HDLC)
						procbytes = hdlc_loop(c, src, numbytes, inbuf);
					else
						procbytes = iraw_loop(c, src, numbytes, inbuf);
@@ -440,16 +425,16 @@ EXPORT_SYMBOL_GPL(gigaset_m10x_input);

/* == data output ========================================================== */

/* Encoding of a PPP packet into an octet stuffed HDLC frame
 * with FCS, opening and closing flags.
/*
 * Encode a data packet into an octet stuffed HDLC frame with FCS,
 * opening and closing flags, preserving headroom data.
 * parameters:
 *	skb		skb containing original packet (freed upon return)
 *	head	number of headroom bytes to allocate in result skb
 *	tail	number of tailroom bytes to allocate in result skb
 *	headroom	number of headroom bytes to preserve
 * Return value:
 *	pointer to newly allocated skb containing the result frame
 */
static struct sk_buff *HDLC_Encode(struct sk_buff *skb, int head, int tail)
static struct sk_buff *HDLC_Encode(struct sk_buff *skb, int headroom)
{
	struct sk_buff *hdlc_skb;
	__u16 fcs;
@@ -471,16 +456,17 @@ static struct sk_buff *HDLC_Encode(struct sk_buff *skb, int head, int tail)

	/* size of new buffer: original size + number of stuffing bytes
	 * + 2 bytes FCS + 2 stuffing bytes for FCS (if needed) + 2 flag bytes
	 * + room for acknowledgement header
	 */
	hdlc_skb = dev_alloc_skb(skb->len + stuf_cnt + 6 + tail + head);
	hdlc_skb = dev_alloc_skb(skb->len + stuf_cnt + 6 + headroom);
	if (!hdlc_skb) {
		dev_kfree_skb(skb);
		return NULL;
	}
	skb_reserve(hdlc_skb, head);

	/* Copy acknowledge request into new skb */
	memcpy(hdlc_skb->head, skb->head, 2);
	/* Copy acknowledgement header into new skb */
	skb_reserve(hdlc_skb, headroom);
	memcpy(hdlc_skb->head, skb->head, headroom);

	/* Add flag sequence in front of everything.. */
	*(skb_put(hdlc_skb, 1)) = PPP_FLAG;
@@ -515,15 +501,16 @@ static struct sk_buff *HDLC_Encode(struct sk_buff *skb, int head, int tail)
	return hdlc_skb;
}

/* Encoding of a raw packet into an octet stuffed bit inverted frame
/*
 * Encode a data packet into an octet stuffed raw bit inverted frame,
 * preserving headroom data.
 * parameters:
 *	skb		skb containing original packet (freed upon return)
 *	head	number of headroom bytes to allocate in result skb
 *	tail	number of tailroom bytes to allocate in result skb
 *	headroom	number of headroom bytes to preserve
 * Return value:
 *	pointer to newly allocated skb containing the result frame
 */
static struct sk_buff *iraw_encode(struct sk_buff *skb, int head, int tail)
static struct sk_buff *iraw_encode(struct sk_buff *skb, int headroom)
{
	struct sk_buff *iraw_skb;
	unsigned char c;
@@ -531,12 +518,15 @@ static struct sk_buff *iraw_encode(struct sk_buff *skb, int head, int tail)
	int len;

	/* worst case: every byte must be stuffed */
	iraw_skb = dev_alloc_skb(2*skb->len + tail + head);
	iraw_skb = dev_alloc_skb(2*skb->len + headroom);
	if (!iraw_skb) {
		dev_kfree_skb(skb);
		return NULL;
	}
	skb_reserve(iraw_skb, head);

	/* Copy acknowledgement header into new skb */
	skb_reserve(iraw_skb, headroom);
	memcpy(iraw_skb->head, skb->head, headroom);

	cp = skb->data;
	len = skb->len;
@@ -555,8 +545,10 @@ static struct sk_buff *iraw_encode(struct sk_buff *skb, int head, int tail)
 * @bcs:	B channel descriptor structure.
 * @skb:	data to send.
 *
 * Called by i4l.c to encode and queue an skb for sending, and start
 * Called by LL to encode and queue an skb for sending, and start
 * transmission if necessary.
 * Once the payload data has been transmitted completely, gigaset_skb_sent()
 * will be called with the first cs->hw_hdr_len bytes of skb->head preserved.
 *
 * Return value:
 *	number of bytes accepted for sending (skb->len) if ok,
@@ -567,10 +559,10 @@ int gigaset_m10x_send_skb(struct bc_state *bcs, struct sk_buff *skb)
	unsigned len = skb->len;
	unsigned long flags;

	if (bcs->proto2 == ISDN_PROTO_L2_HDLC)
		skb = HDLC_Encode(skb, HW_HDR_LEN, 0);
	if (bcs->proto2 == L2_HDLC)
		skb = HDLC_Encode(skb, bcs->cs->hw_hdr_len);
	else
		skb = iraw_encode(skb, HW_HDR_LEN, 0);
		skb = iraw_encode(skb, bcs->cs->hw_hdr_len);
	if (!skb) {
		dev_err(bcs->cs->dev,
			"unable to allocate memory for encoding!\n");
+2 −2
Original line number Diff line number Diff line
@@ -911,7 +911,7 @@ static int starturbs(struct bc_state *bcs)
	int rc;

	/* initialize L2 reception */
	if (bcs->proto2 == ISDN_PROTO_L2_HDLC)
	if (bcs->proto2 == L2_HDLC)
		bcs->inputstate |= INS_flag_hunt;

	/* submit all isochronous input URBs */
@@ -1064,7 +1064,7 @@ static int submit_iso_write_urb(struct isow_urbctx_t *ucx)
					"%s: buffer busy at frame %d",
					__func__, nframe);
				/* tasklet will be restarted from
				   gigaset_send_skb() */
				   gigaset_isoc_send_skb() */
			} else {
				dev_err(ucx->bcs->cs->dev,
					"%s: buffer error %d at frame %d\n",
+27 −23
Original line number Diff line number Diff line
@@ -463,6 +463,12 @@ void gigaset_freecs(struct cardstate *cs)

	switch (cs->cs_init) {
	default:
		/* clear B channel structures */
		for (i = 0; i < cs->channels; ++i) {
			gig_dbg(DEBUG_INIT, "clearing bcs[%d]", i);
			gigaset_freebcs(cs->bcs + i);
		}

		/* clear device sysfs */
		gigaset_free_dev_sysfs(cs);

@@ -477,22 +483,16 @@ void gigaset_freecs(struct cardstate *cs)
	case 2: /* error in initcshw */
		/* Deregister from LL */
		make_invalid(cs, VALID_ID);
		gig_dbg(DEBUG_INIT, "clearing iif");
		gigaset_i4l_cmd(cs, ISDN_STAT_UNLOAD);
		gigaset_isdn_unregister(cs);

		/* fall through */
	case 1: /* error when regestering to LL */
	case 1: /* error when registering to LL */
		gig_dbg(DEBUG_INIT, "clearing at_state");
		clear_at_state(&cs->at_state);
		dealloc_at_states(cs);

		/* fall through */
	case 0: /* error in one call to initbcs */
		for (i = 0; i < cs->channels; ++i) {
			gig_dbg(DEBUG_INIT, "clearing bcs[%d]", i);
			gigaset_freebcs(cs->bcs + i);
		}

	case 0:	/* error in basic setup */
		clear_events(cs);
		gig_dbg(DEBUG_INIT, "freeing inbuf");
		kfree(cs->inbuf);
@@ -620,12 +620,15 @@ static struct bc_state *gigaset_initbcs(struct bc_state *bcs,
	if (cs->ignoreframes) {
		bcs->inputstate |= INS_skip_frame;
		bcs->skb = NULL;
	} else if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL)
		skb_reserve(bcs->skb, HW_HDR_LEN);
	} else {
		bcs->skb = dev_alloc_skb(SBUFSIZE + cs->hw_hdr_len);
		if (bcs->skb != NULL)
			skb_reserve(bcs->skb, cs->hw_hdr_len);
		else {
			pr_err("out of memory\n");
			bcs->inputstate |= INS_skip_frame;
		}
	}

	bcs->channel = channel;
	bcs->cs = cs;
@@ -726,14 +729,6 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels,
	cs->mode = M_UNKNOWN;
	cs->mstate = MS_UNINITIALIZED;

	for (i = 0; i < channels; ++i) {
		gig_dbg(DEBUG_INIT, "setting up bcs[%d].read", i);
		if (!gigaset_initbcs(cs->bcs + i, cs, i)) {
			pr_err("could not allocate channel %d data\n", i);
			goto error;
		}
	}

	++cs->cs_init;

	gig_dbg(DEBUG_INIT, "setting up at_state");
@@ -758,7 +753,7 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels,
	cs->cmdbytes = 0;

	gig_dbg(DEBUG_INIT, "setting up iif");
	if (!gigaset_register_to_LL(cs, modulename)) {
	if (!gigaset_isdn_register(cs, modulename)) {
		pr_err("error registering ISDN device\n");
		goto error;
	}
@@ -777,6 +772,15 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels,
	/* set up device sysfs */
	gigaset_init_dev_sysfs(cs);

	/* set up channel data structures */
	for (i = 0; i < channels; ++i) {
		gig_dbg(DEBUG_INIT, "setting up bcs[%d]", i);
		if (!gigaset_initbcs(cs->bcs + i, cs, i)) {
			pr_err("could not allocate channel %d data\n", i);
			goto error;
		}
	}

	spin_lock_irqsave(&cs->lock, flags);
	cs->running = 1;
	spin_unlock_irqrestore(&cs->lock, flags);
+36 −28
Original line number Diff line number Diff line
@@ -127,7 +127,6 @@
#define ACT_NOTIFY_BC_UP	39
#define ACT_DIAL		40
#define ACT_ACCEPT		41
#define ACT_PROTO_L2		42
#define ACT_HUP			43
#define ACT_IF_LOCK		44
#define ACT_START		45
@@ -365,8 +364,6 @@ struct reply_t gigaset_tab_cid[] =
	{EV_BC_CLOSED, -1, -1, -1,                 -1,-1, {ACT_NOTIFY_BC_DOWN}}, //FIXME

	/* misc. */
	{EV_PROTO_L2,  -1, -1, -1,                 -1,-1, {ACT_PROTO_L2}}, //FIXME

	{RSP_ZCON,     -1, -1, -1,                 -1,-1, {ACT_DEBUG}}, //FIXME
	{RSP_ZCCR,     -1, -1, -1,                 -1,-1, {ACT_DEBUG}}, //FIXME
	{RSP_ZAOC,     -1, -1, -1,                 -1,-1, {ACT_DEBUG}}, //FIXME
@@ -714,7 +711,7 @@ static void disconnect(struct at_state_t **at_state_p)
		/* notify LL */
		if (bcs->chstate & (CHS_D_UP | CHS_NOTIFY_LL)) {
			bcs->chstate &= ~(CHS_D_UP | CHS_NOTIFY_LL);
			gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DHUP);
			gigaset_isdn_hupD(bcs);
		}
	} else {
		/* no B channel assigned: just deallocate */
@@ -872,12 +869,12 @@ static void bchannel_down(struct bc_state *bcs)
{
	if (bcs->chstate & CHS_B_UP) {
		bcs->chstate &= ~CHS_B_UP;
		gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BHUP);
		gigaset_isdn_hupB(bcs);
	}

	if (bcs->chstate & (CHS_D_UP | CHS_NOTIFY_LL)) {
		bcs->chstate &= ~(CHS_D_UP | CHS_NOTIFY_LL);
		gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DHUP);
		gigaset_isdn_hupD(bcs);
	}

	gigaset_free_channel(bcs);
@@ -894,15 +891,16 @@ static void bchannel_up(struct bc_state *bcs)
	}

	bcs->chstate |= CHS_B_UP;
	gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BCONN);
	gigaset_isdn_connB(bcs);
}

static void start_dial(struct at_state_t *at_state, void *data, unsigned seq_index)
{
	struct bc_state *bcs = at_state->bcs;
	struct cardstate *cs = at_state->cs;
	int retval;
	char **commands = data;
	unsigned long flags;
	int i;

	bcs->chstate |= CHS_NOTIFY_LL;

@@ -913,10 +911,10 @@ static void start_dial(struct at_state_t *at_state, void *data, unsigned seq_ind
	}
	spin_unlock_irqrestore(&cs->lock, flags);

	retval = gigaset_isdn_setup_dial(at_state, data);
	if (retval != 0)
		goto error;

	for (i = 0; i < AT_NUM; ++i) {
		kfree(bcs->commands[i]);
		bcs->commands[i] = commands[i];
	}

	at_state->pending_commands |= PC_CID;
	gig_dbg(DEBUG_CMD, "Scheduling PC_CID");
@@ -924,6 +922,10 @@ static void start_dial(struct at_state_t *at_state, void *data, unsigned seq_ind
	return;

error:
	for (i = 0; i < AT_NUM; ++i) {
		kfree(commands[i]);
		commands[i] = NULL;
	}
	at_state->pending_commands |= PC_NOCID;
	gig_dbg(DEBUG_CMD, "Scheduling PC_NOCID");
	cs->commands_pending = 1;
@@ -933,20 +935,31 @@ static void start_dial(struct at_state_t *at_state, void *data, unsigned seq_ind
static void start_accept(struct at_state_t *at_state)
{
	struct cardstate *cs = at_state->cs;
	int retval;
	struct bc_state *bcs = at_state->bcs;
	int i;

	retval = gigaset_isdn_setup_accept(at_state);
	for (i = 0; i < AT_NUM; ++i) {
		kfree(bcs->commands[i]);
		bcs->commands[i] = NULL;
	}

	if (retval == 0) {
		at_state->pending_commands |= PC_ACCEPT;
		gig_dbg(DEBUG_CMD, "Scheduling PC_ACCEPT");
		cs->commands_pending = 1;
	} else {
	bcs->commands[AT_PROTO] = kmalloc(9, GFP_ATOMIC);
	bcs->commands[AT_ISO] = kmalloc(9, GFP_ATOMIC);
	if (!bcs->commands[AT_PROTO] || !bcs->commands[AT_ISO]) {
		dev_err(at_state->cs->dev, "out of memory\n");
		/* error reset */
		at_state->pending_commands |= PC_HUP;
		gig_dbg(DEBUG_CMD, "Scheduling PC_HUP");
		cs->commands_pending = 1;
		return;
	}

	snprintf(bcs->commands[AT_PROTO], 9, "^SBPR=%u\r", bcs->proto2);
	snprintf(bcs->commands[AT_ISO], 9, "^SISO=%u\r", bcs->channel + 1);

	at_state->pending_commands |= PC_ACCEPT;
	gig_dbg(DEBUG_CMD, "Scheduling PC_ACCEPT");
	cs->commands_pending = 1;
}

static void do_start(struct cardstate *cs)
@@ -957,7 +970,7 @@ static void do_start(struct cardstate *cs)
		schedule_init(cs, MS_INIT);

	cs->isdn_up = 1;
	gigaset_i4l_cmd(cs, ISDN_STAT_RUN);
	gigaset_isdn_start(cs);
					// FIXME: not in locked mode
					// FIXME 2: only after init sequence

@@ -975,7 +988,7 @@ static void finish_shutdown(struct cardstate *cs)
	/* Tell the LL that the device is not available .. */
	if (cs->isdn_up) {
		cs->isdn_up = 0;
		gigaset_i4l_cmd(cs, ISDN_STAT_STOP);
		gigaset_isdn_stop(cs);
	}

	/* The rest is done by cleanup_cs () in user mode. */
@@ -1276,7 +1289,7 @@ static void do_action(int action, struct cardstate *cs,
			break;
		}
		bcs->chstate |= CHS_D_UP;
		gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DCONN);
		gigaset_isdn_connD(bcs);
		cs->ops->init_bchannel(bcs);
		break;
	case ACT_DLE1:
@@ -1284,7 +1297,7 @@ static void do_action(int action, struct cardstate *cs,
		bcs = cs->bcs + cs->curchannel;

		bcs->chstate |= CHS_D_UP;
		gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DCONN);
		gigaset_isdn_connD(bcs);
		cs->ops->init_bchannel(bcs);
		break;
	case ACT_FAKEHUP:
@@ -1474,11 +1487,6 @@ static void do_action(int action, struct cardstate *cs,
	case ACT_ACCEPT:
		start_accept(at_state);
		break;
	case ACT_PROTO_L2:
		gig_dbg(DEBUG_CMD, "set protocol to %u",
			(unsigned) ev->parameter);
		at_state->bcs->proto2 = ev->parameter;
		break;
	case ACT_HUP:
		at_state->pending_commands |= PC_HUP;
		cs->commands_pending = 1;
+27 −63
Original line number Diff line number Diff line
@@ -23,7 +23,6 @@
#include <linux/compiler.h>
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/isdnif.h>
#include <linux/usb.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
@@ -40,7 +39,6 @@

#define MAX_REC_PARAMS 10	/* Max. number of params in response string */
#define MAX_RESP_SIZE 512	/* Max. size of a response string */
#define HW_HDR_LEN 2		/* Header size used to store ack info */

#define MAX_EVENTS 64		/* size of event queue */

@@ -216,7 +214,6 @@ void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg,
#define EV_START	-110
#define EV_STOP		-111
#define EV_IF_LOCK	-112
#define EV_PROTO_L2	-113
#define EV_ACCEPT	-114
#define EV_DIAL		-115
#define EV_HUP		-116
@@ -259,6 +256,11 @@ void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg,
#define SM_LOCKED	0
#define SM_ISDN		1 /* default */

/* layer 2 protocols (AT^SBPR=...) */
#define L2_BITSYNC	0
#define L2_HDLC		1
#define L2_VOICE	2

struct gigaset_ops;
struct gigaset_driver;

@@ -395,7 +397,7 @@ struct bc_state {

	unsigned chstate;		/* bitmap (CHS_*) */
	int ignore;
	unsigned proto2;		/* Layer 2 protocol (ISDN_PROTO_L2_*) */
	unsigned proto2;		/* layer 2 protocol (L2_*) */
	char *commands[AT_NUM];		/* see AT_XXXX */

#ifdef CONFIG_GIGASET_DEBUG
@@ -456,12 +458,13 @@ struct cardstate {

	unsigned running;		/* !=0 if events are handled */
	unsigned connected;		/* !=0 if hardware is connected */
	unsigned isdn_up;		/* !=0 after ISDN_STAT_RUN */
	unsigned isdn_up;		/* !=0 after gigaset_isdn_start() */

	unsigned cidmode;

	int myid;			/* id for communication with LL */
	isdn_if iif;
	void *iif;			/* LL interface structure */
	unsigned short hw_hdr_len;	/* headroom needed in data skbs */

	struct reply_t *tabnocid;
	struct reply_t *tabcid;
@@ -616,7 +619,9 @@ struct gigaset_ops {
	int (*baud_rate)(struct cardstate *cs, unsigned cflag);
	int (*set_line_ctrl)(struct cardstate *cs, unsigned cflag);

	/* Called from i4l.c to put an skb into the send-queue. */
	/* Called from LL interface to put an skb into the send-queue.
	 * After sending is completed, gigaset_skb_sent() must be called
	 * with the first cs->hw_hdr_len bytes of skb->head preserved. */
	int (*send_skb)(struct bc_state *bcs, struct sk_buff *skb);

	/* Called from ev-layer.c to process a block of data
@@ -638,8 +643,7 @@ struct gigaset_ops {
 *  Functions implemented in asyncdata.c
 */

/* Called from i4l.c to put an skb into the send-queue.
 * After sending gigaset_skb_sent() should be called. */
/* Called from LL interface to put an skb into the send queue. */
int gigaset_m10x_send_skb(struct bc_state *bcs, struct sk_buff *skb);

/* Called from ev-layer.c to process a block of data
@@ -650,8 +654,7 @@ void gigaset_m10x_input(struct inbuf_t *inbuf);
 *  Functions implemented in isocdata.c
 */

/* Called from i4l.c to put an skb into the send-queue.
 * After sending gigaset_skb_sent() should be called. */
/* Called from LL interface to put an skb into the send queue. */
int gigaset_isoc_send_skb(struct bc_state *bcs, struct sk_buff *skb);

/* Called from ev-layer.c to process a block of data
@@ -674,36 +677,26 @@ void gigaset_isowbuf_init(struct isowbuf_t *iwb, unsigned char idle);
int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size);

/* ===========================================================================
 *  Functions implemented in i4l.c/gigaset.h
 *  Functions implemented in LL interface
 */

/* Called by gigaset_initcs() for setting up with the isdn4linux subsystem */
int gigaset_register_to_LL(struct cardstate *cs, const char *isdnid);
/* Called from common.c for setting up/shutting down with the ISDN subsystem */
int gigaset_isdn_register(struct cardstate *cs, const char *isdnid);
void gigaset_isdn_unregister(struct cardstate *cs);

/* Called from xxx-gigaset.c to indicate completion of sending an skb */
/* Called from hardware module to indicate completion of an skb */
void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb);
void gigaset_skb_rcvd(struct bc_state *bcs, struct sk_buff *skb);
void gigaset_isdn_rcv_err(struct bc_state *bcs);

/* Called from common.c/ev-layer.c to indicate events relevant to the LL */
void gigaset_isdn_start(struct cardstate *cs);
void gigaset_isdn_stop(struct cardstate *cs);
int gigaset_isdn_icall(struct at_state_t *at_state);
int gigaset_isdn_setup_accept(struct at_state_t *at_state);
int gigaset_isdn_setup_dial(struct at_state_t *at_state, void *data);

void gigaset_i4l_cmd(struct cardstate *cs, int cmd);
void gigaset_i4l_channel_cmd(struct bc_state *bcs, int cmd);


static inline void gigaset_isdn_rcv_err(struct bc_state *bcs)
{
	isdn_ctrl response;

	/* error -> LL */
	gig_dbg(DEBUG_CMD, "sending L1ERR");
	response.driver = bcs->cs->myid;
	response.command = ISDN_STAT_L1ERR;
	response.arg = bcs->channel;
	response.parm.errcode = ISDN_STAT_L1ERR_RECV;
	bcs->cs->iif.statcallb(&response);
}
void gigaset_isdn_connD(struct bc_state *bcs);
void gigaset_isdn_hupD(struct bc_state *bcs);
void gigaset_isdn_connB(struct bc_state *bcs);
void gigaset_isdn_hupB(struct bc_state *bcs);

/* ===========================================================================
 *  Functions implemented in ev-layer.c
@@ -816,35 +809,6 @@ static inline void gigaset_bchannel_up(struct bc_state *bcs)
/* handling routines for sk_buff */
/* ============================= */

/* pass received skb to LL
 * Warning: skb must not be accessed anymore!
 */
static inline void gigaset_rcv_skb(struct sk_buff *skb,
				   struct cardstate *cs,
				   struct bc_state *bcs)
{
	cs->iif.rcvcallb_skb(cs->myid, bcs->channel, skb);
	bcs->trans_down++;
}

/* handle reception of corrupted skb
 * Warning: skb must not be accessed anymore!
 */
static inline void gigaset_rcv_error(struct sk_buff *procskb,
				     struct cardstate *cs,
				     struct bc_state *bcs)
{
	if (procskb)
		dev_kfree_skb(procskb);

	if (bcs->ignore)
		--bcs->ignore;
	else {
		++bcs->corrupted;
		gigaset_isdn_rcv_err(bcs);
	}
}

/* append received bytes to inbuf */
int gigaset_fill_inbuf(struct inbuf_t *inbuf, const unsigned char *src,
		       unsigned numbytes);
Loading