mISDNif.h 14.9 KB
Newer Older
Karsten Keil's avatar
Karsten Keil committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
/*
 *
 * Author	Karsten Keil <kkeil@novell.com>
 *
 * Copyright 2008  by Karsten Keil <kkeil@novell.com>
 *
 * This code is free software; you can redistribute it and/or modify
 * it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE
 * version 2.1 as published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU LESSER GENERAL PUBLIC LICENSE for more details.
 *
 */

#ifndef mISDNIF_H
#define mISDNIF_H

#include <stdarg.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/socket.h>

/*
 * ABI Version 32 bit
 *
 * <8 bit> Major version
 *		- changed if any interface become backwards incompatible
 *
 * <8 bit> Minor version
 *              - changed if any interface is extended but backwards compatible
 *
 * <16 bit> Release number
 *              - should be incremented on every checkin
 */
#define	MISDN_MAJOR_VERSION	1
39
#define	MISDN_MINOR_VERSION	1
40
#define MISDN_RELEASE		29
Karsten Keil's avatar
Karsten Keil committed
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82

/* primitives for information exchange
 * generell format
 * <16  bit  0 >
 * <8  bit command>
 *    BIT 8 = 1 LAYER private
 *    BIT 7 = 1 answer
 *    BIT 6 = 1 DATA
 * <8  bit target layer mask>
 *
 * Layer = 00 is reserved for general commands
   Layer = 01  L2 -> HW
   Layer = 02  HW -> L2
   Layer = 04  L3 -> L2
   Layer = 08  L2 -> L3
 * Layer = FF is reserved for broadcast commands
 */

#define MISDN_CMDMASK		0xff00
#define MISDN_LAYERMASK		0x00ff

/* generell commands */
#define OPEN_CHANNEL		0x0100
#define CLOSE_CHANNEL		0x0200
#define CONTROL_CHANNEL		0x0300
#define CHECK_DATA		0x0400

/* layer 2 -> layer 1 */
#define PH_ACTIVATE_REQ		0x0101
#define PH_DEACTIVATE_REQ	0x0201
#define PH_DATA_REQ		0x2001
#define MPH_ACTIVATE_REQ	0x0501
#define MPH_DEACTIVATE_REQ	0x0601
#define MPH_INFORMATION_REQ	0x0701
#define PH_CONTROL_REQ		0x0801

/* layer 1 -> layer 2 */
#define PH_ACTIVATE_IND		0x0102
#define PH_ACTIVATE_CNF		0x4102
#define PH_DEACTIVATE_IND	0x0202
#define PH_DEACTIVATE_CNF	0x4202
#define PH_DATA_IND		0x2002
83
#define PH_DATA_E_IND		0x3002
Karsten Keil's avatar
Karsten Keil committed
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
#define MPH_ACTIVATE_IND	0x0502
#define MPH_DEACTIVATE_IND	0x0602
#define MPH_INFORMATION_IND	0x0702
#define PH_DATA_CNF		0x6002
#define PH_CONTROL_IND		0x0802
#define PH_CONTROL_CNF		0x4802

/* layer 3 -> layer 2 */
#define DL_ESTABLISH_REQ	0x1004
#define DL_RELEASE_REQ		0x1104
#define DL_DATA_REQ		0x3004
#define DL_UNITDATA_REQ		0x3104
#define DL_INFORMATION_REQ	0x0004

/* layer 2 -> layer 3 */
#define DL_ESTABLISH_IND	0x1008
#define DL_ESTABLISH_CNF	0x5008
#define DL_RELEASE_IND		0x1108
#define DL_RELEASE_CNF		0x5108
#define DL_DATA_IND		0x3008
#define DL_UNITDATA_IND		0x3108
#define DL_INFORMATION_IND	0x0008

107
/* intern layer 2 management */
Karsten Keil's avatar
Karsten Keil committed
108 109 110 111 112 113 114 115 116 117
#define MDL_ASSIGN_REQ		0x1804
#define MDL_ASSIGN_IND		0x1904
#define MDL_REMOVE_REQ		0x1A04
#define MDL_REMOVE_IND		0x1B04
#define MDL_STATUS_UP_IND	0x1C04
#define MDL_STATUS_DOWN_IND	0x1D04
#define MDL_STATUS_UI_IND	0x1E04
#define MDL_ERROR_IND		0x1F04
#define MDL_ERROR_RSP		0x5F04

118 119 120 121 122
/* intern layer 2 */
#define DL_TIMER200_IND		0x7004
#define DL_TIMER203_IND		0x7304
#define DL_INTERN_MSG		0x7804

Karsten Keil's avatar
Karsten Keil committed
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
/* DL_INFORMATION_IND types */
#define DL_INFO_L2_CONNECT	0x0001
#define DL_INFO_L2_REMOVED	0x0002

/* PH_CONTROL types */
/* TOUCH TONE IS 0x20XX  XX "0"..."9", "A","B","C","D","*","#" */
#define DTMF_TONE_VAL		0x2000
#define DTMF_TONE_MASK		0x007F
#define DTMF_TONE_START		0x2100
#define DTMF_TONE_STOP		0x2200
#define DTMF_HFC_COEF		0x4000
#define DSP_CONF_JOIN		0x2403
#define DSP_CONF_SPLIT		0x2404
#define DSP_RECEIVE_OFF		0x2405
#define DSP_RECEIVE_ON		0x2406
#define DSP_ECHO_ON		0x2407
#define DSP_ECHO_OFF		0x2408
#define DSP_MIX_ON		0x2409
#define DSP_MIX_OFF		0x240a
#define DSP_DELAY		0x240b
#define DSP_JITTER		0x240c
#define DSP_TXDATA_ON		0x240d
#define DSP_TXDATA_OFF		0x240e
#define DSP_TX_DEJITTER		0x240f
#define DSP_TX_DEJ_OFF		0x2410
#define DSP_TONE_PATT_ON	0x2411
#define DSP_TONE_PATT_OFF	0x2412
#define DSP_VOL_CHANGE_TX	0x2413
#define DSP_VOL_CHANGE_RX	0x2414
#define DSP_BF_ENABLE_KEY	0x2415
#define DSP_BF_DISABLE		0x2416
#define DSP_BF_ACCEPT		0x2416
#define DSP_BF_REJECT		0x2417
#define DSP_PIPELINE_CFG	0x2418
#define HFC_VOL_CHANGE_TX	0x2601
#define HFC_VOL_CHANGE_RX	0x2602
#define HFC_SPL_LOOP_ON		0x2603
#define HFC_SPL_LOOP_OFF	0x2604
161 162 163 164 165 166 167 168 169 170 171 172
/* for T30 FAX and analog modem */
#define HW_MOD_FRM		0x4000
#define HW_MOD_FRH		0x4001
#define HW_MOD_FTM		0x4002
#define HW_MOD_FTH		0x4003
#define HW_MOD_FTS		0x4004
#define HW_MOD_CONNECT		0x4010
#define HW_MOD_OK		0x4011
#define HW_MOD_NOCARR		0x4012
#define HW_MOD_FCERROR		0x4013
#define HW_MOD_READY		0x4014
#define HW_MOD_LASTDATA		0x4015
Karsten Keil's avatar
Karsten Keil committed
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219

/* DSP_TONE_PATT_ON parameter */
#define TONE_OFF			0x0000
#define TONE_GERMAN_DIALTONE		0x0001
#define TONE_GERMAN_OLDDIALTONE		0x0002
#define TONE_AMERICAN_DIALTONE		0x0003
#define TONE_GERMAN_DIALPBX		0x0004
#define TONE_GERMAN_OLDDIALPBX		0x0005
#define TONE_AMERICAN_DIALPBX		0x0006
#define TONE_GERMAN_RINGING		0x0007
#define TONE_GERMAN_OLDRINGING		0x0008
#define TONE_AMERICAN_RINGPBX		0x000b
#define TONE_GERMAN_RINGPBX		0x000c
#define TONE_GERMAN_OLDRINGPBX		0x000d
#define TONE_AMERICAN_RINGING		0x000e
#define TONE_GERMAN_BUSY		0x000f
#define TONE_GERMAN_OLDBUSY		0x0010
#define TONE_AMERICAN_BUSY		0x0011
#define TONE_GERMAN_HANGUP		0x0012
#define TONE_GERMAN_OLDHANGUP		0x0013
#define TONE_AMERICAN_HANGUP		0x0014
#define TONE_SPECIAL_INFO		0x0015
#define TONE_GERMAN_GASSENBESETZT	0x0016
#define TONE_GERMAN_AUFSCHALTTON	0x0016

/* MPH_INFORMATION_IND */
#define L1_SIGNAL_LOS_OFF	0x0010
#define L1_SIGNAL_LOS_ON	0x0011
#define L1_SIGNAL_AIS_OFF	0x0012
#define L1_SIGNAL_AIS_ON	0x0013
#define L1_SIGNAL_RDI_OFF	0x0014
#define L1_SIGNAL_RDI_ON	0x0015
#define L1_SIGNAL_SLIP_RX	0x0020
#define L1_SIGNAL_SLIP_TX	0x0021

/*
 * protocol ids
 * D channel 1-31
 * B channel 33 - 63
 */

#define ISDN_P_NONE		0
#define ISDN_P_BASE		0
#define ISDN_P_TE_S0		0x01
#define ISDN_P_NT_S0  		0x02
#define ISDN_P_TE_E1		0x03
#define ISDN_P_NT_E1  		0x04
220 221 222 223
#define ISDN_P_TE_UP0		0x05
#define ISDN_P_NT_UP0		0x06

#define IS_ISDN_P_TE(p) ((p == ISDN_P_TE_S0) || (p == ISDN_P_TE_E1) || \
224
				(p == ISDN_P_TE_UP0) || (p == ISDN_P_LAPD_TE))
225
#define IS_ISDN_P_NT(p) ((p == ISDN_P_NT_S0) || (p == ISDN_P_NT_E1) || \
226
				(p == ISDN_P_NT_UP0) || (p == ISDN_P_LAPD_NT))
227 228 229 230 231
#define IS_ISDN_P_S0(p) ((p == ISDN_P_TE_S0) || (p == ISDN_P_NT_S0))
#define IS_ISDN_P_E1(p) ((p == ISDN_P_TE_E1) || (p == ISDN_P_NT_E1))
#define IS_ISDN_P_UP0(p) ((p == ISDN_P_TE_UP0) || (p == ISDN_P_NT_UP0))


Karsten Keil's avatar
Karsten Keil committed
232 233 234 235 236 237 238 239 240 241 242 243
#define ISDN_P_LAPD_TE		0x10
#define	ISDN_P_LAPD_NT		0x11

#define ISDN_P_B_MASK		0x1f
#define ISDN_P_B_START		0x20

#define ISDN_P_B_RAW		0x21
#define ISDN_P_B_HDLC		0x22
#define ISDN_P_B_X75SLP		0x23
#define ISDN_P_B_L2DTMF		0x24
#define ISDN_P_B_L2DSP		0x25
#define ISDN_P_B_L2DSPHDLC	0x26
244 245
#define ISDN_P_B_T30_FAX	0x27
#define ISDN_P_B_MODEM_ASYNC	0x28
Karsten Keil's avatar
Karsten Keil committed
246 247 248 249 250

#define OPTION_L2_PMX		1
#define OPTION_L2_PTP		2
#define OPTION_L2_FIXEDTEI	3
#define OPTION_L2_CLEANUP	4
251
#define OPTION_L1_HOLD		5
Karsten Keil's avatar
Karsten Keil committed
252 253 254 255 256 257 258

/* should be in sync with linux/kobject.h:KOBJ_NAME_LEN */
#define MISDN_MAX_IDLEN		20

struct mISDNhead {
	unsigned int	prim;
	unsigned int	id;
259
}  __packed;
Karsten Keil's avatar
Karsten Keil committed
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277

#define MISDN_HEADER_LEN	sizeof(struct mISDNhead)
#define MAX_DATA_SIZE		2048
#define MAX_DATA_MEM		(MAX_DATA_SIZE + MISDN_HEADER_LEN)
#define MAX_DFRAME_LEN		260

#define MISDN_ID_ADDR_MASK	0xFFFF
#define MISDN_ID_TEI_MASK	0xFF00
#define MISDN_ID_SAPI_MASK	0x00FF
#define MISDN_ID_TEI_ANY	0x7F00

#define MISDN_ID_ANY		0xFFFF
#define MISDN_ID_NONE		0xFFFE

#define GROUP_TEI		127
#define TEI_SAPI		63
#define CTRL_SAPI		0

278 279
#define MISDN_MAX_CHANNEL	127
#define MISDN_CHMAP_SIZE	((MISDN_MAX_CHANNEL + 1) >> 3)
Karsten Keil's avatar
Karsten Keil committed
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301

#define SOL_MISDN	0

struct sockaddr_mISDN {
	sa_family_t    family;
	unsigned char	dev;
	unsigned char	channel;
	unsigned char	sapi;
	unsigned char	tei;
};

struct mISDNversion {
	unsigned char	major;
	unsigned char	minor;
	unsigned short	release;
};

struct mISDN_devinfo {
	u_int			id;
	u_int			Dprotocols;
	u_int			Bprotocols;
	u_int			protocol;
302
	u_char			channelmap[MISDN_CHMAP_SIZE];
Karsten Keil's avatar
Karsten Keil committed
303 304 305 306
	u_int			nrbchan;
	char			name[MISDN_MAX_IDLEN];
};

307 308 309 310 311
struct mISDN_devrename {
	u_int			id;
	char			name[MISDN_MAX_IDLEN]; /* new name */
};

312 313
/* MPH_INFORMATION_REQ payload */
struct ph_info_ch {
314 315
	__u32 protocol;
	__u64 Flags;
316 317 318
};

struct ph_info_dch {
319 320 321
	struct ph_info_ch ch;
	__u16 state;
	__u16 num_bch;
322 323 324
};

struct ph_info {
325 326
	struct ph_info_dch dch;
	struct ph_info_ch  bch[];
327 328
};

329 330 331 332 333 334 335 336 337 338 339
/* timer device ioctl */
#define IMADDTIMER	_IOR('I', 64, int)
#define IMDELTIMER	_IOR('I', 65, int)

/* socket ioctls */
#define	IMGETVERSION	_IOR('I', 66, int)
#define	IMGETCOUNT	_IOR('I', 67, int)
#define IMGETDEVINFO	_IOR('I', 68, int)
#define IMCTRLREQ	_IOR('I', 69, int)
#define IMCLEAR_L2	_IOR('I', 70, int)
#define IMSETDEVNAME	_IOR('I', 71, struct mISDN_devrename)
340
#define IMHOLD_L1	_IOR('I', 72, int)
341

342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362
static inline int
test_channelmap(u_int nr, u_char *map)
{
	if (nr <= MISDN_MAX_CHANNEL)
		return map[nr >> 3] & (1 << (nr & 7));
	else
		return 0;
}

static inline void
set_channelmap(u_int nr, u_char *map)
{
	map[nr >> 3] |= (1 << (nr & 7));
}

static inline void
clear_channelmap(u_int nr, u_char *map)
{
	map[nr >> 3] &= ~(1 << (nr & 7));
}

Karsten Keil's avatar
Karsten Keil committed
363 364 365 366 367
/* CONTROL_CHANNEL parameters */
#define MISDN_CTRL_GETOP		0x0000
#define MISDN_CTRL_LOOP			0x0001
#define MISDN_CTRL_CONNECT		0x0002
#define MISDN_CTRL_DISCONNECT		0x0004
368
#define MISDN_CTRL_RX_BUFFER		0x0008
Karsten Keil's avatar
Karsten Keil committed
369 370 371 372 373
#define MISDN_CTRL_PCMCONNECT		0x0010
#define MISDN_CTRL_PCMDISCONNECT	0x0020
#define MISDN_CTRL_SETPEER		0x0040
#define MISDN_CTRL_UNSETPEER		0x0080
#define MISDN_CTRL_RX_OFF		0x0100
374
#define MISDN_CTRL_FILL_EMPTY		0x0200
375
#define MISDN_CTRL_GETPEER		0x0400
376
#define MISDN_CTRL_L1_TIMER3		0x0800
Karsten Keil's avatar
Karsten Keil committed
377 378 379 380 381 382 383 384 385 386 387
#define MISDN_CTRL_HW_FEATURES_OP	0x2000
#define MISDN_CTRL_HW_FEATURES		0x2001
#define MISDN_CTRL_HFC_OP		0x4000
#define MISDN_CTRL_HFC_PCM_CONN		0x4001
#define MISDN_CTRL_HFC_PCM_DISC		0x4002
#define MISDN_CTRL_HFC_CONF_JOIN	0x4003
#define MISDN_CTRL_HFC_CONF_SPLIT	0x4004
#define MISDN_CTRL_HFC_RECEIVE_OFF	0x4005
#define MISDN_CTRL_HFC_RECEIVE_ON	0x4006
#define MISDN_CTRL_HFC_ECHOCAN_ON 	0x4007
#define MISDN_CTRL_HFC_ECHOCAN_OFF 	0x4008
388 389
#define MISDN_CTRL_HFC_WD_INIT		0x4009
#define MISDN_CTRL_HFC_WD_RESET		0x400A
Karsten Keil's avatar
Karsten Keil committed
390

391 392 393 394 395 396
/* special RX buffer value for MISDN_CTRL_RX_BUFFER request.p1 is the minimum
 * buffer size request.p2 the maximum. Using  MISDN_CTRL_RX_SIZE_IGNORE will
 * not change the value, but still read back the actual stetting.
 */
#define MISDN_CTRL_RX_SIZE_IGNORE	-1

Karsten Keil's avatar
Karsten Keil committed
397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433
/* socket options */
#define MISDN_TIME_STAMP		0x0001

struct mISDN_ctrl_req {
	int		op;
	int		channel;
	int		p1;
	int		p2;
};

/* muxer options */
#define MISDN_OPT_ALL		1
#define MISDN_OPT_TEIMGR	2

#ifdef __KERNEL__
#include <linux/list.h>
#include <linux/skbuff.h>
#include <linux/net.h>
#include <net/sock.h>
#include <linux/completion.h>

#define DEBUG_CORE		0x000000ff
#define DEBUG_CORE_FUNC		0x00000002
#define DEBUG_SOCKET		0x00000004
#define DEBUG_MANAGER		0x00000008
#define DEBUG_SEND_ERR		0x00000010
#define DEBUG_MSG_THREAD	0x00000020
#define DEBUG_QUEUE_FUNC	0x00000040
#define DEBUG_L1		0x0000ff00
#define DEBUG_L1_FSM		0x00000200
#define DEBUG_L2		0x00ff0000
#define DEBUG_L2_FSM		0x00020000
#define DEBUG_L2_CTRL		0x00040000
#define DEBUG_L2_RECV		0x00080000
#define DEBUG_L2_TEI		0x00100000
#define DEBUG_L2_TEIFSM		0x00200000
#define DEBUG_TIMER		0x01000000
434
#define DEBUG_CLOCK		0x02000000
Karsten Keil's avatar
Karsten Keil committed
435 436 437 438 439 440 441 442 443 444 445 446 447

#define mISDN_HEAD_P(s)		((struct mISDNhead *)&s->cb[0])
#define mISDN_HEAD_PRIM(s)	(((struct mISDNhead *)&s->cb[0])->prim)
#define mISDN_HEAD_ID(s)	(((struct mISDNhead *)&s->cb[0])->id)

/* socket states */
#define MISDN_OPEN	1
#define MISDN_BOUND	2
#define MISDN_CLOSED	3

struct mISDNchannel;
struct mISDNdevice;
struct mISDNstack;
448
struct mISDNclock;
Karsten Keil's avatar
Karsten Keil committed
449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499

struct channel_req {
	u_int			protocol;
	struct sockaddr_mISDN	adr;
	struct mISDNchannel	*ch;
};

typedef	int	(ctrl_func_t)(struct mISDNchannel *, u_int, void *);
typedef	int	(send_func_t)(struct mISDNchannel *, struct sk_buff *);
typedef int	(create_func_t)(struct channel_req *);

struct Bprotocol {
	struct list_head	list;
	char			*name;
	u_int			Bprotocols;
	create_func_t		*create;
};

struct mISDNchannel {
	struct list_head	list;
	u_int			protocol;
	u_int			nr;
	u_long			opt;
	u_int			addr;
	struct mISDNstack	*st;
	struct mISDNchannel	*peer;
	send_func_t		*send;
	send_func_t		*recv;
	ctrl_func_t		*ctrl;
};

struct mISDN_sock_list {
	struct hlist_head	head;
	rwlock_t		lock;
};

struct mISDN_sock {
	struct sock		sk;
	struct mISDNchannel	ch;
	u_int			cmask;
	struct mISDNdevice	*dev;
};



struct mISDNdevice {
	struct mISDNchannel	D;
	u_int			id;
	u_int			Dprotocols;
	u_int			Bprotocols;
	u_int			nrbchan;
500
	u_char			channelmap[MISDN_CHMAP_SIZE];
Karsten Keil's avatar
Karsten Keil committed
501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524
	struct list_head	bchannels;
	struct mISDNchannel	*teimgr;
	struct device		dev;
};

struct mISDNstack {
	u_long			status;
	struct mISDNdevice	*dev;
	struct task_struct	*thread;
	struct completion	*notify;
	wait_queue_head_t	workq;
	struct sk_buff_head	msgq;
	struct list_head	layer2;
	struct mISDNchannel	*layer1;
	struct mISDNchannel	own;
	struct mutex		lmutex; /* protect lists */
	struct mISDN_sock_list	l1sock;
#ifdef MISDN_MSG_STATS
	u_int			msg_cnt;
	u_int			sleep_cnt;
	u_int			stopped_cnt;
#endif
};

525 526 527 528 529 530 531 532 533 534
typedef	int	(clockctl_func_t)(void *, int);

struct	mISDNclock {
	struct list_head	list;
	char			name[64];
	int			pri;
	clockctl_func_t		*ctl;
	void			*priv;
};

535
/* global alloc/queue functions */
Karsten Keil's avatar
Karsten Keil committed
536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556

static inline struct sk_buff *
mI_alloc_skb(unsigned int len, gfp_t gfp_mask)
{
	struct sk_buff	*skb;

	skb = alloc_skb(len + MISDN_HEADER_LEN, gfp_mask);
	if (likely(skb))
		skb_reserve(skb, MISDN_HEADER_LEN);
	return skb;
}

static inline struct sk_buff *
_alloc_mISDN_skb(u_int prim, u_int id, u_int len, void *dp, gfp_t gfp_mask)
{
	struct sk_buff	*skb = mI_alloc_skb(len, gfp_mask);
	struct mISDNhead *hh;

	if (!skb)
		return NULL;
	if (len)
557
		skb_put_data(skb, dp, len);
Karsten Keil's avatar
Karsten Keil committed
558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580
	hh = mISDN_HEAD_P(skb);
	hh->prim = prim;
	hh->id = id;
	return skb;
}

static inline void
_queue_data(struct mISDNchannel *ch, u_int prim,
    u_int id, u_int len, void *dp, gfp_t gfp_mask)
{
	struct sk_buff		*skb;

	if (!ch->peer)
		return;
	skb = _alloc_mISDN_skb(prim, id, len, dp, gfp_mask);
	if (!skb)
		return;
	if (ch->recv(ch->peer, skb))
		dev_kfree_skb(skb);
}

/* global register/unregister functions */

581 582
extern int	mISDN_register_device(struct mISDNdevice *,
					struct device *parent, char *name);
Karsten Keil's avatar
Karsten Keil committed
583 584 585
extern void	mISDN_unregister_device(struct mISDNdevice *);
extern int	mISDN_register_Bprotocol(struct Bprotocol *);
extern void	mISDN_unregister_Bprotocol(struct Bprotocol *);
586 587 588
extern struct mISDNclock *mISDN_register_clock(char *, int, clockctl_func_t *,
						void *);
extern void	mISDN_unregister_clock(struct mISDNclock *);
Karsten Keil's avatar
Karsten Keil committed
589

590 591
static inline struct mISDNdevice *dev_to_mISDN(struct device *dev)
{
592 593 594 595
	if (dev)
		return dev_get_drvdata(dev);
	else
		return NULL;
596 597
}

Karsten Keil's avatar
Karsten Keil committed
598
extern void	set_channel_address(struct mISDNchannel *, u_int, u_int);
599
extern void	mISDN_clock_update(struct mISDNclock *, int, ktime_t *);
600
extern unsigned short mISDN_clock_get(void);
601
extern const char *mISDNDevName4ch(struct mISDNchannel *);
Karsten Keil's avatar
Karsten Keil committed
602 603 604

#endif /* __KERNEL__ */
#endif /* mISDNIF_H */