- make mqueue branch HEAD

NEWCTRL_BRANCH
Karsten Keil 17 years ago
parent 44cf601712
commit 56f18961c0
  1. 41
      drivers/isdn/hardware/mISDN/Kconfig.v2.6
  2. 26
      drivers/isdn/hardware/mISDN/Makefile
  3. 27
      drivers/isdn/hardware/mISDN/Makefile.v2.6
  4. 787
      drivers/isdn/hardware/mISDN/app_plci.c
  5. 44
      drivers/isdn/hardware/mISDN/appl.c
  6. 40
      drivers/isdn/hardware/mISDN/arcofi.c
  7. 6
      drivers/isdn/hardware/mISDN/arcofi.h
  8. 19
      drivers/isdn/hardware/mISDN/asn1.h
  9. 74
      drivers/isdn/hardware/mISDN/asn1_comp.c
  10. 23
      drivers/isdn/hardware/mISDN/asn1_enc.c
  11. 2
      drivers/isdn/hardware/mISDN/asn1_enc.h
  12. 565
      drivers/isdn/hardware/mISDN/avm_fritz.c
  13. 156
      drivers/isdn/hardware/mISDN/bchannel.c
  14. 98
      drivers/isdn/hardware/mISDN/bchannel.h
  15. 15
      drivers/isdn/hardware/mISDN/capi.c
  16. 133
      drivers/isdn/hardware/mISDN/contr.c
  17. 116
      drivers/isdn/hardware/mISDN/core.c
  18. 41
      drivers/isdn/hardware/mISDN/core.h
  19. 116
      drivers/isdn/hardware/mISDN/dchannel.c
  20. 92
      drivers/isdn/hardware/mISDN/dchannel.h
  21. 4
      drivers/isdn/hardware/mISDN/debug.h
  22. 98
      drivers/isdn/hardware/mISDN/dsp.h
  23. 2
      drivers/isdn/hardware/mISDN/dsp_blowfish.c
  24. 639
      drivers/isdn/hardware/mISDN/dsp_cmx.c
  25. 506
      drivers/isdn/hardware/mISDN/dsp_core.c
  26. 2
      drivers/isdn/hardware/mISDN/dsp_dtmf.c
  27. 4
      drivers/isdn/hardware/mISDN/dsp_tones.c
  28. 21
      drivers/isdn/hardware/mISDN/dss1.h
  29. 77
      drivers/isdn/hardware/mISDN/dtmf.c
  30. 22
      drivers/isdn/hardware/mISDN/helper.c
  31. 66
      drivers/isdn/hardware/mISDN/helper.h
  32. 3761
      drivers/isdn/hardware/mISDN/hfc_multi.c
  33. 140
      drivers/isdn/hardware/mISDN/hfc_multi.h
  34. 1543
      drivers/isdn/hardware/mISDN/hfc_pci.c
  35. 1826
      drivers/isdn/hardware/mISDN/hfcs_usb.c
  36. 32
      drivers/isdn/hardware/mISDN/hfcs_usb.h
  37. 2
      drivers/isdn/hardware/mISDN/i4l_mISDN.c
  38. 475
      drivers/isdn/hardware/mISDN/isac.c
  39. 10
      drivers/isdn/hardware/mISDN/isac.h
  40. 693
      drivers/isdn/hardware/mISDN/isar.c
  41. 12
      drivers/isdn/hardware/mISDN/isar.h
  42. 819
      drivers/isdn/hardware/mISDN/l3_udss1.c
  43. 124
      drivers/isdn/hardware/mISDN/l3helper.c
  44. 160
      drivers/isdn/hardware/mISDN/layer1.c
  45. 2
      drivers/isdn/hardware/mISDN/layer1.h
  46. 274
      drivers/isdn/hardware/mISDN/layer2.c
  47. 3
      drivers/isdn/hardware/mISDN/layer2.h
  48. 16
      drivers/isdn/hardware/mISDN/layer3.c
  49. 4
      drivers/isdn/hardware/mISDN/layer3.h
  50. 60
      drivers/isdn/hardware/mISDN/m_capi.h
  51. 8
      drivers/isdn/hardware/mISDN/memdbg.c
  52. 60
      drivers/isdn/hardware/mISDN/ncci.c
  53. 3
      drivers/isdn/hardware/mISDN/plci.c
  54. 385
      drivers/isdn/hardware/mISDN/sedl_fax.c
  55. 1005
      drivers/isdn/hardware/mISDN/stack.c
  56. 292
      drivers/isdn/hardware/mISDN/supp_serv.c
  57. 610
      drivers/isdn/hardware/mISDN/udevice.c
  58. 829
      drivers/isdn/hardware/mISDN/w6692.c
  59. 114
      drivers/isdn/hardware/mISDN/x25_dte.c
  60. 52
      drivers/isdn/hardware/mISDN/x25_l3.c
  61. 4
      drivers/isdn/hardware/mISDN/x25_l3.h
  62. 15
      include/linux/isdn_compat.h
  63. 350
      include/linux/mISDNif.h
  64. 19
      std2kern
  65. 2
      stddiff

@ -67,6 +67,18 @@ config MISDN_HFCUSB
Enable support for USB ISDN TAs with Cologne Chip AG's
HFC-S USB ISDN Controller
config MISDN_HFCMINI
bool "Support for 'HFC-S mini' based TAs"
depends on PCI
help
Enable support for Cologne Chip AG's 'HFC-S mini' Evaluation Card
config MISDN_XHFC
bool "Support for XHFC based cards"
depends on PCI
help
Enable support for Cologne Chips AG's XHFC Evaluation Card
config MISDN_SPEEDFAX
bool "Support for Sedlbauer Speedfax+"
depends on PCI || ISA
@ -85,12 +97,39 @@ config MISDN_DSP
Enable support for digital audio processing capability.
This module may be used for special applications that require
cross connecting of bchannels, conferencing, dtmf decoding
tone generation, and Blowfish encryption and decryption.
echo cancelation, tone generation, and Blowfish encryption and
decryption.
It may use hardware features if available.
E.g. it is required for PBX4Linux. Go to http://isdn.jolly.de
and get more informations about this module and it's usage.
If unsure, say 'N'.
config MISDN_LOOP
bool "Loop device"
help
Enable support for loop device.
This module may be used for special applications that provide
bchannel data from user space. Applications can directly
access bchannels, so applications can be integrated into DSP
audio processing.
E.g. it is required for PBX4Linux. Go to http://isdn.jolly.de
and get more informations about this module and it's usage.
If unsure, say 'N'.
config MISDN_L1OIP
bool "ISDN over IP tunnel"
help
Enable support for ISDN over IP tunnel.
It features:
- layer 1 control via network keepalive frames
- dynamic IP exchange, if one or both peers have dynamic IPs
- channel bundeling for reduced IP overhead
- BRI (S0) and PRI (S2M) interface
NOTE: This protocol is called 'Layer 1 over IP' and is not
compatible with ISDNoIP (Agfeo) or TDMoIP.
endif
endmenu

@ -3,6 +3,9 @@
# EXTRA_CFLAGS += -S -g
#
ifdef MINCLUDES
CFLAGS += -I$(MINCLUDES)
endif
ifdef CONFIG_MISDN_MEMDEBUG
EXTRA_CFLAGS += -DMISDN_MEMDEBUG
endif
@ -28,8 +31,13 @@ ifdef CONFIG_MISDN_HFCUSB
obj-$(CONFIG_MISDN_DRV) += hfcsusb.o
endif
ifdef CONFIG_MISDN_HFCMINI
obj-$(CONFIG_MISDN_DRV) += hfcsmini.o
endif
ifdef CONFIG_MISDN_SPEEDFAX
obj-$(CONFIG_MISDN_DRV) += sedlfax.o
# obj-$(CONFIG_MISDN_DRV) += faxl3.o
endif
ifdef CONFIG_MISDN_W6692
@ -40,10 +48,18 @@ ifdef CONFIG_MISDN_HFCMULTI
obj-$(CONFIG_MISDN_DRV) += hfcmulti.o
endif
ifdef CONFIG_MISDN_XHFC
obj-$(CONFIG_MISDN_DRV) += xhfc.o
endif
ifdef CONFIG_MISDN_DSP
obj-$(CONFIG_MISDN_DRV) += mISDN_dsp.o
endif
ifdef CONFIG_MISDN_LOOP
obj-$(CONFIG_MISDN_DRV) += mISDN_loop.o
endif
ifdef CONFIG_I4L_CAPI_LAYER
obj-$(CONFIG_MISDN_DRV) += I4LmISDN.o
endif
@ -54,11 +70,14 @@ sedlfax-objs := sedl_fax.o isar.o
avmfritz-objs := avm_fritz.o
hfcpci-objs := hfc_pci.o
hfcsusb-objs := hfcs_usb.o
hfcsmini-objs := hfcs_mini.o
w6692pci-objs := w6692.o
hfcmulti-objs := hfc_multi.o
xhfc-objs := xhfc_su.o xhfc_pci2pi.o
mISDN_isac-objs := isac.o arcofi.o
mISDN_core-objs := core.o stack.o udevice.o helper.o debug.o fsm.o \
dchannel.o bchannel.o l3helper.o
channel.o l3helper.o \
sysfs_obj.o sysfs_inst.o sysfs_st.o
ifdef CONFIG_MISDN_MEMDEBUG
mISDN_core-objs += memdbg.o
endif
@ -70,8 +89,9 @@ mISDN_capi-objs := capi.o contr.o listen.o appl.o plci.o app_plci.o ncci.o asn1.
asn1_basic_service.o asn1_address.o asn1_enc.o capi_enc.o \
supp_serv.o
mISDN_dtmf-objs := dtmf.o
mISDN_dsp-objs := dsp_core.o dsp_cmx.o dsp_tones.o dsp_dtmf.o dsp_audio.o dsp_blowfish.o
mISDN_dsp-objs := dsp_core.o dsp_cmx.o dsp_tones.o dsp_dtmf.o dsp_audio.o dsp_blowfish.o dsp_cancel.o
mISDN_loop-objs := loop.o
mISDN_x25dte-objs := x25_dte.o x25_l3.o
I4LmISDN-objs := i4l_mISDN.o
include Rules.mISDN

@ -3,6 +3,9 @@
# EXTRA_CFLAGS += -S -g
#
ifdef MINCLUDES
CFLAGS += -I$(MINCLUDES)
endif
ifdef CONFIG_MISDN_MEMDEBUG
EXTRA_CFLAGS += -DMISDN_MEMDEBUG
endif
@ -28,9 +31,13 @@ ifdef CONFIG_MISDN_HFCUSB
obj-$(CONFIG_MISDN_DRV) += hfcsusb.o
endif
ifdef CONFIG_MISDN_HFCMINI
obj-$(CONFIG_MISDN_DRV) += hfcsmini.o
endif
ifdef CONFIG_MISDN_SPEEDFAX
obj-$(CONFIG_MISDN_DRV) += sedlfax.o
obj-$(CONFIG_MISDN_DRV) += faxl3.o
# obj-$(CONFIG_MISDN_DRV) += faxl3.o
endif
ifdef CONFIG_MISDN_W6692
@ -41,10 +48,18 @@ ifdef CONFIG_MISDN_HFCMULTI
obj-$(CONFIG_MISDN_DRV) += hfcmulti.o
endif
ifdef CONFIG_MISDN_XHFC
obj-$(CONFIG_MISDN_DRV) += xhfc.o
endif
ifdef CONFIG_MISDN_DSP
obj-$(CONFIG_MISDN_DRV) += mISDN_dsp.o
endif
ifdef CONFIG_MISDN_LOOP
obj-$(CONFIG_MISDN_DRV) += mISDN_loop.o
endif
ifdef CONFIG_I4L_CAPI_LAYER
obj-$(CONFIG_MISDN_DRV) += I4LmISDN.o
endif
@ -55,11 +70,14 @@ sedlfax-objs := sedl_fax.o isar.o
avmfritz-objs := avm_fritz.o
hfcpci-objs := hfc_pci.o
hfcsusb-objs := hfcs_usb.o
hfcsmini-objs := hfcs_mini.o
w6692pci-objs := w6692.o
hfcmulti-objs := hfc_multi.o
xhfc-objs := xhfc_su.o xhfc_pci2pi.o
mISDN_isac-objs := isac.o arcofi.o
mISDN_core-objs := core.o stack.o udevice.o helper.o debug.o fsm.o \
dchannel.o bchannel.o l3helper.o
channel.o l3helper.o \
sysfs_obj.o sysfs_inst.o sysfs_st.o
ifdef CONFIG_MISDN_MEMDEBUG
mISDN_core-objs += memdbg.o
endif
@ -71,6 +89,9 @@ mISDN_capi-objs := capi.o contr.o listen.o appl.o plci.o app_plci.o ncci.o asn1.
asn1_basic_service.o asn1_address.o asn1_enc.o capi_enc.o \
supp_serv.o
mISDN_dtmf-objs := dtmf.o
mISDN_dsp-objs := dsp_core.o dsp_cmx.o dsp_tones.o dsp_dtmf.o dsp_audio.o dsp_blowfish.o
mISDN_dsp-objs := dsp_core.o dsp_cmx.o dsp_tones.o dsp_dtmf.o dsp_audio.o dsp_blowfish.o dsp_cancel.o
mISDN_loop-objs := loop.o
mISDN_x25dte-objs := x25_dte.o x25_l3.o
I4LmISDN-objs := i4l_mISDN.o

File diff suppressed because it is too large Load Diff

@ -161,45 +161,31 @@ FacilityReq(Application_t *appl, struct sk_buff *skb)
dev_kfree_skb(skb);
}
__u16
void
ApplicationSendMessage(Application_t *appl, struct sk_buff *skb)
{
Plci_t *plci;
AppPlci_t *aplci;
Ncci_t *ncci;
__u16 ret = CAPI_NOERROR;
__u16 ret;
switch (CAPICMD(CAPIMSG_COMMAND(skb->data), CAPIMSG_SUBCOMMAND(skb->data))) {
// for NCCI state machine
case CAPI_DATA_B3_REQ:
case CAPI_DATA_B3_RESP:
case CAPI_CONNECT_B3_RESP:
case CAPI_CONNECT_B3_ACTIVE_RESP:
case CAPI_DISCONNECT_B3_REQ:
case CAPI_DISCONNECT_B3_RESP:
case CAPI_RESET_B3_REQ:
case CAPI_RESET_B3_RESP:
// new NCCI
case CAPI_CONNECT_B3_REQ:
aplci = getAppPlci4addr(appl, CAPIMSG_CONTROL(skb->data));
if (!aplci) {
AnswerMessage2Application(appl, skb, CapiIllContrPlciNcci);
goto free;
}
ncci = getNCCI4addr(aplci, CAPIMSG_NCCI(skb->data), GET_NCCI_EXACT);
if (!ncci) {
int_error();
AnswerMessage2Application(appl, skb, CapiIllContrPlciNcci);
goto free;
}
ret = ncciSendMessage(ncci, skb);
ConnectB3Request(aplci, skb);
break;
// new NCCI
case CAPI_CONNECT_B3_REQ:
// maybe already down NCCI
case CAPI_DISCONNECT_B3_RESP:
aplci = getAppPlci4addr(appl, CAPIMSG_CONTROL(skb->data));
if (!aplci) {
AnswerMessage2Application(appl, skb, CapiIllContrPlciNcci);
goto free;
}
ConnectB3Request(aplci, skb);
DisconnectB3Request(aplci, skb);
break;
// for PLCI state machine
case CAPI_INFO_REQ:
@ -215,6 +201,9 @@ ApplicationSendMessage(Application_t *appl, struct sk_buff *skb)
goto free;
}
ret = AppPlciSendMessage(aplci, skb);
if (ret) {
int_error();
}
break;
case CAPI_CONNECT_REQ:
if (ControllerNewPlci(appl->contr, &plci, MISDN_ID_ANY)) {
@ -227,11 +216,17 @@ ApplicationSendMessage(Application_t *appl, struct sk_buff *skb)
goto free;
}
ret = AppPlciSendMessage(aplci, skb);
if (ret) {
int_error();
}
break;
// for LISTEN state machine
case CAPI_LISTEN_REQ:
ret = listenSendMessage(appl, skb);
if (ret) {
int_error();
}
break;
// other
@ -248,13 +243,12 @@ ApplicationSendMessage(Application_t *appl, struct sk_buff *skb)
default:
applDebug(appl, CAPI_DBG_WARN, "applSendMessage: %#x %#x not handled!",
CAPIMSG_COMMAND(skb->data), CAPIMSG_SUBCOMMAND(skb->data));
ret = CAPI_ILLCMDORSUBCMDORMSGTOSMALL;
break;
}
return(ret);
return;
free:
dev_kfree_skb(skb);
return(ret);
return;
}
AppPlci_t *

@ -8,19 +8,20 @@
*
*/
#include "dchannel.h"
#include "channel.h"
#include "layer1.h"
#include "isac.h"
#include "arcofi.h"
#include "debug.h"
#include "helper.h"
#define ARCOFI_TIMER_VALUE 20
static void
add_arcofi_timer(dchannel_t *dch) {
add_arcofi_timer(channel_t *dch) {
isac_chip_t *isac = dch->hw;
if (test_and_set_bit(FLG_ARCOFI_TIMER, &dch->DFlags)) {
if (test_and_set_bit(FLG_ARCOFI_TIMER, &dch->Flags)) {
del_timer(&isac->arcofitimer);
}
init_timer(&isac->arcofitimer);
@ -29,7 +30,7 @@ add_arcofi_timer(dchannel_t *dch) {
}
static void
send_arcofi(dchannel_t *dch) {
send_arcofi(channel_t *dch) {
u_char val;
isac_chip_t *isac = dch->hw;
@ -45,15 +46,15 @@ send_arcofi(dchannel_t *dch) {
}
isac->mocr &= 0x0f;
isac->mocr |= 0xa0;
dch->write_reg(dch->inst.data, ISAC_MOCR, isac->mocr);
val = dch->read_reg(dch->inst.data, ISAC_MOSR);
dch->write_reg(dch->inst.data, ISAC_MOX1, isac->mon_tx[isac->mon_txp++]);
dch->write_reg(dch->inst.privat, ISAC_MOCR, isac->mocr);
val = dch->read_reg(dch->inst.privat, ISAC_MOSR);
dch->write_reg(dch->inst.privat, ISAC_MOX1, isac->mon_tx[isac->mon_txp++]);
isac->mocr |= 0x10;
dch->write_reg(dch->inst.data, ISAC_MOCR, isac->mocr);
dch->write_reg(dch->inst.privat, ISAC_MOCR, isac->mocr);
}
int
arcofi_fsm(dchannel_t *dch, int event, void *data) {
arcofi_fsm(channel_t *dch, int event, void *data) {
isac_chip_t *isac = dch->hw;
if (dch->debug & L1_DEB_MONITOR) {
@ -61,7 +62,7 @@ arcofi_fsm(dchannel_t *dch, int event, void *data) {
}
if (event == ARCOFI_TIMEOUT) {
isac->arcofi_state = ARCOFI_NOP;
test_and_set_bit(FLG_ARCOFI_ERROR, &dch->DFlags);
test_and_set_bit(FLG_ARCOFI_ERROR, &dch->Flags);
wake_up(&isac->arcofi_wait);
return(1);
}
@ -84,7 +85,7 @@ arcofi_fsm(dchannel_t *dch, int event, void *data) {
isac->arcofi_list->next;
send_arcofi(dch);
} else {
if (test_and_clear_bit(FLG_ARCOFI_TIMER, &dch->DFlags)) {
if (test_and_clear_bit(FLG_ARCOFI_TIMER, &dch->Flags)) {
del_timer(&isac->arcofitimer);
}
isac->arcofi_state = ARCOFI_NOP;
@ -95,13 +96,20 @@ arcofi_fsm(dchannel_t *dch, int event, void *data) {
break;
case ARCOFI_RECEIVE:
if (event == ARCOFI_RX_END) {
struct sk_buff *skb = data;
// FIXME handle message
if (skb)
kfree_skb(skb);
else
int_error();
if (isac->arcofi_list->next) {
isac->arcofi_list =
isac->arcofi_list->next;
isac->arcofi_state = ARCOFI_TRANSMIT;
send_arcofi(dch);
} else {
if (test_and_clear_bit(FLG_ARCOFI_TIMER, &dch->DFlags)) {
if (test_and_clear_bit(FLG_ARCOFI_TIMER, &dch->Flags)) {
del_timer(&isac->arcofitimer);
}
isac->arcofi_state = ARCOFI_NOP;
@ -117,21 +125,21 @@ arcofi_fsm(dchannel_t *dch, int event, void *data) {
}
static void
arcofi_timer(dchannel_t *dch) {
arcofi_timer(channel_t *dch) {
arcofi_fsm(dch, ARCOFI_TIMEOUT, NULL);
}
void
clear_arcofi(dchannel_t *dch) {
clear_arcofi(channel_t *dch) {
isac_chip_t *isac = dch->hw;
if (test_and_clear_bit(FLG_ARCOFI_TIMER, &dch->DFlags)) {
if (test_and_clear_bit(FLG_ARCOFI_TIMER, &dch->Flags)) {
del_timer(&isac->arcofitimer);
}
}
void
init_arcofi(dchannel_t *dch) {
init_arcofi(channel_t *dch) {
isac_chip_t *isac = dch->hw;
isac->arcofitimer.function = (void *) arcofi_timer;

@ -27,6 +27,6 @@ struct arcofi_msg {
u_char msg[10];
};
extern int arcofi_fsm(dchannel_t *, int, void *);
extern void init_arcofi(dchannel_t *);
extern void clear_arcofi(dchannel_t *);
extern int arcofi_fsm(channel_t *, int, void *);
extern void init_arcofi(channel_t *);
extern void clear_arcofi(channel_t *);

@ -15,6 +15,13 @@ typedef enum {
reject = 4,
} asn1Component;
typedef enum {
GeneralP = 0,
InvokeP = 1,
ReturnResultP= 2,
ReturnErrorP = 3,
} asn1Problem;
struct PublicPartyNumber {
int publicTypeOfNumber;
char numberDigits[30];
@ -88,20 +95,28 @@ struct asn1ReturnError {
__u16 errorValue;
};
struct asn1Reject {
int invokeId;
asn1Problem problem;
__u16 problemValue;
};
struct asn1_parm {
asn1Component comp;
union {
struct asn1Invoke inv;
struct asn1ReturnResult retResult;
struct asn1ReturnError retError;
struct asn1Reject reject;
} u;
};
#undef ASN1_DEBUG
// #define ASN1_DEBUG
#ifdef ASN1_DEBUG
#define print_asn1msg(dummy, fmt, args...) printk(fmt, ## args)
#define print_asn1msg(dummy, fmt, args...) printk(KERN_DEBUG fmt, ## args)
#else
#define print_asn1msg(dummy, fmt, args...)
#endif
@ -194,7 +209,7 @@ int ParseLen(u_char *p, u_char *end, int *len);
} else { \
if (!(the_tag) & ASN1_TAG_OPT) { \
print_asn1msg(PRT_DEBUG_DECODE, " DEBUG> err 4 %s:%d\n", __FUNCTION__, __LINE__); \
return -1; \
return -1; \
} \
} \
} while (0)

@ -137,6 +137,68 @@ ParseReturnErrorComponent(struct asn1_parm *pc, u_char *p, u_char *end, int dumm
return p - beg;
}
int
ParseProblemValue(struct asn1_parm *pc, u_char *p, u_char *end, asn1Problem prob)
{
INIT;
pc->u.reject.problem = prob;
print_asn1msg(PRT_DEBUG_DECODE, "ParseProblemValue: %d %d\n", prob, *p);
pc->u.reject.problemValue = *p++;
return p - beg;
}
int
ParseRejectProblem(struct asn1_parm *pc, u_char *p, u_char *end)
{
INIT;
XCHOICE_1(ParseProblemValue, ASN1_TAG_CONTEXT_SPECIFIC, 0, GeneralP);
XCHOICE_1(ParseProblemValue, ASN1_TAG_CONTEXT_SPECIFIC, 1, InvokeP);
XCHOICE_1(ParseProblemValue, ASN1_TAG_CONTEXT_SPECIFIC, 2, ReturnResultP);
XCHOICE_1(ParseProblemValue, ASN1_TAG_CONTEXT_SPECIFIC, 3, ReturnErrorP);
XCHOICE_DEFAULT;
}
int
ParseRejectComponent(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
{
int invokeId = -1;
int rval;
INIT;
pc->comp = reject;
XSEQUENCE_OPT_1(ParseInvokeId, ASN1_TAG_INTEGER, ASN1_NOT_TAGGED, &invokeId);
XSEQUENCE_OPT(ParseNull, ASN1_TAG_NULL, ASN1_NOT_TAGGED);
print_asn1msg(PRT_DEBUG_DECODE, "ParseRejectComponent: invokeId %d\n", invokeId);
pc->u.reject.invokeId = invokeId;
rval = ParseRejectProblem(pc, p, end);
print_asn1msg(PRT_DEBUG_DECODE, "ParseRejectComponent: rval %d\n", rval);
if (rval > 0)
p += rval;
else
return(-1);
return p - beg;
}
int
ParseUnknownComponent(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
{
int invokeId;
INIT;
pc->comp = tag;
return end - beg;
}
int
ParseComponent(struct asn1_parm *pc, u_char *p, u_char *end)
{
@ -145,7 +207,17 @@ ParseComponent(struct asn1_parm *pc, u_char *p, u_char *end)
XCHOICE(ParseInvokeComponent, ASN1_TAG_SEQUENCE, 1);
XCHOICE(ParseReturnResultComponent, ASN1_TAG_SEQUENCE, 2);
XCHOICE(ParseReturnErrorComponent, ASN1_TAG_SEQUENCE, 3);
// XCHOICE(ParseRejectComponent, ASN1_TAG_SEQUENCE, 4);
XCHOICE(ParseRejectComponent, ASN1_TAG_SEQUENCE, 4);
XCHOICE(ParseUnknownComponent, ASN1_TAG_SEQUENCE, 5);
XCHOICE(ParseUnknownComponent, ASN1_TAG_SEQUENCE, 6);
XCHOICE(ParseUnknownComponent, ASN1_TAG_SEQUENCE, 7);
XCHOICE(ParseUnknownComponent, ASN1_TAG_SEQUENCE, 8);
XCHOICE(ParseUnknownComponent, ASN1_TAG_SEQUENCE, 9);
XCHOICE(ParseUnknownComponent, ASN1_TAG_SEQUENCE, 10);
XCHOICE(ParseUnknownComponent, ASN1_TAG_SEQUENCE, 11);
XCHOICE(ParseUnknownComponent, ASN1_TAG_SEQUENCE, 12);
XCHOICE(ParseUnknownComponent, ASN1_TAG_SEQUENCE, 13);
XCHOICE(ParseUnknownComponent, ASN1_TAG_SEQUENCE, 14);
XCHOICE_DEFAULT;
}

@ -13,6 +13,14 @@ int encodeNull(__u8 *dest)
return 2;
}
int encodeBoolean(__u8 *dest, __u32 i)
{
dest[0] = 0x01; // BOOLEAN
dest[1] = 1; // length 1
dest[3] = i ? 1:0; // Value
return 3;
}
int encodeInt(__u8 *dest, __u32 i)
{
__u8 *p;
@ -176,3 +184,18 @@ int encodeInterrogationDiversion(__u8 *dest, struct FacReqCFInterrogateParameter
return p - dest;
}
int encodeInvokeDeflection(__u8 *dest, struct FacReqCDeflection *CD)
{
__u8 *p;
dest[0] = 0x30; // sequence
dest[1] = 0; // length
p = &dest[2];
p += encodeAddress(p, CD->DeflectedToNumber, CD->DeflectedToSubaddress);
p += encodeBoolean(p, CD->PresentationAllowed);
dest[1] = p - &dest[2];
return p - dest;
}

@ -5,6 +5,7 @@
#include "asn1.h"
int encodeNull(__u8 *dest);
int encodeBoolean(__u8 *dest, __u32 i);
int encodeInt(__u8 *dest, __u32 i);
int encodeEnum(__u8 *dest, __u32 i);
int encodeNumberDigits(__u8 *dest, __u8 *nd, __u8 len);
@ -15,3 +16,4 @@ int encodeAddress(__u8 *dest, __u8 *facilityPartyNumber, __u8 *calledPartySubadd
int encodeActivationDiversion(__u8 *dest, struct FacReqCFActivate *CFActivate);
int encodeDeactivationDiversion(__u8 *dest,struct FacReqCFDeactivate *CFDeactivate);
int encodeInterrogationDiversion(__u8 *dest, struct FacReqCFInterrogateParameters *params);
int encodeInvokeDeflection(__u8 *dest, struct FacReqCDeflection *CD);

@ -17,16 +17,11 @@
#include <linux/isapnp.h>
#endif
#include <linux/delay.h>
#include "dchannel.h"
#include "bchannel.h"
#include "channel.h"
#include "isac.h"
#include "layer1.h"
#include "helper.h"
#include "debug.h"
#define SPIN_DEBUG
#define LOCK_STATISTIC
#include "hw_lock.h"
static const char *avm_fritz_rev = "$Revision$";
@ -131,34 +126,29 @@ typedef struct hdlc_hw {
typedef struct _fritzpnppci {
struct list_head list;
void *pdev;
union {
#if defined(CONFIG_PNP)
#ifdef NEW_ISAPNP
struct pnp_dev *pnp;
#else
struct pci_dev *pnp;
#endif
#endif
struct pci_dev *pci;
} dev;
u_int type;
u_int irq;
u_int irqcnt;
u_int addr;
mISDN_HWlock_t lock;
spinlock_t lock;
isac_chip_t isac;
hdlc_hw_t hdlc[2];
dchannel_t dch;
bchannel_t bch[2];
channel_t dch;
channel_t bch[2];
u_char ctrlreg;
} fritzpnppci;
static int lock_dev(void *data, int nowait)
{
register mISDN_HWlock_t *lock = &((fritzpnppci *)data)->lock;
return(lock_HW(lock, nowait));
}
static void unlock_dev(void *data)
{
register mISDN_HWlock_t *lock = &((fritzpnppci *)data)->lock;
unlock_HW(lock);
}
/* Interface functions */
static u_char
@ -244,11 +234,11 @@ fcpci2_write_isac_fifo(void *fc, unsigned char * data, int size)
}
static inline
bchannel_t *Sel_BCS(fritzpnppci *fc, int channel)
channel_t *Sel_BCS(fritzpnppci *fc, int channel)
{
if (fc->bch[0].protocol && (fc->bch[0].channel == channel))
if (test_bit(FLG_ACTIVE, &fc->bch[0].Flags) && (fc->bch[0].channel == channel))
return(&fc->bch[0]);
else if (fc->bch[1].protocol && (fc->bch[1].channel == channel))
else if (test_bit(FLG_ACTIVE, &fc->bch[1].Flags) && (fc->bch[1].channel == channel))
return(&fc->bch[1]);
else
return(NULL);
@ -281,8 +271,8 @@ __write_ctrl_pciv2(fritzpnppci *fc, hdlc_hw_t *hdlc, int channel) {
}
void
write_ctrl(bchannel_t *bch, int which) {
fritzpnppci *fc = bch->inst.data;
write_ctrl(channel_t *bch, int which) {
fritzpnppci *fc = bch->inst.privat;
hdlc_hw_t *hdlc = bch->hw;
if (fc->dch.debug & L1_DEB_HSCX)
@ -343,48 +333,64 @@ read_status(fritzpnppci *fc, int channel)
return(0);
}
static void
enable_hwirq(fritzpnppci *fc)
{
fc->ctrlreg |= AVM_STATUS0_ENA_IRQ;
outb(fc->ctrlreg, fc->addr + 2);
}
static void
disable_hwirq(fritzpnppci *fc)
{
fc->ctrlreg &= ~((u_char)AVM_STATUS0_ENA_IRQ);
outb(fc->ctrlreg, fc->addr + 2);
}
static int
modehdlc(bchannel_t *bch, int bc, int protocol)
modehdlc(channel_t *bch, int bc, int protocol)
{
hdlc_hw_t *hdlc = bch->hw;
if (bch->debug & L1_DEB_HSCX)
mISDN_debugprint(&bch->inst, "hdlc %c protocol %x-->%x ch %d-->%d",
'A' + bch->channel, bch->protocol, protocol, bch->channel, bc);
'A' + bch->channel, bch->state, protocol, bch->channel, bc);
if ((protocol != -1) && (bc != bch->channel))
printk(KERN_WARNING "%s: fritzcard mismatch channel(%d/%d)\n", __FUNCTION__, bch->channel, bc);
hdlc->ctrl.ctrl = 0;
switch (protocol) {
case (-1): /* used for init */
bch->protocol = -1;
bch->state = -1;
bch->channel = bc;
case (ISDN_PID_NONE):
if (bch->protocol == ISDN_PID_NONE)
if (bch->state == ISDN_PID_NONE)
break;
hdlc->ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS;
hdlc->ctrl.sr.mode = HDLC_MODE_TRANS;
write_ctrl(bch, 5);
bch->protocol = ISDN_PID_NONE;
bch->state = ISDN_PID_NONE;
test_and_clear_bit(FLG_HDLC, &bch->Flags);
test_and_clear_bit(FLG_TRANSPARENT, &bch->Flags);
break;
case (ISDN_PID_L1_B_64TRANS):
bch->protocol = protocol;
bch->state = protocol;
hdlc->ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS;
hdlc->ctrl.sr.mode = HDLC_MODE_TRANS;
write_ctrl(bch, 5);
hdlc->ctrl.sr.cmd = HDLC_CMD_XRS;
write_ctrl(bch, 1);
hdlc->ctrl.sr.cmd = 0;
bch_sched_event(bch, B_XMTBUFREADY);
test_and_set_bit(FLG_TRANSPARENT, &bch->Flags);
break;
case (ISDN_PID_L1_B_64HDLC):
bch->protocol = protocol;
bch->state = protocol;
hdlc->ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS;
hdlc->ctrl.sr.mode = HDLC_MODE_ITF_FLG;
write_ctrl(bch, 5);
hdlc->ctrl.sr.cmd = HDLC_CMD_XRS;
write_ctrl(bch, 1);
hdlc->ctrl.sr.cmd = 0;
bch_sched_event(bch, B_XMTBUFREADY);
test_and_set_bit(FLG_HDLC, &bch->Flags);
break;
default:
mISDN_debugprint(&bch->inst, "prot not known %x", protocol);
@ -394,24 +400,30 @@ modehdlc(bchannel_t *bch, int bc, int protocol)
}
static void
hdlc_empty_fifo(bchannel_t *bch, int count)
hdlc_empty_fifo(channel_t *bch, int count)
{
register u_int *ptr;
u_char *p;
u_char idx = bch->channel ? AVM_HDLC_2 : AVM_HDLC_1;
int cnt=0;
fritzpnppci *fc = bch->inst.data;
fritzpnppci *fc = bch->inst.privat;
if ((fc->dch.debug & L1_DEB_HSCX) && !(fc->dch.debug & L1_DEB_HSCX_FIFO))
mISDN_debugprint(&bch->inst, "hdlc_empty_fifo %d", count);
if (bch->rx_idx + count > MAX_DATA_MEM) {
if (fc->dch.debug & L1_DEB_WARN)
mISDN_debugprint(&bch->inst, "hdlc_empty_fifo: incoming packet too large");
if (!bch->rx_skb) {
if (!(bch->rx_skb = alloc_stack_skb(bch->maxlen, bch->up_headerlen))) {
printk(KERN_WARNING "mISDN: B receive out of memory\n");
return;
}
}
if ((bch->rx_skb->len + count) > bch->maxlen) {
if (bch->debug & L1_DEB_WARN)
mISDN_debugprint(&bch->inst, "hdlc_empty_fifo overrun %d",
bch->rx_skb->len + count);
return;
}
p = bch->rx_buf + bch->rx_idx;
p = skb_put(bch->rx_skb, count);
ptr = (u_int *)p;
bch->rx_idx += count;
if (fc->type == AVM_FRITZ_PCIV2) {
while (cnt < count) {
#ifdef __powerpc__
@ -447,23 +459,23 @@ hdlc_empty_fifo(bchannel_t *bch, int count)
}
}
if (fc->dch.debug & L1_DEB_HSCX_FIFO) {
char *t = bch->blog;
char *t = bch->log;
if (fc->type == AVM_FRITZ_PNP)
p = (u_char *) ptr;
t += sprintf(t, "hdlc_empty_fifo %c cnt %d",
bch->channel ? 'B' : 'A', count);
mISDN_QuickHex(t, p, count);
mISDN_debugprint(&bch->inst, bch->blog);
mISDN_debugprint(&bch->inst, bch->log);
}
}
#define HDLC_FIFO_SIZE 32
static void
hdlc_fill_fifo(bchannel_t *bch)
hdlc_fill_fifo(channel_t *bch)
{
fritzpnppci *fc = bch->inst.data;
fritzpnppci *fc = bch->inst.privat;
hdlc_hw_t *hdlc = bch->hw;
int count, cnt =0;
u_char *p;
@ -471,15 +483,17 @@ hdlc_fill_fifo(bchannel_t *bch)
if ((bch->debug & L1_DEB_HSCX) && !(bch->debug & L1_DEB_HSCX_FIFO))
mISDN_debugprint(&bch->inst, "%s", __FUNCTION__);
count = bch->tx_len - bch->tx_idx;
if (!bch->tx_skb)
return;
count = bch->tx_skb->len - bch->tx_idx;
if (count <= 0)
return;
p = bch->tx_buf + bch->tx_idx;
p = bch->tx_skb->data + bch->tx_idx;
hdlc->ctrl.sr.cmd &= ~HDLC_CMD_XME;
if (count > HDLC_FIFO_SIZE) {
count = HDLC_FIFO_SIZE;
} else {
if (bch->protocol != ISDN_PID_L1_B_64TRANS)
if (test_bit(FLG_HDLC, &bch->Flags))
hdlc->ctrl.sr.cmd |= HDLC_CMD_XME;
}
if ((bch->debug & L1_DEB_HSCX) && !(bch->debug & L1_DEB_HSCX_FIFO))
@ -524,44 +538,49 @@ hdlc_fill_fifo(bchannel_t *bch)
}
}
if (bch->debug & L1_DEB_HSCX_FIFO) {
char *t = bch->blog;
char *t = bch->log;
if (fc->type == AVM_FRITZ_PNP)
p = (u_char *) ptr;
t += sprintf(t, "hdlc_fill_fifo %c cnt %d",
bch->channel ? 'B' : 'A', count);
mISDN_QuickHex(t, p, count);
mISDN_debugprint(&bch->inst, bch->blog);
mISDN_debugprint(&bch->inst, bch->log);
}
}
static void
HDLC_irq_xpr(bchannel_t *bch)
HDLC_irq_xpr(channel_t *bch)
{
if (bch->tx_idx < bch->tx_len)
if (bch->tx_skb && bch->tx_idx < bch->tx_skb->len)
hdlc_fill_fifo(bch);
else {
if (bch->tx_skb)
dev_kfree_skb(bch->tx_skb);
bch->tx_idx = 0;
if (test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag)) {
if (bch->next_skb) {
bch->tx_len = bch->next_skb->len;
memcpy(bch->tx_buf, bch->next_skb->data, bch->tx_len);
if (test_bit(FLG_TX_NEXT, &bch->Flags)) {
bch->tx_skb = bch->next_skb;
if (bch->tx_skb) {
mISDN_head_t *hh = mISDN_HEAD_P(bch->tx_skb);
bch->next_skb = NULL;
test_and_clear_bit(FLG_TX_NEXT, &bch->Flags);
queue_ch_frame(bch, CONFIRM, hh->dinfo, NULL);
hdlc_fill_fifo(bch);
} else {
bch->tx_len = 0;
printk(KERN_WARNING "hdlc tx irq TX_NEXT without skb\n");
test_and_clear_bit(BC_FLG_TX_BUSY, &bch->Flag);
test_and_clear_bit(FLG_TX_NEXT, &bch->Flags);
test_and_clear_bit(FLG_TX_BUSY, &bch->Flags);
}
} else {
bch->tx_len = 0;
test_and_clear_bit(BC_FLG_TX_BUSY, &bch->Flag);
bch->tx_skb = NULL;
test_and_clear_bit(FLG_TX_BUSY, &bch->Flags);
}
bch_sched_event(bch, B_XMTBUFREADY);
}
}
static void
HDLC_irq(bchannel_t *bch, u_int stat)
HDLC_irq(channel_t *bch, u_int stat)
{
int len;
struct sk_buff *skb;
@ -580,43 +599,58 @@ HDLC_irq(bchannel_t *bch, u_int stat)
write_ctrl(bch, 1);
hdlc->ctrl.sr.cmd &= ~HDLC_CMD_RRS;
write_ctrl(bch, 1);
bch->rx_idx = 0;
if (bch->rx_skb)
skb_trim(bch->rx_skb, 0);
} else {
if (!(len = (stat & HDLC_STAT_RML_MASK)>>8))
len = 32;
hdlc_empty_fifo(bch, len);
if ((stat & HDLC_STAT_RME) || (bch->protocol == ISDN_PID_L1_B_64TRANS)) {
if (!bch->rx_skb)
goto handle_tx;
if ((stat & HDLC_STAT_RME) || test_bit(FLG_TRANSPARENT, &bch->Flags)) {
if (((stat & HDLC_STAT_CRCVFRRAB)==HDLC_STAT_CRCVFR) ||
(bch->protocol == ISDN_PID_L1_B_64TRANS)) {
if (!(skb = alloc_stack_skb(bch->rx_idx, bch->up_headerlen)))
printk(KERN_WARNING "HDLC: receive out of memory\n");
else {
memcpy(skb_put(skb, bch->rx_idx),
bch->rx_buf, bch->rx_idx);
skb_queue_tail(&bch->rqueue, skb);
test_bit(FLG_TRANSPARENT, &bch->Flags)) {
if (bch->rx_skb->len < MISDN_COPY_SIZE) {
skb = alloc_stack_skb(bch->rx_skb->len, bch->up_headerlen);
if (skb) {
memcpy(skb_put(skb, bch->rx_skb->len),
bch->rx_skb->data, bch->rx_skb->len);
skb_trim(bch->rx_skb, 0);
} else {
skb = bch->rx_skb;
bch->rx_skb = NULL;
}
} else {
skb = bch->rx_skb;
bch->rx_skb = NULL;
}
bch->rx_idx = 0;
bch_sched_event(bch, B_RCVBUFREADY);
queue_ch_frame(bch, INDICATION, MISDN_ID_ANY, skb);
} else {
if (bch->debug & L1_DEB_HSCX)
mISDN_debugprint(&bch->inst, "invalid frame");
else
mISDN_debugprint(&bch->inst, "ch%d invalid frame %#x", bch->channel, stat);
bch->rx_idx = 0;
skb_trim(bch->rx_skb, 0);
}
}
}
}
handle_tx:
if (stat & HDLC_INT_XDU) {
/* Here we lost an TX interrupt, so
* restart transmitting the whole frame on HDLC
* in transparent mode we send the next data
*/
if (bch->debug & L1_DEB_WARN)
mISDN_debugprint(&bch->inst, "ch%d XDU tx_len(%d) tx_idx(%d) Flag(%lx)",
bch->channel, bch->tx_len, bch->tx_idx, bch->Flag);
if (bch->tx_len) {
if (bch->protocol != ISDN_PID_L1_B_64TRANS)
if (bch->debug & L1_DEB_WARN) {
if (bch->tx_skb)
mISDN_debugprint(&bch->inst, "ch%d XDU tx_len(%d) tx_idx(%d) Flags(%lx)",
bch->channel, bch->tx_skb->len, bch->tx_idx, bch->Flags);
else
mISDN_debugprint(&bch->inst, "ch%d XDU no tx_skb Flags(%lx)",
bch->channel, bch->Flags);
}
if (bch->tx_skb && bch->tx_skb->len) {
if (!test_bit(FLG_TRANSPARENT, &bch->Flags))
bch->tx_idx = 0;
}
hdlc->ctrl.sr.xml = 0;
@ -633,7 +667,7 @@ static inline void
HDLC_irq_main(fritzpnppci *fc)
{
u_int stat;
bchannel_t *bch;
channel_t *bch;
stat = read_status(fc, 0);
if (stat & HDLC_INT_MASK) {
@ -657,50 +691,20 @@ static irqreturn_t
avm_fritz_interrupt(int intno, void *dev_id, struct pt_regs *regs)
{
fritzpnppci *fc = dev_id;
u_long flags;
u_char val;
u_char sval;
spin_lock_irqsave(&fc->lock.lock, flags);
#ifdef SPIN_DEBUG
fc->lock.spin_adr = (void *)0x2001;
#endif
spin_lock(&fc->lock);
sval = inb(fc->addr + 2);
if (fc->dch.debug & L1_DEB_INTSTAT)
mISDN_debugprint(&fc->dch.inst, "irq stat0 %x", sval);
if ((sval & AVM_STATUS0_IRQ_MASK) == AVM_STATUS0_IRQ_MASK) {
/* possible a shared IRQ reqest */
#ifdef SPIN_DEBUG
fc->lock.spin_adr = NULL;
#endif
spin_unlock_irqrestore(&fc->lock.lock, flags);
spin_unlock(&fc->lock);
return IRQ_NONE;
}
fc->irqcnt++;
if (test_and_set_bit(STATE_FLAG_BUSY, &fc->lock.state)) {
printk(KERN_ERR "%s: STATE_FLAG_BUSY allready activ, should never happen state:%lx\n",
__FUNCTION__, fc->lock.state);
#ifdef SPIN_DEBUG
printk(KERN_ERR "%s: previous lock:%p\n",
__FUNCTION__, fc->lock.busy_adr);
#endif
#ifdef LOCK_STATISTIC
fc->lock.irq_fail++;
#endif
} else {
#ifdef LOCK_STATISTIC
fc->lock.irq_ok++;
#endif
#ifdef SPIN_DEBUG
fc->lock.busy_adr = avm_fritz_interrupt;
#endif
}
test_and_set_bit(STATE_FLAG_INIRQ, &fc->lock.state);
#ifdef SPIN_DEBUG
fc->lock.spin_adr = NULL;
#endif
spin_unlock_irqrestore(&fc->lock.lock, flags);
if (!(sval & AVM_STATUS0_IRQ_ISAC)) {
val = ReadISAC(fc, ISAC_ISTA);
mISDN_isac_interrupt(&fc->dch, val);
@ -712,21 +716,7 @@ avm_fritz_interrupt(int intno, void *dev_id, struct pt_regs *regs)
WriteISAC(fc, ISAC_MASK, 0xFF);
WriteISAC(fc, ISAC_MASK, 0x0);
}
spin_lock_irqsave(&fc->lock.lock, flags);
#ifdef SPIN_DEBUG
fc->lock.spin_adr = (void *)0x2002;
#endif
if (!test_and_clear_bit(STATE_FLAG_INIRQ, &fc->lock.state)) {
}
if (!test_and_clear_bit(STATE_FLAG_BUSY, &fc->lock.state)) {
printk(KERN_ERR "%s: STATE_FLAG_BUSY not locked state(%lx)\n",
__FUNCTION__, fc->lock.state);
}
#ifdef SPIN_DEBUG
fc->lock.busy_adr = NULL;
fc->lock.spin_adr = NULL;
#endif
spin_unlock_irqrestore(&fc->lock.lock, flags);
spin_unlock(&fc->lock);
return IRQ_HANDLED;
}
@ -734,50 +724,20 @@ static irqreturn_t
avm_fritzv2_interrupt(int intno, void *dev_id, struct pt_regs *regs)
{
fritzpnppci *fc = dev_id;
u_long flags;
u_char val;
u_char sval;
spin_lock_irqsave(&fc->lock.lock, flags);
#ifdef SPIN_DEBUG
fc->lock.spin_adr = (void *)0x2001;
#endif
spin_lock(&fc->lock);
sval = inb(fc->addr + 2);
if (fc->dch.debug & L1_DEB_INTSTAT)
mISDN_debugprint(&fc->dch.inst, "irq stat0 %x", sval);
if (!(sval & AVM_STATUS0_IRQ_MASK)) {
/* possible a shared IRQ reqest */
#ifdef SPIN_DEBUG
fc->lock.spin_adr = NULL;
#endif
spin_unlock_irqrestore(&fc->lock.lock, flags);
spin_unlock(&fc->lock);
return IRQ_NONE;
}
fc->irqcnt++;
if (test_and_set_bit(STATE_FLAG_BUSY, &fc->lock.state)) {
printk(KERN_ERR "%s: STATE_FLAG_BUSY allready activ, should never happen state:%lx\n",
__FUNCTION__, fc->lock.state);
#ifdef SPIN_DEBUG
printk(KERN_ERR "%s: previous lock:%p\n",
__FUNCTION__, fc->lock.busy_adr);
#endif
#ifdef LOCK_STATISTIC
fc->lock.irq_fail++;
#endif
} else {
#ifdef LOCK_STATISTIC
fc->lock.irq_ok++;
#endif
#ifdef SPIN_DEBUG
fc->lock.busy_adr = avm_fritz_interrupt;
#endif
}
test_and_set_bit(STATE_FLAG_INIRQ, &fc->lock.state);
#ifdef SPIN_DEBUG
fc->lock.spin_adr = NULL;
#endif
spin_unlock_irqrestore(&fc->lock.lock, flags);
if (sval & AVM_STATUS0_IRQ_HDLC) {
HDLC_irq_main(fc);
}
@ -792,86 +752,59 @@ avm_fritzv2_interrupt(int intno, void *dev_id, struct pt_regs *regs)
udelay(1);
outb(fc->ctrlreg, fc->addr + 2);
}
spin_lock_irqsave(&fc->lock.lock, flags);
#ifdef SPIN_DEBUG
fc->lock.spin_adr = (void *)0x2002;
#endif
if (!test_and_clear_bit(STATE_FLAG_INIRQ, &fc->lock.state)) {
}
if (!test_and_clear_bit(STATE_FLAG_BUSY, &fc->lock.state)) {
printk(KERN_ERR "%s: STATE_FLAG_BUSY not locked state(%lx)\n",
__FUNCTION__, fc->lock.state);
}
#ifdef SPIN_DEBUG
fc->lock.busy_adr = NULL;
fc->lock.spin_adr = NULL;
#endif
spin_unlock_irqrestore(&fc->lock.lock, flags);
spin_unlock(&fc->lock);
return IRQ_HANDLED;
}
static int
hdlc_down(mISDNif_t *hif, struct sk_buff *skb)
hdlc_down(mISDNinstance_t *inst, struct sk_buff *skb)
{
bchannel_t *bch;
int ret = -EINVAL;
mISDN_head_t *hh;
channel_t *bch;
int ret = 0;
mISDN_head_t *hh = mISDN_HEAD_P(skb);
u_long flags;
if (!hif || !skb)
return(ret);
hh = mISDN_HEAD_P(skb);
bch = hif->fdata;
if ((hh->prim == PH_DATA_REQ) ||
(hh->prim == (DL_DATA | REQUEST))) {
if (bch->next_skb) {
mISDN_debugprint(&bch->inst, " l2l1 next_skb exist this shouldn't happen");
return(-EBUSY);
}
bch->inst.lock(bch->inst.data, 0);
if (test_and_set_bit(BC_FLG_TX_BUSY, &bch->Flag)) {
test_and_set_bit(BC_FLG_TX_NEXT, &bch->Flag);
bch->next_skb = skb;
bch->inst.unlock(bch->inst.data);
return(0);
} else {
bch->tx_len = skb->len;
memcpy(bch->tx_buf, skb->data, bch->tx_len);
bch->tx_idx = 0;
bch = container_of(inst, channel_t, inst);
if ((hh->prim == PH_DATA_REQ) || (hh->prim == DL_DATA_REQ)) {
spin_lock_irqsave(inst->hwlock, flags);
ret = channel_senddata(bch, hh->dinfo, skb);
if (ret > 0) { /* direct TX */
hdlc_fill_fifo(bch);
bch->inst.unlock(bch->inst.data);
skb_trim(skb, 0);
return(if_newhead(&bch->inst.up, hh->prim | CONFIRM,
hh->dinfo, skb));
ret = 0;
}
} else if ((hh->prim == (PH_ACTIVATE | REQUEST)) ||
spin_unlock_irqrestore(inst->hwlock, flags);
return(ret);
}
if ((hh->prim == (PH_ACTIVATE | REQUEST)) ||
(hh->prim == (DL_ESTABLISH | REQUEST))) {