diff options
author | Arnd Bergmann <arnd@arndb.de> | 2019-04-18 23:47:35 +0300 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2019-05-31 12:12:45 +0300 |
commit | 85993b8c9786fb24975dbcabebb1c75790d4fb6a (patch) | |
tree | 48b6d667c6258b44a4915acbd403f17c1b1c9cf5 /drivers/isdn | |
parent | 8e6c8aa3b52e573a6db1f58b2ba9a9106a012963 (diff) | |
download | linux-85993b8c9786fb24975dbcabebb1c75790d4fb6a.tar.xz |
isdn: remove hisax driver
With the decline of ISDN, this seems to have become almost completely
obsolete, and even in the past years before that, almost all remaining
users appear to have used mISDN instead.
Birger Harzenetter noted that he is still using i4l/hisax to take
advantage of the 'divert' driver for call diversion, but otherwise uses
mISDN on the same hardware. This is a rare edge case as far as I
can tell, but we are still breaking an actively used work flow
(see https://xkcd.com/1172/).
We debated moving i4l/hisax to staging as an intermediate step, but as
he is not likely to change the setup, and that would just delay breaking
this use case. The alternatives here are to stay on stable kernels
< 5.2, to create an external driver repository for isdn4linux, or to
add divert functionality to mISDN.
Cc: Birger Harzenetter <WIMPy@yeti.dk>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'drivers/isdn')
102 files changed, 0 insertions, 55481 deletions
diff --git a/drivers/isdn/Makefile b/drivers/isdn/Makefile index e7d3d8f2ad5a..7487f0bbe855 100644 --- a/drivers/isdn/Makefile +++ b/drivers/isdn/Makefile @@ -8,7 +8,6 @@ obj-$(CONFIG_ISDN_CAPI) += capi/ obj-$(CONFIG_MISDN) += mISDN/ obj-$(CONFIG_ISDN) += hardware/ obj-$(CONFIG_ISDN_DIVERSION) += divert/ -obj-$(CONFIG_ISDN_DRV_HISAX) += hisax/ obj-$(CONFIG_ISDN_DRV_LOOP) += isdnloop/ obj-$(CONFIG_HYSDN) += hysdn/ obj-$(CONFIG_ISDN_DRV_GIGASET) += gigaset/ diff --git a/drivers/isdn/hisax/Kconfig b/drivers/isdn/hisax/Kconfig deleted file mode 100644 index 43d98ccf5ff6..000000000000 --- a/drivers/isdn/hisax/Kconfig +++ /dev/null @@ -1,423 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only - -menu "Passive cards" - -config ISDN_DRV_HISAX - tristate "HiSax SiemensChipSet driver support" - select CRC_CCITT - ---help--- - This is a driver supporting the Siemens chipset on various - ISDN-cards (like AVM A1, Elsa ISDN cards, Teles S0-16.0, Teles - S0-16.3, Teles S0-8, Teles/Creatix PnP, ITK micro ix1 and many - compatibles). - - HiSax is just the name of this driver, not the name of any hardware. - - If you have a card with such a chipset, you should say Y here and - also to the configuration option of the driver for your particular - card, below. - -if ISDN_DRV_HISAX - -comment "D-channel protocol features" - -config HISAX_EURO - bool "HiSax Support for EURO/DSS1" - help - Say Y or N according to the D-channel protocol which your local - telephone service company provides. - - The call control protocol E-DSS1 is used in most European countries. - If unsure, say Y. - -config DE_AOC - bool "Support for german chargeinfo" - depends on HISAX_EURO - help - If you want that the HiSax hardware driver sends messages to the - upper level of the isdn code on each AOCD (Advice Of Charge, During - the call -- transmission of the fee information during a call) and - on each AOCE (Advice Of Charge, at the End of the call -- - transmission of fee information at the end of the call), say Y here. - This works only in Germany. - -config HISAX_NO_SENDCOMPLETE - bool "Disable sending complete" - depends on HISAX_EURO - help - If you have trouble with some ugly exchanges or you live in - Australia select this option. - -config HISAX_NO_LLC - bool "Disable sending low layer compatibility" - depends on HISAX_EURO - help - If you have trouble with some ugly exchanges try to select this - option. - -config HISAX_NO_KEYPAD - bool "Disable keypad protocol option" - depends on HISAX_EURO - help - If you like to send special dial strings including * or # without - using the keypad protocol, select this option. - -config HISAX_1TR6 - bool "HiSax Support for german 1TR6" - help - Say Y or N according to the D-channel protocol which your local - telephone service company provides. - - 1TR6 is an old call control protocol which was used in Germany - before E-DSS1 was established. Nowadays, all new lines in Germany - use E-DSS1. - -config HISAX_NI1 - bool "HiSax Support for US NI1" - help - Enable this if you like to use ISDN in US on a NI1 basic rate - interface. - -config HISAX_MAX_CARDS - int "Maximum number of cards supported by HiSax" - default "8" - help - This option allows you to specify the maximum number of cards which - the HiSax driver will be able to handle. - -comment "HiSax supported cards" - -config HISAX_16_0 - bool "Teles 16.0/8.0" - depends on ISA - help - This enables HiSax support for the Teles ISDN-cards S0-16.0, S0-8 - and many compatibles. - - See <file:Documentation/isdn/README.HiSax> on how to configure it - using the different cards, a different D-channel protocol, or - non-standard IRQ/port/shmem settings. - -config HISAX_16_3 - bool "Teles 16.3 or PNP or PCMCIA" - help - This enables HiSax support for the Teles ISDN-cards S0-16.3 the - Teles/Creatix PnP and the Teles PCMCIA. - - See <file:Documentation/isdn/README.HiSax> on how to configure it - using the different cards, a different D-channel protocol, or - non-standard IRQ/port settings. - -config HISAX_TELESPCI - bool "Teles PCI" - depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || (XTENSA && !CPU_LITTLE_ENDIAN))) - help - This enables HiSax support for the Teles PCI. - See <file:Documentation/isdn/README.HiSax> on how to configure it. - -config HISAX_S0BOX - bool "Teles S0Box" - help - This enables HiSax support for the Teles/Creatix parallel port - S0BOX. See <file:Documentation/isdn/README.HiSax> on how to - configure it. - -config HISAX_AVM_A1 - bool "AVM A1 (Fritz)" - depends on ISA - help - This enables HiSax support for the AVM A1 (aka "Fritz"). - - See <file:Documentation/isdn/README.HiSax> on how to configure it - using the different cards, a different D-channel protocol, or - non-standard IRQ/port settings. - -config HISAX_FRITZPCI - bool "AVM PnP/PCI (Fritz!PnP/PCI)" - depends on BROKEN || !PPC64 - help - This enables HiSax support for the AVM "Fritz!PnP" and "Fritz!PCI". - See <file:Documentation/isdn/README.HiSax> on how to configure it. - -config HISAX_AVM_A1_PCMCIA - bool "AVM A1 PCMCIA (Fritz)" - help - This enables HiSax support for the AVM A1 "Fritz!PCMCIA"). - See <file:Documentation/isdn/README.HiSax> on how to configure it. - -config HISAX_ELSA - bool "Elsa cards" - help - This enables HiSax support for the Elsa Mircolink ISA cards, for the - Elsa Quickstep series cards and Elsa PCMCIA. - - See <file:Documentation/isdn/README.HiSax> on how to configure it - using the different cards, a different D-channel protocol, or - non-standard IRQ/port settings. - -config HISAX_IX1MICROR2 - bool "ITK ix1-micro Revision 2" - depends on ISA - help - This enables HiSax support for the ITK ix1-micro Revision 2 card. - - See <file:Documentation/isdn/README.HiSax> on how to configure it - using the different cards, a different D-channel protocol, or - non-standard IRQ/port settings. - -config HISAX_DIEHLDIVA - bool "Eicon.Diehl Diva cards" - help - This enables HiSax support for the Eicon.Diehl Diva none PRO - versions passive ISDN cards. - - See <file:Documentation/isdn/README.HiSax> on how to configure it - using the different cards, a different D-channel protocol, or - non-standard IRQ/port settings. - -config HISAX_ASUSCOM - bool "ASUSCOM ISA cards" - depends on ISA - help - This enables HiSax support for the AsusCom and their OEM versions - passive ISDN ISA cards. - - See <file:Documentation/isdn/README.HiSax> on how to configure it - using the different cards, a different D-channel protocol, or - non-standard IRQ/port settings. - -config HISAX_TELEINT - bool "TELEINT cards" - depends on ISA - help - This enables HiSax support for the TELEINT SA1 semiactiv ISDN card. - - See <file:Documentation/isdn/README.HiSax> on how to configure it - using the different cards, a different D-channel protocol, or - non-standard IRQ/port settings. - -config HISAX_HFCS - bool "HFC-S based cards" - depends on ISA - help - This enables HiSax support for the HFC-S 2BDS0 based cards, like - teles 16.3c. - - See <file:Documentation/isdn/README.HiSax> on how to configure it - using the different cards, a different D-channel protocol, or - non-standard IRQ/port settings. - -config HISAX_SEDLBAUER - bool "Sedlbauer cards" - help - This enables HiSax support for the Sedlbauer passive ISDN cards. - - See <file:Documentation/isdn/README.HiSax> on how to configure it - using the different cards, a different D-channel protocol, or - non-standard IRQ/port settings. - -config HISAX_SPORTSTER - bool "USR Sportster internal TA" - depends on ISA - help - This enables HiSax support for the USR Sportster internal TA card. - - See <file:Documentation/isdn/README.HiSax> on how to configure it - using a different D-channel protocol, or non-standard IRQ/port - settings. - -config HISAX_MIC - bool "MIC card" - depends on ISA - help - This enables HiSax support for the ITH MIC card. - - See <file:Documentation/isdn/README.HiSax> on how to configure it - using a different D-channel protocol, or non-standard IRQ/port - settings. - -config HISAX_NETJET - bool "NETjet card" - depends on PCI && (BROKEN || !(PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || (XTENSA && !CPU_LITTLE_ENDIAN) || MICROBLAZE)) - depends on VIRT_TO_BUS - help - This enables HiSax support for the NetJet from Traverse - Technologies. - - See <file:Documentation/isdn/README.HiSax> on how to configure it - using a different D-channel protocol, or non-standard IRQ/port - settings. - -config HISAX_NETJET_U - bool "NETspider U card" - depends on PCI && (BROKEN || !(PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || (XTENSA && !CPU_LITTLE_ENDIAN) || MICROBLAZE)) - depends on VIRT_TO_BUS - help - This enables HiSax support for the Netspider U interface ISDN card - from Traverse Technologies. - See <file:Documentation/isdn/README.HiSax> on how to configure it - using a different D-channel protocol, or non-standard IRQ/port - settings. - -config HISAX_NICCY - bool "Niccy PnP/PCI card" - help - This enables HiSax support for the Dr. Neuhaus Niccy PnP or PCI. - - See <file:Documentation/isdn/README.HiSax> on how to configure it - using a different D-channel protocol, or non-standard IRQ/port - settings. - -config HISAX_ISURF - bool "Siemens I-Surf card" - depends on ISA - help - This enables HiSax support for the Siemens I-Talk/I-Surf card with - ISAR chip. - See <file:Documentation/isdn/README.HiSax> on how to configure it - using a different D-channel protocol, or non-standard IRQ/port - settings. - -config HISAX_HSTSAPHIR - bool "HST Saphir card" - depends on ISA - help - This enables HiSax support for the HST Saphir card. - - See <file:Documentation/isdn/README.HiSax> on how to configure it - using a different D-channel protocol, or non-standard IRQ/port - settings. - -config HISAX_BKM_A4T - bool "Telekom A4T card" - depends on PCI - help - This enables HiSax support for the Telekom A4T card. - - See <file:Documentation/isdn/README.HiSax> on how to configure it - using a different D-channel protocol, or non-standard IRQ/port - settings. - -config HISAX_SCT_QUADRO - bool "Scitel Quadro card" - depends on PCI - help - This enables HiSax support for the Scitel Quadro card. - - See <file:Documentation/isdn/README.HiSax> on how to configure it - using a different D-channel protocol, or non-standard IRQ/port - settings. - -config HISAX_GAZEL - bool "Gazel cards" - help - This enables HiSax support for the Gazel cards. - - See <file:Documentation/isdn/README.HiSax> on how to configure it - using a different D-channel protocol, or non-standard IRQ/port - settings. - -config HISAX_HFC_PCI - bool "HFC PCI-Bus cards" - depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || (XTENSA && !CPU_LITTLE_ENDIAN))) - help - This enables HiSax support for the HFC-S PCI 2BDS0 based cards. - - For more information see under - <file:Documentation/isdn/README.hfc-pci>. - -config HISAX_W6692 - bool "Winbond W6692 based cards" - depends on PCI - help - This enables HiSax support for Winbond W6692 based PCI ISDN cards. - - See <file:Documentation/isdn/README.HiSax> on how to configure it - using a different D-channel protocol, or non-standard IRQ/port - settings. - -config HISAX_HFC_SX - bool "HFC-S+, HFC-SP, HFC-PCMCIA cards" - help - This enables HiSax support for the HFC-S+, HFC-SP and HFC-PCMCIA - cards. This code is not finished yet. - -config HISAX_ENTERNOW_PCI - bool "Formula-n enter:now PCI card" - depends on HISAX_NETJET && PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || (XTENSA && !CPU_LITTLE_ENDIAN))) - help - This enables HiSax support for the Formula-n enter:now PCI - ISDN card. - -config HISAX_DEBUG - bool "HiSax debugging" - help - This enables debugging code in the new-style HiSax drivers, i.e. - the ST5481 USB driver currently. - If in doubt, say yes. - -comment "HiSax PCMCIA card service modules" - -config HISAX_SEDLBAUER_CS - tristate "Sedlbauer PCMCIA cards" - depends on PCMCIA && HISAX_SEDLBAUER - help - This enables the PCMCIA client driver for the Sedlbauer Speed Star - and Speed Star II cards. - -config HISAX_ELSA_CS - tristate "ELSA PCMCIA MicroLink cards" - depends on PCMCIA && HISAX_ELSA - help - This enables the PCMCIA client driver for the Elsa PCMCIA MicroLink - card. - -config HISAX_AVM_A1_CS - tristate "AVM A1 PCMCIA cards" - depends on PCMCIA && ISDN_DRV_HISAX - help - This enables the PCMCIA client driver for the AVM A1 / Fritz!Card - PCMCIA cards. - -config HISAX_TELES_CS - tristate "TELES PCMCIA cards" - depends on PCMCIA && HISAX_16_3 - help - This enables the PCMCIA client driver for the Teles PCMCIA cards. - -comment "HiSax sub driver modules" - -config HISAX_ST5481 - tristate "ST5481 USB ISDN modem" - depends on USB - select ISDN_HDLC - select CRC_CCITT - select BITREVERSE - help - This enables the driver for ST5481 based USB ISDN adapters, - e.g. the BeWan Gazel 128 USB - -config HISAX_HFCUSB - tristate "HFC USB based ISDN modems" - depends on USB - help - This enables the driver for HFC USB based ISDN modems. - -config HISAX_HFC4S8S - tristate "HFC-4S/8S based ISDN cards" - help - This enables the driver for HFC-4S/8S based ISDN cards. - -config HISAX_FRITZ_PCIPNP - tristate "AVM Fritz!Card PCI/PCIv2/PnP support" - depends on PCI - help - This enables the driver for the AVM Fritz!Card PCI, - Fritz!Card PCI v2 and Fritz!Card PnP. - (the latter also needs you to select "ISA Plug and Play support" - from the menu "Plug and Play configuration") - -endif - -endmenu - diff --git a/drivers/isdn/hisax/Makefile b/drivers/isdn/hisax/Makefile deleted file mode 100644 index 3eca9d23f1c2..000000000000 --- a/drivers/isdn/hisax/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# Makefile for the hisax ISDN device driver - -# The target object and module list name. - -# Define maximum number of cards - -ccflags-y := -DHISAX_MAX_CARDS=$(CONFIG_HISAX_MAX_CARDS) - -obj-$(CONFIG_ISDN_DRV_HISAX) += hisax.o -obj-$(CONFIG_HISAX_SEDLBAUER_CS) += sedlbauer_cs.o -obj-$(CONFIG_HISAX_ELSA_CS) += elsa_cs.o -obj-$(CONFIG_HISAX_AVM_A1_CS) += avma1_cs.o -obj-$(CONFIG_HISAX_TELES_CS) += teles_cs.o -obj-$(CONFIG_HISAX_ST5481) += hisax_st5481.o -obj-$(CONFIG_HISAX_HFCUSB) += hfc_usb.o -obj-$(CONFIG_HISAX_HFC4S8S) += hfc4s8s_l1.o -obj-$(CONFIG_HISAX_FRITZ_PCIPNP) += hisax_isac.o hisax_fcpcipnp.o - -# Multipart objects. - -hisax_st5481-y := st5481_init.o st5481_usb.o st5481_d.o \ - st5481_b.o - -hisax-y := config.o isdnl1.o tei.o isdnl2.o isdnl3.o \ - lmgr.o q931.o callc.o fsm.o -hisax-$(CONFIG_HISAX_EURO) += l3dss1.o -hisax-$(CONFIG_HISAX_NI1) += l3ni1.o -hisax-$(CONFIG_HISAX_1TR6) += l3_1tr6.o - -hisax-$(CONFIG_HISAX_16_0) += teles0.o isac.o arcofi.o hscx.o -hisax-$(CONFIG_HISAX_16_3) += teles3.o isac.o arcofi.o hscx.o -hisax-$(CONFIG_HISAX_TELESPCI) += telespci.o isac.o arcofi.o hscx.o -hisax-$(CONFIG_HISAX_S0BOX) += s0box.o isac.o arcofi.o hscx.o -hisax-$(CONFIG_HISAX_AVM_A1) += avm_a1.o isac.o arcofi.o hscx.o -hisax-$(CONFIG_HISAX_AVM_A1_PCMCIA) += avm_a1p.o isac.o arcofi.o hscx.o -hisax-$(CONFIG_HISAX_FRITZPCI) += avm_pci.o isac.o arcofi.o -hisax-$(CONFIG_HISAX_ELSA) += elsa.o isac.o arcofi.o hscx.o -hisax-$(CONFIG_HISAX_IX1MICROR2) += ix1_micro.o isac.o arcofi.o hscx.o -hisax-$(CONFIG_HISAX_DIEHLDIVA) += diva.o isac.o arcofi.o hscx.o ipacx.o -hisax-$(CONFIG_HISAX_ASUSCOM) += asuscom.o isac.o arcofi.o hscx.o -hisax-$(CONFIG_HISAX_TELEINT) += teleint.o isac.o arcofi.o hfc_2bs0.o -hisax-$(CONFIG_HISAX_SEDLBAUER) += sedlbauer.o isac.o arcofi.o hscx.o \ - isar.o -hisax-$(CONFIG_HISAX_SPORTSTER) += sportster.o isac.o arcofi.o hscx.o -hisax-$(CONFIG_HISAX_MIC) += mic.o isac.o arcofi.o hscx.o -hisax-$(CONFIG_HISAX_NETJET) += nj_s.o netjet.o isac.o arcofi.o -hisax-$(CONFIG_HISAX_NETJET_U) += nj_u.o netjet.o icc.o -hisax-$(CONFIG_HISAX_HFCS) += hfcscard.o hfc_2bds0.o -hisax-$(CONFIG_HISAX_HFC_PCI) += hfc_pci.o -hisax-$(CONFIG_HISAX_HFC_SX) += hfc_sx.o -hisax-$(CONFIG_HISAX_NICCY) += niccy.o isac.o arcofi.o hscx.o -hisax-$(CONFIG_HISAX_ISURF) += isurf.o isac.o arcofi.o isar.o -hisax-$(CONFIG_HISAX_HSTSAPHIR) += saphir.o isac.o arcofi.o hscx.o -hisax-$(CONFIG_HISAX_BKM_A4T) += bkm_a4t.o isac.o arcofi.o jade.o -hisax-$(CONFIG_HISAX_SCT_QUADRO) += bkm_a8.o isac.o arcofi.o hscx.o -hisax-$(CONFIG_HISAX_GAZEL) += gazel.o isac.o arcofi.o hscx.o -hisax-$(CONFIG_HISAX_W6692) += w6692.o -hisax-$(CONFIG_HISAX_ENTERNOW_PCI) += enternow_pci.o amd7930_fn.o - diff --git a/drivers/isdn/hisax/amd7930_fn.c b/drivers/isdn/hisax/amd7930_fn.c deleted file mode 100644 index 6c336366128c..000000000000 --- a/drivers/isdn/hisax/amd7930_fn.c +++ /dev/null @@ -1,794 +0,0 @@ -/* gerdes_amd7930.c,v 0.99 2001/10/02 - * - * gerdes_amd7930.c Amd 79C30A and 79C32A specific routines - * (based on HiSax driver by Karsten Keil) - * - * Author Christoph Ersfeld <info@formula-n.de> - * Formula-n Europe AG (www.formula-n.com) - * previously Gerdes AG - * - * - * This file is (c) under GNU PUBLIC LICENSE - * - * - * Notes: - * Version 0.99 is the first release of this driver and there are - * certainly a few bugs. - * - * Please don't report any malfunction to me without sending - * (compressed) debug-logs. - * It would be nearly impossible to retrace it. - * - * Log D-channel-processing as follows: - * - * 1. Load hisax with card-specific parameters, this example ist for - * Formula-n enter:now ISDN PCI and compatible - * (f.e. Gerdes Power ISDN PCI) - * - * modprobe hisax type=41 protocol=2 id=gerdes - * - * if you chose an other value for id, you need to modify the - * code below, too. - * - * 2. set debug-level - * - * hisaxctrl gerdes 1 0x3ff - * hisaxctrl gerdes 11 0x4f - * cat /dev/isdnctrl >> ~/log & - * - * Please take also a look into /var/log/messages if there is - * anything importand concerning HISAX. - * - * - * Credits: - * Programming the driver for Formula-n enter:now ISDN PCI and - * necessary this driver for the used Amd 7930 D-channel-controller - * was spnsored by Formula-n Europe AG. - * Thanks to Karsten Keil and Petr Novak, who gave me support in - * Hisax-specific questions. - * I want so say special thanks to Carl-Friedrich Braun, who had to - * answer a lot of questions about generally ISDN and about handling - * of the Amd-Chip. - * - */ - - -#include "hisax.h" -#include "isdnl1.h" -#include "isac.h" -#include "amd7930_fn.h" -#include <linux/interrupt.h> -#include <linux/init.h> -#include <linux/gfp.h> - -static void Amd7930_new_ph(struct IsdnCardState *cs); - -static WORD initAMD[] = { - 0x0100, - - 0x00A5, 3, 0x01, 0x40, 0x58, // LPR, LMR1, LMR2 - 0x0086, 1, 0x0B, // DMR1 (D-Buffer TH-Interrupts on) - 0x0087, 1, 0xFF, // DMR2 - 0x0092, 1, 0x03, // EFCR (extended mode d-channel-fifo on) - 0x0090, 4, 0xFE, 0xFF, 0x02, 0x0F, // FRAR4, SRAR4, DMR3, DMR4 (address recognition ) - 0x0084, 2, 0x80, 0x00, // DRLR - 0x00C0, 1, 0x47, // PPCR1 - 0x00C8, 1, 0x01, // PPCR2 - - 0x0102, - 0x0107, - 0x01A1, 1, - 0x0121, 1, - 0x0189, 2, - - 0x0045, 4, 0x61, 0x72, 0x00, 0x00, // MCR1, MCR2, MCR3, MCR4 - 0x0063, 2, 0x08, 0x08, // GX - 0x0064, 2, 0x08, 0x08, // GR - 0x0065, 2, 0x99, 0x00, // GER - 0x0066, 2, 0x7C, 0x8B, // STG - 0x0067, 2, 0x00, 0x00, // FTGR1, FTGR2 - 0x0068, 2, 0x20, 0x20, // ATGR1, ATGR2 - 0x0069, 1, 0x4F, // MMR1 - 0x006A, 1, 0x00, // MMR2 - 0x006C, 1, 0x40, // MMR3 - 0x0021, 1, 0x02, // INIT - 0x00A3, 1, 0x40, // LMR1 - - 0xFFFF -}; - - -static void /* macro wWordAMD */ -WriteWordAmd7930(struct IsdnCardState *cs, BYTE reg, WORD val) -{ - wByteAMD(cs, 0x00, reg); - wByteAMD(cs, 0x01, LOBYTE(val)); - wByteAMD(cs, 0x01, HIBYTE(val)); -} - -static WORD /* macro rWordAMD */ -ReadWordAmd7930(struct IsdnCardState *cs, BYTE reg) -{ - WORD res; - /* direct access register */ - if (reg < 8) { - res = rByteAMD(cs, reg); - res += 256 * rByteAMD(cs, reg); - } - /* indirect access register */ - else { - wByteAMD(cs, 0x00, reg); - res = rByteAMD(cs, 0x01); - res += 256 * rByteAMD(cs, 0x01); - } - return (res); -} - - -static void -Amd7930_ph_command(struct IsdnCardState *cs, u_char command, char *s) -{ - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "AMD7930: %s: ph_command 0x%02X", s, command); - - cs->dc.amd7930.lmr1 = command; - wByteAMD(cs, 0xA3, command); -} - - - -static BYTE i430States[] = { -// to reset F3 F4 F5 F6 F7 F8 AR from - 0x01, 0x02, 0x00, 0x00, 0x00, 0x07, 0x05, 0x00, // init - 0x01, 0x02, 0x00, 0x00, 0x00, 0x07, 0x05, 0x00, // reset - 0x01, 0x02, 0x00, 0x00, 0x00, 0x09, 0x05, 0x04, // F3 - 0x01, 0x02, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, // F4 - 0x01, 0x02, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, // F5 - 0x01, 0x03, 0x00, 0x00, 0x00, 0x06, 0x05, 0x00, // F6 - 0x11, 0x13, 0x00, 0x00, 0x1B, 0x00, 0x15, 0x00, // F7 - 0x01, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, // F8 - 0x01, 0x03, 0x00, 0x00, 0x00, 0x09, 0x00, 0x0A}; // AR - - -/* Row init - reset F3 F4 F5 F6 F7 F8 AR */ -static BYTE stateHelper[] = { 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; - - - - -static void -Amd7930_get_state(struct IsdnCardState *cs) { - BYTE lsr = rByteAMD(cs, 0xA1); - cs->dc.amd7930.ph_state = (lsr & 0x7) + 2; - Amd7930_new_ph(cs); -} - - - -static void -Amd7930_new_ph(struct IsdnCardState *cs) -{ - u_char index = stateHelper[cs->dc.amd7930.old_state] * 8 + stateHelper[cs->dc.amd7930.ph_state] - 1; - u_char message = i430States[index]; - - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "AMD7930: new_ph %d, old_ph %d, message %d, index %d", - cs->dc.amd7930.ph_state, cs->dc.amd7930.old_state, message & 0x0f, index); - - cs->dc.amd7930.old_state = cs->dc.amd7930.ph_state; - - /* abort transmit if nessesary */ - if ((message & 0xf0) && (cs->tx_skb)) { - wByteAMD(cs, 0x21, 0xC2); - wByteAMD(cs, 0x21, 0x02); - } - - switch (message & 0x0f) { - - case (1): - l1_msg(cs, HW_RESET | INDICATION, NULL); - Amd7930_get_state(cs); - break; - case (2): /* init, Card starts in F3 */ - l1_msg(cs, HW_DEACTIVATE | CONFIRM, NULL); - break; - case (3): - l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL); - break; - case (4): - l1_msg(cs, HW_POWERUP | CONFIRM, NULL); - Amd7930_ph_command(cs, 0x50, "HW_ENABLE REQUEST"); - break; - case (5): - l1_msg(cs, HW_RSYNC | INDICATION, NULL); - break; - case (6): - l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL); - break; - case (7): /* init, Card starts in F7 */ - l1_msg(cs, HW_RSYNC | INDICATION, NULL); - l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL); - break; - case (8): - l1_msg(cs, HW_POWERUP | CONFIRM, NULL); - /* fall through */ - case (9): - Amd7930_ph_command(cs, 0x40, "HW_ENABLE REQ cleared if set"); - l1_msg(cs, HW_RSYNC | INDICATION, NULL); - l1_msg(cs, HW_INFO2 | INDICATION, NULL); - l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL); - break; - case (10): - Amd7930_ph_command(cs, 0x40, "T3 expired, HW_ENABLE REQ cleared"); - cs->dc.amd7930.old_state = 3; - break; - case (11): - l1_msg(cs, HW_INFO2 | INDICATION, NULL); - break; - default: - break; - } -} - - - -static void -Amd7930_bh(struct work_struct *work) -{ - struct IsdnCardState *cs = - container_of(work, struct IsdnCardState, tqueue); - struct PStack *stptr; - - if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) { - if (cs->debug) - debugl1(cs, "Amd7930: bh, D-Channel Busy cleared"); - stptr = cs->stlist; - while (stptr != NULL) { - stptr->l1.l1l2(stptr, PH_PAUSE | CONFIRM, NULL); - stptr = stptr->next; - } - } - if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) { - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "AMD7930: bh, D_L1STATECHANGE"); - Amd7930_new_ph(cs); - } - - if (test_and_clear_bit(D_RCVBUFREADY, &cs->event)) { - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "AMD7930: bh, D_RCVBUFREADY"); - DChannel_proc_rcv(cs); - } - - if (test_and_clear_bit(D_XMTBUFREADY, &cs->event)) { - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "AMD7930: bh, D_XMTBUFREADY"); - DChannel_proc_xmt(cs); - } -} - -static void -Amd7930_empty_Dfifo(struct IsdnCardState *cs, int flag) -{ - - BYTE stat, der; - BYTE *ptr; - struct sk_buff *skb; - - - if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO)) - debugl1(cs, "Amd7930: empty_Dfifo"); - - - ptr = cs->rcvbuf + cs->rcvidx; - - /* AMD interrupts off */ - AmdIrqOff(cs); - - /* read D-Channel-Fifo*/ - stat = rByteAMD(cs, 0x07); // DSR2 - - /* while Data in Fifo ... */ - while ((stat & 2) && ((ptr-cs->rcvbuf) < MAX_DFRAME_LEN_L1)) { - *ptr = rByteAMD(cs, 0x04); // DCRB - ptr++; - stat = rByteAMD(cs, 0x07); // DSR2 - cs->rcvidx = ptr - cs->rcvbuf; - - /* Paket ready? */ - if (stat & 1) { - - der = rWordAMD(cs, 0x03); - - /* no errors, packet ok */ - if (!der && !flag) { - rWordAMD(cs, 0x89); // clear DRCR - - if ((cs->rcvidx) > 0) { - if (!(skb = alloc_skb(cs->rcvidx, GFP_ATOMIC))) - printk(KERN_WARNING "HiSax: Amd7930: empty_Dfifo, D receive out of memory!\n"); - else { - /* Debugging */ - if (cs->debug & L1_DEB_ISAC_FIFO) { - char *t = cs->dlog; - - t += sprintf(t, "Amd7930: empty_Dfifo cnt: %d |", cs->rcvidx); - QuickHex(t, cs->rcvbuf, cs->rcvidx); - debugl1(cs, "%s", cs->dlog); - } - /* moves received data in sk-buffer */ - skb_put_data(skb, cs->rcvbuf, - cs->rcvidx); - skb_queue_tail(&cs->rq, skb); - } - } - - } - /* throw damaged packets away, reset receive-buffer, indicate RX */ - ptr = cs->rcvbuf; - cs->rcvidx = 0; - schedule_event(cs, D_RCVBUFREADY); - } - } - /* Packet to long, overflow */ - if (cs->rcvidx >= MAX_DFRAME_LEN_L1) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "AMD7930: empty_Dfifo L2-Framelength overrun"); - cs->rcvidx = 0; - return; - } - /* AMD interrupts on */ - AmdIrqOn(cs); -} - - -static void -Amd7930_fill_Dfifo(struct IsdnCardState *cs) -{ - - WORD dtcrr, dtcrw, len, count; - BYTE txstat, dmr3; - BYTE *ptr, *deb_ptr; - - if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO)) - debugl1(cs, "Amd7930: fill_Dfifo"); - - if ((!cs->tx_skb) || (cs->tx_skb->len <= 0)) - return; - - dtcrw = 0; - if (!cs->dc.amd7930.tx_xmtlen) - /* new Frame */ - len = dtcrw = cs->tx_skb->len; - /* continue frame */ - else len = cs->dc.amd7930.tx_xmtlen; - - - /* AMD interrupts off */ - AmdIrqOff(cs); - - deb_ptr = ptr = cs->tx_skb->data; - - /* while free place in tx-fifo available and data in sk-buffer */ - txstat = 0x10; - while ((txstat & 0x10) && (cs->tx_cnt < len)) { - wByteAMD(cs, 0x04, *ptr); - ptr++; - cs->tx_cnt++; - txstat = rByteAMD(cs, 0x07); - } - count = ptr - cs->tx_skb->data; - skb_pull(cs->tx_skb, count); - - - dtcrr = rWordAMD(cs, 0x85); // DTCR - dmr3 = rByteAMD(cs, 0x8E); - - if (cs->debug & L1_DEB_ISAC) { - debugl1(cs, "Amd7930: fill_Dfifo, DMR3: 0x%02X, DTCR read: 0x%04X write: 0x%02X 0x%02X", dmr3, dtcrr, LOBYTE(dtcrw), HIBYTE(dtcrw)); - } - - /* writeing of dtcrw starts transmit */ - if (!cs->dc.amd7930.tx_xmtlen) { - wWordAMD(cs, 0x85, dtcrw); - cs->dc.amd7930.tx_xmtlen = dtcrw; - } - - if (test_and_set_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) { - debugl1(cs, "Amd7930: fill_Dfifo dbusytimer running"); - del_timer(&cs->dbusytimer); - } - cs->dbusytimer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ) / 1000); - add_timer(&cs->dbusytimer); - - if (cs->debug & L1_DEB_ISAC_FIFO) { - char *t = cs->dlog; - - t += sprintf(t, "Amd7930: fill_Dfifo cnt: %d |", count); - QuickHex(t, deb_ptr, count); - debugl1(cs, "%s", cs->dlog); - } - /* AMD interrupts on */ - AmdIrqOn(cs); -} - - -void Amd7930_interrupt(struct IsdnCardState *cs, BYTE irflags) -{ - BYTE dsr1, dsr2, lsr; - WORD der; - - while (irflags) - { - - dsr1 = rByteAMD(cs, 0x02); - der = rWordAMD(cs, 0x03); - dsr2 = rByteAMD(cs, 0x07); - lsr = rByteAMD(cs, 0xA1); - - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "Amd7930: interrupt: flags: 0x%02X, DSR1: 0x%02X, DSR2: 0x%02X, LSR: 0x%02X, DER=0x%04X", irflags, dsr1, dsr2, lsr, der); - - /* D error -> read DER and DSR2 bit 2 */ - if (der || (dsr2 & 4)) { - - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "Amd7930: interrupt: D error DER=0x%04X", der); - - /* RX, TX abort if collision detected */ - if (der & 2) { - wByteAMD(cs, 0x21, 0xC2); - wByteAMD(cs, 0x21, 0x02); - if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) - del_timer(&cs->dbusytimer); - if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags)) - schedule_event(cs, D_CLEARBUSY); - /* restart frame */ - if (cs->tx_skb) { - skb_push(cs->tx_skb, cs->tx_cnt); - cs->tx_cnt = 0; - cs->dc.amd7930.tx_xmtlen = 0; - Amd7930_fill_Dfifo(cs); - } else { - printk(KERN_WARNING "HiSax: Amd7930 D-Collision, no skb\n"); - debugl1(cs, "Amd7930: interrupt: D-Collision, no skb"); - } - } - /* remove damaged data from fifo */ - Amd7930_empty_Dfifo(cs, 1); - - if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) - del_timer(&cs->dbusytimer); - if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags)) - schedule_event(cs, D_CLEARBUSY); - /* restart TX-Frame */ - if (cs->tx_skb) { - skb_push(cs->tx_skb, cs->tx_cnt); - cs->tx_cnt = 0; - cs->dc.amd7930.tx_xmtlen = 0; - Amd7930_fill_Dfifo(cs); - } - } - - /* D TX FIFO empty -> fill */ - if (irflags & 1) { - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "Amd7930: interrupt: clear Timer and fill D-TX-FIFO if data"); - - /* AMD interrupts off */ - AmdIrqOff(cs); - - if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) - del_timer(&cs->dbusytimer); - if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags)) - schedule_event(cs, D_CLEARBUSY); - if (cs->tx_skb) { - if (cs->tx_skb->len) - Amd7930_fill_Dfifo(cs); - } - /* AMD interrupts on */ - AmdIrqOn(cs); - } - - - /* D RX FIFO full or tiny packet in Fifo -> empty */ - if ((irflags & 2) || (dsr1 & 2)) { - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "Amd7930: interrupt: empty D-FIFO"); - Amd7930_empty_Dfifo(cs, 0); - } - - - /* D-Frame transmit complete */ - if (dsr1 & 64) { - if (cs->debug & L1_DEB_ISAC) { - debugl1(cs, "Amd7930: interrupt: transmit packet ready"); - } - /* AMD interrupts off */ - AmdIrqOff(cs); - - if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) - del_timer(&cs->dbusytimer); - if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags)) - schedule_event(cs, D_CLEARBUSY); - - if (cs->tx_skb) { - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "Amd7930: interrupt: TX-Packet ready, freeing skb"); - dev_kfree_skb_irq(cs->tx_skb); - cs->tx_cnt = 0; - cs->dc.amd7930.tx_xmtlen = 0; - cs->tx_skb = NULL; - } - if ((cs->tx_skb = skb_dequeue(&cs->sq))) { - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "Amd7930: interrupt: TX-Packet ready, next packet dequeued"); - cs->tx_cnt = 0; - cs->dc.amd7930.tx_xmtlen = 0; - Amd7930_fill_Dfifo(cs); - } - else - schedule_event(cs, D_XMTBUFREADY); - /* AMD interrupts on */ - AmdIrqOn(cs); - } - - /* LIU status interrupt -> read LSR, check statechanges */ - if (lsr & 0x38) { - /* AMD interrupts off */ - AmdIrqOff(cs); - - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "Amd: interrupt: LSR=0x%02X, LIU is in state %d", lsr, ((lsr & 0x7) + 2)); - - cs->dc.amd7930.ph_state = (lsr & 0x7) + 2; - - schedule_event(cs, D_L1STATECHANGE); - /* AMD interrupts on */ - AmdIrqOn(cs); - } - - /* reads Interrupt-Register again. If there is a new interrupt-flag: restart handler */ - irflags = rByteAMD(cs, 0x00); - } - -} - -static void -Amd7930_l1hw(struct PStack *st, int pr, void *arg) -{ - struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware; - struct sk_buff *skb = arg; - u_long flags; - - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "Amd7930: l1hw called, pr: 0x%04X", pr); - - switch (pr) { - case (PH_DATA | REQUEST): - if (cs->debug & DEB_DLOG_HEX) - LogFrame(cs, skb->data, skb->len); - if (cs->debug & DEB_DLOG_VERBOSE) - dlogframe(cs, skb, 0); - spin_lock_irqsave(&cs->lock, flags); - if (cs->tx_skb) { - skb_queue_tail(&cs->sq, skb); -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - Logl2Frame(cs, skb, "Amd7930: l1hw: PH_DATA Queued", 0); -#endif - } else { - cs->tx_skb = skb; - cs->tx_cnt = 0; - cs->dc.amd7930.tx_xmtlen = 0; -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - Logl2Frame(cs, skb, "Amd7930: l1hw: PH_DATA", 0); -#endif - Amd7930_fill_Dfifo(cs); - } - spin_unlock_irqrestore(&cs->lock, flags); - break; - case (PH_PULL | INDICATION): - spin_lock_irqsave(&cs->lock, flags); - if (cs->tx_skb) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "Amd7930: l1hw: l2l1 tx_skb exist this shouldn't happen"); - skb_queue_tail(&cs->sq, skb); - spin_unlock_irqrestore(&cs->lock, flags); - break; - } - if (cs->debug & DEB_DLOG_HEX) - LogFrame(cs, skb->data, skb->len); - if (cs->debug & DEB_DLOG_VERBOSE) - dlogframe(cs, skb, 0); - cs->tx_skb = skb; - cs->tx_cnt = 0; - cs->dc.amd7930.tx_xmtlen = 0; -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - Logl2Frame(cs, skb, "Amd7930: l1hw: PH_DATA_PULLED", 0); -#endif - Amd7930_fill_Dfifo(cs); - spin_unlock_irqrestore(&cs->lock, flags); - break; - case (PH_PULL | REQUEST): -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - debugl1(cs, "Amd7930: l1hw: -> PH_REQUEST_PULL, skb: %s", (cs->tx_skb) ? "yes" : "no"); -#endif - if (!cs->tx_skb) { - test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); - } else - test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - break; - case (HW_RESET | REQUEST): - spin_lock_irqsave(&cs->lock, flags); - if (cs->dc.amd7930.ph_state == 8) { - /* b-channels off, PH-AR cleared - * change to F3 */ - Amd7930_ph_command(cs, 0x20, "HW_RESET REQUEST"); //LMR1 bit 5 - spin_unlock_irqrestore(&cs->lock, flags); - } else { - Amd7930_ph_command(cs, 0x40, "HW_RESET REQUEST"); - cs->dc.amd7930.ph_state = 2; - spin_unlock_irqrestore(&cs->lock, flags); - Amd7930_new_ph(cs); - } - break; - case (HW_ENABLE | REQUEST): - cs->dc.amd7930.ph_state = 9; - Amd7930_new_ph(cs); - break; - case (HW_INFO3 | REQUEST): - // automatic - break; - case (HW_TESTLOOP | REQUEST): - /* not implemented yet */ - break; - case (HW_DEACTIVATE | RESPONSE): - skb_queue_purge(&cs->rq); - skb_queue_purge(&cs->sq); - if (cs->tx_skb) { - dev_kfree_skb(cs->tx_skb); - cs->tx_skb = NULL; - } - if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) - del_timer(&cs->dbusytimer); - if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags)) - schedule_event(cs, D_CLEARBUSY); - break; - default: - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "Amd7930: l1hw: unknown %04x", pr); - break; - } -} - -static void -setstack_Amd7930(struct PStack *st, struct IsdnCardState *cs) -{ - - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "Amd7930: setstack called"); - - st->l1.l1hw = Amd7930_l1hw; -} - - -static void -DC_Close_Amd7930(struct IsdnCardState *cs) { - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "Amd7930: DC_Close called"); -} - - -static void -dbusy_timer_handler(struct timer_list *t) -{ - struct IsdnCardState *cs = from_timer(cs, t, dbusytimer); - u_long flags; - struct PStack *stptr; - WORD dtcr, der; - BYTE dsr1, dsr2; - - - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "Amd7930: dbusy_timer expired!"); - - if (test_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) { - spin_lock_irqsave(&cs->lock, flags); - /* D Transmit Byte Count Register: - * Counts down packet's number of Bytes, 0 if packet ready */ - dtcr = rWordAMD(cs, 0x85); - dsr1 = rByteAMD(cs, 0x02); - dsr2 = rByteAMD(cs, 0x07); - der = rWordAMD(cs, 0x03); - - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "Amd7930: dbusy_timer_handler: DSR1=0x%02X, DSR2=0x%02X, DER=0x%04X, cs->tx_skb->len=%u, tx_stat=%u, dtcr=%u, cs->tx_cnt=%u", dsr1, dsr2, der, cs->tx_skb->len, cs->dc.amd7930.tx_xmtlen, dtcr, cs->tx_cnt); - - if ((cs->dc.amd7930.tx_xmtlen - dtcr) < cs->tx_cnt) { /* D-Channel Busy */ - test_and_set_bit(FLG_L1_DBUSY, &cs->HW_Flags); - stptr = cs->stlist; - spin_unlock_irqrestore(&cs->lock, flags); - while (stptr != NULL) { - stptr->l1.l1l2(stptr, PH_PAUSE | INDICATION, NULL); - stptr = stptr->next; - } - - } else { - /* discard frame; reset transceiver */ - test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags); - if (cs->tx_skb) { - dev_kfree_skb_any(cs->tx_skb); - cs->tx_cnt = 0; - cs->tx_skb = NULL; - cs->dc.amd7930.tx_xmtlen = 0; - } else { - printk(KERN_WARNING "HiSax: Amd7930: D-Channel Busy no skb\n"); - debugl1(cs, "Amd7930: D-Channel Busy no skb"); - - } - /* Transmitter reset, abort transmit */ - wByteAMD(cs, 0x21, 0x82); - wByteAMD(cs, 0x21, 0x02); - spin_unlock_irqrestore(&cs->lock, flags); - cs->irq_func(cs->irq, cs); - - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "Amd7930: dbusy_timer_handler: Transmitter reset"); - } - } -} - - - -void Amd7930_init(struct IsdnCardState *cs) -{ - WORD *ptr; - BYTE cmd, cnt; - - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "Amd7930: initamd called"); - - cs->dc.amd7930.tx_xmtlen = 0; - cs->dc.amd7930.old_state = 0; - cs->dc.amd7930.lmr1 = 0x40; - cs->dc.amd7930.ph_command = Amd7930_ph_command; - cs->setstack_d = setstack_Amd7930; - cs->DC_Close = DC_Close_Amd7930; - - /* AMD Initialisation */ - for (ptr = initAMD; *ptr != 0xFFFF; ) { - cmd = LOBYTE(*ptr); - - /* read */ - if (*ptr++ >= 0x100) { - if (cmd < 8) - /* reset register */ - rByteAMD(cs, cmd); - else { - wByteAMD(cs, 0x00, cmd); - for (cnt = *ptr++; cnt > 0; cnt--) - rByteAMD(cs, 0x01); - } - } - /* write */ - else if (cmd < 8) - wByteAMD(cs, cmd, LOBYTE(*ptr++)); - - else { - wByteAMD(cs, 0x00, cmd); - for (cnt = *ptr++; cnt > 0; cnt--) - wByteAMD(cs, 0x01, LOBYTE(*ptr++)); - } - } -} - -void setup_Amd7930(struct IsdnCardState *cs) -{ - INIT_WORK(&cs->tqueue, Amd7930_bh); - timer_setup(&cs->dbusytimer, dbusy_timer_handler, 0); -} diff --git a/drivers/isdn/hisax/amd7930_fn.h b/drivers/isdn/hisax/amd7930_fn.h deleted file mode 100644 index 1f4d80c5e5a6..000000000000 --- a/drivers/isdn/hisax/amd7930_fn.h +++ /dev/null @@ -1,37 +0,0 @@ -/* drivers/isdn/hisax/amd7930_fn.h - * - * gerdes_amd7930.h Header-file included by - * gerdes_amd7930.c - * - * Author Christoph Ersfeld <info@formula-n.de> - * Formula-n Europe AG (www.formula-n.com) - * previously Gerdes AG - * - * - * This file is (c) under GNU PUBLIC LICENSE - */ - - - - -#define BYTE unsigned char -#define WORD unsigned int -#define rByteAMD(cs, reg) cs->readisac(cs, reg) -#define wByteAMD(cs, reg, val) cs->writeisac(cs, reg, val) -#define rWordAMD(cs, reg) ReadWordAmd7930(cs, reg) -#define wWordAMD(cs, reg, val) WriteWordAmd7930(cs, reg, val) -#define HIBYTE(w) ((unsigned char)((w & 0xff00) / 256)) -#define LOBYTE(w) ((unsigned char)(w & 0x00ff)) - -#define AmdIrqOff(cs) cs->dc.amd7930.setIrqMask(cs, 0) -#define AmdIrqOn(cs) cs->dc.amd7930.setIrqMask(cs, 1) - -#define AMD_CR 0x00 -#define AMD_DR 0x01 - - -#define DBUSY_TIMER_VALUE 80 - -extern void Amd7930_interrupt(struct IsdnCardState *, unsigned char); -extern void Amd7930_init(struct IsdnCardState *); -extern void setup_Amd7930(struct IsdnCardState *); diff --git a/drivers/isdn/hisax/arcofi.c b/drivers/isdn/hisax/arcofi.c deleted file mode 100644 index 2f784f96d439..000000000000 --- a/drivers/isdn/hisax/arcofi.c +++ /dev/null @@ -1,131 +0,0 @@ -/* $Id: arcofi.c,v 1.14.2.3 2004/01/13 14:31:24 keil Exp $ - * - * Ansteuerung ARCOFI 2165 - * - * Author Karsten Keil - * Copyright by Karsten Keil <keil@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/sched.h> -#include "hisax.h" -#include "isdnl1.h" -#include "isac.h" -#include "arcofi.h" - -#define ARCOFI_TIMER_VALUE 20 - -static void -add_arcofi_timer(struct IsdnCardState *cs) { - if (test_and_set_bit(FLG_ARCOFI_TIMER, &cs->HW_Flags)) { - del_timer(&cs->dc.isac.arcofitimer); - } - cs->dc.isac.arcofitimer.expires = jiffies + ((ARCOFI_TIMER_VALUE * HZ) / 1000); - add_timer(&cs->dc.isac.arcofitimer); -} - -static void -send_arcofi(struct IsdnCardState *cs) { - add_arcofi_timer(cs); - cs->dc.isac.mon_txp = 0; - cs->dc.isac.mon_txc = cs->dc.isac.arcofi_list->len; - memcpy(cs->dc.isac.mon_tx, cs->dc.isac.arcofi_list->msg, cs->dc.isac.mon_txc); - switch (cs->dc.isac.arcofi_bc) { - case 0: break; - case 1: cs->dc.isac.mon_tx[1] |= 0x40; - break; - default: break; - } - cs->dc.isac.mocr &= 0x0f; - cs->dc.isac.mocr |= 0xa0; - cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); - (void) cs->readisac(cs, ISAC_MOSR); - cs->writeisac(cs, ISAC_MOX1, cs->dc.isac.mon_tx[cs->dc.isac.mon_txp++]); - cs->dc.isac.mocr |= 0x10; - cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); -} - -int -arcofi_fsm(struct IsdnCardState *cs, int event, void *data) { - if (cs->debug & L1_DEB_MONITOR) { - debugl1(cs, "arcofi state %d event %d", cs->dc.isac.arcofi_state, event); - } - if (event == ARCOFI_TIMEOUT) { - cs->dc.isac.arcofi_state = ARCOFI_NOP; - test_and_set_bit(FLG_ARCOFI_ERROR, &cs->HW_Flags); - wake_up(&cs->dc.isac.arcofi_wait); - return (1); - } - switch (cs->dc.isac.arcofi_state) { - case ARCOFI_NOP: - if (event == ARCOFI_START) { - cs->dc.isac.arcofi_list = data; - cs->dc.isac.arcofi_state = ARCOFI_TRANSMIT; - send_arcofi(cs); - } - break; - case ARCOFI_TRANSMIT: - if (event == ARCOFI_TX_END) { - if (cs->dc.isac.arcofi_list->receive) { - add_arcofi_timer(cs); - cs->dc.isac.arcofi_state = ARCOFI_RECEIVE; - } else { - if (cs->dc.isac.arcofi_list->next) { - cs->dc.isac.arcofi_list = - cs->dc.isac.arcofi_list->next; - send_arcofi(cs); - } else { - if (test_and_clear_bit(FLG_ARCOFI_TIMER, &cs->HW_Flags)) { - del_timer(&cs->dc.isac.arcofitimer); - } - cs->dc.isac.arcofi_state = ARCOFI_NOP; - wake_up(&cs->dc.isac.arcofi_wait); - } - } - } - break; - case ARCOFI_RECEIVE: - if (event == ARCOFI_RX_END) { - if (cs->dc.isac.arcofi_list->next) { - cs->dc.isac.arcofi_list = - cs->dc.isac.arcofi_list->next; - cs->dc.isac.arcofi_state = ARCOFI_TRANSMIT; - send_arcofi(cs); - } else { - if (test_and_clear_bit(FLG_ARCOFI_TIMER, &cs->HW_Flags)) { - del_timer(&cs->dc.isac.arcofitimer); - } - cs->dc.isac.arcofi_state = ARCOFI_NOP; - wake_up(&cs->dc.isac.arcofi_wait); - } - } - break; - default: - debugl1(cs, "Arcofi unknown state %x", cs->dc.isac.arcofi_state); - return (2); - } - return (0); -} - -static void -arcofi_timer(struct timer_list *t) { - struct IsdnCardState *cs = from_timer(cs, t, dc.isac.arcofitimer); - arcofi_fsm(cs, ARCOFI_TIMEOUT, NULL); -} - -void -clear_arcofi(struct IsdnCardState *cs) { - if (test_and_clear_bit(FLG_ARCOFI_TIMER, &cs->HW_Flags)) { - del_timer(&cs->dc.isac.arcofitimer); - } -} - -void -init_arcofi(struct IsdnCardState *cs) { - timer_setup(&cs->dc.isac.arcofitimer, arcofi_timer, 0); - init_waitqueue_head(&cs->dc.isac.arcofi_wait); - test_and_set_bit(HW_ARCOFI, &cs->HW_Flags); -} diff --git a/drivers/isdn/hisax/arcofi.h b/drivers/isdn/hisax/arcofi.h deleted file mode 100644 index b9c77529fabf..000000000000 --- a/drivers/isdn/hisax/arcofi.h +++ /dev/null @@ -1,27 +0,0 @@ -/* $Id: arcofi.h,v 1.6.6.2 2001/09/23 22:24:46 kai Exp $ - * - * Ansteuerung ARCOFI 2165 - * - * Author Karsten Keil - * Copyright by Karsten Keil <keil@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#define ARCOFI_USE 1 - -/* states */ -#define ARCOFI_NOP 0 -#define ARCOFI_TRANSMIT 1 -#define ARCOFI_RECEIVE 2 -/* events */ -#define ARCOFI_START 1 -#define ARCOFI_TX_END 2 -#define ARCOFI_RX_END 3 -#define ARCOFI_TIMEOUT 4 - -extern int arcofi_fsm(struct IsdnCardState *cs, int event, void *data); -extern void init_arcofi(struct IsdnCardState *cs); -extern void clear_arcofi(struct IsdnCardState *cs); diff --git a/drivers/isdn/hisax/asuscom.c b/drivers/isdn/hisax/asuscom.c deleted file mode 100644 index 74c871495e81..000000000000 --- a/drivers/isdn/hisax/asuscom.c +++ /dev/null @@ -1,423 +0,0 @@ -/* $Id: asuscom.c,v 1.14.2.4 2004/01/13 23:48:39 keil Exp $ - * - * low level stuff for ASUSCOM NETWORK INC. ISDNLink cards - * - * Author Karsten Keil - * Copyright by Karsten Keil <keil@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * Thanks to ASUSCOM NETWORK INC. Taiwan and Dynalink NL for information - * - */ - -#include <linux/init.h> -#include <linux/isapnp.h> -#include "hisax.h" -#include "isac.h" -#include "ipac.h" -#include "hscx.h" -#include "isdnl1.h" - -static const char *Asuscom_revision = "$Revision: 1.14.2.4 $"; - -#define byteout(addr, val) outb(val, addr) -#define bytein(addr) inb(addr) - -#define ASUS_ISAC 0 -#define ASUS_HSCX 1 -#define ASUS_ADR 2 -#define ASUS_CTRL_U7 3 -#define ASUS_CTRL_POTS 5 - -#define ASUS_IPAC_ALE 0 -#define ASUS_IPAC_DATA 1 - -#define ASUS_ISACHSCX 1 -#define ASUS_IPAC 2 - -/* CARD_ADR (Write) */ -#define ASUS_RESET 0x80 /* Bit 7 Reset-Leitung */ - -static inline u_char -readreg(unsigned int ale, unsigned int adr, u_char off) -{ - register u_char ret; - - byteout(ale, off); - ret = bytein(adr); - return (ret); -} - -static inline void -readfifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size) -{ - byteout(ale, off); - insb(adr, data, size); -} - - -static inline void -writereg(unsigned int ale, unsigned int adr, u_char off, u_char data) -{ - byteout(ale, off); - byteout(adr, data); -} - -static inline void -writefifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size) -{ - byteout(ale, off); - outsb(adr, data, size); -} - -/* Interface functions */ - -static u_char -ReadISAC(struct IsdnCardState *cs, u_char offset) -{ - return (readreg(cs->hw.asus.adr, cs->hw.asus.isac, offset)); -} - -static void -WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value) -{ - writereg(cs->hw.asus.adr, cs->hw.asus.isac, offset, value); -} - -static void -ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - readfifo(cs->hw.asus.adr, cs->hw.asus.isac, 0, data, size); -} - -static void -WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - writefifo(cs->hw.asus.adr, cs->hw.asus.isac, 0, data, size); -} - -static u_char -ReadISAC_IPAC(struct IsdnCardState *cs, u_char offset) -{ - return (readreg(cs->hw.asus.adr, cs->hw.asus.isac, offset | 0x80)); -} - -static void -WriteISAC_IPAC(struct IsdnCardState *cs, u_char offset, u_char value) -{ - writereg(cs->hw.asus.adr, cs->hw.asus.isac, offset | 0x80, value); -} - -static void -ReadISACfifo_IPAC(struct IsdnCardState *cs, u_char *data, int size) -{ - readfifo(cs->hw.asus.adr, cs->hw.asus.isac, 0x80, data, size); -} - -static void -WriteISACfifo_IPAC(struct IsdnCardState *cs, u_char *data, int size) -{ - writefifo(cs->hw.asus.adr, cs->hw.asus.isac, 0x80, data, size); -} - -static u_char -ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset) -{ - return (readreg(cs->hw.asus.adr, - cs->hw.asus.hscx, offset + (hscx ? 0x40 : 0))); -} - -static void -WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) -{ - writereg(cs->hw.asus.adr, - cs->hw.asus.hscx, offset + (hscx ? 0x40 : 0), value); -} - -/* - * fast interrupt HSCX stuff goes here - */ - -#define READHSCX(cs, nr, reg) readreg(cs->hw.asus.adr, \ - cs->hw.asus.hscx, reg + (nr ? 0x40 : 0)) -#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.asus.adr, \ - cs->hw.asus.hscx, reg + (nr ? 0x40 : 0), data) - -#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.asus.adr, \ - cs->hw.asus.hscx, (nr ? 0x40 : 0), ptr, cnt) - -#define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.asus.adr, \ - cs->hw.asus.hscx, (nr ? 0x40 : 0), ptr, cnt) - -#include "hscx_irq.c" - -static irqreturn_t -asuscom_interrupt(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - u_char val; - u_long flags; - - spin_lock_irqsave(&cs->lock, flags); - val = readreg(cs->hw.asus.adr, cs->hw.asus.hscx, HSCX_ISTA + 0x40); -Start_HSCX: - if (val) - hscx_int_main(cs, val); - val = readreg(cs->hw.asus.adr, cs->hw.asus.isac, ISAC_ISTA); -Start_ISAC: - if (val) - isac_interrupt(cs, val); - val = readreg(cs->hw.asus.adr, cs->hw.asus.hscx, HSCX_ISTA + 0x40); - if (val) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "HSCX IntStat after IntRoutine"); - goto Start_HSCX; - } - val = readreg(cs->hw.asus.adr, cs->hw.asus.isac, ISAC_ISTA); - if (val) { - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "ISAC IntStat after IntRoutine"); - goto Start_ISAC; - } - writereg(cs->hw.asus.adr, cs->hw.asus.hscx, HSCX_MASK, 0xFF); - writereg(cs->hw.asus.adr, cs->hw.asus.hscx, HSCX_MASK + 0x40, 0xFF); - writereg(cs->hw.asus.adr, cs->hw.asus.isac, ISAC_MASK, 0xFF); - writereg(cs->hw.asus.adr, cs->hw.asus.isac, ISAC_MASK, 0x0); - writereg(cs->hw.asus.adr, cs->hw.asus.hscx, HSCX_MASK, 0x0); - writereg(cs->hw.asus.adr, cs->hw.asus.hscx, HSCX_MASK + 0x40, 0x0); - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -static irqreturn_t -asuscom_interrupt_ipac(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - u_char ista, val, icnt = 5; - u_long flags; - - spin_lock_irqsave(&cs->lock, flags); - ista = readreg(cs->hw.asus.adr, cs->hw.asus.isac, IPAC_ISTA); -Start_IPAC: - if (cs->debug & L1_DEB_IPAC) - debugl1(cs, "IPAC ISTA %02X", ista); - if (ista & 0x0f) { - val = readreg(cs->hw.asus.adr, cs->hw.asus.hscx, HSCX_ISTA + 0x40); - if (ista & 0x01) - val |= 0x01; - if (ista & 0x04) - val |= 0x02; - if (ista & 0x08) - val |= 0x04; - if (val) - hscx_int_main(cs, val); - } - if (ista & 0x20) { - val = 0xfe & readreg(cs->hw.asus.adr, cs->hw.asus.isac, ISAC_ISTA | 0x80); - if (val) { - isac_interrupt(cs, val); - } - } - if (ista & 0x10) { - val = 0x01; - isac_interrupt(cs, val); - } - ista = readreg(cs->hw.asus.adr, cs->hw.asus.isac, IPAC_ISTA); - if ((ista & 0x3f) && icnt) { - icnt--; - goto Start_IPAC; - } - if (!icnt) - printk(KERN_WARNING "ASUS IRQ LOOP\n"); - writereg(cs->hw.asus.adr, cs->hw.asus.isac, IPAC_MASK, 0xFF); - writereg(cs->hw.asus.adr, cs->hw.asus.isac, IPAC_MASK, 0xC0); - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -static void -release_io_asuscom(struct IsdnCardState *cs) -{ - int bytecnt = 8; - - if (cs->hw.asus.cfg_reg) - release_region(cs->hw.asus.cfg_reg, bytecnt); -} - -static void -reset_asuscom(struct IsdnCardState *cs) -{ - if (cs->subtyp == ASUS_IPAC) - writereg(cs->hw.asus.adr, cs->hw.asus.isac, IPAC_POTA2, 0x20); - else - byteout(cs->hw.asus.adr, ASUS_RESET); /* Reset On */ - mdelay(10); - if (cs->subtyp == ASUS_IPAC) - writereg(cs->hw.asus.adr, cs->hw.asus.isac, IPAC_POTA2, 0x0); - else - byteout(cs->hw.asus.adr, 0); /* Reset Off */ - mdelay(10); - if (cs->subtyp == ASUS_IPAC) { - writereg(cs->hw.asus.adr, cs->hw.asus.isac, IPAC_CONF, 0x0); - writereg(cs->hw.asus.adr, cs->hw.asus.isac, IPAC_ACFG, 0xff); - writereg(cs->hw.asus.adr, cs->hw.asus.isac, IPAC_AOE, 0x0); - writereg(cs->hw.asus.adr, cs->hw.asus.isac, IPAC_MASK, 0xc0); - writereg(cs->hw.asus.adr, cs->hw.asus.isac, IPAC_PCFG, 0x12); - } -} - -static int -Asus_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - u_long flags; - - switch (mt) { - case CARD_RESET: - spin_lock_irqsave(&cs->lock, flags); - reset_asuscom(cs); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_RELEASE: - release_io_asuscom(cs); - return (0); - case CARD_INIT: - spin_lock_irqsave(&cs->lock, flags); - cs->debug |= L1_DEB_IPAC; - inithscxisac(cs, 3); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_TEST: - return (0); - } - return (0); -} - -#ifdef __ISAPNP__ -static struct isapnp_device_id asus_ids[] = { - { ISAPNP_VENDOR('A', 'S', 'U'), ISAPNP_FUNCTION(0x1688), - ISAPNP_VENDOR('A', 'S', 'U'), ISAPNP_FUNCTION(0x1688), - (unsigned long) "Asus1688 PnP" }, - { ISAPNP_VENDOR('A', 'S', 'U'), ISAPNP_FUNCTION(0x1690), - ISAPNP_VENDOR('A', 'S', 'U'), ISAPNP_FUNCTION(0x1690), - (unsigned long) "Asus1690 PnP" }, - { ISAPNP_VENDOR('S', 'I', 'E'), ISAPNP_FUNCTION(0x0020), - ISAPNP_VENDOR('S', 'I', 'E'), ISAPNP_FUNCTION(0x0020), - (unsigned long) "Isurf2 PnP" }, - { ISAPNP_VENDOR('E', 'L', 'F'), ISAPNP_FUNCTION(0x0000), - ISAPNP_VENDOR('E', 'L', 'F'), ISAPNP_FUNCTION(0x0000), - (unsigned long) "Iscas TE320" }, - { 0, } -}; - -static struct isapnp_device_id *ipid = &asus_ids[0]; -static struct pnp_card *pnp_c = NULL; -#endif - -int setup_asuscom(struct IsdnCard *card) -{ - int bytecnt; - struct IsdnCardState *cs = card->cs; - u_char val; - char tmp[64]; - - strcpy(tmp, Asuscom_revision); - printk(KERN_INFO "HiSax: Asuscom ISDNLink driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_ASUSCOM) - return (0); -#ifdef __ISAPNP__ - if (!card->para[1] && isapnp_present()) { - struct pnp_dev *pnp_d; - while (ipid->card_vendor) { - if ((pnp_c = pnp_find_card(ipid->card_vendor, - ipid->card_device, pnp_c))) { - pnp_d = NULL; - if ((pnp_d = pnp_find_dev(pnp_c, - ipid->vendor, ipid->function, pnp_d))) { - int err; - - printk(KERN_INFO "HiSax: %s detected\n", - (char *)ipid->driver_data); - pnp_disable_dev(pnp_d); - err = pnp_activate_dev(pnp_d); - if (err < 0) { - printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n", - __func__, err); - return (0); - } - card->para[1] = pnp_port_start(pnp_d, 0); - card->para[0] = pnp_irq(pnp_d, 0); - if (card->para[0] == -1 || !card->para[1]) { - printk(KERN_ERR "AsusPnP:some resources are missing %ld/%lx\n", - card->para[0], card->para[1]); - pnp_disable_dev(pnp_d); - return (0); - } - break; - } else { - printk(KERN_ERR "AsusPnP: PnP error card found, no device\n"); - } - } - ipid++; - pnp_c = NULL; - } - if (!ipid->card_vendor) { - printk(KERN_INFO "AsusPnP: no ISAPnP card found\n"); - return (0); - } - } -#endif - bytecnt = 8; - cs->hw.asus.cfg_reg = card->para[1]; - cs->irq = card->para[0]; - if (!request_region(cs->hw.asus.cfg_reg, bytecnt, "asuscom isdn")) { - printk(KERN_WARNING - "HiSax: ISDNLink config port %x-%x already in use\n", - cs->hw.asus.cfg_reg, - cs->hw.asus.cfg_reg + bytecnt); - return (0); - } - printk(KERN_INFO "ISDNLink: defined at 0x%x IRQ %d\n", - cs->hw.asus.cfg_reg, cs->irq); - setup_isac(cs); - cs->BC_Read_Reg = &ReadHSCX; - cs->BC_Write_Reg = &WriteHSCX; - cs->BC_Send_Data = &hscx_fill_fifo; - cs->cardmsg = &Asus_card_msg; - val = readreg(cs->hw.asus.cfg_reg + ASUS_IPAC_ALE, - cs->hw.asus.cfg_reg + ASUS_IPAC_DATA, IPAC_ID); - if ((val == 1) || (val == 2)) { - cs->subtyp = ASUS_IPAC; - cs->hw.asus.adr = cs->hw.asus.cfg_reg + ASUS_IPAC_ALE; - cs->hw.asus.isac = cs->hw.asus.cfg_reg + ASUS_IPAC_DATA; - cs->hw.asus.hscx = cs->hw.asus.cfg_reg + ASUS_IPAC_DATA; - test_and_set_bit(HW_IPAC, &cs->HW_Flags); - cs->readisac = &ReadISAC_IPAC; - cs->writeisac = &WriteISAC_IPAC; - cs->readisacfifo = &ReadISACfifo_IPAC; - cs->writeisacfifo = &WriteISACfifo_IPAC; - cs->irq_func = &asuscom_interrupt_ipac; - printk(KERN_INFO "Asus: IPAC version %x\n", val); - } else { - cs->subtyp = ASUS_ISACHSCX; - cs->hw.asus.adr = cs->hw.asus.cfg_reg + ASUS_ADR; - cs->hw.asus.isac = cs->hw.asus.cfg_reg + ASUS_ISAC; - cs->hw.asus.hscx = cs->hw.asus.cfg_reg + ASUS_HSCX; - cs->hw.asus.u7 = cs->hw.asus.cfg_reg + ASUS_CTRL_U7; - cs->hw.asus.pots = cs->hw.asus.cfg_reg + ASUS_CTRL_POTS; - cs->readisac = &ReadISAC; - cs->writeisac = &WriteISAC; - cs->readisacfifo = &ReadISACfifo; - cs->writeisacfifo = &WriteISACfifo; - cs->irq_func = &asuscom_interrupt; - ISACVersion(cs, "ISDNLink:"); - if (HscxVersion(cs, "ISDNLink:")) { - printk(KERN_WARNING - "ISDNLink: wrong HSCX versions check IO address\n"); - release_io_asuscom(cs); - return (0); - } - } - return (1); -} diff --git a/drivers/isdn/hisax/avm_a1.c b/drivers/isdn/hisax/avm_a1.c deleted file mode 100644 index 7dd74087ad72..000000000000 --- a/drivers/isdn/hisax/avm_a1.c +++ /dev/null @@ -1,307 +0,0 @@ -/* $Id: avm_a1.c,v 2.15.2.4 2004/01/13 21:46:03 keil Exp $ - * - * low level stuff for AVM A1 (Fritz) isdn cards - * - * Author Karsten Keil - * Copyright by Karsten Keil <keil@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/init.h> -#include "hisax.h" -#include "isac.h" -#include "hscx.h" -#include "isdnl1.h" - -static const char *avm_revision = "$Revision: 2.15.2.4 $"; - -#define AVM_A1_STAT_ISAC 0x01 -#define AVM_A1_STAT_HSCX 0x02 -#define AVM_A1_STAT_TIMER 0x04 - -#define byteout(addr, val) outb(val, addr) -#define bytein(addr) inb(addr) - -static inline u_char -readreg(unsigned int adr, u_char off) -{ - return (bytein(adr + off)); -} - -static inline void -writereg(unsigned int adr, u_char off, u_char data) -{ - byteout(adr + off, data); -} - - -static inline void -read_fifo(unsigned int adr, u_char *data, int size) -{ - insb(adr, data, size); -} - -static void -write_fifo(unsigned int adr, u_char *data, int size) -{ - outsb(adr, data, size); -} - -/* Interface functions */ - -static u_char -ReadISAC(struct IsdnCardState *cs, u_char offset) -{ - return (readreg(cs->hw.avm.isac, offset)); -} - -static void -WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value) -{ - writereg(cs->hw.avm.isac, offset, value); -} - -static void -ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - read_fifo(cs->hw.avm.isacfifo, data, size); -} - -static void -WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - write_fifo(cs->hw.avm.isacfifo, data, size); -} - -static u_char -ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset) -{ - return (readreg(cs->hw.avm.hscx[hscx], offset)); -} - -static void -WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) -{ - writereg(cs->hw.avm.hscx[hscx], offset, value); -} - -/* - * fast interrupt HSCX stuff goes here - */ - -#define READHSCX(cs, nr, reg) readreg(cs->hw.avm.hscx[nr], reg) -#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.avm.hscx[nr], reg, data) -#define READHSCXFIFO(cs, nr, ptr, cnt) read_fifo(cs->hw.avm.hscxfifo[nr], ptr, cnt) -#define WRITEHSCXFIFO(cs, nr, ptr, cnt) write_fifo(cs->hw.avm.hscxfifo[nr], ptr, cnt) - -#include "hscx_irq.c" - -static irqreturn_t -avm_a1_interrupt(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - u_char val, sval; - u_long flags; - - spin_lock_irqsave(&cs->lock, flags); - while (((sval = bytein(cs->hw.avm.cfg_reg)) & 0xf) != 0x7) { - if (!(sval & AVM_A1_STAT_TIMER)) { - byteout(cs->hw.avm.cfg_reg, 0x1E); - sval = bytein(cs->hw.avm.cfg_reg); - } else if (cs->debug & L1_DEB_INTSTAT) - debugl1(cs, "avm IntStatus %x", sval); - if (!(sval & AVM_A1_STAT_HSCX)) { - val = readreg(cs->hw.avm.hscx[1], HSCX_ISTA); - if (val) - hscx_int_main(cs, val); - } - if (!(sval & AVM_A1_STAT_ISAC)) { - val = readreg(cs->hw.avm.isac, ISAC_ISTA); - if (val) - isac_interrupt(cs, val); - } - } - writereg(cs->hw.avm.hscx[0], HSCX_MASK, 0xFF); - writereg(cs->hw.avm.hscx[1], HSCX_MASK, 0xFF); - writereg(cs->hw.avm.isac, ISAC_MASK, 0xFF); - writereg(cs->hw.avm.isac, ISAC_MASK, 0x0); - writereg(cs->hw.avm.hscx[0], HSCX_MASK, 0x0); - writereg(cs->hw.avm.hscx[1], HSCX_MASK, 0x0); - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -static inline void -release_ioregs(struct IsdnCardState *cs, int mask) -{ - release_region(cs->hw.avm.cfg_reg, 8); - if (mask & 1) - release_region(cs->hw.avm.isac + 32, 32); - if (mask & 2) - release_region(cs->hw.avm.isacfifo, 1); - if (mask & 4) - release_region(cs->hw.avm.hscx[0] + 32, 32); - if (mask & 8) - release_region(cs->hw.avm.hscxfifo[0], 1); - if (mask & 0x10) - release_region(cs->hw.avm.hscx[1] + 32, 32); - if (mask & 0x20) - release_region(cs->hw.avm.hscxfifo[1], 1); -} - -static int -AVM_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - u_long flags; - - switch (mt) { - case CARD_RESET: - return (0); - case CARD_RELEASE: - release_ioregs(cs, 0x3f); - return (0); - case CARD_INIT: - spin_lock_irqsave(&cs->lock, flags); - inithscxisac(cs, 1); - byteout(cs->hw.avm.cfg_reg, 0x16); - byteout(cs->hw.avm.cfg_reg, 0x1E); - inithscxisac(cs, 2); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_TEST: - return (0); - } - return (0); -} - -int setup_avm_a1(struct IsdnCard *card) -{ - u_char val; - struct IsdnCardState *cs = card->cs; - char tmp[64]; - - strcpy(tmp, avm_revision); - printk(KERN_INFO "HiSax: AVM driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_A1) - return (0); - - cs->hw.avm.cfg_reg = card->para[1] + 0x1800; - cs->hw.avm.isac = card->para[1] + 0x1400 - 0x20; - cs->hw.avm.hscx[0] = card->para[1] + 0x400 - 0x20; - cs->hw.avm.hscx[1] = card->para[1] + 0xc00 - 0x20; - cs->hw.avm.isacfifo = card->para[1] + 0x1000; - cs->hw.avm.hscxfifo[0] = card->para[1]; - cs->hw.avm.hscxfifo[1] = card->para[1] + 0x800; - cs->irq = card->para[0]; - if (!request_region(cs->hw.avm.cfg_reg, 8, "avm cfg")) { - printk(KERN_WARNING - "HiSax: AVM A1 config port %x-%x already in use\n", - cs->hw.avm.cfg_reg, - cs->hw.avm.cfg_reg + 8); - return (0); - } - if (!request_region(cs->hw.avm.isac + 32, 32, "HiSax isac")) { - printk(KERN_WARNING - "HiSax: AVM A1 isac ports %x-%x already in use\n", - cs->hw.avm.isac + 32, - cs->hw.avm.isac + 64); - release_ioregs(cs, 0); - return (0); - } - if (!request_region(cs->hw.avm.isacfifo, 1, "HiSax isac fifo")) { - printk(KERN_WARNING - "HiSax: AVM A1 isac fifo port %x already in use\n", - cs->hw.avm.isacfifo); - release_ioregs(cs, 1); - return (0); - } - if (!request_region(cs->hw.avm.hscx[0] + 32, 32, "HiSax hscx A")) { - printk(KERN_WARNING - "HiSax: AVM A1 hscx A ports %x-%x already in use\n", - cs->hw.avm.hscx[0] + 32, - cs->hw.avm.hscx[0] + 64); - release_ioregs(cs, 3); - return (0); - } - if (!request_region(cs->hw.avm.hscxfifo[0], 1, "HiSax hscx A fifo")) { - printk(KERN_WARNING - "HiSax: AVM A1 hscx A fifo port %x already in use\n", - cs->hw.avm.hscxfifo[0]); - release_ioregs(cs, 7); - return (0); - } - if (!request_region(cs->hw.avm.hscx[1] + 32, 32, "HiSax hscx B")) { - printk(KERN_WARNING - "HiSax: AVM A1 hscx B ports %x-%x already in use\n", - cs->hw.avm.hscx[1] + 32, - cs->hw.avm.hscx[1] + 64); - release_ioregs(cs, 0xf); - return (0); - } - if (!request_region(cs->hw.avm.hscxfifo[1], 1, "HiSax hscx B fifo")) { - printk(KERN_WARNING - "HiSax: AVM A1 hscx B fifo port %x already in use\n", - cs->hw.avm.hscxfifo[1]); - release_ioregs(cs, 0x1f); - return (0); - } - byteout(cs->hw.avm.cfg_reg, 0x0); - HZDELAY(HZ / 5 + 1); - byteout(cs->hw.avm.cfg_reg, 0x1); - HZDELAY(HZ / 5 + 1); - byteout(cs->hw.avm.cfg_reg, 0x0); - HZDELAY(HZ / 5 + 1); - val = cs->irq; - if (val == 9) - val = 2; - byteout(cs->hw.avm.cfg_reg + 1, val); - HZDELAY(HZ / 5 + 1); - byteout(cs->hw.avm.cfg_reg, 0x0); - HZDELAY(HZ / 5 + 1); - - val = bytein(cs->hw.avm.cfg_reg); - printk(KERN_INFO "AVM A1: Byte at %x is %x\n", - cs->hw.avm.cfg_reg, val); - val = bytein(cs->hw.avm.cfg_reg + 3); - printk(KERN_INFO "AVM A1: Byte at %x is %x\n", - cs->hw.avm.cfg_reg + 3, val); - val = bytein(cs->hw.avm.cfg_reg + 2); - printk(KERN_INFO "AVM A1: Byte at %x is %x\n", - cs->hw.avm.cfg_reg + 2, val); - val = bytein(cs->hw.avm.cfg_reg); - printk(KERN_INFO "AVM A1: Byte at %x is %x\n", - cs->hw.avm.cfg_reg, val); - - printk(KERN_INFO "HiSax: AVM A1 config irq:%d cfg:0x%X\n", - cs->irq, - cs->hw.avm.cfg_reg); - printk(KERN_INFO - "HiSax: isac:0x%X/0x%X\n", - cs->hw.avm.isac + 32, cs->hw.avm.isacfifo); - printk(KERN_INFO - "HiSax: hscx A:0x%X/0x%X hscx B:0x%X/0x%X\n", - cs->hw.avm.hscx[0] + 32, cs->hw.avm.hscxfifo[0], - cs->hw.avm.hscx[1] + 32, cs->hw.avm.hscxfifo[1]); - - cs->readisac = &ReadISAC; - cs->writeisac = &WriteISAC; - cs->readisacfifo = &ReadISACfifo; - cs->writeisacfifo = &WriteISACfifo; - cs->BC_Read_Reg = &ReadHSCX; - cs->BC_Write_Reg = &WriteHSCX; - cs->BC_Send_Data = &hscx_fill_fifo; - setup_isac(cs); - cs->cardmsg = &AVM_card_msg; - cs->irq_func = &avm_a1_interrupt; - ISACVersion(cs, "AVM A1:"); - if (HscxVersion(cs, "AVM A1:")) { - printk(KERN_WARNING - "AVM A1: wrong HSCX versions check IO address\n"); - release_ioregs(cs, 0x3f); - return (0); - } - return (1); -} diff --git a/drivers/isdn/hisax/avm_a1p.c b/drivers/isdn/hisax/avm_a1p.c deleted file mode 100644 index bc52d54ff5e1..000000000000 --- a/drivers/isdn/hisax/avm_a1p.c +++ /dev/null @@ -1,267 +0,0 @@ -/* $Id: avm_a1p.c,v 2.9.2.5 2004/01/24 20:47:19 keil Exp $ - * - * low level stuff for the following AVM cards: - * A1 PCMCIA - * FRITZ!Card PCMCIA - * FRITZ!Card PCMCIA 2.0 - * - * Author Carsten Paeth - * Copyright by Carsten Paeth <calle@calle.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#include <linux/init.h> -#include "hisax.h" -#include "isac.h" -#include "hscx.h" -#include "isdnl1.h" - -/* register offsets */ -#define ADDRREG_OFFSET 0x02 -#define DATAREG_OFFSET 0x03 -#define ASL0_OFFSET 0x04 -#define ASL1_OFFSET 0x05 -#define MODREG_OFFSET 0x06 -#define VERREG_OFFSET 0x07 - -/* address offsets */ -#define ISAC_FIFO_OFFSET 0x00 -#define ISAC_REG_OFFSET 0x20 -#define HSCX_CH_DIFF 0x40 -#define HSCX_FIFO_OFFSET 0x80 -#define HSCX_REG_OFFSET 0xa0 - -/* read bits ASL0 */ -#define ASL0_R_TIMER 0x10 /* active low */ -#define ASL0_R_ISAC 0x20 /* active low */ -#define ASL0_R_HSCX 0x40 /* active low */ -#define ASL0_R_TESTBIT 0x80 -#define ASL0_R_IRQPENDING (ASL0_R_ISAC | ASL0_R_HSCX | ASL0_R_TIMER) - -/* write bits ASL0 */ -#define ASL0_W_RESET 0x01 -#define ASL0_W_TDISABLE 0x02 -#define ASL0_W_TRESET 0x04 -#define ASL0_W_IRQENABLE 0x08 -#define ASL0_W_TESTBIT 0x80 - -/* write bits ASL1 */ -#define ASL1_W_LED0 0x10 -#define ASL1_W_LED1 0x20 -#define ASL1_W_ENABLE_S0 0xC0 - -#define byteout(addr, val) outb(val, addr) -#define bytein(addr) inb(addr) - -static const char *avm_revision = "$Revision: 2.9.2.5 $"; - -static inline u_char -ReadISAC(struct IsdnCardState *cs, u_char offset) -{ - u_char ret; - - offset -= 0x20; - byteout(cs->hw.avm.cfg_reg + ADDRREG_OFFSET, ISAC_REG_OFFSET + offset); - ret = bytein(cs->hw.avm.cfg_reg + DATAREG_OFFSET); - return ret; -} - -static inline void -WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value) -{ - offset -= 0x20; - byteout(cs->hw.avm.cfg_reg + ADDRREG_OFFSET, ISAC_REG_OFFSET + offset); - byteout(cs->hw.avm.cfg_reg + DATAREG_OFFSET, value); -} - -static inline void -ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - byteout(cs->hw.avm.cfg_reg + ADDRREG_OFFSET, ISAC_FIFO_OFFSET); - insb(cs->hw.avm.cfg_reg + DATAREG_OFFSET, data, size); -} - -static inline void -WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - byteout(cs->hw.avm.cfg_reg + ADDRREG_OFFSET, ISAC_FIFO_OFFSET); - outsb(cs->hw.avm.cfg_reg + DATAREG_OFFSET, data, size); -} - -static inline u_char -ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset) -{ - u_char ret; - - offset -= 0x20; - byteout(cs->hw.avm.cfg_reg + ADDRREG_OFFSET, - HSCX_REG_OFFSET + hscx * HSCX_CH_DIFF + offset); - ret = bytein(cs->hw.avm.cfg_reg + DATAREG_OFFSET); - return ret; -} - -static inline void -WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) -{ - offset -= 0x20; - byteout(cs->hw.avm.cfg_reg + ADDRREG_OFFSET, - HSCX_REG_OFFSET + hscx * HSCX_CH_DIFF + offset); - byteout(cs->hw.avm.cfg_reg + DATAREG_OFFSET, value); -} - -static inline void -ReadHSCXfifo(struct IsdnCardState *cs, int hscx, u_char *data, int size) -{ - byteout(cs->hw.avm.cfg_reg + ADDRREG_OFFSET, - HSCX_FIFO_OFFSET + hscx * HSCX_CH_DIFF); - insb(cs->hw.avm.cfg_reg + DATAREG_OFFSET, data, size); -} - -static inline void -WriteHSCXfifo(struct IsdnCardState *cs, int hscx, u_char *data, int size) -{ - byteout(cs->hw.avm.cfg_reg + ADDRREG_OFFSET, - HSCX_FIFO_OFFSET + hscx * HSCX_CH_DIFF); - outsb(cs->hw.avm.cfg_reg + DATAREG_OFFSET, data, size); -} - -/* - * fast interrupt HSCX stuff goes here - */ - -#define READHSCX(cs, nr, reg) ReadHSCX(cs, nr, reg) -#define WRITEHSCX(cs, nr, reg, data) WriteHSCX(cs, nr, reg, data) -#define READHSCXFIFO(cs, nr, ptr, cnt) ReadHSCXfifo(cs, nr, ptr, cnt) -#define WRITEHSCXFIFO(cs, nr, ptr, cnt) WriteHSCXfifo(cs, nr, ptr, cnt) - -#include "hscx_irq.c" - -static irqreturn_t -avm_a1p_interrupt(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - u_char val, sval; - u_long flags; - - spin_lock_irqsave(&cs->lock, flags); - while ((sval = (~bytein(cs->hw.avm.cfg_reg + ASL0_OFFSET) & ASL0_R_IRQPENDING))) { - if (cs->debug & L1_DEB_INTSTAT) - debugl1(cs, "avm IntStatus %x", sval); - if (sval & ASL0_R_HSCX) { - val = ReadHSCX(cs, 1, HSCX_ISTA); - if (val) - hscx_int_main(cs, val); - } - if (sval & ASL0_R_ISAC) { - val = ReadISAC(cs, ISAC_ISTA); - if (val) - isac_interrupt(cs, val); - } - } - WriteHSCX(cs, 0, HSCX_MASK, 0xff); - WriteHSCX(cs, 1, HSCX_MASK, 0xff); - WriteISAC(cs, ISAC_MASK, 0xff); - WriteISAC(cs, ISAC_MASK, 0x00); - WriteHSCX(cs, 0, HSCX_MASK, 0x00); - WriteHSCX(cs, 1, HSCX_MASK, 0x00); - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -static int -AVM_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - u_long flags; - - switch (mt) { - case CARD_RESET: - spin_lock_irqsave(&cs->lock, flags); - byteout(cs->hw.avm.cfg_reg + ASL0_OFFSET, 0x00); - HZDELAY(HZ / 5 + 1); - byteout(cs->hw.avm.cfg_reg + ASL0_OFFSET, ASL0_W_RESET); - HZDELAY(HZ / 5 + 1); - byteout(cs->hw.avm.cfg_reg + ASL0_OFFSET, 0x00); - spin_unlock_irqrestore(&cs->lock, flags); - return 0; - - case CARD_RELEASE: - /* free_irq is done in HiSax_closecard(). */ - /* free_irq(cs->irq, cs); */ - return 0; - - case CARD_INIT: - spin_lock_irqsave(&cs->lock, flags); - byteout(cs->hw.avm.cfg_reg + ASL0_OFFSET, ASL0_W_TDISABLE | ASL0_W_TRESET | ASL0_W_IRQENABLE); - clear_pending_isac_ints(cs); - clear_pending_hscx_ints(cs); - inithscxisac(cs, 1); - inithscxisac(cs, 2); - spin_unlock_irqrestore(&cs->lock, flags); - return 0; - - case CARD_TEST: - /* we really don't need it for the PCMCIA Version */ - return 0; - - default: - /* all card drivers ignore others, so we do the same */ - return 0; - } - return 0; -} - -int setup_avm_a1_pcmcia(struct IsdnCard *card) -{ - u_char model, vers; - struct IsdnCardState *cs = card->cs; - char tmp[64]; - - - strcpy(tmp, avm_revision); - printk(KERN_INFO "HiSax: AVM A1 PCMCIA driver Rev. %s\n", - HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_A1_PCMCIA) - return (0); - - cs->hw.avm.cfg_reg = card->para[1]; - cs->irq = card->para[0]; - - - byteout(cs->hw.avm.cfg_reg + ASL1_OFFSET, ASL1_W_ENABLE_S0); - byteout(cs->hw.avm.cfg_reg + ASL0_OFFSET, 0x00); - HZDELAY(HZ / 5 + 1); - byteout(cs->hw.avm.cfg_reg + ASL0_OFFSET, ASL0_W_RESET); - HZDELAY(HZ / 5 + 1); - byteout(cs->hw.avm.cfg_reg + ASL0_OFFSET, 0x00); - - byteout(cs->hw.avm.cfg_reg + ASL0_OFFSET, ASL0_W_TDISABLE | ASL0_W_TRESET); - - model = bytein(cs->hw.avm.cfg_reg + MODREG_OFFSET); - vers = bytein(cs->hw.avm.cfg_reg + VERREG_OFFSET); - - printk(KERN_INFO "AVM A1 PCMCIA: io 0x%x irq %d model %d version %d\n", - cs->hw.avm.cfg_reg, cs->irq, model, vers); - - setup_isac(cs); - cs->readisac = &ReadISAC; - cs->writeisac = &WriteISAC; - cs->readisacfifo = &ReadISACfifo; - cs->writeisacfifo = &WriteISACfifo; - cs->BC_Read_Reg = &ReadHSCX; - cs->BC_Write_Reg = &WriteHSCX; - cs->BC_Send_Data = &hscx_fill_fifo; - cs->cardmsg = &AVM_card_msg; - cs->irq_flags = IRQF_SHARED; - cs->irq_func = &avm_a1p_interrupt; - - ISACVersion(cs, "AVM A1 PCMCIA:"); - if (HscxVersion(cs, "AVM A1 PCMCIA:")) { - printk(KERN_WARNING - "AVM A1 PCMCIA: wrong HSCX versions check IO address\n"); - return (0); - } - return (1); -} diff --git a/drivers/isdn/hisax/avm_pci.c b/drivers/isdn/hisax/avm_pci.c deleted file mode 100644 index b161456c942e..000000000000 --- a/drivers/isdn/hisax/avm_pci.c +++ /dev/null @@ -1,904 +0,0 @@ -/* $Id: avm_pci.c,v 1.29.2.4 2004/02/11 13:21:32 keil Exp $ - * - * low level stuff for AVM Fritz!PCI and ISA PnP isdn cards - * - * Author Karsten Keil - * Copyright by Karsten Keil <keil@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * Thanks to AVM, Berlin for information - * - */ - -#include <linux/init.h> -#include "hisax.h" -#include "isac.h" -#include "isdnl1.h" -#include <linux/pci.h> -#include <linux/slab.h> -#include <linux/isapnp.h> -#include <linux/interrupt.h> - -static const char *avm_pci_rev = "$Revision: 1.29.2.4 $"; - -#define AVM_FRITZ_PCI 1 -#define AVM_FRITZ_PNP 2 - -#define HDLC_FIFO 0x0 -#define HDLC_STATUS 0x4 - -#define AVM_HDLC_1 0x00 -#define AVM_HDLC_2 0x01 -#define AVM_ISAC_FIFO 0x02 -#define AVM_ISAC_REG_LOW 0x04 -#define AVM_ISAC_REG_HIGH 0x06 - -#define AVM_STATUS0_IRQ_ISAC 0x01 -#define AVM_STATUS0_IRQ_HDLC 0x02 -#define AVM_STATUS0_IRQ_TIMER 0x04 -#define AVM_STATUS0_IRQ_MASK 0x07 - -#define AVM_STATUS0_RESET 0x01 -#define AVM_STATUS0_DIS_TIMER 0x02 -#define AVM_STATUS0_RES_TIMER 0x04 -#define AVM_STATUS0_ENA_IRQ 0x08 -#define AVM_STATUS0_TESTBIT 0x10 - -#define AVM_STATUS1_INT_SEL 0x0f -#define AVM_STATUS1_ENA_IOM 0x80 - -#define HDLC_MODE_ITF_FLG 0x01 -#define HDLC_MODE_TRANS 0x02 -#define HDLC_MODE_CCR_7 0x04 -#define HDLC_MODE_CCR_16 0x08 -#define HDLC_MODE_TESTLOOP 0x80 - -#define HDLC_INT_XPR 0x80 -#define HDLC_INT_XDU 0x40 -#define HDLC_INT_RPR 0x20 -#define HDLC_INT_MASK 0xE0 - -#define HDLC_STAT_RME 0x01 -#define HDLC_STAT_RDO 0x10 -#define HDLC_STAT_CRCVFRRAB 0x0E -#define HDLC_STAT_CRCVFR 0x06 -#define HDLC_STAT_RML_MASK 0x3f00 - -#define HDLC_CMD_XRS 0x80 -#define HDLC_CMD_XME 0x01 -#define HDLC_CMD_RRS 0x20 -#define HDLC_CMD_XML_MASK 0x3f00 - - -/* Interface functions */ - -static u_char -ReadISAC(struct IsdnCardState *cs, u_char offset) -{ - register u_char idx = (offset > 0x2f) ? AVM_ISAC_REG_HIGH : AVM_ISAC_REG_LOW; - register u_char val; - - outb(idx, cs->hw.avm.cfg_reg + 4); - val = inb(cs->hw.avm.isac + (offset & 0xf)); - return (val); -} - -static void -WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value) -{ - register u_char idx = (offset > 0x2f) ? AVM_ISAC_REG_HIGH : AVM_ISAC_REG_LOW; - - outb(idx, cs->hw.avm.cfg_reg + 4); - outb(value, cs->hw.avm.isac + (offset & 0xf)); -} - -static void -ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - outb(AVM_ISAC_FIFO, cs->hw.avm.cfg_reg + 4); - insb(cs->hw.avm.isac, data, size); -} - -static void -WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - outb(AVM_ISAC_FIFO, cs->hw.avm.cfg_reg + 4); - outsb(cs->hw.avm.isac, data, size); -} - -static inline u_int -ReadHDLCPCI(struct IsdnCardState *cs, int chan, u_char offset) -{ - register u_int idx = chan ? AVM_HDLC_2 : AVM_HDLC_1; - register u_int val; - - outl(idx, cs->hw.avm.cfg_reg + 4); - val = inl(cs->hw.avm.isac + offset); - return (val); -} - -static inline void -WriteHDLCPCI(struct IsdnCardState *cs, int chan, u_char offset, u_int value) -{ - register u_int idx = chan ? AVM_HDLC_2 : AVM_HDLC_1; - - outl(idx, cs->hw.avm.cfg_reg + 4); - outl(value, cs->hw.avm.isac + offset); -} - -static inline u_char -ReadHDLCPnP(struct IsdnCardState *cs, int chan, u_char offset) -{ - register u_char idx = chan ? AVM_HDLC_2 : AVM_HDLC_1; - register u_char val; - - outb(idx, cs->hw.avm.cfg_reg + 4); - val = inb(cs->hw.avm.isac + offset); - return (val); -} - -static inline void -WriteHDLCPnP(struct IsdnCardState *cs, int chan, u_char offset, u_char value) -{ - register u_char idx = chan ? AVM_HDLC_2 : AVM_HDLC_1; - - outb(idx, cs->hw.avm.cfg_reg + 4); - outb(value, cs->hw.avm.isac + offset); -} - -static u_char -ReadHDLC_s(struct IsdnCardState *cs, int chan, u_char offset) -{ - return (0xff & ReadHDLCPCI(cs, chan, offset)); -} - -static void -WriteHDLC_s(struct IsdnCardState *cs, int chan, u_char offset, u_char value) -{ - WriteHDLCPCI(cs, chan, offset, value); -} - -static inline -struct BCState *Sel_BCS(struct IsdnCardState *cs, int channel) -{ - if (cs->bcs[0].mode && (cs->bcs[0].channel == channel)) - return (&cs->bcs[0]); - else if (cs->bcs[1].mode && (cs->bcs[1].channel == channel)) - return (&cs->bcs[1]); - else - return (NULL); -} - -static void -write_ctrl(struct BCState *bcs, int which) { - - if (bcs->cs->debug & L1_DEB_HSCX) - debugl1(bcs->cs, "hdlc %c wr%x ctrl %x", - 'A' + bcs->channel, which, bcs->hw.hdlc.ctrl.ctrl); - if (bcs->cs->subtyp == AVM_FRITZ_PCI) { - WriteHDLCPCI(bcs->cs, bcs->channel, HDLC_STATUS, bcs->hw.hdlc.ctrl.ctrl); - } else { - if (which & 4) - WriteHDLCPnP(bcs->cs, bcs->channel, HDLC_STATUS + 2, - bcs->hw.hdlc.ctrl.sr.mode); - if (which & 2) - WriteHDLCPnP(bcs->cs, bcs->channel, HDLC_STATUS + 1, - bcs->hw.hdlc.ctrl.sr.xml); - if (which & 1) - WriteHDLCPnP(bcs->cs, bcs->channel, HDLC_STATUS, - bcs->hw.hdlc.ctrl.sr.cmd); - } -} - -static void -modehdlc(struct BCState *bcs, int mode, int bc) -{ - struct IsdnCardState *cs = bcs->cs; - int hdlc = bcs->channel; - - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "hdlc %c mode %d --> %d ichan %d --> %d", - 'A' + hdlc, bcs->mode, mode, hdlc, bc); - bcs->hw.hdlc.ctrl.ctrl = 0; - switch (mode) { - case (-1): /* used for init */ - bcs->mode = 1; - bcs->channel = bc; - bc = 0; - /* fall through */ - case (L1_MODE_NULL): - if (bcs->mode == L1_MODE_NULL) - return; - bcs->hw.hdlc.ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS; - bcs->hw.hdlc.ctrl.sr.mode = HDLC_MODE_TRANS; - write_ctrl(bcs, 5); - bcs->mode = L1_MODE_NULL; - bcs->channel = bc; - break; - case (L1_MODE_TRANS): - bcs->mode = mode; - bcs->channel = bc; - bcs->hw.hdlc.ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS; - bcs->hw.hdlc.ctrl.sr.mode = HDLC_MODE_TRANS; - write_ctrl(bcs, 5); - bcs->hw.hdlc.ctrl.sr.cmd = HDLC_CMD_XRS; - write_ctrl(bcs, 1); - bcs->hw.hdlc.ctrl.sr.cmd = 0; - schedule_event(bcs, B_XMTBUFREADY); - break; - case (L1_MODE_HDLC): - bcs->mode = mode; - bcs->channel = bc; - bcs->hw.hdlc.ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS; - bcs->hw.hdlc.ctrl.sr.mode = HDLC_MODE_ITF_FLG; - write_ctrl(bcs, 5); - bcs->hw.hdlc.ctrl.sr.cmd = HDLC_CMD_XRS; - write_ctrl(bcs, 1); - bcs->hw.hdlc.ctrl.sr.cmd = 0; - schedule_event(bcs, B_XMTBUFREADY); - break; - } -} - -static inline void -hdlc_empty_fifo(struct BCState *bcs, int count) -{ - register u_int *ptr; - u_char *p; - u_char idx = bcs->channel ? AVM_HDLC_2 : AVM_HDLC_1; - int cnt = 0; - struct IsdnCardState *cs = bcs->cs; - - if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) - debugl1(cs, "hdlc_empty_fifo %d", count); - if (bcs->hw.hdlc.rcvidx + count > HSCX_BUFMAX) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "hdlc_empty_fifo: incoming packet too large"); - return; - } - p = bcs->hw.hdlc.rcvbuf + bcs->hw.hdlc.rcvidx; - ptr = (u_int *)p; - bcs->hw.hdlc.rcvidx += count; - if (cs->subtyp == AVM_FRITZ_PCI) { - outl(idx, cs->hw.avm.cfg_reg + 4); - while (cnt < count) { -#ifdef __powerpc__ - *ptr++ = in_be32((unsigned *)(cs->hw.avm.isac + _IO_BASE)); -#else - *ptr++ = inl(cs->hw.avm.isac); -#endif /* __powerpc__ */ - cnt += 4; - } - } else { - outb(idx, cs->hw.avm.cfg_reg + 4); - while (cnt < count) { - *p++ = inb(cs->hw.avm.isac); - cnt++; - } - } - if (cs->debug & L1_DEB_HSCX_FIFO) { - char *t = bcs->blog; - - if (cs->subtyp == AVM_FRITZ_PNP) - p = (u_char *) ptr; - t += sprintf(t, "hdlc_empty_fifo %c cnt %d", - bcs->channel ? 'B' : 'A', count); - QuickHex(t, p, count); - debugl1(cs, "%s", bcs->blog); - } -} - -static inline void -hdlc_fill_fifo(struct BCState *bcs) -{ - struct IsdnCardState *cs = bcs->cs; - int count, cnt = 0; - int fifo_size = 32; - u_char *p; - u_int *ptr; - - if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) - debugl1(cs, "hdlc_fill_fifo"); - if (!bcs->tx_skb) - return; - if (bcs->tx_skb->len <= 0) - return; - - bcs->hw.hdlc.ctrl.sr.cmd &= ~HDLC_CMD_XME; - if (bcs->tx_skb->len > fifo_size) { - count = fifo_size; - } else { - count = bcs->tx_skb->len; - if (bcs->mode != L1_MODE_TRANS) - bcs->hw.hdlc.ctrl.sr.cmd |= HDLC_CMD_XME; - } - if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) - debugl1(cs, "hdlc_fill_fifo %d/%u", count, bcs->tx_skb->len); - p = bcs->tx_skb->data; - ptr = (u_int *)p; - skb_pull(bcs->tx_skb, count); - bcs->tx_cnt -= count; - bcs->hw.hdlc.count += count; - bcs->hw.hdlc.ctrl.sr.xml = ((count == fifo_size) ? 0 : count); - write_ctrl(bcs, 3); /* sets the correct index too */ - if (cs->subtyp == AVM_FRITZ_PCI) { - while (cnt < count) { -#ifdef __powerpc__ - out_be32((unsigned *)(cs->hw.avm.isac + _IO_BASE), *ptr++); -#else - outl(*ptr++, cs->hw.avm.isac); -#endif /* __powerpc__ */ - cnt += 4; - } - } else { - while (cnt < count) { - outb(*p++, cs->hw.avm.isac); - cnt++; - } - } - if (cs->debug & L1_DEB_HSCX_FIFO) { - char *t = bcs->blog; - - if (cs->subtyp == AVM_FRITZ_PNP) - p = (u_char *) ptr; - t += sprintf(t, "hdlc_fill_fifo %c cnt %d", - bcs->channel ? 'B' : 'A', count); - QuickHex(t, p, count); - debugl1(cs, "%s", bcs->blog); - } -} - -static void -HDLC_irq(struct BCState *bcs, u_int stat) { - int len; - struct sk_buff *skb; - - if (bcs->cs->debug & L1_DEB_HSCX) - debugl1(bcs->cs, "ch%d stat %#x", bcs->channel, stat); - if (stat & HDLC_INT_RPR) { - if (stat & HDLC_STAT_RDO) { - if (bcs->cs->debug & L1_DEB_HSCX) - debugl1(bcs->cs, "RDO"); - else - debugl1(bcs->cs, "ch%d stat %#x", bcs->channel, stat); - bcs->hw.hdlc.ctrl.sr.xml = 0; - bcs->hw.hdlc.ctrl.sr.cmd |= HDLC_CMD_RRS; - write_ctrl(bcs, 1); - bcs->hw.hdlc.ctrl.sr.cmd &= ~HDLC_CMD_RRS; - write_ctrl(bcs, 1); - bcs->hw.hdlc.rcvidx = 0; - } else { - if (!(len = (stat & HDLC_STAT_RML_MASK) >> 8)) - len = 32; - hdlc_empty_fifo(bcs, len); - if ((stat & HDLC_STAT_RME) || (bcs->mode == L1_MODE_TRANS)) { - if (((stat & HDLC_STAT_CRCVFRRAB) == HDLC_STAT_CRCVFR) || - (bcs->mode == L1_MODE_TRANS)) { - if (!(skb = dev_alloc_skb(bcs->hw.hdlc.rcvidx))) - printk(KERN_WARNING "HDLC: receive out of memory\n"); - else { - skb_put_data(skb, - bcs->hw.hdlc.rcvbuf, - bcs->hw.hdlc.rcvidx); - skb_queue_tail(&bcs->rqueue, skb); - } - bcs->hw.hdlc.rcvidx = 0; - schedule_event(bcs, B_RCVBUFREADY); - } else { - if (bcs->cs->debug & L1_DEB_HSCX) - debugl1(bcs->cs, "invalid frame"); - else - debugl1(bcs->cs, "ch%d invalid frame %#x", bcs->channel, stat); - bcs->hw.hdlc.rcvidx = 0; - } - } - } - } - if (stat & HDLC_INT_XDU) { - /* Here we lost an TX interrupt, so - * restart transmitting the whole frame. - */ - if (bcs->tx_skb) { - skb_push(bcs->tx_skb, bcs->hw.hdlc.count); - bcs->tx_cnt += bcs->hw.hdlc.count; - bcs->hw.hdlc.count = 0; - if (bcs->cs->debug & L1_DEB_WARN) - debugl1(bcs->cs, "ch%d XDU", bcs->channel); - } else if (bcs->cs->debug & L1_DEB_WARN) - debugl1(bcs->cs, "ch%d XDU without skb", bcs->channel); - bcs->hw.hdlc.ctrl.sr.xml = 0; - bcs->hw.hdlc.ctrl.sr.cmd |= HDLC_CMD_XRS; - write_ctrl(bcs, 1); - bcs->hw.hdlc.ctrl.sr.cmd &= ~HDLC_CMD_XRS; - write_ctrl(bcs, 1); - hdlc_fill_fifo(bcs); - } else if (stat & HDLC_INT_XPR) { - if (bcs->tx_skb) { - if (bcs->tx_skb->len) { - hdlc_fill_fifo(bcs); - return; - } else { - if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) && - (PACKET_NOACK != bcs->tx_skb->pkt_type)) { - u_long flags; - spin_lock_irqsave(&bcs->aclock, flags); - bcs->ackcnt += bcs->hw.hdlc.count; - spin_unlock_irqrestore(&bcs->aclock, flags); - schedule_event(bcs, B_ACKPENDING); - } - dev_kfree_skb_irq(bcs->tx_skb); - bcs->hw.hdlc.count = 0; - bcs->tx_skb = NULL; - } - } - if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) { - bcs->hw.hdlc.count = 0; - test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); - hdlc_fill_fifo(bcs); - } else { - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - schedule_event(bcs, B_XMTBUFREADY); - } - } -} - -static inline void -HDLC_irq_main(struct IsdnCardState *cs) -{ - u_int stat; - struct BCState *bcs; - - if (cs->subtyp == AVM_FRITZ_PCI) { - stat = ReadHDLCPCI(cs, 0, HDLC_STATUS); - } else { - stat = ReadHDLCPnP(cs, 0, HDLC_STATUS); - if (stat & HDLC_INT_RPR) - stat |= (ReadHDLCPnP(cs, 0, HDLC_STATUS + 1)) << 8; - } - if (stat & HDLC_INT_MASK) { - if (!(bcs = Sel_BCS(cs, 0))) { - if (cs->debug) - debugl1(cs, "hdlc spurious channel 0 IRQ"); - } else - HDLC_irq(bcs, stat); - } - if (cs->subtyp == AVM_FRITZ_PCI) { - stat = ReadHDLCPCI(cs, 1, HDLC_STATUS); - } else { - stat = ReadHDLCPnP(cs, 1, HDLC_STATUS); - if (stat & HDLC_INT_RPR) - stat |= (ReadHDLCPnP(cs, 1, HDLC_STATUS + 1)) << 8; - } - if (stat & HDLC_INT_MASK) { - if (!(bcs = Sel_BCS(cs, 1))) { - if (cs->debug) - debugl1(cs, "hdlc spurious channel 1 IRQ"); - } else - HDLC_irq(bcs, stat); - } -} - -static void -hdlc_l2l1(struct PStack *st, int pr, void *arg) -{ - struct BCState *bcs = st->l1.bcs; - struct sk_buff *skb = arg; - u_long flags; - - switch (pr) { - case (PH_DATA | REQUEST): - spin_lock_irqsave(&bcs->cs->lock, flags); - if (bcs->tx_skb) { - skb_queue_tail(&bcs->squeue, skb); - } else { - bcs->tx_skb = skb; - test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); - bcs->hw.hdlc.count = 0; - bcs->cs->BC_Send_Data(bcs); - } - spin_unlock_irqrestore(&bcs->cs->lock, flags); - break; - case (PH_PULL | INDICATION): - spin_lock_irqsave(&bcs->cs->lock, flags); - if (bcs->tx_skb) { - printk(KERN_WARNING "hdlc_l2l1: this shouldn't happen\n"); - } else { - test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); - bcs->tx_skb = skb; - bcs->hw.hdlc.count = 0; - bcs->cs->BC_Send_Data(bcs); - } - spin_unlock_irqrestore(&bcs->cs->lock, flags); - break; - case (PH_PULL | REQUEST): - if (!bcs->tx_skb) { - test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); - } else - test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - break; - case (PH_ACTIVATE | REQUEST): - spin_lock_irqsave(&bcs->cs->lock, flags); - test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag); - modehdlc(bcs, st->l1.mode, st->l1.bc); - spin_unlock_irqrestore(&bcs->cs->lock, flags); - l1_msg_b(st, pr, arg); - break; - case (PH_DEACTIVATE | REQUEST): - l1_msg_b(st, pr, arg); - break; - case (PH_DEACTIVATE | CONFIRM): - spin_lock_irqsave(&bcs->cs->lock, flags); - test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag); - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - modehdlc(bcs, 0, st->l1.bc); - spin_unlock_irqrestore(&bcs->cs->lock, flags); - st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL); - break; - } -} - -static void -close_hdlcstate(struct BCState *bcs) -{ - modehdlc(bcs, 0, 0); - if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) { - kfree(bcs->hw.hdlc.rcvbuf); - bcs->hw.hdlc.rcvbuf = NULL; - kfree(bcs->blog); - bcs->blog = NULL; - skb_queue_purge(&bcs->rqueue); - skb_queue_purge(&bcs->squeue); - if (bcs->tx_skb) { - dev_kfree_skb_any(bcs->tx_skb); - bcs->tx_skb = NULL; - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - } - } -} - -static int -open_hdlcstate(struct IsdnCardState *cs, struct BCState *bcs) -{ - if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { - if (!(bcs->hw.hdlc.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) { - printk(KERN_WARNING - "HiSax: No memory for hdlc.rcvbuf\n"); - return (1); - } - if (!(bcs->blog = kmalloc(MAX_BLOG_SPACE, GFP_ATOMIC))) { - printk(KERN_WARNING - "HiSax: No memory for bcs->blog\n"); - test_and_clear_bit(BC_FLG_INIT, &bcs->Flag); - kfree(bcs->hw.hdlc.rcvbuf); - bcs->hw.hdlc.rcvbuf = NULL; - return (2); - } - skb_queue_head_init(&bcs->rqueue); - skb_queue_head_init(&bcs->squeue); - } - bcs->tx_skb = NULL; - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - bcs->event = 0; - bcs->hw.hdlc.rcvidx = 0; - bcs->tx_cnt = 0; - return (0); -} - -static int -setstack_hdlc(struct PStack *st, struct BCState *bcs) -{ - bcs->channel = st->l1.bc; - if (open_hdlcstate(st->l1.hardware, bcs)) - return (-1); - st->l1.bcs = bcs; - st->l2.l2l1 = hdlc_l2l1; - setstack_manager(st); - bcs->st = st; - setstack_l1_B(st); - return (0); -} - -#if 0 -void __init -clear_pending_hdlc_ints(struct IsdnCardState *cs) -{ - u_int val; - - if (cs->subtyp == AVM_FRITZ_PCI) { - val = ReadHDLCPCI(cs, 0, HDLC_STATUS); - debugl1(cs, "HDLC 1 STA %x", val); - val = ReadHDLCPCI(cs, 1, HDLC_STATUS); - debugl1(cs, "HDLC 2 STA %x", val); - } else { - val = ReadHDLCPnP(cs, 0, HDLC_STATUS); - debugl1(cs, "HDLC 1 STA %x", val); - val = ReadHDLCPnP(cs, 0, HDLC_STATUS + 1); - debugl1(cs, "HDLC 1 RML %x", val); - val = ReadHDLCPnP(cs, 0, HDLC_STATUS + 2); - debugl1(cs, "HDLC 1 MODE %x", val); - val = ReadHDLCPnP(cs, 0, HDLC_STATUS + 3); - debugl1(cs, "HDLC 1 VIN %x", val); - val = ReadHDLCPnP(cs, 1, HDLC_STATUS); - debugl1(cs, "HDLC 2 STA %x", val); - val = ReadHDLCPnP(cs, 1, HDLC_STATUS + 1); - debugl1(cs, "HDLC 2 RML %x", val); - val = ReadHDLCPnP(cs, 1, HDLC_STATUS + 2); - debugl1(cs, "HDLC 2 MODE %x", val); - val = ReadHDLCPnP(cs, 1, HDLC_STATUS + 3); - debugl1(cs, "HDLC 2 VIN %x", val); - } -} -#endif /* 0 */ - -static void -inithdlc(struct IsdnCardState *cs) -{ - cs->bcs[0].BC_SetStack = setstack_hdlc; - cs->bcs[1].BC_SetStack = setstack_hdlc; - cs->bcs[0].BC_Close = close_hdlcstate; - cs->bcs[1].BC_Close = close_hdlcstate; - modehdlc(cs->bcs, -1, 0); - modehdlc(cs->bcs + 1, -1, 1); -} - -static irqreturn_t -avm_pcipnp_interrupt(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - u_long flags; - u_char val; - u_char sval; - - spin_lock_irqsave(&cs->lock, flags); - sval = inb(cs->hw.avm.cfg_reg + 2); - if ((sval & AVM_STATUS0_IRQ_MASK) == AVM_STATUS0_IRQ_MASK) { - /* possible a shared IRQ reqest */ - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_NONE; - } - if (!(sval & AVM_STATUS0_IRQ_ISAC)) { - val = ReadISAC(cs, ISAC_ISTA); - isac_interrupt(cs, val); - } - if (!(sval & AVM_STATUS0_IRQ_HDLC)) { - HDLC_irq_main(cs); - } - WriteISAC(cs, ISAC_MASK, 0xFF); - WriteISAC(cs, ISAC_MASK, 0x0); - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -static void -reset_avmpcipnp(struct IsdnCardState *cs) -{ - printk(KERN_INFO "AVM PCI/PnP: reset\n"); - outb(AVM_STATUS0_RESET | AVM_STATUS0_DIS_TIMER, cs->hw.avm.cfg_reg + 2); - mdelay(10); - outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER | AVM_STATUS0_ENA_IRQ, cs->hw.avm.cfg_reg + 2); - outb(AVM_STATUS1_ENA_IOM | cs->irq, cs->hw.avm.cfg_reg + 3); - mdelay(10); - printk(KERN_INFO "AVM PCI/PnP: S1 %x\n", inb(cs->hw.avm.cfg_reg + 3)); -} - -static int -AVM_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - u_long flags; - - switch (mt) { - case CARD_RESET: - spin_lock_irqsave(&cs->lock, flags); - reset_avmpcipnp(cs); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_RELEASE: - outb(0, cs->hw.avm.cfg_reg + 2); - release_region(cs->hw.avm.cfg_reg, 32); - return (0); - case CARD_INIT: - spin_lock_irqsave(&cs->lock, flags); - reset_avmpcipnp(cs); - clear_pending_isac_ints(cs); - initisac(cs); - inithdlc(cs); - outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER, - cs->hw.avm.cfg_reg + 2); - WriteISAC(cs, ISAC_MASK, 0); - outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER | - AVM_STATUS0_ENA_IRQ, cs->hw.avm.cfg_reg + 2); - /* RESET Receiver and Transmitter */ - WriteISAC(cs, ISAC_CMDR, 0x41); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_TEST: - return (0); - } - return (0); -} - -static int avm_setup_rest(struct IsdnCardState *cs) -{ - u_int val, ver; - - cs->hw.avm.isac = cs->hw.avm.cfg_reg + 0x10; - if (!request_region(cs->hw.avm.cfg_reg, 32, - (cs->subtyp == AVM_FRITZ_PCI) ? "avm PCI" : "avm PnP")) { - printk(KERN_WARNING - "HiSax: Fritz!PCI/PNP config port %x-%x already in use\n", - cs->hw.avm.cfg_reg, - cs->hw.avm.cfg_reg + 31); - return (0); - } - switch (cs->subtyp) { - case AVM_FRITZ_PCI: - val = inl(cs->hw.avm.cfg_reg); - printk(KERN_INFO "AVM PCI: stat %#x\n", val); - printk(KERN_INFO "AVM PCI: Class %X Rev %d\n", - val & 0xff, (val >> 8) & 0xff); - cs->BC_Read_Reg = &ReadHDLC_s; - cs->BC_Write_Reg = &WriteHDLC_s; - break; - case AVM_FRITZ_PNP: - val = inb(cs->hw.avm.cfg_reg); - ver = inb(cs->hw.avm.cfg_reg + 1); - printk(KERN_INFO "AVM PnP: Class %X Rev %d\n", val, ver); - cs->BC_Read_Reg = &ReadHDLCPnP; - cs->BC_Write_Reg = &WriteHDLCPnP; - break; - default: - printk(KERN_WARNING "AVM unknown subtype %d\n", cs->subtyp); - return (0); - } - printk(KERN_INFO "HiSax: %s config irq:%d base:0x%X\n", - (cs->subtyp == AVM_FRITZ_PCI) ? "AVM Fritz!PCI" : "AVM Fritz!PnP", - cs->irq, cs->hw.avm.cfg_reg); - - setup_isac(cs); - cs->readisac = &ReadISAC; - cs->writeisac = &WriteISAC; - cs->readisacfifo = &ReadISACfifo; - cs->writeisacfifo = &WriteISACfifo; - cs->BC_Send_Data = &hdlc_fill_fifo; - cs->cardmsg = &AVM_card_msg; - cs->irq_func = &avm_pcipnp_interrupt; - cs->writeisac(cs, ISAC_MASK, 0xFF); - ISACVersion(cs, (cs->subtyp == AVM_FRITZ_PCI) ? "AVM PCI:" : "AVM PnP:"); - return (1); -} - -#ifndef __ISAPNP__ - -static int avm_pnp_setup(struct IsdnCardState *cs) -{ - return (1); /* no-op: success */ -} - -#else - -static struct pnp_card *pnp_avm_c = NULL; - -static int avm_pnp_setup(struct IsdnCardState *cs) -{ - struct pnp_dev *pnp_avm_d = NULL; - - if (!isapnp_present()) - return (1); /* no-op: success */ - - if ((pnp_avm_c = pnp_find_card( - ISAPNP_VENDOR('A', 'V', 'M'), - ISAPNP_FUNCTION(0x0900), pnp_avm_c))) { - if ((pnp_avm_d = pnp_find_dev(pnp_avm_c, - ISAPNP_VENDOR('A', 'V', 'M'), - ISAPNP_FUNCTION(0x0900), pnp_avm_d))) { - int err; - - pnp_disable_dev(pnp_avm_d); - err = pnp_activate_dev(pnp_avm_d); - if (err < 0) { - printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n", - __func__, err); - return (0); - } - cs->hw.avm.cfg_reg = - pnp_port_start(pnp_avm_d, 0); - cs->irq = pnp_irq(pnp_avm_d, 0); - if (cs->irq == -1) { - printk(KERN_ERR "FritzPnP:No IRQ\n"); - return (0); - } - if (!cs->hw.avm.cfg_reg) { - printk(KERN_ERR "FritzPnP:No IO address\n"); - return (0); - } - cs->subtyp = AVM_FRITZ_PNP; - - return (2); /* goto 'ready' label */ - } - } - - return (1); -} - -#endif /* __ISAPNP__ */ - -#ifndef CONFIG_PCI - -static int avm_pci_setup(struct IsdnCardState *cs) -{ - return (1); /* no-op: success */ -} - -#else - -static struct pci_dev *dev_avm = NULL; - -static int avm_pci_setup(struct IsdnCardState *cs) -{ - if ((dev_avm = hisax_find_pci_device(PCI_VENDOR_ID_AVM, - PCI_DEVICE_ID_AVM_A1, dev_avm))) { - - if (pci_enable_device(dev_avm)) - return (0); - - cs->irq = dev_avm->irq; - if (!cs->irq) { - printk(KERN_ERR "FritzPCI: No IRQ for PCI card found\n"); - return (0); - } - - cs->hw.avm.cfg_reg = pci_resource_start(dev_avm, 1); - if (!cs->hw.avm.cfg_reg) { - printk(KERN_ERR "FritzPCI: No IO-Adr for PCI card found\n"); - return (0); - } - - cs->subtyp = AVM_FRITZ_PCI; - } else { - printk(KERN_WARNING "FritzPCI: No PCI card found\n"); - return (0); - } - - cs->irq_flags |= IRQF_SHARED; - - return (1); -} - -#endif /* CONFIG_PCI */ - -int setup_avm_pcipnp(struct IsdnCard *card) -{ - struct IsdnCardState *cs = card->cs; - char tmp[64]; - int rc; - - strcpy(tmp, avm_pci_rev); - printk(KERN_INFO "HiSax: AVM PCI driver Rev. %s\n", HiSax_getrev(tmp)); - - if (cs->typ != ISDN_CTYPE_FRITZPCI) - return (0); - - if (card->para[1]) { - /* old manual method */ - cs->hw.avm.cfg_reg = card->para[1]; - cs->irq = card->para[0]; - cs->subtyp = AVM_FRITZ_PNP; - goto ready; - } - - rc = avm_pnp_setup(cs); - if (rc < 1) - return (0); - if (rc == 2) - goto ready; - - rc = avm_pci_setup(cs); - if (rc < 1) - return (0); - -ready: - return avm_setup_rest(cs); -} diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c deleted file mode 100644 index baad94ec1f4a..000000000000 --- a/drivers/isdn/hisax/avma1_cs.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * PCMCIA client driver for AVM A1 / Fritz!PCMCIA - * - * Author Carsten Paeth - * Copyright 1998-2001 by Carsten Paeth <calle@calle.in-berlin.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/kernel.h> -#include <linux/init.h> -#include <linux/ptrace.h> -#include <linux/slab.h> -#include <linux/string.h> -#include <asm/io.h> - -#include <pcmcia/cistpl.h> -#include <pcmcia/ds.h> -#include "hisax_cfg.h" - -MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for AVM A1/Fritz!PCMCIA cards"); -MODULE_AUTHOR("Carsten Paeth"); -MODULE_LICENSE("GPL"); - - -/*====================================================================*/ - -/* Parameters that can be set with 'insmod' */ - -static int isdnprot = 2; - -module_param(isdnprot, int, 0); - -/*====================================================================*/ - -static int avma1cs_config(struct pcmcia_device *link); -static void avma1cs_release(struct pcmcia_device *link); -static void avma1cs_detach(struct pcmcia_device *p_dev); - -static int avma1cs_probe(struct pcmcia_device *p_dev) -{ - dev_dbg(&p_dev->dev, "avma1cs_attach()\n"); - - /* General socket configuration */ - p_dev->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; - p_dev->config_index = 1; - p_dev->config_regs = PRESENT_OPTION; - - return avma1cs_config(p_dev); -} /* avma1cs_attach */ - -static void avma1cs_detach(struct pcmcia_device *link) -{ - dev_dbg(&link->dev, "avma1cs_detach(0x%p)\n", link); - avma1cs_release(link); - kfree(link->priv); -} /* avma1cs_detach */ - -static int avma1cs_configcheck(struct pcmcia_device *p_dev, void *priv_data) -{ - p_dev->resource[0]->end = 16; - p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; - p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; - p_dev->io_lines = 5; - - return pcmcia_request_io(p_dev); -} - - -static int avma1cs_config(struct pcmcia_device *link) -{ - int i = -1; - char devname[128]; - IsdnCard_t icard; - int busy = 0; - - dev_dbg(&link->dev, "avma1cs_config(0x%p)\n", link); - - devname[0] = 0; - if (link->prod_id[1]) - strlcpy(devname, link->prod_id[1], sizeof(devname)); - - if (pcmcia_loop_config(link, avma1cs_configcheck, NULL)) - return -ENODEV; - - do { - /* - * allocate an interrupt line - */ - if (!link->irq) { - /* undo */ - pcmcia_disable_device(link); - break; - } - - /* - * configure the PCMCIA socket - */ - i = pcmcia_enable_device(link); - if (i != 0) { - pcmcia_disable_device(link); - break; - } - - } while (0); - - /* If any step failed, release any partially configured state */ - if (i != 0) { - avma1cs_release(link); - return -ENODEV; - } - - icard.para[0] = link->irq; - icard.para[1] = link->resource[0]->start; - icard.protocol = isdnprot; - icard.typ = ISDN_CTYPE_A1_PCMCIA; - - i = hisax_init_pcmcia(link, &busy, &icard); - if (i < 0) { - printk(KERN_ERR "avma1_cs: failed to initialize AVM A1 " - "PCMCIA %d at i/o %#x\n", i, - (unsigned int) link->resource[0]->start); - avma1cs_release(link); - return -ENODEV; - } - link->priv = (void *) (unsigned long) i; - - return 0; -} /* avma1cs_config */ - -static void avma1cs_release(struct pcmcia_device *link) -{ - unsigned long minor = (unsigned long) link->priv; - - dev_dbg(&link->dev, "avma1cs_release(0x%p)\n", link); - - /* now unregister function with hisax */ - HiSax_closecard(minor); - - pcmcia_disable_device(link); -} /* avma1cs_release */ - -static const struct pcmcia_device_id avma1cs_ids[] = { - PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN A", 0x95d42008, 0xadc9d4bb), - PCMCIA_DEVICE_PROD_ID12("ISDN", "CARD", 0x8d9761c8, 0x01c5aa7b), - PCMCIA_DEVICE_NULL -}; -MODULE_DEVICE_TABLE(pcmcia, avma1cs_ids); - -static struct pcmcia_driver avma1cs_driver = { - .owner = THIS_MODULE, - .name = "avma1_cs", - .probe = avma1cs_probe, - .remove = avma1cs_detach, - .id_table = avma1cs_ids, -}; -module_pcmcia_driver(avma1cs_driver); diff --git a/drivers/isdn/hisax/bkm_a4t.c b/drivers/isdn/hisax/bkm_a4t.c deleted file mode 100644 index c360164bde1b..000000000000 --- a/drivers/isdn/hisax/bkm_a4t.c +++ /dev/null @@ -1,358 +0,0 @@ -/* $Id: bkm_a4t.c,v 1.22.2.4 2004/01/14 16:04:48 keil Exp $ - * - * low level stuff for T-Berkom A4T - * - * Author Roland Klabunde - * Copyright by Roland Klabunde <R.Klabunde@Berkom.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - - -#include <linux/init.h> -#include "hisax.h" -#include "isac.h" -#include "hscx.h" -#include "jade.h" -#include "isdnl1.h" -#include <linux/pci.h> -#include "bkm_ax.h" - -static const char *bkm_a4t_revision = "$Revision: 1.22.2.4 $"; - - -static inline u_char -readreg(unsigned int ale, unsigned long adr, u_char off) -{ - register u_int ret; - unsigned int *po = (unsigned int *) adr; /* Postoffice */ - - *po = (GCS_2 | PO_WRITE | off); - __WAITI20__(po); - *po = (ale | PO_READ); - __WAITI20__(po); - ret = *po; - return ((unsigned char) ret); -} - - -static inline void -readfifo(unsigned int ale, unsigned long adr, u_char off, u_char *data, int size) -{ - int i; - for (i = 0; i < size; i++) - *data++ = readreg(ale, adr, off); -} - - -static inline void -writereg(unsigned int ale, unsigned long adr, u_char off, u_char data) -{ - unsigned int *po = (unsigned int *) adr; /* Postoffice */ - *po = (GCS_2 | PO_WRITE | off); - __WAITI20__(po); - *po = (ale | PO_WRITE | data); - __WAITI20__(po); -} - - -static inline void -writefifo(unsigned int ale, unsigned long adr, u_char off, u_char *data, int size) -{ - int i; - - for (i = 0; i < size; i++) - writereg(ale, adr, off, *data++); -} - - -/* Interface functions */ - -static u_char -ReadISAC(struct IsdnCardState *cs, u_char offset) -{ - return (readreg(cs->hw.ax.isac_ale, cs->hw.ax.isac_adr, offset)); -} - -static void -WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value) -{ - writereg(cs->hw.ax.isac_ale, cs->hw.ax.isac_adr, offset, value); -} - -static void -ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - readfifo(cs->hw.ax.isac_ale, cs->hw.ax.isac_adr, 0, data, size); -} - -static void -WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - writefifo(cs->hw.ax.isac_ale, cs->hw.ax.isac_adr, 0, data, size); -} - -static u_char -ReadJADE(struct IsdnCardState *cs, int jade, u_char offset) -{ - return (readreg(cs->hw.ax.jade_ale, cs->hw.ax.jade_adr, offset + (jade == -1 ? 0 : (jade ? 0xC0 : 0x80)))); -} - -static void -WriteJADE(struct IsdnCardState *cs, int jade, u_char offset, u_char value) -{ - writereg(cs->hw.ax.jade_ale, cs->hw.ax.jade_adr, offset + (jade == -1 ? 0 : (jade ? 0xC0 : 0x80)), value); -} - -/* - * fast interrupt JADE stuff goes here - */ - -#define READJADE(cs, nr, reg) readreg(cs->hw.ax.jade_ale, \ - cs->hw.ax.jade_adr, reg + (nr == -1 ? 0 : (nr ? 0xC0 : 0x80))) -#define WRITEJADE(cs, nr, reg, data) writereg(cs->hw.ax.jade_ale, \ - cs->hw.ax.jade_adr, reg + (nr == -1 ? 0 : (nr ? 0xC0 : 0x80)), data) - -#define READJADEFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.ax.jade_ale, \ - cs->hw.ax.jade_adr, (nr == -1 ? 0 : (nr ? 0xC0 : 0x80)), ptr, cnt) -#define WRITEJADEFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.ax.jade_ale, \ - cs->hw.ax.jade_adr, (nr == -1 ? 0 : (nr ? 0xC0 : 0x80)), ptr, cnt) - -#include "jade_irq.c" - -static irqreturn_t -bkm_interrupt(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - u_char val = 0; - u_long flags; - I20_REGISTER_FILE *pI20_Regs; - - spin_lock_irqsave(&cs->lock, flags); - pI20_Regs = (I20_REGISTER_FILE *) (cs->hw.ax.base); - - /* ISDN interrupt pending? */ - if (pI20_Regs->i20IntStatus & intISDN) { - /* Reset the ISDN interrupt */ - pI20_Regs->i20IntStatus = intISDN; - /* Disable ISDN interrupt */ - pI20_Regs->i20IntCtrl &= ~intISDN; - /* Channel A first */ - val = readreg(cs->hw.ax.jade_ale, cs->hw.ax.jade_adr, jade_HDLC_ISR + 0x80); - if (val) { - jade_int_main(cs, val, 0); - } - /* Channel B */ - val = readreg(cs->hw.ax.jade_ale, cs->hw.ax.jade_adr, jade_HDLC_ISR + 0xC0); - if (val) { - jade_int_main(cs, val, 1); - } - /* D-Channel */ - val = readreg(cs->hw.ax.isac_ale, cs->hw.ax.isac_adr, ISAC_ISTA); - if (val) { - isac_interrupt(cs, val); - } - /* Reenable ISDN interrupt */ - pI20_Regs->i20IntCtrl |= intISDN; - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; - } else { - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_NONE; - } -} - -static void -release_io_bkm(struct IsdnCardState *cs) -{ - if (cs->hw.ax.base) { - iounmap((void *) cs->hw.ax.base); - cs->hw.ax.base = 0; - } -} - -static void -enable_bkm_int(struct IsdnCardState *cs, unsigned bEnable) -{ - if (cs->typ == ISDN_CTYPE_BKM_A4T) { - I20_REGISTER_FILE *pI20_Regs = (I20_REGISTER_FILE *) (cs->hw.ax.base); - if (bEnable) - pI20_Regs->i20IntCtrl |= (intISDN | intPCI); - else - /* CAUTION: This disables the video capture driver too */ - pI20_Regs->i20IntCtrl &= ~(intISDN | intPCI); - } -} - -static void -reset_bkm(struct IsdnCardState *cs) -{ - if (cs->typ == ISDN_CTYPE_BKM_A4T) { - I20_REGISTER_FILE *pI20_Regs = (I20_REGISTER_FILE *) (cs->hw.ax.base); - /* Issue the I20 soft reset */ - pI20_Regs->i20SysControl = 0xFF; /* all in */ - mdelay(10); - /* Remove the soft reset */ - pI20_Regs->i20SysControl = sysRESET | 0xFF; - mdelay(10); - /* Set our configuration */ - pI20_Regs->i20SysControl = sysRESET | sysCFG; - /* Issue ISDN reset */ - pI20_Regs->i20GuestControl = guestWAIT_CFG | - g_A4T_JADE_RES | - g_A4T_ISAR_RES | - g_A4T_ISAC_RES | - g_A4T_JADE_BOOTR | - g_A4T_ISAR_BOOTR; - mdelay(10); - - /* Remove RESET state from ISDN */ - pI20_Regs->i20GuestControl &= ~(g_A4T_ISAC_RES | - g_A4T_JADE_RES | - g_A4T_ISAR_RES); - mdelay(10); - } -} - -static int -BKM_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - u_long flags; - - switch (mt) { - case CARD_RESET: - /* Disable ints */ - spin_lock_irqsave(&cs->lock, flags); - enable_bkm_int(cs, 0); - reset_bkm(cs); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_RELEASE: - /* Sanity */ - spin_lock_irqsave(&cs->lock, flags); - enable_bkm_int(cs, 0); - reset_bkm(cs); - spin_unlock_irqrestore(&cs->lock, flags); - release_io_bkm(cs); - return (0); - case CARD_INIT: - spin_lock_irqsave(&cs->lock, flags); - clear_pending_isac_ints(cs); - clear_pending_jade_ints(cs); - initisac(cs); - initjade(cs); - /* Enable ints */ - enable_bkm_int(cs, 1); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_TEST: - return (0); - } - return (0); -} - -static int a4t_pci_probe(struct pci_dev *dev_a4t, struct IsdnCardState *cs, - u_int *found, u_int *pci_memaddr) -{ - u16 sub_sys; - u16 sub_vendor; - - sub_vendor = dev_a4t->subsystem_vendor; - sub_sys = dev_a4t->subsystem_device; - if ((sub_sys == PCI_DEVICE_ID_BERKOM_A4T) && (sub_vendor == PCI_VENDOR_ID_BERKOM)) { - if (pci_enable_device(dev_a4t)) - return (0); /* end loop & function */ - *found = 1; - *pci_memaddr = pci_resource_start(dev_a4t, 0); - cs->irq = dev_a4t->irq; - return (1); /* end loop */ - } - - return (-1); /* continue looping */ -} - -static int a4t_cs_init(struct IsdnCard *card, struct IsdnCardState *cs, - u_int pci_memaddr) -{ - I20_REGISTER_FILE *pI20_Regs; - - if (!cs->irq) { /* IRQ range check ?? */ - printk(KERN_WARNING "HiSax: Telekom A4T: No IRQ\n"); - return (0); - } - cs->hw.ax.base = (long) ioremap(pci_memaddr, 4096); - /* Check suspecious address */ - pI20_Regs = (I20_REGISTER_FILE *) (cs->hw.ax.base); - if ((pI20_Regs->i20IntStatus & 0x8EFFFFFF) != 0) { - printk(KERN_WARNING "HiSax: Telekom A4T address " - "%lx-%lx suspicious\n", - cs->hw.ax.base, cs->hw.ax.base + 4096); - iounmap((void *) cs->hw.ax.base); - cs->hw.ax.base = 0; - return (0); - } - cs->hw.ax.isac_adr = cs->hw.ax.base + PO_OFFSET; - cs->hw.ax.jade_adr = cs->hw.ax.base + PO_OFFSET; - cs->hw.ax.isac_ale = GCS_1; - cs->hw.ax.jade_ale = GCS_3; - - printk(KERN_INFO "HiSax: Telekom A4T: Card configured at " - "0x%lX IRQ %d\n", - cs->hw.ax.base, cs->irq); - - setup_isac(cs); - cs->readisac = &ReadISAC; - cs->writeisac = &WriteISAC; - cs->readisacfifo = &ReadISACfifo; - cs->writeisacfifo = &WriteISACfifo; - cs->BC_Read_Reg = &ReadJADE; - cs->BC_Write_Reg = &WriteJADE; - cs->BC_Send_Data = &jade_fill_fifo; - cs->cardmsg = &BKM_card_msg; - cs->irq_func = &bkm_interrupt; - cs->irq_flags |= IRQF_SHARED; - ISACVersion(cs, "Telekom A4T:"); - /* Jade version */ - JadeVersion(cs, "Telekom A4T:"); - - return (1); -} - -static struct pci_dev *dev_a4t = NULL; - -int setup_bkm_a4t(struct IsdnCard *card) -{ - struct IsdnCardState *cs = card->cs; - char tmp[64]; - u_int pci_memaddr = 0, found = 0; - int ret; - - strcpy(tmp, bkm_a4t_revision); - printk(KERN_INFO "HiSax: T-Berkom driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ == ISDN_CTYPE_BKM_A4T) { - cs->subtyp = BKM_A4T; - } else - return (0); - - while ((dev_a4t = hisax_find_pci_device(PCI_VENDOR_ID_ZORAN, - PCI_DEVICE_ID_ZORAN_36120, dev_a4t))) { - ret = a4t_pci_probe(dev_a4t, cs, &found, &pci_memaddr); - if (!ret) - return (0); - if (ret > 0) - break; - } - if (!found) { - printk(KERN_WARNING "HiSax: Telekom A4T: Card not found\n"); - return (0); - } - if (!pci_memaddr) { - printk(KERN_WARNING "HiSax: Telekom A4T: " - "No Memory base address\n"); - return (0); - } - - return a4t_cs_init(card, cs, pci_memaddr); -} diff --git a/drivers/isdn/hisax/bkm_a8.c b/drivers/isdn/hisax/bkm_a8.c deleted file mode 100644 index dd663ea57ec6..000000000000 --- a/drivers/isdn/hisax/bkm_a8.c +++ /dev/null @@ -1,433 +0,0 @@ -/* $Id: bkm_a8.c,v 1.22.2.4 2004/01/15 14:02:34 keil Exp $ - * - * low level stuff for Scitel Quadro (4*S0, passive) - * - * Author Roland Klabunde - * Copyright by Roland Klabunde <R.Klabunde@Berkom.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - - -#include <linux/init.h> -#include "hisax.h" -#include "isac.h" -#include "ipac.h" -#include "hscx.h" -#include "isdnl1.h" -#include <linux/pci.h> -#include "bkm_ax.h" - -#define ATTEMPT_PCI_REMAPPING /* Required for PLX rev 1 */ - -static const char sct_quadro_revision[] = "$Revision: 1.22.2.4 $"; - -static const char *sct_quadro_subtypes[] = -{ - "", - "#1", - "#2", - "#3", - "#4" -}; - - -#define wordout(addr, val) outw(val, addr) -#define wordin(addr) inw(addr) - -static inline u_char -readreg(unsigned int ale, unsigned int adr, u_char off) -{ - register u_char ret; - wordout(ale, off); - ret = wordin(adr) & 0xFF; - return (ret); -} - -static inline void -readfifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size) -{ - int i; - wordout(ale, off); - for (i = 0; i < size; i++) - data[i] = wordin(adr) & 0xFF; -} - - -static inline void -writereg(unsigned int ale, unsigned int adr, u_char off, u_char data) -{ - wordout(ale, off); - wordout(adr, data); -} - -static inline void -writefifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size) -{ - int i; - wordout(ale, off); - for (i = 0; i < size; i++) - wordout(adr, data[i]); -} - -/* Interface functions */ - -static u_char -ReadISAC(struct IsdnCardState *cs, u_char offset) -{ - return (readreg(cs->hw.ax.base, cs->hw.ax.data_adr, offset | 0x80)); -} - -static void -WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value) -{ - writereg(cs->hw.ax.base, cs->hw.ax.data_adr, offset | 0x80, value); -} - -static void -ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - readfifo(cs->hw.ax.base, cs->hw.ax.data_adr, 0x80, data, size); -} - -static void -WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - writefifo(cs->hw.ax.base, cs->hw.ax.data_adr, 0x80, data, size); -} - - -static u_char -ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset) -{ - return (readreg(cs->hw.ax.base, cs->hw.ax.data_adr, offset + (hscx ? 0x40 : 0))); -} - -static void -WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) -{ - writereg(cs->hw.ax.base, cs->hw.ax.data_adr, offset + (hscx ? 0x40 : 0), value); -} - -/* Set the specific ipac to active */ -static void -set_ipac_active(struct IsdnCardState *cs, u_int active) -{ - /* set irq mask */ - writereg(cs->hw.ax.base, cs->hw.ax.data_adr, IPAC_MASK, - active ? 0xc0 : 0xff); -} - -/* - * fast interrupt HSCX stuff goes here - */ - -#define READHSCX(cs, nr, reg) readreg(cs->hw.ax.base, \ - cs->hw.ax.data_adr, reg + (nr ? 0x40 : 0)) -#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.ax.base, \ - cs->hw.ax.data_adr, reg + (nr ? 0x40 : 0), data) -#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.ax.base, \ - cs->hw.ax.data_adr, (nr ? 0x40 : 0), ptr, cnt) -#define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.ax.base, \ - cs->hw.ax.data_adr, (nr ? 0x40 : 0), ptr, cnt) - -#include "hscx_irq.c" - -static irqreturn_t -bkm_interrupt_ipac(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - u_char ista, val, icnt = 5; - u_long flags; - - spin_lock_irqsave(&cs->lock, flags); - ista = readreg(cs->hw.ax.base, cs->hw.ax.data_adr, IPAC_ISTA); - if (!(ista & 0x3f)) { /* not this IPAC */ - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_NONE; - } -Start_IPAC: - if (cs->debug & L1_DEB_IPAC) - debugl1(cs, "IPAC ISTA %02X", ista); - if (ista & 0x0f) { - val = readreg(cs->hw.ax.base, cs->hw.ax.data_adr, HSCX_ISTA + 0x40); - if (ista & 0x01) - val |= 0x01; - if (ista & 0x04) - val |= 0x02; - if (ista & 0x08) - val |= 0x04; - if (val) { - hscx_int_main(cs, val); - } - } - if (ista & 0x20) { - val = 0xfe & readreg(cs->hw.ax.base, cs->hw.ax.data_adr, ISAC_ISTA | 0x80); - if (val) { - isac_interrupt(cs, val); - } - } - if (ista & 0x10) { - val = 0x01; - isac_interrupt(cs, val); - } - ista = readreg(cs->hw.ax.base, cs->hw.ax.data_adr, IPAC_ISTA); - if ((ista & 0x3f) && icnt) { - icnt--; - goto Start_IPAC; - } - if (!icnt) - printk(KERN_WARNING "HiSax: Scitel Quadro (%s) IRQ LOOP\n", - sct_quadro_subtypes[cs->subtyp]); - writereg(cs->hw.ax.base, cs->hw.ax.data_adr, IPAC_MASK, 0xFF); - writereg(cs->hw.ax.base, cs->hw.ax.data_adr, IPAC_MASK, 0xC0); - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -static void -release_io_sct_quadro(struct IsdnCardState *cs) -{ - release_region(cs->hw.ax.base & 0xffffffc0, 128); - if (cs->subtyp == SCT_1) - release_region(cs->hw.ax.plx_adr, 64); -} - -static void -enable_bkm_int(struct IsdnCardState *cs, unsigned bEnable) -{ - if (cs->typ == ISDN_CTYPE_SCT_QUADRO) { - if (bEnable) - wordout(cs->hw.ax.plx_adr + 0x4C, (wordin(cs->hw.ax.plx_adr + 0x4C) | 0x41)); - else - wordout(cs->hw.ax.plx_adr + 0x4C, (wordin(cs->hw.ax.plx_adr + 0x4C) & ~0x41)); - } -} - -static void -reset_bkm(struct IsdnCardState *cs) -{ - if (cs->subtyp == SCT_1) { - wordout(cs->hw.ax.plx_adr + 0x50, (wordin(cs->hw.ax.plx_adr + 0x50) & ~4)); - mdelay(10); - /* Remove the soft reset */ - wordout(cs->hw.ax.plx_adr + 0x50, (wordin(cs->hw.ax.plx_adr + 0x50) | 4)); - mdelay(10); - } -} - -static int -BKM_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - u_long flags; - - switch (mt) { - case CARD_RESET: - spin_lock_irqsave(&cs->lock, flags); - /* Disable ints */ - set_ipac_active(cs, 0); - enable_bkm_int(cs, 0); - reset_bkm(cs); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_RELEASE: - /* Sanity */ - spin_lock_irqsave(&cs->lock, flags); - set_ipac_active(cs, 0); - enable_bkm_int(cs, 0); - spin_unlock_irqrestore(&cs->lock, flags); - release_io_sct_quadro(cs); - return (0); - case CARD_INIT: - spin_lock_irqsave(&cs->lock, flags); - cs->debug |= L1_DEB_IPAC; - set_ipac_active(cs, 1); - inithscxisac(cs, 3); - /* Enable ints */ - enable_bkm_int(cs, 1); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_TEST: - return (0); - } - return (0); -} - -static int sct_alloc_io(u_int adr, u_int len) -{ - if (!request_region(adr, len, "scitel")) { - printk(KERN_WARNING - "HiSax: Scitel port %#x-%#x already in use\n", - adr, adr + len); - return (1); - } - return (0); -} - -static struct pci_dev *dev_a8 = NULL; -static u16 sub_vendor_id = 0; -static u16 sub_sys_id = 0; -static u_char pci_bus = 0; -static u_char pci_device_fn = 0; -static u_char pci_irq = 0; - -int setup_sct_quadro(struct IsdnCard *card) -{ - struct IsdnCardState *cs = card->cs; - char tmp[64]; - u_int found = 0; - u_int pci_ioaddr1, pci_ioaddr2, pci_ioaddr3, pci_ioaddr4, pci_ioaddr5; - - strcpy(tmp, sct_quadro_revision); - printk(KERN_INFO "HiSax: T-Berkom driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ == ISDN_CTYPE_SCT_QUADRO) { - cs->subtyp = SCT_1; /* Preset */ - } else - return (0); - - /* Identify subtype by para[0] */ - if (card->para[0] >= SCT_1 && card->para[0] <= SCT_4) - cs->subtyp = card->para[0]; - else { - printk(KERN_WARNING "HiSax: Scitel Quadro: Invalid " - "subcontroller in configuration, default to 1\n"); - return (0); - } - if ((cs->subtyp != SCT_1) && ((sub_sys_id != PCI_DEVICE_ID_BERKOM_SCITEL_QUADRO) || - (sub_vendor_id != PCI_VENDOR_ID_BERKOM))) - return (0); - if (cs->subtyp == SCT_1) { - while ((dev_a8 = hisax_find_pci_device(PCI_VENDOR_ID_PLX, - PCI_DEVICE_ID_PLX_9050, dev_a8))) { - - sub_vendor_id = dev_a8->subsystem_vendor; - sub_sys_id = dev_a8->subsystem_device; - if ((sub_sys_id == PCI_DEVICE_ID_BERKOM_SCITEL_QUADRO) && - (sub_vendor_id == PCI_VENDOR_ID_BERKOM)) { - if (pci_enable_device(dev_a8)) - return (0); - pci_ioaddr1 = pci_resource_start(dev_a8, 1); - pci_irq = dev_a8->irq; - pci_bus = dev_a8->bus->number; - pci_device_fn = dev_a8->devfn; - found = 1; - break; - } - } - if (!found) { - printk(KERN_WARNING "HiSax: Scitel Quadro (%s): " - "Card not found\n", - sct_quadro_subtypes[cs->subtyp]); - return (0); - } -#ifdef ATTEMPT_PCI_REMAPPING -/* HACK: PLX revision 1 bug: PLX address bit 7 must not be set */ - if ((pci_ioaddr1 & 0x80) && (dev_a8->revision == 1)) { - printk(KERN_WARNING "HiSax: Scitel Quadro (%s): " - "PLX rev 1, remapping required!\n", - sct_quadro_subtypes[cs->subtyp]); - /* Restart PCI negotiation */ - pci_write_config_dword(dev_a8, PCI_BASE_ADDRESS_1, (u_int)-1); - /* Move up by 0x80 byte */ - pci_ioaddr1 += 0x80; - pci_ioaddr1 &= PCI_BASE_ADDRESS_IO_MASK; - pci_write_config_dword(dev_a8, PCI_BASE_ADDRESS_1, pci_ioaddr1); - dev_a8->resource[1].start = pci_ioaddr1; - } -#endif /* End HACK */ - } - if (!pci_irq) { /* IRQ range check ?? */ - printk(KERN_WARNING "HiSax: Scitel Quadro (%s): No IRQ\n", - sct_quadro_subtypes[cs->subtyp]); - return (0); - } - pci_read_config_dword(dev_a8, PCI_BASE_ADDRESS_1, &pci_ioaddr1); - pci_read_config_dword(dev_a8, PCI_BASE_ADDRESS_2, &pci_ioaddr2); - pci_read_config_dword(dev_a8, PCI_BASE_ADDRESS_3, &pci_ioaddr3); - pci_read_config_dword(dev_a8, PCI_BASE_ADDRESS_4, &pci_ioaddr4); - pci_read_config_dword(dev_a8, PCI_BASE_ADDRESS_5, &pci_ioaddr5); - if (!pci_ioaddr1 || !pci_ioaddr2 || !pci_ioaddr3 || !pci_ioaddr4 || !pci_ioaddr5) { - printk(KERN_WARNING "HiSax: Scitel Quadro (%s): " - "No IO base address(es)\n", - sct_quadro_subtypes[cs->subtyp]); - return (0); - } - pci_ioaddr1 &= PCI_BASE_ADDRESS_IO_MASK; - pci_ioaddr2 &= PCI_BASE_ADDRESS_IO_MASK; - pci_ioaddr3 &= PCI_BASE_ADDRESS_IO_MASK; - pci_ioaddr4 &= PCI_BASE_ADDRESS_IO_MASK; - pci_ioaddr5 &= PCI_BASE_ADDRESS_IO_MASK; - /* Take over */ - cs->irq = pci_irq; - cs->irq_flags |= IRQF_SHARED; - /* pci_ioaddr1 is unique to all subdevices */ - /* pci_ioaddr2 is for the fourth subdevice only */ - /* pci_ioaddr3 is for the third subdevice only */ - /* pci_ioaddr4 is for the second subdevice only */ - /* pci_ioaddr5 is for the first subdevice only */ - cs->hw.ax.plx_adr = pci_ioaddr1; - /* Enter all ipac_base addresses */ - switch (cs->subtyp) { - case 1: - cs->hw.ax.base = pci_ioaddr5 + 0x00; - if (sct_alloc_io(pci_ioaddr1, 128)) - return (0); - if (sct_alloc_io(pci_ioaddr5, 64)) - return (0); - /* disable all IPAC */ - writereg(pci_ioaddr5, pci_ioaddr5 + 4, - IPAC_MASK, 0xFF); - writereg(pci_ioaddr4 + 0x08, pci_ioaddr4 + 0x0c, - IPAC_MASK, 0xFF); - writereg(pci_ioaddr3 + 0x10, pci_ioaddr3 + 0x14, - IPAC_MASK, 0xFF); - writereg(pci_ioaddr2 + 0x20, pci_ioaddr2 + 0x24, - IPAC_MASK, 0xFF); - break; - case 2: - cs->hw.ax.base = pci_ioaddr4 + 0x08; - if (sct_alloc_io(pci_ioaddr4, 64)) - return (0); - break; - case 3: - cs->hw.ax.base = pci_ioaddr3 + 0x10; - if (sct_alloc_io(pci_ioaddr3, 64)) - return (0); - break; - case 4: - cs->hw.ax.base = pci_ioaddr2 + 0x20; - if (sct_alloc_io(pci_ioaddr2, 64)) - return (0); - break; - } - /* For isac and hscx data path */ - cs->hw.ax.data_adr = cs->hw.ax.base + 4; - - printk(KERN_INFO "HiSax: Scitel Quadro (%s) configured at " - "0x%.4lX, 0x%.4lX, 0x%.4lX and IRQ %d\n", - sct_quadro_subtypes[cs->subtyp], - cs->hw.ax.plx_adr, - cs->hw.ax.base, - cs->hw.ax.data_adr, - cs->irq); - - test_and_set_bit(HW_IPAC, &cs->HW_Flags); - - cs->readisac = &ReadISAC; - cs->writeisac = &WriteISAC; - cs->readisacfifo = &ReadISACfifo; - cs->writeisacfifo = &WriteISACfifo; - - cs->BC_Read_Reg = &ReadHSCX; - cs->BC_Write_Reg = &WriteHSCX; - cs->BC_Send_Data = &hscx_fill_fifo; - cs->cardmsg = &BKM_card_msg; - cs->irq_func = &bkm_interrupt_ipac; - - printk(KERN_INFO "HiSax: Scitel Quadro (%s): IPAC Version %d\n", - sct_quadro_subtypes[cs->subtyp], - readreg(cs->hw.ax.base, cs->hw.ax.data_adr, IPAC_ID)); - return (1); -} diff --git a/drivers/isdn/hisax/bkm_ax.h b/drivers/isdn/hisax/bkm_ax.h deleted file mode 100644 index 27ff8a88679b..000000000000 --- a/drivers/isdn/hisax/bkm_ax.h +++ /dev/null @@ -1,119 +0,0 @@ -/* $Id: bkm_ax.h,v 1.5.6.3 2001/09/23 22:24:46 kai Exp $ - * - * low level decls for T-Berkom cards A4T and Scitel Quadro (4*S0, passive) - * - * Author Roland Klabunde - * Copyright by Roland Klabunde <R.Klabunde@Berkom.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#ifndef __BKM_AX_H__ -#define __BKM_AX_H__ - -/* Supported boards (subtypes) */ -#define SCT_1 1 -#define SCT_2 2 -#define SCT_3 3 -#define SCT_4 4 -#define BKM_A4T 5 - -#define PLX_ADDR_PLX 0x14 /* Addr PLX configuration */ -#define PLX_ADDR_ISAC 0x18 /* Addr ISAC */ -#define PLX_ADDR_HSCX 0x1C /* Addr HSCX */ -#define PLX_ADDR_ALE 0x20 /* Addr ALE */ -#define PLX_ADDR_ALEPLUS 0x24 /* Next Addr behind ALE */ - -#define PLX_SUBVEN 0x2C /* Offset SubVendor */ -#define PLX_SUBSYS 0x2E /* Offset SubSystem */ - - -/* Application specific registers I20 (Siemens SZB6120H) */ -typedef struct { - /* Video front end horizontal configuration register */ - volatile u_int i20VFEHorzCfg; /* Offset 00 */ - /* Video front end vertical configuration register */ - volatile u_int i20VFEVertCfg; /* Offset 04 */ - /* Video front end scaler and pixel format register */ - volatile u_int i20VFEScaler; /* Offset 08 */ - /* Video display top register */ - volatile u_int i20VDispTop; /* Offset 0C */ - /* Video display bottom register */ - volatile u_int i20VDispBottom; /* Offset 10 */ - /* Video stride, status and frame grab register */ - volatile u_int i20VidFrameGrab;/* Offset 14 */ - /* Video display configuration register */ - volatile u_int i20VDispCfg; /* Offset 18 */ - /* Video masking map top */ - volatile u_int i20VMaskTop; /* Offset 1C */ - /* Video masking map bottom */ - volatile u_int i20VMaskBottom; /* Offset 20 */ - /* Overlay control register */ - volatile u_int i20OvlyControl; /* Offset 24 */ - /* System, PCI and general purpose pins control register */ - volatile u_int i20SysControl; /* Offset 28 */ -#define sysRESET 0x01000000 /* bit 24:Softreset (Low) */ - /* GPIO 4...0: Output fixed for our cfg! */ -#define sysCFG 0x000000E0 /* GPIO 7,6,5: Input */ - /* General purpose pins and guest bus control register */ - volatile u_int i20GuestControl;/* Offset 2C */ -#define guestWAIT_CFG 0x00005555 /* 4 PCI waits for all */ -#define guestISDN_INT_E 0x01000000 /* ISDN Int en (low) */ -#define guestVID_INT_E 0x02000000 /* Video interrupt en (low) */ -#define guestADI1_INT_R 0x04000000 /* ADI #1 int req (low) */ -#define guestADI2_INT_R 0x08000000 /* ADI #2 int req (low) */ -#define guestISDN_RES 0x10000000 /* ISDN reset bit (high) */ -#define guestADI1_INT_S 0x20000000 /* ADI #1 int pending (low) */ -#define guestADI2_INT_S 0x40000000 /* ADI #2 int pending (low) */ -#define guestISDN_INT_S 0x80000000 /* ISAC int pending (low) */ - -#define g_A4T_JADE_RES 0x01000000 /* JADE Reset (High) */ -#define g_A4T_ISAR_RES 0x02000000 /* ISAR Reset (High) */ -#define g_A4T_ISAC_RES 0x04000000 /* ISAC Reset (High) */ -#define g_A4T_JADE_BOOTR 0x08000000 /* JADE enable boot SRAM (Low) NOT USED */ -#define g_A4T_ISAR_BOOTR 0x10000000 /* ISAR enable boot SRAM (Low) NOT USED */ -#define g_A4T_JADE_INT_S 0x20000000 /* JADE interrupt pnd (Low) */ -#define g_A4T_ISAR_INT_S 0x40000000 /* ISAR interrupt pnd (Low) */ -#define g_A4T_ISAC_INT_S 0x80000000 /* ISAC interrupt pnd (Low) */ - - volatile u_int i20CodeSource; /* Offset 30 */ - volatile u_int i20CodeXferCtrl;/* Offset 34 */ - volatile u_int i20CodeMemPtr; /* Offset 38 */ - - volatile u_int i20IntStatus; /* Offset 3C */ - volatile u_int i20IntCtrl; /* Offset 40 */ -#define intISDN 0x40000000 /* GIRQ1En (ISAC/ADI) (High) */ -#define intVID 0x20000000 /* GIRQ0En (VSYNC) (High) */ -#define intCOD 0x10000000 /* CodRepIrqEn (High) */ -#define intPCI 0x01000000 /* PCI IntA enable (High) */ - - volatile u_int i20I2CCtrl; /* Offset 44 */ -} I20_REGISTER_FILE, *PI20_REGISTER_FILE; - -/* - * Postoffice structure for A4T - * - */ -#define PO_OFFSET 0x00000200 /* Postoffice offset from base */ - -#define GCS_0 0x00000000 /* Guest bus chip selects */ -#define GCS_1 0x00100000 -#define GCS_2 0x00200000 -#define GCS_3 0x00300000 - -#define PO_READ 0x00000000 /* R/W from/to guest bus */ -#define PO_WRITE 0x00800000 - -#define PO_PEND 0x02000000 - -#define POSTOFFICE(postoffice) *(volatile unsigned int *)(postoffice) - -/* Wait unlimited (don't worry) */ -#define __WAITI20__(postoffice) \ - do { \ - while ((POSTOFFICE(postoffice) & PO_PEND)) ; \ - } while (0) - -#endif /* __BKM_AX_H__ */ diff --git a/drivers/isdn/hisax/callc.c b/drivers/isdn/hisax/callc.c deleted file mode 100644 index 9ee06328784c..000000000000 --- a/drivers/isdn/hisax/callc.c +++ /dev/null @@ -1,1792 +0,0 @@ -/* $Id: callc.c,v 2.59.2.4 2004/02/11 13:21:32 keil Exp $ - * - * Author Karsten Keil - * Copyright by Karsten Keil <keil@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * For changes and modifications please read - * Documentation/isdn/HiSax.cert - * - * based on the teles driver from Jan den Ouden - * - * Thanks to Jan den Ouden - * Fritz Elfert - * - */ - -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/init.h> -#include "hisax.h" -#include <linux/isdn/capicmd.h> - -const char *lli_revision = "$Revision: 2.59.2.4 $"; - -extern struct IsdnCard cards[]; - -static int init_b_st(struct Channel *chanp, int incoming); -static void release_b_st(struct Channel *chanp); - -static struct Fsm callcfsm; -static int chancount; - -/* experimental REJECT after ALERTING for CALLBACK to beat the 4s delay */ -#define ALERT_REJECT 0 - -/* Value to delay the sending of the first B-channel packet after CONNECT - * here is no value given by ITU, but experience shows that 300 ms will - * work on many networks, if you or your other side is behind local exchanges - * a greater value may be recommented. If the delay is to short the first paket - * will be lost and autodetect on many comercial routers goes wrong ! - * You can adjust this value on runtime with - * hisaxctrl <id> 2 <value> - * value is in milliseconds - */ -#define DEFAULT_B_DELAY 300 - -/* Flags for remembering action done in lli */ - -#define FLG_START_B 0 - -/* - * Find card with given driverId - */ -static inline struct IsdnCardState * -hisax_findcard(int driverid) -{ - int i; - - for (i = 0; i < nrcards; i++) - if (cards[i].cs) - if (cards[i].cs->myid == driverid) - return (cards[i].cs); - return (struct IsdnCardState *) 0; -} - -static __printf(3, 4) void - link_debug(struct Channel *chanp, int direction, char *fmt, ...) -{ - va_list args; - char tmp[16]; - - va_start(args, fmt); - sprintf(tmp, "Ch%d %s ", chanp->chan, - direction ? "LL->HL" : "HL->LL"); - VHiSax_putstatus(chanp->cs, tmp, fmt, args); - va_end(args); -} - -enum { - ST_NULL, /* 0 inactive */ - ST_OUT_DIAL, /* 1 outgoing, SETUP send; awaiting confirm */ - ST_IN_WAIT_LL, /* 2 incoming call received; wait for LL confirm */ - ST_IN_ALERT_SENT, /* 3 incoming call received; ALERT send */ - ST_IN_WAIT_CONN_ACK, /* 4 incoming CONNECT send; awaiting CONN_ACK */ - ST_WAIT_BCONN, /* 5 CONNECT/CONN_ACK received, awaiting b-channel prot. estbl. */ - ST_ACTIVE, /* 6 active, b channel prot. established */ - ST_WAIT_BRELEASE, /* 7 call clear. (initiator), awaiting b channel prot. rel. */ - ST_WAIT_BREL_DISC, /* 8 call clear. (receiver), DISCONNECT req. received */ - ST_WAIT_DCOMMAND, /* 9 call clear. (receiver), awaiting DCHANNEL message */ - ST_WAIT_DRELEASE, /* 10 DISCONNECT sent, awaiting RELEASE */ - ST_WAIT_D_REL_CNF, /* 11 RELEASE sent, awaiting RELEASE confirm */ - ST_IN_PROCEED_SEND, /* 12 incoming call, proceeding send */ -}; - - -#define STATE_COUNT (ST_IN_PROCEED_SEND + 1) - -static char *strState[] = -{ - "ST_NULL", - "ST_OUT_DIAL", - "ST_IN_WAIT_LL", - "ST_IN_ALERT_SENT", - "ST_IN_WAIT_CONN_ACK", - "ST_WAIT_BCONN", - "ST_ACTIVE", - "ST_WAIT_BRELEASE", - "ST_WAIT_BREL_DISC", - "ST_WAIT_DCOMMAND", - "ST_WAIT_DRELEASE", - "ST_WAIT_D_REL_CNF", - "ST_IN_PROCEED_SEND", -}; - -enum { - EV_DIAL, /* 0 */ - EV_SETUP_CNF, /* 1 */ - EV_ACCEPTB, /* 2 */ - EV_DISCONNECT_IND, /* 3 */ - EV_RELEASE, /* 4 */ - EV_LEASED, /* 5 */ - EV_LEASED_REL, /* 6 */ - EV_SETUP_IND, /* 7 */ - EV_ACCEPTD, /* 8 */ - EV_SETUP_CMPL_IND, /* 9 */ - EV_BC_EST, /* 10 */ - EV_WRITEBUF, /* 11 */ - EV_HANGUP, /* 12 */ - EV_BC_REL, /* 13 */ - EV_CINF, /* 14 */ - EV_SUSPEND, /* 15 */ - EV_RESUME, /* 16 */ - EV_NOSETUP_RSP, /* 17 */ - EV_SETUP_ERR, /* 18 */ - EV_CONNECT_ERR, /* 19 */ - EV_PROCEED, /* 20 */ - EV_ALERT, /* 21 */ - EV_REDIR, /* 22 */ -}; - -#define EVENT_COUNT (EV_REDIR + 1) - -static char *strEvent[] = -{ - "EV_DIAL", - "EV_SETUP_CNF", - "EV_ACCEPTB", - "EV_DISCONNECT_IND", - "EV_RELEASE", - "EV_LEASED", - "EV_LEASED_REL", - "EV_SETUP_IND", - "EV_ACCEPTD", - "EV_SETUP_CMPL_IND", - "EV_BC_EST", - "EV_WRITEBUF", - "EV_HANGUP", - "EV_BC_REL", - "EV_CINF", - "EV_SUSPEND", - "EV_RESUME", - "EV_NOSETUP_RSP", - "EV_SETUP_ERR", - "EV_CONNECT_ERR", - "EV_PROCEED", - "EV_ALERT", - "EV_REDIR", -}; - - -static inline void -HL_LL(struct Channel *chanp, int command) -{ - isdn_ctrl ic; - - ic.driver = chanp->cs->myid; - ic.command = command; - ic.arg = chanp->chan; - chanp->cs->iif.statcallb(&ic); -} - -static inline void -lli_deliver_cause(struct Channel *chanp) -{ - isdn_ctrl ic; - - if (!chanp->proc) - return; - if (chanp->proc->para.cause == NO_CAUSE) - return; - ic.driver = chanp->cs->myid; - ic.command = ISDN_STAT_CAUSE; - ic.arg = chanp->chan; - if (chanp->cs->protocol == ISDN_PTYPE_EURO) - sprintf(ic.parm.num, "E%02X%02X", chanp->proc->para.loc & 0x7f, - chanp->proc->para.cause & 0x7f); - else - sprintf(ic.parm.num, "%02X%02X", chanp->proc->para.loc & 0x7f, - chanp->proc->para.cause & 0x7f); - chanp->cs->iif.statcallb(&ic); -} - -static inline void -lli_close(struct FsmInst *fi) -{ - struct Channel *chanp = fi->userdata; - - FsmChangeState(fi, ST_NULL); - chanp->Flags = 0; - chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan); -} - -static void -lli_leased_in(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - isdn_ctrl ic; - int ret; - - if (!chanp->leased) - return; - chanp->cs->cardmsg(chanp->cs, MDL_INFO_SETUP, (void *) (long)chanp->chan); - FsmChangeState(fi, ST_IN_WAIT_LL); - if (chanp->debug & 1) - link_debug(chanp, 0, "STAT_ICALL_LEASED"); - ic.driver = chanp->cs->myid; - ic.command = ((chanp->chan < 2) ? ISDN_STAT_ICALL : ISDN_STAT_ICALLW); - ic.arg = chanp->chan; - ic.parm.setup.si1 = 7; - ic.parm.setup.si2 = 0; - ic.parm.setup.plan = 0; - ic.parm.setup.screen = 0; - sprintf(ic.parm.setup.eazmsn, "%d", chanp->chan + 1); - sprintf(ic.parm.setup.phone, "LEASED%d", chanp->cs->myid); - ret = chanp->cs->iif.statcallb(&ic); - if (chanp->debug & 1) - link_debug(chanp, 1, "statcallb ret=%d", ret); - if (!ret) { - chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan); - FsmChangeState(fi, ST_NULL); - } -} - - -/* - * Dial out - */ -static void -lli_init_bchan_out(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - - FsmChangeState(fi, ST_WAIT_BCONN); - if (chanp->debug & 1) - link_debug(chanp, 0, "STAT_DCONN"); - HL_LL(chanp, ISDN_STAT_DCONN); - init_b_st(chanp, 0); - chanp->b_st->lli.l4l3(chanp->b_st, DL_ESTABLISH | REQUEST, NULL); -} - -static void -lli_prep_dialout(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - - FsmDelTimer(&chanp->drel_timer, 60); - FsmDelTimer(&chanp->dial_timer, 73); - chanp->l2_active_protocol = chanp->l2_protocol; - chanp->incoming = 0; - chanp->cs->cardmsg(chanp->cs, MDL_INFO_SETUP, (void *) (long)chanp->chan); - if (chanp->leased) { - lli_init_bchan_out(fi, event, arg); - } else { - FsmChangeState(fi, ST_OUT_DIAL); - chanp->d_st->lli.l4l3(chanp->d_st, CC_SETUP | REQUEST, chanp); - } -} - -static void -lli_resume(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - - FsmDelTimer(&chanp->drel_timer, 60); - FsmDelTimer(&chanp->dial_timer, 73); - chanp->l2_active_protocol = chanp->l2_protocol; - chanp->incoming = 0; - chanp->cs->cardmsg(chanp->cs, MDL_INFO_SETUP, (void *) (long)chanp->chan); - if (chanp->leased) { - lli_init_bchan_out(fi, event, arg); - } else { - FsmChangeState(fi, ST_OUT_DIAL); - chanp->d_st->lli.l4l3(chanp->d_st, CC_RESUME | REQUEST, chanp); - } -} - -static void -lli_go_active(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - isdn_ctrl ic; - - - FsmChangeState(fi, ST_ACTIVE); - chanp->data_open = !0; - if (chanp->bcs->conmsg) - strcpy(ic.parm.num, chanp->bcs->conmsg); - else - ic.parm.num[0] = 0; - if (chanp->debug & 1) - link_debug(chanp, 0, "STAT_BCONN %s", ic.parm.num); - ic.driver = chanp->cs->myid; - ic.command = ISDN_STAT_BCONN; - ic.arg = chanp->chan; - chanp->cs->iif.statcallb(&ic); - chanp->cs->cardmsg(chanp->cs, MDL_INFO_CONN, (void *) (long)chanp->chan); -} - - -/* - * RESUME - */ - -/* incoming call */ - -static void -lli_deliver_call(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - isdn_ctrl ic; - int ret; - - chanp->cs->cardmsg(chanp->cs, MDL_INFO_SETUP, (void *) (long)chanp->chan); - /* - * Report incoming calls only once to linklevel, use CallFlags - * which is set to 3 with each broadcast message in isdnl1.c - * and resetted if a interface answered the STAT_ICALL. - */ - if (1) { /* for only one TEI */ - FsmChangeState(fi, ST_IN_WAIT_LL); - if (chanp->debug & 1) - link_debug(chanp, 0, (chanp->chan < 2) ? "STAT_ICALL" : "STAT_ICALLW"); - ic.driver = chanp->cs->myid; - ic.command = ((chanp->chan < 2) ? ISDN_STAT_ICALL : ISDN_STAT_ICALLW); - - ic.arg = chanp->chan; - /* - * No need to return "unknown" for calls without OAD, - * cause that's handled in linklevel now (replaced by '0') - */ - memcpy(&ic.parm.setup, &chanp->proc->para.setup, sizeof(setup_parm)); - ret = chanp->cs->iif.statcallb(&ic); - if (chanp->debug & 1) - link_debug(chanp, 1, "statcallb ret=%d", ret); - - switch (ret) { - case 1: /* OK, someone likes this call */ - FsmDelTimer(&chanp->drel_timer, 61); - FsmChangeState(fi, ST_IN_ALERT_SENT); - chanp->d_st->lli.l4l3(chanp->d_st, CC_ALERTING | REQUEST, chanp->proc); - break; - case 5: /* direct redirect */ - case 4: /* Proceeding desired */ - FsmDelTimer(&chanp->drel_timer, 61); - FsmChangeState(fi, ST_IN_PROCEED_SEND); - chanp->d_st->lli.l4l3(chanp->d_st, CC_PROCEED_SEND | REQUEST, chanp->proc); - if (ret == 5) { - memcpy(&chanp->setup, &ic.parm.setup, sizeof(setup_parm)); - chanp->d_st->lli.l4l3(chanp->d_st, CC_REDIR | REQUEST, chanp->proc); - } - break; - case 2: /* Rejecting Call */ - break; - case 3: /* incomplete number */ - FsmDelTimer(&chanp->drel_timer, 61); - chanp->d_st->lli.l4l3(chanp->d_st, CC_MORE_INFO | REQUEST, chanp->proc); - break; - case 0: /* OK, nobody likes this call */ - default: /* statcallb problems */ - chanp->d_st->lli.l4l3(chanp->d_st, CC_IGNORE | REQUEST, chanp->proc); - chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan); - FsmChangeState(fi, ST_NULL); - break; - } - } else { - chanp->d_st->lli.l4l3(chanp->d_st, CC_IGNORE | REQUEST, chanp->proc); - chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan); - } -} - -static void -lli_send_dconnect(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - - FsmChangeState(fi, ST_IN_WAIT_CONN_ACK); - chanp->d_st->lli.l4l3(chanp->d_st, CC_SETUP | RESPONSE, chanp->proc); -} - -static void -lli_send_alert(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - - FsmChangeState(fi, ST_IN_ALERT_SENT); - chanp->d_st->lli.l4l3(chanp->d_st, CC_ALERTING | REQUEST, chanp->proc); -} - -static void -lli_send_redir(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - - chanp->d_st->lli.l4l3(chanp->d_st, CC_REDIR | REQUEST, chanp->proc); -} - -static void -lli_init_bchan_in(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - - FsmChangeState(fi, ST_WAIT_BCONN); - if (chanp->debug & 1) - link_debug(chanp, 0, "STAT_DCONN"); - HL_LL(chanp, ISDN_STAT_DCONN); - chanp->l2_active_protocol = chanp->l2_protocol; - chanp->incoming = !0; - init_b_st(chanp, !0); - chanp->b_st->lli.l4l3(chanp->b_st, DL_ESTABLISH | REQUEST, NULL); -} - -static void -lli_setup_rsp(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - - if (chanp->leased) { - lli_init_bchan_in(fi, event, arg); - } else { - FsmChangeState(fi, ST_IN_WAIT_CONN_ACK); -#ifdef WANT_ALERT - chanp->d_st->lli.l4l3(chanp->d_st, CC_ALERTING | REQUEST, chanp->proc); -#endif - chanp->d_st->lli.l4l3(chanp->d_st, CC_SETUP | RESPONSE, chanp->proc); - } -} - -/* Call suspend */ - -static void -lli_suspend(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - - chanp->d_st->lli.l4l3(chanp->d_st, CC_SUSPEND | REQUEST, chanp->proc); -} - -/* Call clearing */ - -static void -lli_leased_hup(struct FsmInst *fi, struct Channel *chanp) -{ - isdn_ctrl ic; - - ic.driver = chanp->cs->myid; - ic.command = ISDN_STAT_CAUSE; - ic.arg = chanp->chan; - sprintf(ic.parm.num, "L0010"); - chanp->cs->iif.statcallb(&ic); - if (chanp->debug & 1) - link_debug(chanp, 0, "STAT_DHUP"); - HL_LL(chanp, ISDN_STAT_DHUP); - lli_close(fi); -} - -static void -lli_disconnect_req(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - - if (chanp->leased) { - lli_leased_hup(fi, chanp); - } else { - FsmChangeState(fi, ST_WAIT_DRELEASE); - if (chanp->proc) - chanp->proc->para.cause = 0x10; /* Normal Call Clearing */ - chanp->d_st->lli.l4l3(chanp->d_st, CC_DISCONNECT | REQUEST, - chanp->proc); - } -} - -static void -lli_disconnect_reject(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - - if (chanp->leased) { - lli_leased_hup(fi, chanp); - } else { - FsmChangeState(fi, ST_WAIT_DRELEASE); - if (chanp->proc) - chanp->proc->para.cause = 0x15; /* Call Rejected */ - chanp->d_st->lli.l4l3(chanp->d_st, CC_DISCONNECT | REQUEST, - chanp->proc); - } -} - -static void -lli_dhup_close(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - - if (chanp->leased) { - lli_leased_hup(fi, chanp); - } else { - if (chanp->debug & 1) - link_debug(chanp, 0, "STAT_DHUP"); - lli_deliver_cause(chanp); - HL_LL(chanp, ISDN_STAT_DHUP); - lli_close(fi); - } -} - -static void -lli_reject_req(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - - if (chanp->leased) { - lli_leased_hup(fi, chanp); - return; - } -#ifndef ALERT_REJECT - if (chanp->proc) - chanp->proc->para.cause = 0x15; /* Call Rejected */ - chanp->d_st->lli.l4l3(chanp->d_st, CC_REJECT | REQUEST, chanp->proc); - lli_dhup_close(fi, event, arg); -#else - FsmRestartTimer(&chanp->drel_timer, 40, EV_HANGUP, NULL, 63); - FsmChangeState(fi, ST_IN_ALERT_SENT); - chanp->d_st->lli.l4l3(chanp->d_st, CC_ALERTING | REQUEST, chanp->proc); -#endif -} - -static void -lli_disconn_bchan(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - - chanp->data_open = 0; - FsmChangeState(fi, ST_WAIT_BRELEASE); - chanp->b_st->lli.l4l3(chanp->b_st, DL_RELEASE | REQUEST, NULL); -} - -static void -lli_start_disc(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - - if (chanp->leased) { - lli_leased_hup(fi, chanp); - } else { - lli_disconnect_req(fi, event, arg); - } -} - -static void -lli_rel_b_disc(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - - release_b_st(chanp); - lli_start_disc(fi, event, arg); -} - -static void -lli_bhup_disc(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - - if (chanp->debug & 1) - link_debug(chanp, 0, "STAT_BHUP"); - HL_LL(chanp, ISDN_STAT_BHUP); - lli_rel_b_disc(fi, event, arg); -} - -static void -lli_bhup_rel_b(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - - FsmChangeState(fi, ST_WAIT_DCOMMAND); - chanp->data_open = 0; - if (chanp->debug & 1) - link_debug(chanp, 0, "STAT_BHUP"); - HL_LL(chanp, ISDN_STAT_BHUP); - release_b_st(chanp); -} - -static void -lli_release_bchan(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - - chanp->data_open = 0; - FsmChangeState(fi, ST_WAIT_BREL_DISC); - chanp->b_st->lli.l4l3(chanp->b_st, DL_RELEASE | REQUEST, NULL); -} - - -static void -lli_rel_b_dhup(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - - release_b_st(chanp); - lli_dhup_close(fi, event, arg); -} - -static void -lli_bhup_dhup(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - - if (chanp->debug & 1) - link_debug(chanp, 0, "STAT_BHUP"); - HL_LL(chanp, ISDN_STAT_BHUP); - lli_rel_b_dhup(fi, event, arg); -} - -static void -lli_abort(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - - chanp->data_open = 0; - chanp->b_st->lli.l4l3(chanp->b_st, DL_RELEASE | REQUEST, NULL); - lli_bhup_dhup(fi, event, arg); -} - -static void -lli_release_req(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - - if (chanp->leased) { - lli_leased_hup(fi, chanp); - } else { - FsmChangeState(fi, ST_WAIT_D_REL_CNF); - chanp->d_st->lli.l4l3(chanp->d_st, CC_RELEASE | REQUEST, - chanp->proc); - } -} - -static void -lli_rel_b_release_req(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - - release_b_st(chanp); - lli_release_req(fi, event, arg); -} - -static void -lli_bhup_release_req(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - - if (chanp->debug & 1) - link_debug(chanp, 0, "STAT_BHUP"); - HL_LL(chanp, ISDN_STAT_BHUP); - lli_rel_b_release_req(fi, event, arg); -} - - -/* processing charge info */ -static void -lli_charge_info(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - isdn_ctrl ic; - - ic.driver = chanp->cs->myid; - ic.command = ISDN_STAT_CINF; - ic.arg = chanp->chan; - sprintf(ic.parm.num, "%d", chanp->proc->para.chargeinfo); - chanp->cs->iif.statcallb(&ic); -} - -/* error procedures */ - -static void -lli_dchan_not_ready(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - - if (chanp->debug & 1) - link_debug(chanp, 0, "STAT_DHUP"); - HL_LL(chanp, ISDN_STAT_DHUP); -} - -static void -lli_no_setup_rsp(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - - if (chanp->debug & 1) - link_debug(chanp, 0, "STAT_DHUP"); - HL_LL(chanp, ISDN_STAT_DHUP); - lli_close(fi); -} - -static void -lli_error(struct FsmInst *fi, int event, void *arg) -{ - FsmChangeState(fi, ST_WAIT_DRELEASE); -} - -static void -lli_failure_l(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - isdn_ctrl ic; - - FsmChangeState(fi, ST_NULL); - ic.driver = chanp->cs->myid; - ic.command = ISDN_STAT_CAUSE; - ic.arg = chanp->chan; - sprintf(ic.parm.num, "L%02X%02X", 0, 0x2f); - chanp->cs->iif.statcallb(&ic); - HL_LL(chanp, ISDN_STAT_DHUP); - chanp->Flags = 0; - chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan); -} - -static void -lli_rel_b_fail(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - - release_b_st(chanp); - lli_failure_l(fi, event, arg); -} - -static void -lli_bhup_fail(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - - if (chanp->debug & 1) - link_debug(chanp, 0, "STAT_BHUP"); - HL_LL(chanp, ISDN_STAT_BHUP); - lli_rel_b_fail(fi, event, arg); -} - -static void -lli_failure_a(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - - chanp->data_open = 0; - chanp->b_st->lli.l4l3(chanp->b_st, DL_RELEASE | REQUEST, NULL); - lli_bhup_fail(fi, event, arg); -} - -/* *INDENT-OFF* */ -static struct FsmNode fnlist[] __initdata = -{ - {ST_NULL, EV_DIAL, lli_prep_dialout}, - {ST_NULL, EV_RESUME, lli_resume}, - {ST_NULL, EV_SETUP_IND, lli_deliver_call}, - {ST_NULL, EV_LEASED, lli_leased_in}, - {ST_OUT_DIAL, EV_SETUP_CNF, lli_init_bchan_out}, - {ST_OUT_DIAL, EV_HANGUP, lli_disconnect_req}, - {ST_OUT_DIAL, EV_DISCONNECT_IND, lli_release_req}, - {ST_OUT_DIAL, EV_RELEASE, lli_dhup_close}, - {ST_OUT_DIAL, EV_NOSETUP_RSP, lli_no_setup_rsp}, - {ST_OUT_DIAL, EV_SETUP_ERR, lli_error}, - {ST_IN_WAIT_LL, EV_LEASED_REL, lli_failure_l}, - {ST_IN_WAIT_LL, EV_ACCEPTD, lli_setup_rsp}, - {ST_IN_WAIT_LL, EV_HANGUP, lli_reject_req}, - {ST_IN_WAIT_LL, EV_DISCONNECT_IND, lli_release_req}, - {ST_IN_WAIT_LL, EV_RELEASE, lli_dhup_close}, - {ST_IN_WAIT_LL, EV_SETUP_IND, lli_deliver_call}, - {ST_IN_WAIT_LL, EV_SETUP_ERR, lli_error}, - {ST_IN_ALERT_SENT, EV_SETUP_CMPL_IND, lli_init_bchan_in}, - {ST_IN_ALERT_SENT, EV_ACCEPTD, lli_send_dconnect}, - {ST_IN_ALERT_SENT, EV_HANGUP, lli_disconnect_reject}, - {ST_IN_ALERT_SENT, EV_DISCONNECT_IND, lli_release_req}, - {ST_IN_ALERT_SENT, EV_RELEASE, lli_dhup_close}, - {ST_IN_ALERT_SENT, EV_REDIR, lli_send_redir}, - {ST_IN_PROCEED_SEND, EV_REDIR, lli_send_redir}, - {ST_IN_PROCEED_SEND, EV_ALERT, lli_send_alert}, - {ST_IN_PROCEED_SEND, EV_ACCEPTD, lli_send_dconnect}, - {ST_IN_PROCEED_SEND, EV_HANGUP, lli_disconnect_reject}, - {ST_IN_PROCEED_SEND, EV_DISCONNECT_IND, lli_dhup_close}, - {ST_IN_ALERT_SENT, EV_RELEASE, lli_dhup_close}, - {ST_IN_WAIT_CONN_ACK, EV_SETUP_CMPL_IND, lli_init_bchan_in}, - {ST_IN_WAIT_CONN_ACK, EV_HANGUP, lli_disconnect_req}, - {ST_IN_WAIT_CONN_ACK, EV_DISCONNECT_IND, lli_release_req}, - {ST_IN_WAIT_CONN_ACK, EV_RELEASE, lli_dhup_close}, - {ST_IN_WAIT_CONN_ACK, EV_CONNECT_ERR, lli_error}, - {ST_WAIT_BCONN, EV_BC_EST, lli_go_active}, - {ST_WAIT_BCONN, EV_BC_REL, lli_rel_b_disc}, - {ST_WAIT_BCONN, EV_HANGUP, lli_rel_b_disc}, - {ST_WAIT_BCONN, EV_DISCONNECT_IND, lli_rel_b_release_req}, - {ST_WAIT_BCONN, EV_RELEASE, lli_rel_b_dhup}, - {ST_WAIT_BCONN, EV_LEASED_REL, lli_rel_b_fail}, - {ST_WAIT_BCONN, EV_CINF, lli_charge_info}, - {ST_ACTIVE, EV_CINF, lli_charge_info}, - {ST_ACTIVE, EV_BC_REL, lli_bhup_rel_b}, - {ST_ACTIVE, EV_SUSPEND, lli_suspend}, - {ST_ACTIVE, EV_HANGUP, lli_disconn_bchan}, - {ST_ACTIVE, EV_DISCONNECT_IND, lli_release_bchan}, - {ST_ACTIVE, EV_RELEASE, lli_abort}, - {ST_ACTIVE, EV_LEASED_REL, lli_failure_a}, - {ST_WAIT_BRELEASE, EV_BC_REL, lli_bhup_disc}, - {ST_WAIT_BRELEASE, EV_DISCONNECT_IND, lli_bhup_release_req}, - {ST_WAIT_BRELEASE, EV_RELEASE, lli_bhup_dhup}, - {ST_WAIT_BRELEASE, EV_LEASED_REL, lli_bhup_fail}, - {ST_WAIT_BREL_DISC, EV_BC_REL, lli_bhup_release_req}, - {ST_WAIT_BREL_DISC, EV_RELEASE, lli_bhup_dhup}, - {ST_WAIT_DCOMMAND, EV_HANGUP, lli_start_disc}, - {ST_WAIT_DCOMMAND, EV_DISCONNECT_IND, lli_release_req}, - {ST_WAIT_DCOMMAND, EV_RELEASE, lli_dhup_close}, - {ST_WAIT_DCOMMAND, EV_LEASED_REL, lli_failure_l}, - {ST_WAIT_DRELEASE, EV_RELEASE, lli_dhup_close}, - {ST_WAIT_DRELEASE, EV_DIAL, lli_dchan_not_ready}, - /* ETS 300-104 16.1 */ - {ST_WAIT_D_REL_CNF, EV_RELEASE, lli_dhup_close}, - {ST_WAIT_D_REL_CNF, EV_DIAL, lli_dchan_not_ready}, -}; -/* *INDENT-ON* */ - -int __init -CallcNew(void) -{ - callcfsm.state_count = STATE_COUNT; - callcfsm.event_count = EVENT_COUNT; - callcfsm.strEvent = strEvent; - callcfsm.strState = strState; - return FsmNew(&callcfsm, fnlist, ARRAY_SIZE(fnlist)); -} - -void -CallcFree(void) -{ - FsmFree(&callcfsm); -} - -static void -release_b_st(struct Channel *chanp) -{ - struct PStack *st = chanp->b_st; - - if (test_and_clear_bit(FLG_START_B, &chanp->Flags)) { - chanp->bcs->BC_Close(chanp->bcs); - switch (chanp->l2_active_protocol) { - case (ISDN_PROTO_L2_X75I): - releasestack_isdnl2(st); - break; - case (ISDN_PROTO_L2_HDLC): - case (ISDN_PROTO_L2_HDLC_56K): - case (ISDN_PROTO_L2_TRANS): - case (ISDN_PROTO_L2_MODEM): - case (ISDN_PROTO_L2_FAX): - releasestack_transl2(st); - break; - } - } -} - -static struct Channel -*selectfreechannel(struct PStack *st, int bch) -{ - struct IsdnCardState *cs = st->l1.hardware; - struct Channel *chanp = st->lli.userdata; - int i; - - if (test_bit(FLG_TWO_DCHAN, &cs->HW_Flags)) - i = 1; - else - i = 0; - - if (!bch) { - i = 2; /* virtual channel */ - chanp += 2; - } - - while (i < ((bch) ? cs->chanlimit : (2 + MAX_WAITING_CALLS))) { - if (chanp->fi.state == ST_NULL) - return (chanp); - chanp++; - i++; - } - - if (bch) /* number of channels is limited */ { - i = 2; /* virtual channel */ - chanp = st->lli.userdata; - chanp += i; - while (i < (2 + MAX_WAITING_CALLS)) { - if (chanp->fi.state == ST_NULL) - return (chanp); - chanp++; - i++; - } - } - return (NULL); -} - -static void stat_redir_result(struct IsdnCardState *cs, int chan, ulong result) -{ isdn_ctrl ic; - - ic.driver = cs->myid; - ic.command = ISDN_STAT_REDIR; - ic.arg = chan; - ic.parm.num[0] = result; - cs->iif.statcallb(&ic); -} /* stat_redir_result */ - -static void -dchan_l3l4(struct PStack *st, int pr, void *arg) -{ - struct l3_process *pc = arg; - struct IsdnCardState *cs = st->l1.hardware; - struct Channel *chanp; - - if (!pc) - return; - - if (pr == (CC_SETUP | INDICATION)) { - if (!(chanp = selectfreechannel(pc->st, pc->para.bchannel))) { - pc->para.cause = 0x11; /* User busy */ - pc->st->lli.l4l3(pc->st, CC_REJECT | REQUEST, pc); - } else { - chanp->proc = pc; - pc->chan = chanp; - FsmEvent(&chanp->fi, EV_SETUP_IND, NULL); - } - return; - } - if (!(chanp = pc->chan)) - return; - - switch (pr) { - case (CC_MORE_INFO | INDICATION): - FsmEvent(&chanp->fi, EV_SETUP_IND, NULL); - break; - case (CC_DISCONNECT | INDICATION): - FsmEvent(&chanp->fi, EV_DISCONNECT_IND, NULL); - break; - case (CC_RELEASE | CONFIRM): - FsmEvent(&chanp->fi, EV_RELEASE, NULL); - break; - case (CC_SUSPEND | CONFIRM): - FsmEvent(&chanp->fi, EV_RELEASE, NULL); - break; - case (CC_RESUME | CONFIRM): - FsmEvent(&chanp->fi, EV_SETUP_CNF, NULL); - break; - case (CC_RESUME_ERR): - FsmEvent(&chanp->fi, EV_RELEASE, NULL); - break; - case (CC_RELEASE | INDICATION): - FsmEvent(&chanp->fi, EV_RELEASE, NULL); - break; - case (CC_SETUP_COMPL | INDICATION): - FsmEvent(&chanp->fi, EV_SETUP_CMPL_IND, NULL); - break; - case (CC_SETUP | CONFIRM): - FsmEvent(&chanp->fi, EV_SETUP_CNF, NULL); - break; - case (CC_CHARGE | INDICATION): - FsmEvent(&chanp->fi, EV_CINF, NULL); - break; - case (CC_NOSETUP_RSP): - FsmEvent(&chanp->fi, EV_NOSETUP_RSP, NULL); - break; - case (CC_SETUP_ERR): - FsmEvent(&chanp->fi, EV_SETUP_ERR, NULL); - break; - case (CC_CONNECT_ERR): - FsmEvent(&chanp->fi, EV_CONNECT_ERR, NULL); - break; - case (CC_RELEASE_ERR): - FsmEvent(&chanp->fi, EV_RELEASE, NULL); - break; - case (CC_PROCEED_SEND | INDICATION): - case (CC_PROCEEDING | INDICATION): - case (CC_ALERTING | INDICATION): - case (CC_PROGRESS | INDICATION): - case (CC_NOTIFY | INDICATION): - break; - case (CC_REDIR | INDICATION): - stat_redir_result(cs, chanp->chan, pc->redir_result); - break; - default: - if (chanp->debug & 0x800) { - HiSax_putstatus(chanp->cs, "Ch", - "%d L3->L4 unknown primitiv %#x", - chanp->chan, pr); - } - } -} - -static void -dummy_pstack(struct PStack *st, int pr, void *arg) { - printk(KERN_WARNING"call to dummy_pstack pr=%04x arg %lx\n", pr, (long)arg); -} - -static int -init_PStack(struct PStack **stp) { - *stp = kmalloc(sizeof(struct PStack), GFP_KERNEL); - if (!*stp) - return -ENOMEM; - (*stp)->next = NULL; - (*stp)->l1.l1l2 = dummy_pstack; - (*stp)->l1.l1hw = dummy_pstack; - (*stp)->l1.l1tei = dummy_pstack; - (*stp)->l2.l2tei = dummy_pstack; - (*stp)->l2.l2l1 = dummy_pstack; - (*stp)->l2.l2l3 = dummy_pstack; - (*stp)->l3.l3l2 = dummy_pstack; - (*stp)->l3.l3ml3 = dummy_pstack; - (*stp)->l3.l3l4 = dummy_pstack; - (*stp)->lli.l4l3 = dummy_pstack; - (*stp)->ma.layer = dummy_pstack; - return 0; -} - -static int -init_d_st(struct Channel *chanp) -{ - struct PStack *st; - struct IsdnCardState *cs = chanp->cs; - char tmp[16]; - int err; - - err = init_PStack(&chanp->d_st); - if (err) - return err; - st = chanp->d_st; - st->next = NULL; - HiSax_addlist(cs, st); - setstack_HiSax(st, cs); - st->l2.sap = 0; - st->l2.tei = -1; - st->l2.flag = 0; - test_and_set_bit(FLG_MOD128, &st->l2.flag); - test_and_set_bit(FLG_LAPD, &st->l2.flag); - test_and_set_bit(FLG_ORIG, &st->l2.flag); - st->l2.maxlen = MAX_DFRAME_LEN; - st->l2.window = 1; - st->l2.T200 = 1000; /* 1000 milliseconds */ - st->l2.N200 = 3; /* try 3 times */ - st->l2.T203 = 10000; /* 10000 milliseconds */ - if (test_bit(FLG_TWO_DCHAN, &cs->HW_Flags)) - sprintf(tmp, "DCh%d Q.921 ", chanp->chan); - else - sprintf(tmp, "DCh Q.921 "); - setstack_isdnl2(st, tmp); - setstack_l3dc(st, chanp); - st->lli.userdata = chanp; - st->l3.l3l4 = dchan_l3l4; - - return 0; -} - -static __printf(2, 3) void - callc_debug(struct FsmInst *fi, char *fmt, ...) -{ - va_list args; - struct Channel *chanp = fi->userdata; - char tmp[16]; - - va_start(args, fmt); - sprintf(tmp, "Ch%d callc ", chanp->chan); - VHiSax_putstatus(chanp->cs, tmp, fmt, args); - va_end(args); -} - -static int -init_chan(int chan, struct IsdnCardState *csta) -{ - struct Channel *chanp = csta->channel + chan; - int err; - - chanp->cs = csta; - chanp->bcs = csta->bcs + chan; - chanp->chan = chan; - chanp->incoming = 0; - chanp->debug = 0; - chanp->Flags = 0; - chanp->leased = 0; - err = init_PStack(&chanp->b_st); - if (err) - return err; - chanp->b_st->l1.delay = DEFAULT_B_DELAY; - chanp->fi.fsm = &callcfsm; - chanp->fi.state = ST_NULL; - chanp->fi.debug = 0; - chanp->fi.userdata = chanp; - chanp->fi.printdebug = callc_debug; - FsmInitTimer(&chanp->fi, &chanp->dial_timer); - FsmInitTimer(&chanp->fi, &chanp->drel_timer); - if (!chan || (test_bit(FLG_TWO_DCHAN, &csta->HW_Flags) && chan < 2)) { - err = init_d_st(chanp); - if (err) - return err; - } else { - chanp->d_st = csta->channel->d_st; - } - chanp->data_open = 0; - return 0; -} - -int -CallcNewChan(struct IsdnCardState *csta) { - int i, err; - - chancount += 2; - err = init_chan(0, csta); - if (err) - return err; - err = init_chan(1, csta); - if (err) - return err; - printk(KERN_INFO "HiSax: 2 channels added\n"); - - for (i = 0; i < MAX_WAITING_CALLS; i++) { - err = init_chan(i + 2, csta); - if (err) - return err; - } - printk(KERN_INFO "HiSax: MAX_WAITING_CALLS added\n"); - if (test_bit(FLG_PTP, &csta->channel->d_st->l2.flag)) { - printk(KERN_INFO "LAYER2 WATCHING ESTABLISH\n"); - csta->channel->d_st->lli.l4l3(csta->channel->d_st, - DL_ESTABLISH | REQUEST, NULL); - } - return (0); -} - -static void -release_d_st(struct Channel *chanp) -{ - struct PStack *st = chanp->d_st; - - if (!st) - return; - releasestack_isdnl2(st); - releasestack_isdnl3(st); - HiSax_rmlist(st->l1.hardware, st); - kfree(st); - chanp->d_st = NULL; -} - -void -CallcFreeChan(struct IsdnCardState *csta) -{ - int i; - - for (i = 0; i < 2; i++) { - FsmDelTimer(&csta->channel[i].drel_timer, 74); - FsmDelTimer(&csta->channel[i].dial_timer, 75); - if (i || test_bit(FLG_TWO_DCHAN, &csta->HW_Flags)) - release_d_st(csta->channel + i); - if (csta->channel[i].b_st) { - release_b_st(csta->channel + i); - kfree(csta->channel[i].b_st); - csta->channel[i].b_st = NULL; - } else - printk(KERN_WARNING "CallcFreeChan b_st ch%d already freed\n", i); - if (i || test_bit(FLG_TWO_DCHAN, &csta->HW_Flags)) { - release_d_st(csta->channel + i); - } else - csta->channel[i].d_st = NULL; - } -} - -static void -lldata_handler(struct PStack *st, int pr, void *arg) -{ - struct Channel *chanp = (struct Channel *) st->lli.userdata; - struct sk_buff *skb = arg; - - switch (pr) { - case (DL_DATA | INDICATION): - if (chanp->data_open) { - if (chanp->debug & 0x800) - link_debug(chanp, 0, "lldata: %d", skb->len); - chanp->cs->iif.rcvcallb_skb(chanp->cs->myid, chanp->chan, skb); - } else { - link_debug(chanp, 0, "lldata: channel not open"); - dev_kfree_skb(skb); - } - break; - case (DL_ESTABLISH | INDICATION): - case (DL_ESTABLISH | CONFIRM): - FsmEvent(&chanp->fi, EV_BC_EST, NULL); - break; - case (DL_RELEASE | INDICATION): - case (DL_RELEASE | CONFIRM): - FsmEvent(&chanp->fi, EV_BC_REL, NULL); - break; - default: - printk(KERN_WARNING "lldata_handler unknown primitive %#x\n", - pr); - break; - } -} - -static void -lltrans_handler(struct PStack *st, int pr, void *arg) -{ - struct Channel *chanp = (struct Channel *) st->lli.userdata; - struct sk_buff *skb = arg; - - switch (pr) { - case (PH_DATA | INDICATION): - if (chanp->data_open) { - if (chanp->debug & 0x800) - link_debug(chanp, 0, "lltrans: %d", skb->len); - chanp->cs->iif.rcvcallb_skb(chanp->cs->myid, chanp->chan, skb); - } else { - link_debug(chanp, 0, "lltrans: channel not open"); - dev_kfree_skb(skb); - } - break; - case (PH_ACTIVATE | INDICATION): - case (PH_ACTIVATE | CONFIRM): - FsmEvent(&chanp->fi, EV_BC_EST, NULL); - break; - case (PH_DEACTIVATE | INDICATION): - case (PH_DEACTIVATE | CONFIRM): - FsmEvent(&chanp->fi, EV_BC_REL, NULL); - break; - default: - printk(KERN_WARNING "lltrans_handler unknown primitive %#x\n", - pr); - break; - } -} - -void -lli_writewakeup(struct PStack *st, int len) -{ - struct Channel *chanp = st->lli.userdata; - isdn_ctrl ic; - - if (chanp->debug & 0x800) - link_debug(chanp, 0, "llwakeup: %d", len); - ic.driver = chanp->cs->myid; - ic.command = ISDN_STAT_BSENT; - ic.arg = chanp->chan; - ic.parm.length = len; - chanp->cs->iif.statcallb(&ic); -} - -static int -init_b_st(struct Channel *chanp, int incoming) -{ - struct PStack *st = chanp->b_st; - struct IsdnCardState *cs = chanp->cs; - char tmp[16]; - - st->l1.hardware = cs; - if (chanp->leased) - st->l1.bc = chanp->chan & 1; - else - st->l1.bc = chanp->proc->para.bchannel - 1; - switch (chanp->l2_active_protocol) { - case (ISDN_PROTO_L2_X75I): - case (ISDN_PROTO_L2_HDLC): - st->l1.mode = L1_MODE_HDLC; - break; - case (ISDN_PROTO_L2_HDLC_56K): - st->l1.mode = L1_MODE_HDLC_56K; - break; - case (ISDN_PROTO_L2_TRANS): - st->l1.mode = L1_MODE_TRANS; - break; - case (ISDN_PROTO_L2_MODEM): - st->l1.mode = L1_MODE_V32; - break; - case (ISDN_PROTO_L2_FAX): - st->l1.mode = L1_MODE_FAX; - break; - } - chanp->bcs->conmsg = NULL; - if (chanp->bcs->BC_SetStack(st, chanp->bcs)) - return (-1); - st->l2.flag = 0; - test_and_set_bit(FLG_LAPB, &st->l2.flag); - st->l2.maxlen = MAX_DATA_SIZE; - if (!incoming) - test_and_set_bit(FLG_ORIG, &st->l2.flag); - st->l2.T200 = 1000; /* 1000 milliseconds */ - st->l2.window = 7; - st->l2.N200 = 4; /* try 4 times */ - st->l2.T203 = 5000; /* 5000 milliseconds */ - st->l3.debug = 0; - switch (chanp->l2_active_protocol) { - case (ISDN_PROTO_L2_X75I): - sprintf(tmp, "Ch%d X.75", chanp->chan); - setstack_isdnl2(st, tmp); - setstack_l3bc(st, chanp); - st->l2.l2l3 = lldata_handler; - st->lli.userdata = chanp; - test_and_clear_bit(FLG_LLI_L1WAKEUP, &st->lli.flag); - test_and_set_bit(FLG_LLI_L2WAKEUP, &st->lli.flag); - st->l2.l2m.debug = chanp->debug & 16; - st->l2.debug = chanp->debug & 64; - break; - case (ISDN_PROTO_L2_HDLC): - case (ISDN_PROTO_L2_HDLC_56K): - case (ISDN_PROTO_L2_TRANS): - case (ISDN_PROTO_L2_MODEM): - case (ISDN_PROTO_L2_FAX): - st->l1.l1l2 = lltrans_handler; - st->lli.userdata = chanp; - test_and_set_bit(FLG_LLI_L1WAKEUP, &st->lli.flag); - test_and_clear_bit(FLG_LLI_L2WAKEUP, &st->lli.flag); - setstack_transl2(st); - setstack_l3bc(st, chanp); - break; - } - test_and_set_bit(FLG_START_B, &chanp->Flags); - return (0); -} - -static void -leased_l4l3(struct PStack *st, int pr, void *arg) -{ - struct Channel *chanp = (struct Channel *) st->lli.userdata; - struct sk_buff *skb = arg; - - switch (pr) { - case (DL_DATA | REQUEST): - link_debug(chanp, 0, "leased line d-channel DATA"); - dev_kfree_skb(skb); - break; - case (DL_ESTABLISH | REQUEST): - st->l2.l2l1(st, PH_ACTIVATE | REQUEST, NULL); - break; - case (DL_RELEASE | REQUEST): - break; - default: - printk(KERN_WARNING "transd_l4l3 unknown primitive %#x\n", - pr); - break; - } -} - -static void -leased_l1l2(struct PStack *st, int pr, void *arg) -{ - struct Channel *chanp = (struct Channel *) st->lli.userdata; - struct sk_buff *skb = arg; - int i, event = EV_LEASED_REL; - - switch (pr) { - case (PH_DATA | INDICATION): - link_debug(chanp, 0, "leased line d-channel DATA"); - dev_kfree_skb(skb); - break; - case (PH_ACTIVATE | INDICATION): - case (PH_ACTIVATE | CONFIRM): - event = EV_LEASED; - /* fall through */ - case (PH_DEACTIVATE | INDICATION): - case (PH_DEACTIVATE | CONFIRM): - if (test_bit(FLG_TWO_DCHAN, &chanp->cs->HW_Flags)) - i = 1; - else - i = 0; - while (i < 2) { - FsmEvent(&chanp->fi, event, NULL); - chanp++; - i++; - } - break; - default: - printk(KERN_WARNING - "transd_l1l2 unknown primitive %#x\n", pr); - break; - } -} - -static void -distr_debug(struct IsdnCardState *csta, int debugflags) -{ - int i; - struct Channel *chanp = csta->channel; - - for (i = 0; i < (2 + MAX_WAITING_CALLS); i++) { - chanp[i].debug = debugflags; - chanp[i].fi.debug = debugflags & 2; - chanp[i].d_st->l2.l2m.debug = debugflags & 8; - chanp[i].b_st->l2.l2m.debug = debugflags & 0x10; - chanp[i].d_st->l2.debug = debugflags & 0x20; - chanp[i].b_st->l2.debug = debugflags & 0x40; - chanp[i].d_st->l3.l3m.debug = debugflags & 0x80; - chanp[i].b_st->l3.l3m.debug = debugflags & 0x100; - chanp[i].b_st->ma.tei_m.debug = debugflags & 0x200; - chanp[i].b_st->ma.debug = debugflags & 0x200; - chanp[i].d_st->l1.l1m.debug = debugflags & 0x1000; - chanp[i].b_st->l1.l1m.debug = debugflags & 0x2000; - } - if (debugflags & 4) - csta->debug |= DEB_DLOG_HEX; - else - csta->debug &= ~DEB_DLOG_HEX; -} - -static char tmpbuf[256]; - -static void -capi_debug(struct Channel *chanp, capi_msg *cm) -{ - char *t = tmpbuf; - - t += QuickHex(t, (u_char *)cm, (cm->Length > 50) ? 50 : cm->Length); - t--; - *t = 0; - HiSax_putstatus(chanp->cs, "Ch", "%d CAPIMSG %s", chanp->chan, tmpbuf); -} - -static void -lli_got_fac_req(struct Channel *chanp, capi_msg *cm) { - if ((cm->para[0] != 3) || (cm->para[1] != 0)) - return; - if (cm->para[2] < 3) - return; - if (cm->para[4] != 0) - return; - switch (cm->para[3]) { - case 4: /* Suspend */ - strncpy(chanp->setup.phone, &cm->para[5], cm->para[5] + 1); - FsmEvent(&chanp->fi, EV_SUSPEND, cm); - break; - case 5: /* Resume */ - strncpy(chanp->setup.phone, &cm->para[5], cm->para[5] + 1); - if (chanp->fi.state == ST_NULL) { - FsmEvent(&chanp->fi, EV_RESUME, cm); - } else { - FsmDelTimer(&chanp->dial_timer, 72); - FsmAddTimer(&chanp->dial_timer, 80, EV_RESUME, cm, 73); - } - break; - } -} - -static void -lli_got_manufacturer(struct Channel *chanp, struct IsdnCardState *cs, capi_msg *cm) { - if ((cs->typ == ISDN_CTYPE_ELSA) || (cs->typ == ISDN_CTYPE_ELSA_PNP) || - (cs->typ == ISDN_CTYPE_ELSA_PCI)) { - if (cs->hw.elsa.MFlag) { - cs->cardmsg(cs, CARD_AUX_IND, cm->para); - } - } -} - - -/***************************************************************/ -/* Limit the available number of channels for the current card */ -/***************************************************************/ -static int -set_channel_limit(struct IsdnCardState *cs, int chanmax) -{ - isdn_ctrl ic; - int i, ii; - - if ((chanmax < 0) || (chanmax > 2)) - return (-EINVAL); - cs->chanlimit = 0; - for (ii = 0; ii < 2; ii++) { - ic.driver = cs->myid; - ic.command = ISDN_STAT_DISCH; - ic.arg = ii; - if (ii >= chanmax) - ic.parm.num[0] = 0; /* disabled */ - else - ic.parm.num[0] = 1; /* enabled */ - i = cs->iif.statcallb(&ic); - if (i) return (-EINVAL); - if (ii < chanmax) - cs->chanlimit++; - } - return (0); -} /* set_channel_limit */ - -int -HiSax_command(isdn_ctrl *ic) -{ - struct IsdnCardState *csta = hisax_findcard(ic->driver); - struct PStack *st; - struct Channel *chanp; - int i; - u_int num; - - if (!csta) { - printk(KERN_ERR - "HiSax: if_command %d called with invalid driverId %d!\n", - ic->command, ic->driver); - return -ENODEV; - } - switch (ic->command) { - case (ISDN_CMD_SETEAZ): - chanp = csta->channel + ic->arg; - break; - case (ISDN_CMD_SETL2): - chanp = csta->channel + (ic->arg & 0xff); - if (chanp->debug & 1) - link_debug(chanp, 1, "SETL2 card %d %ld", - csta->cardnr + 1, ic->arg >> 8); - chanp->l2_protocol = ic->arg >> 8; - break; - case (ISDN_CMD_SETL3): - chanp = csta->channel + (ic->arg & 0xff); - if (chanp->debug & 1) - link_debug(chanp, 1, "SETL3 card %d %ld", - csta->cardnr + 1, ic->arg >> 8); - chanp->l3_protocol = ic->arg >> 8; - break; - case (ISDN_CMD_DIAL): - chanp = csta->channel + (ic->arg & 0xff); - if (chanp->debug & 1) - link_debug(chanp, 1, "DIAL %s -> %s (%d,%d)", - ic->parm.setup.eazmsn, ic->parm.setup.phone, - ic->parm.setup.si1, ic->parm.setup.si2); - memcpy(&chanp->setup, &ic->parm.setup, sizeof(setup_parm)); - if (!strcmp(chanp->setup.eazmsn, "0")) - chanp->setup.eazmsn[0] = '\0'; - /* this solution is dirty and may be change, if - * we make a callreference based callmanager */ - if (chanp->fi.state == ST_NULL) { - FsmEvent(&chanp->fi, EV_DIAL, NULL); - } else { - FsmDelTimer(&chanp->dial_timer, 70); - FsmAddTimer(&chanp->dial_timer, 50, EV_DIAL, NULL, 71); - } - break; - case (ISDN_CMD_ACCEPTB): - chanp = csta->channel + ic->arg; - if (chanp->debug & 1) - link_debug(chanp, 1, "ACCEPTB"); - FsmEvent(&chanp->fi, EV_ACCEPTB, NULL); - break; - case (ISDN_CMD_ACCEPTD): - chanp = csta->channel + ic->arg; - memcpy(&chanp->setup, &ic->parm.setup, sizeof(setup_parm)); - if (chanp->debug & 1) - link_debug(chanp, 1, "ACCEPTD"); - FsmEvent(&chanp->fi, EV_ACCEPTD, NULL); - break; - case (ISDN_CMD_HANGUP): - chanp = csta->channel + ic->arg; - if (chanp->debug & 1) - link_debug(chanp, 1, "HANGUP"); - FsmEvent(&chanp->fi, EV_HANGUP, NULL); - break; - case (CAPI_PUT_MESSAGE): - chanp = csta->channel + ic->arg; - if (chanp->debug & 1) - capi_debug(chanp, &ic->parm.cmsg); - if (ic->parm.cmsg.Length < 8) - break; - switch (ic->parm.cmsg.Command) { - case CAPI_FACILITY: - if (ic->parm.cmsg.Subcommand == CAPI_REQ) - lli_got_fac_req(chanp, &ic->parm.cmsg); - break; - case CAPI_MANUFACTURER: - if (ic->parm.cmsg.Subcommand == CAPI_REQ) - lli_got_manufacturer(chanp, csta, &ic->parm.cmsg); - break; - default: - break; - } - break; - case (ISDN_CMD_IOCTL): - switch (ic->arg) { - case (0): - num = *(unsigned int *) ic->parm.num; - HiSax_reportcard(csta->cardnr, num); - break; - case (1): - num = *(unsigned int *) ic->parm.num; - distr_debug(csta, num); - printk(KERN_DEBUG "HiSax: debugging flags card %d set to %x\n", - csta->cardnr + 1, num); - HiSax_putstatus(csta, "debugging flags ", - "card %d set to %x", csta->cardnr + 1, num); - break; - case (2): - num = *(unsigned int *) ic->parm.num; - csta->channel[0].b_st->l1.delay = num; - csta->channel[1].b_st->l1.delay = num; - HiSax_putstatus(csta, "delay ", "card %d set to %d ms", - csta->cardnr + 1, num); - printk(KERN_DEBUG "HiSax: delay card %d set to %d ms\n", - csta->cardnr + 1, num); - break; - case (5): /* set card in leased mode */ - num = *(unsigned int *) ic->parm.num; - if ((num < 1) || (num > 2)) { - HiSax_putstatus(csta, "Set LEASED ", - "wrong channel %d", num); - printk(KERN_WARNING "HiSax: Set LEASED wrong channel %d\n", - num); - } else { - num--; - chanp = csta->channel + num; - chanp->leased = 1; - HiSax_putstatus(csta, "Card", - "%d channel %d set leased mode\n", - csta->cardnr + 1, num + 1); - chanp->d_st->l1.l1l2 = leased_l1l2; - chanp->d_st->lli.l4l3 = leased_l4l3; - chanp->d_st->lli.l4l3(chanp->d_st, - DL_ESTABLISH | REQUEST, NULL); - } - break; - case (6): /* set B-channel test loop */ - num = *(unsigned int *) ic->parm.num; - if (csta->stlist) - csta->stlist->l2.l2l1(csta->stlist, - PH_TESTLOOP | REQUEST, (void *) (long)num); - break; - case (7): /* set card in PTP mode */ - num = *(unsigned int *) ic->parm.num; - if (test_bit(FLG_TWO_DCHAN, &csta->HW_Flags)) { - printk(KERN_ERR "HiSax PTP mode only with one TEI possible\n"); - } else if (num) { - test_and_set_bit(FLG_PTP, &csta->channel[0].d_st->l2.flag); - test_and_set_bit(FLG_FIXED_TEI, &csta->channel[0].d_st->l2.flag); - csta->channel[0].d_st->l2.tei = 0; - HiSax_putstatus(csta, "set card ", "in PTP mode"); - printk(KERN_DEBUG "HiSax: set card in PTP mode\n"); - printk(KERN_INFO "LAYER2 WATCHING ESTABLISH\n"); - csta->channel[0].d_st->lli.l4l3(csta->channel[0].d_st, - DL_ESTABLISH | REQUEST, NULL); - } else { - test_and_clear_bit(FLG_PTP, &csta->channel[0].d_st->l2.flag); - test_and_clear_bit(FLG_FIXED_TEI, &csta->channel[0].d_st->l2.flag); - HiSax_putstatus(csta, "set card ", "in PTMP mode"); - printk(KERN_DEBUG "HiSax: set card in PTMP mode\n"); - } - break; - case (8): /* set card in FIXED TEI mode */ - num = *(unsigned int *)ic->parm.num; - chanp = csta->channel + (num & 1); - num = num >> 1; - if (num == 127) { - test_and_clear_bit(FLG_FIXED_TEI, &chanp->d_st->l2.flag); - chanp->d_st->l2.tei = -1; - HiSax_putstatus(csta, "set card ", "in VAR TEI mode"); - printk(KERN_DEBUG "HiSax: set card in VAR TEI mode\n"); - } else { - test_and_set_bit(FLG_FIXED_TEI, &chanp->d_st->l2.flag); - chanp->d_st->l2.tei = num; - HiSax_putstatus(csta, "set card ", "in FIXED TEI (%d) mode", num); - printk(KERN_DEBUG "HiSax: set card in FIXED TEI (%d) mode\n", - num); - } - chanp->d_st->lli.l4l3(chanp->d_st, - DL_ESTABLISH | REQUEST, NULL); - break; - case (11): - num = csta->debug & DEB_DLOG_HEX; - csta->debug = *(unsigned int *) ic->parm.num; - csta->debug |= num; - HiSax_putstatus(cards[0].cs, "l1 debugging ", - "flags card %d set to %x", - csta->cardnr + 1, csta->debug); - printk(KERN_DEBUG "HiSax: l1 debugging flags card %d set to %x\n", - csta->cardnr + 1, csta->debug); - break; - case (13): - csta->channel[0].d_st->l3.debug = *(unsigned int *) ic->parm.num; - csta->channel[1].d_st->l3.debug = *(unsigned int *) ic->parm.num; - HiSax_putstatus(cards[0].cs, "l3 debugging ", - "flags card %d set to %x\n", csta->cardnr + 1, - *(unsigned int *) ic->parm.num); - printk(KERN_DEBUG "HiSax: l3 debugging flags card %d set to %x\n", - csta->cardnr + 1, *(unsigned int *) ic->parm.num); - break; - case (10): - i = *(unsigned int *) ic->parm.num; - return (set_channel_limit(csta, i)); - default: - if (csta->auxcmd) - return (csta->auxcmd(csta, ic)); - printk(KERN_DEBUG "HiSax: invalid ioctl %d\n", - (int) ic->arg); - return (-EINVAL); - } - break; - - case (ISDN_CMD_PROCEED): - chanp = csta->channel + ic->arg; - if (chanp->debug & 1) - link_debug(chanp, 1, "PROCEED"); - FsmEvent(&chanp->fi, EV_PROCEED, NULL); - break; - - case (ISDN_CMD_ALERT): - chanp = csta->channel + ic->arg; - if (chanp->debug & 1) - link_debug(chanp, 1, "ALERT"); - FsmEvent(&chanp->fi, EV_ALERT, NULL); - break; - - case (ISDN_CMD_REDIR): - chanp = csta->channel + ic->arg; - if (chanp->debug & 1) - link_debug(chanp, 1, "REDIR"); - memcpy(&chanp->setup, &ic->parm.setup, sizeof(setup_parm)); - FsmEvent(&chanp->fi, EV_REDIR, NULL); - break; - - /* protocol specific io commands */ - case (ISDN_CMD_PROT_IO): - for (st = csta->stlist; st; st = st->next) - if (st->protocol == (ic->arg & 0xFF)) - return (st->lli.l4l3_proto(st, ic)); - return (-EINVAL); - break; - default: - if (csta->auxcmd) - return (csta->auxcmd(csta, ic)); - return (-EINVAL); - } - return (0); -} - -int -HiSax_writebuf_skb(int id, int chan, int ack, struct sk_buff *skb) -{ - struct IsdnCardState *csta = hisax_findcard(id); - struct Channel *chanp; - struct PStack *st; - int len = skb->len; - struct sk_buff *nskb; - - if (!csta) { - printk(KERN_ERR - "HiSax: if_sendbuf called with invalid driverId!\n"); - return -ENODEV; - } - chanp = csta->channel + chan; - st = chanp->b_st; - if (!chanp->data_open) { - link_debug(chanp, 1, "writebuf: channel not open"); - return -EIO; - } - if (len > MAX_DATA_SIZE) { - link_debug(chanp, 1, "writebuf: packet too large (%d bytes)", len); - printk(KERN_WARNING "HiSax_writebuf: packet too large (%d bytes) !\n", - len); - return -EINVAL; - } - if (len) { - if ((len + chanp->bcs->tx_cnt) > MAX_DATA_MEM) { - /* Must return 0 here, since this is not an error - * but a temporary lack of resources. - */ - if (chanp->debug & 0x800) - link_debug(chanp, 1, "writebuf: no buffers for %d bytes", len); - return 0; - } else if (chanp->debug & 0x800) - link_debug(chanp, 1, "writebuf %d/%d/%d", len, chanp->bcs->tx_cnt, MAX_DATA_MEM); - nskb = skb_clone(skb, GFP_ATOMIC); - if (nskb) { - nskb->truesize = nskb->len; - if (!ack) - nskb->pkt_type = PACKET_NOACK; - if (chanp->l2_active_protocol == ISDN_PROTO_L2_X75I) - st->l3.l3l2(st, DL_DATA | REQUEST, nskb); - else { - chanp->bcs->tx_cnt += len; - st->l2.l2l1(st, PH_DATA | REQUEST, nskb); - } - dev_kfree_skb(skb); - } else - len = 0; - } - return (len); -} diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c deleted file mode 100644 index de965115a183..000000000000 --- a/drivers/isdn/hisax/config.c +++ /dev/null @@ -1,1993 +0,0 @@ -/* $Id: config.c,v 2.84.2.5 2004/02/11 13:21:33 keil Exp $ - * - * Author Karsten Keil - * Copyright by Karsten Keil <keil@isdn4linux.de> - * by Kai Germaschewski <kai.germaschewski@gmx.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * For changes and modifications please read - * Documentation/isdn/HiSax.cert - * - * based on the teles driver from Jan den Ouden - * - */ - -#include <linux/types.h> -#include <linux/stddef.h> -#include <linux/timer.h> -#include <linux/init.h> -#include "hisax.h" -#include <linux/module.h> -#include <linux/kernel_stat.h> -#include <linux/workqueue.h> -#include <linux/interrupt.h> -#include <linux/slab.h> -#define HISAX_STATUS_BUFSIZE 4096 - -/* - * This structure array contains one entry per card. An entry looks - * like this: - * - * { type, protocol, p0, p1, p2, NULL } - * - * type - * 1 Teles 16.0 p0=irq p1=membase p2=iobase - * 2 Teles 8.0 p0=irq p1=membase - * 3 Teles 16.3 p0=irq p1=iobase - * 4 Creatix PNP p0=irq p1=IO0 (ISAC) p2=IO1 (HSCX) - * 5 AVM A1 (Fritz) p0=irq p1=iobase - * 6 ELSA PC [p0=iobase] or nothing (autodetect) - * 7 ELSA Quickstep p0=irq p1=iobase - * 8 Teles PCMCIA p0=irq p1=iobase - * 9 ITK ix1-micro p0=irq p1=iobase - * 10 ELSA PCMCIA p0=irq p1=iobase - * 11 Eicon.Diehl Diva p0=irq p1=iobase - * 12 Asuscom ISDNLink p0=irq p1=iobase - * 13 Teleint p0=irq p1=iobase - * 14 Teles 16.3c p0=irq p1=iobase - * 15 Sedlbauer speed p0=irq p1=iobase - * 15 Sedlbauer PC/104 p0=irq p1=iobase - * 15 Sedlbauer speed pci no parameter - * 16 USR Sportster internal p0=irq p1=iobase - * 17 MIC card p0=irq p1=iobase - * 18 ELSA Quickstep 1000PCI no parameter - * 19 Compaq ISDN S0 ISA card p0=irq p1=IO0 (HSCX) p2=IO1 (ISAC) p3=IO2 - * 20 Travers Technologies NETjet-S PCI card - * 21 TELES PCI no parameter - * 22 Sedlbauer Speed Star p0=irq p1=iobase - * 23 reserved - * 24 Dr Neuhaus Niccy PnP/PCI card p0=irq p1=IO0 p2=IO1 (PnP only) - * 25 Teles S0Box p0=irq p1=iobase (from isapnp setup) - * 26 AVM A1 PCMCIA (Fritz) p0=irq p1=iobase - * 27 AVM PnP/PCI p0=irq p1=iobase (PCI no parameter) - * 28 Sedlbauer Speed Fax+ p0=irq p1=iobase (from isapnp setup) - * 29 Siemens I-Surf p0=irq p1=iobase p2=memory (from isapnp setup) - * 30 ACER P10 p0=irq p1=iobase (from isapnp setup) - * 31 HST Saphir p0=irq p1=iobase - * 32 Telekom A4T none - * 33 Scitel Quadro p0=subcontroller (4*S0, subctrl 1...4) - * 34 Gazel ISDN cards - * 35 HFC 2BDS0 PCI none - * 36 Winbond 6692 PCI none - * 37 HFC 2BDS0 S+/SP p0=irq p1=iobase - * 38 Travers Technologies NETspider-U PCI card - * 39 HFC 2BDS0-SP PCMCIA p0=irq p1=iobase - * 40 hotplug interface - * 41 Formula-n enter:now ISDN PCI a/b none - * - * protocol can be either ISDN_PTYPE_EURO or ISDN_PTYPE_1TR6 or ISDN_PTYPE_NI1 - * - * - */ - -const char *CardType[] = { - "No Card", "Teles 16.0", "Teles 8.0", "Teles 16.3", - "Creatix/Teles PnP", "AVM A1", "Elsa ML", "Elsa Quickstep", - "Teles PCMCIA", "ITK ix1-micro Rev.2", "Elsa PCMCIA", - "Eicon.Diehl Diva", "ISDNLink", "TeleInt", "Teles 16.3c", - "Sedlbauer Speed Card", "USR Sportster", "ith mic Linux", - "Elsa PCI", "Compaq ISA", "NETjet-S", "Teles PCI", - "Sedlbauer Speed Star (PCMCIA)", "AMD 7930", "NICCY", "S0Box", - "AVM A1 (PCMCIA)", "AVM Fritz PnP/PCI", "Sedlbauer Speed Fax +", - "Siemens I-Surf", "Acer P10", "HST Saphir", "Telekom A4T", - "Scitel Quadro", "Gazel", "HFC 2BDS0 PCI", "Winbond 6692", - "HFC 2BDS0 SX", "NETspider-U", "HFC-2BDS0-SP PCMCIA", - "Hotplug", "Formula-n enter:now PCI a/b", -}; - -#ifdef CONFIG_HISAX_ELSA -#define DEFAULT_CARD ISDN_CTYPE_ELSA -#define DEFAULT_CFG {0, 0, 0, 0} -#endif - -#ifdef CONFIG_HISAX_AVM_A1 -#undef DEFAULT_CARD -#undef DEFAULT_CFG -#define DEFAULT_CARD ISDN_CTYPE_A1 -#define DEFAULT_CFG {10, 0x340, 0, 0} -#endif - -#ifdef CONFIG_HISAX_AVM_A1_PCMCIA -#undef DEFAULT_CARD -#undef DEFAULT_CFG -#define DEFAULT_CARD ISDN_CTYPE_A1_PCMCIA -#define DEFAULT_CFG {11, 0x170, 0, 0} -#endif - -#ifdef CONFIG_HISAX_FRITZPCI -#undef DEFAULT_CARD -#undef DEFAULT_CFG -#define DEFAULT_CARD ISDN_CTYPE_FRITZPCI -#define DEFAULT_CFG {0, 0, 0, 0} -#endif - -#ifdef CONFIG_HISAX_16_3 -#undef DEFAULT_CARD -#undef DEFAULT_CFG -#define DEFAULT_CARD ISDN_CTYPE_16_3 -#define DEFAULT_CFG {15, 0x180, 0, 0} -#endif - -#ifdef CONFIG_HISAX_S0BOX -#undef DEFAULT_CARD -#undef DEFAULT_CFG -#define DEFAULT_CARD ISDN_CTYPE_S0BOX -#define DEFAULT_CFG {7, 0x378, 0, 0} -#endif - -#ifdef CONFIG_HISAX_16_0 -#undef DEFAULT_CARD -#undef DEFAULT_CFG -#define DEFAULT_CARD ISDN_CTYPE_16_0 -#define DEFAULT_CFG {15, 0xd0000, 0xd80, 0} -#endif - -#ifdef CONFIG_HISAX_TELESPCI -#undef DEFAULT_CARD -#undef DEFAULT_CFG -#define DEFAULT_CARD ISDN_CTYPE_TELESPCI -#define DEFAULT_CFG {0, 0, 0, 0} -#endif - -#ifdef CONFIG_HISAX_IX1MICROR2 -#undef DEFAULT_CARD -#undef DEFAULT_CFG -#define DEFAULT_CARD ISDN_CTYPE_IX1MICROR2 -#define DEFAULT_CFG {5, 0x390, 0, 0} -#endif - -#ifdef CONFIG_HISAX_DIEHLDIVA -#undef DEFAULT_CARD -#undef DEFAULT_CFG -#define DEFAULT_CARD ISDN_CTYPE_DIEHLDIVA -#define DEFAULT_CFG {0, 0x0, 0, 0} -#endif - -#ifdef CONFIG_HISAX_ASUSCOM -#undef DEFAULT_CARD -#undef DEFAULT_CFG -#define DEFAULT_CARD ISDN_CTYPE_ASUSCOM -#define DEFAULT_CFG {5, 0x200, 0, 0} -#endif - -#ifdef CONFIG_HISAX_TELEINT -#undef DEFAULT_CARD -#undef DEFAULT_CFG -#define DEFAULT_CARD ISDN_CTYPE_TELEINT -#define DEFAULT_CFG {5, 0x300, 0, 0} -#endif - -#ifdef CONFIG_HISAX_SEDLBAUER -#undef DEFAULT_CARD -#undef DEFAULT_CFG -#define DEFAULT_CARD ISDN_CTYPE_SEDLBAUER -#define DEFAULT_CFG {11, 0x270, 0, 0} -#endif - -#ifdef CONFIG_HISAX_SPORTSTER -#undef DEFAULT_CARD -#undef DEFAULT_CFG -#define DEFAULT_CARD ISDN_CTYPE_SPORTSTER -#define DEFAULT_CFG {7, 0x268, 0, 0} -#endif - -#ifdef CONFIG_HISAX_MIC -#undef DEFAULT_CARD -#undef DEFAULT_CFG -#define DEFAULT_CARD ISDN_CTYPE_MIC -#define DEFAULT_CFG {12, 0x3e0, 0, 0} -#endif - -#ifdef CONFIG_HISAX_NETJET -#undef DEFAULT_CARD -#undef DEFAULT_CFG -#define DEFAULT_CARD ISDN_CTYPE_NETJET_S -#define DEFAULT_CFG {0, 0, 0, 0} -#endif - -#ifdef CONFIG_HISAX_HFCS -#undef DEFAULT_CARD -#undef DEFAULT_CFG -#define DEFAULT_CARD ISDN_CTYPE_TELES3C -#define DEFAULT_CFG {5, 0x500, 0, 0} -#endif - -#ifdef CONFIG_HISAX_HFC_PCI -#undef DEFAULT_CARD -#undef DEFAULT_CFG -#define DEFAULT_CARD ISDN_CTYPE_HFC_PCI -#define DEFAULT_CFG {0, 0, 0, 0} -#endif - -#ifdef CONFIG_HISAX_HFC_SX -#undef DEFAULT_CARD -#undef DEFAULT_CFG -#define DEFAULT_CARD ISDN_CTYPE_HFC_SX -#define DEFAULT_CFG {5, 0x2E0, 0, 0} -#endif - -#ifdef CONFIG_HISAX_NICCY -#undef DEFAULT_CARD -#undef DEFAULT_CFG -#define DEFAULT_CARD ISDN_CTYPE_NICCY -#define DEFAULT_CFG {0, 0x0, 0, 0} -#endif - -#ifdef CONFIG_HISAX_ISURF -#undef DEFAULT_CARD -#undef DEFAULT_CFG -#define DEFAULT_CARD ISDN_CTYPE_ISURF -#define DEFAULT_CFG {5, 0x100, 0xc8000, 0} -#endif - -#ifdef CONFIG_HISAX_HSTSAPHIR -#undef DEFAULT_CARD -#undef DEFAULT_CFG -#define DEFAULT_CARD ISDN_CTYPE_HSTSAPHIR -#define DEFAULT_CFG {5, 0x250, 0, 0} -#endif - -#ifdef CONFIG_HISAX_BKM_A4T -#undef DEFAULT_CARD -#undef DEFAULT_CFG -#define DEFAULT_CARD ISDN_CTYPE_BKM_A4T -#define DEFAULT_CFG {0, 0x0, 0, 0} -#endif - -#ifdef CONFIG_HISAX_SCT_QUADRO -#undef DEFAULT_CARD -#undef DEFAULT_CFG -#define DEFAULT_CARD ISDN_CTYPE_SCT_QUADRO -#define DEFAULT_CFG {1, 0x0, 0, 0} -#endif - -#ifdef CONFIG_HISAX_GAZEL -#undef DEFAULT_CARD -#undef DEFAULT_CFG -#define DEFAULT_CARD ISDN_CTYPE_GAZEL -#define DEFAULT_CFG {15, 0x180, 0, 0} -#endif - -#ifdef CONFIG_HISAX_W6692 -#undef DEFAULT_CARD -#undef DEFAULT_CFG -#define DEFAULT_CARD ISDN_CTYPE_W6692 -#define DEFAULT_CFG {0, 0, 0, 0} -#endif - -#ifdef CONFIG_HISAX_NETJET_U -#undef DEFAULT_CARD -#undef DEFAULT_CFG -#define DEFAULT_CARD ISDN_CTYPE_NETJET_U -#define DEFAULT_CFG {0, 0, 0, 0} -#endif - -#ifdef CONFIG_HISAX_1TR6 -#define DEFAULT_PROTO ISDN_PTYPE_1TR6 -#define DEFAULT_PROTO_NAME "1TR6" -#endif -#ifdef CONFIG_HISAX_NI1 -#undef DEFAULT_PROTO -#define DEFAULT_PROTO ISDN_PTYPE_NI1 -#undef DEFAULT_PROTO_NAME -#define DEFAULT_PROTO_NAME "NI1" -#endif -#ifdef CONFIG_HISAX_EURO -#undef DEFAULT_PROTO -#define DEFAULT_PROTO ISDN_PTYPE_EURO -#undef DEFAULT_PROTO_NAME -#define DEFAULT_PROTO_NAME "EURO" -#endif -#ifndef DEFAULT_PROTO -#define DEFAULT_PROTO ISDN_PTYPE_UNKNOWN -#define DEFAULT_PROTO_NAME "UNKNOWN" -#endif -#ifndef DEFAULT_CARD -#define DEFAULT_CARD 0 -#define DEFAULT_CFG {0, 0, 0, 0} -#endif - -#define FIRST_CARD { \ - DEFAULT_CARD, \ - DEFAULT_PROTO, \ - DEFAULT_CFG, \ - NULL, \ - } - -struct IsdnCard cards[HISAX_MAX_CARDS] = { - FIRST_CARD, -}; - -#define HISAX_IDSIZE (HISAX_MAX_CARDS * 8) -static char HiSaxID[HISAX_IDSIZE] = { 0, }; - -static char *HiSax_id = HiSaxID; -#ifdef MODULE -/* Variables for insmod */ -static int type[HISAX_MAX_CARDS] = { 0, }; -static int protocol[HISAX_MAX_CARDS] = { 0, }; -static int io[HISAX_MAX_CARDS] = { 0, }; -#undef IO0_IO1 -#ifdef CONFIG_HISAX_16_3 -#define IO0_IO1 -#endif -#ifdef CONFIG_HISAX_NICCY -#undef IO0_IO1 -#define IO0_IO1 -#endif -#ifdef IO0_IO1 -static int io0[HISAX_MAX_CARDS] = { 0, }; -static int io1[HISAX_MAX_CARDS] = { 0, }; -#endif -static int irq[HISAX_MAX_CARDS] = { 0, }; -static int mem[HISAX_MAX_CARDS] = { 0, }; -static char *id = HiSaxID; - -MODULE_DESCRIPTION("ISDN4Linux: Driver for passive ISDN cards"); -MODULE_AUTHOR("Karsten Keil"); -MODULE_LICENSE("GPL"); -module_param_array(type, int, NULL, 0); -module_param_array(protocol, int, NULL, 0); -module_param_hw_array(io, int, ioport, NULL, 0); -module_param_hw_array(irq, int, irq, NULL, 0); -module_param_hw_array(mem, int, iomem, NULL, 0); -module_param(id, charp, 0); -#ifdef IO0_IO1 -module_param_hw_array(io0, int, ioport, NULL, 0); -module_param_hw_array(io1, int, ioport, NULL, 0); -#endif -#endif /* MODULE */ - -int nrcards; - -char *HiSax_getrev(const char *revision) -{ - char *rev; - char *p; - - if ((p = strchr(revision, ':'))) { - rev = p + 2; - p = strchr(rev, '$'); - *--p = 0; - } else - rev = "???"; - return rev; -} - -static void __init HiSaxVersion(void) -{ - char tmp[64]; - - printk(KERN_INFO "HiSax: Linux Driver for passive ISDN cards\n"); -#ifdef MODULE - printk(KERN_INFO "HiSax: Version 3.5 (module)\n"); -#else - printk(KERN_INFO "HiSax: Version 3.5 (kernel)\n"); -#endif - strcpy(tmp, l1_revision); - printk(KERN_INFO "HiSax: Layer1 Revision %s\n", HiSax_getrev(tmp)); - strcpy(tmp, l2_revision); - printk(KERN_INFO "HiSax: Layer2 Revision %s\n", HiSax_getrev(tmp)); - strcpy(tmp, tei_revision); - printk(KERN_INFO "HiSax: TeiMgr Revision %s\n", HiSax_getrev(tmp)); - strcpy(tmp, l3_revision); - printk(KERN_INFO "HiSax: Layer3 Revision %s\n", HiSax_getrev(tmp)); - strcpy(tmp, lli_revision); - printk(KERN_INFO "HiSax: LinkLayer Revision %s\n", - HiSax_getrev(tmp)); -} - -#ifndef MODULE -#define MAX_ARG (HISAX_MAX_CARDS * 5) -static int __init HiSax_setup(char *line) -{ - int i, j, argc; - int ints[MAX_ARG + 1]; - char *str; - - str = get_options(line, MAX_ARG, ints); - argc = ints[0]; - printk(KERN_DEBUG "HiSax_setup: argc(%d) str(%s)\n", argc, str); - i = 0; - j = 1; - while (argc && (i < HISAX_MAX_CARDS)) { - cards[i].protocol = DEFAULT_PROTO; - if (argc) { - cards[i].typ = ints[j]; - j++; - argc--; - } - if (argc) { - cards[i].protocol = ints[j]; - j++; - argc--; - } - if (argc) { - cards[i].para[0] = ints[j]; - j++; - argc--; - } - if (argc) { - cards[i].para[1] = ints[j]; - j++; - argc--; - } - if (argc) { - cards[i].para[2] = ints[j]; - j++; - argc--; - } - i++; - } - if (str && *str) { - if (strlen(str) < HISAX_IDSIZE) - strcpy(HiSaxID, str); - else - printk(KERN_WARNING "HiSax: ID too long!"); - } else - strcpy(HiSaxID, "HiSax"); - - HiSax_id = HiSaxID; - return 1; -} - -__setup("hisax=", HiSax_setup); -#endif /* MODULES */ - -#if CARD_TELES0 -extern int setup_teles0(struct IsdnCard *card); -#endif - -#if CARD_TELES3 -extern int setup_teles3(struct IsdnCard *card); -#endif - -#if CARD_S0BOX -extern int setup_s0box(struct IsdnCard *card); -#endif - -#if CARD_TELESPCI -extern int setup_telespci(struct IsdnCard *card); -#endif - -#if CARD_AVM_A1 -extern int setup_avm_a1(struct IsdnCard *card); -#endif - -#if CARD_AVM_A1_PCMCIA -extern int setup_avm_a1_pcmcia(struct IsdnCard *card); -#endif - -#if CARD_FRITZPCI -extern int setup_avm_pcipnp(struct IsdnCard *card); -#endif - -#if CARD_ELSA -extern int setup_elsa(struct IsdnCard *card); -#endif - -#if CARD_IX1MICROR2 -extern int setup_ix1micro(struct IsdnCard *card); -#endif - -#if CARD_DIEHLDIVA -extern int setup_diva(struct IsdnCard *card); -#endif - -#if CARD_ASUSCOM -extern int setup_asuscom(struct IsdnCard *card); -#endif - -#if CARD_TELEINT -extern int setup_TeleInt(struct IsdnCard *card); -#endif - -#if CARD_SEDLBAUER -extern int setup_sedlbauer(struct IsdnCard *card); -#endif - -#if CARD_SPORTSTER -extern int setup_sportster(struct IsdnCard *card); -#endif - -#if CARD_MIC -extern int setup_mic(struct IsdnCard *card); -#endif - -#if CARD_NETJET_S -extern int setup_netjet_s(struct IsdnCard *card); -#endif - -#if CARD_HFCS -extern int setup_hfcs(struct IsdnCard *card); -#endif - -#if CARD_HFC_PCI -extern int setup_hfcpci(struct IsdnCard *card); -#endif - -#if CARD_HFC_SX -extern int setup_hfcsx(struct IsdnCard *card); -#endif - -#if CARD_NICCY -extern int setup_niccy(struct IsdnCard *card); -#endif - -#if CARD_ISURF -extern int setup_isurf(struct IsdnCard *card); -#endif - -#if CARD_HSTSAPHIR -extern int setup_saphir(struct IsdnCard *card); -#endif - -#if CARD_BKM_A4T -extern int setup_bkm_a4t(struct IsdnCard *card); -#endif - -#if CARD_SCT_QUADRO -extern int setup_sct_quadro(struct IsdnCard *card); -#endif - -#if CARD_GAZEL -extern int setup_gazel(struct IsdnCard *card); -#endif - -#if CARD_W6692 -extern int setup_w6692(struct IsdnCard *card); -#endif - -#if CARD_NETJET_U -extern int setup_netjet_u(struct IsdnCard *card); -#endif - -#if CARD_FN_ENTERNOW_PCI -extern int setup_enternow_pci(struct IsdnCard *card); -#endif - -/* - * Find card with given driverId - */ -static inline struct IsdnCardState *hisax_findcard(int driverid) -{ - int i; - - for (i = 0; i < nrcards; i++) - if (cards[i].cs) - if (cards[i].cs->myid == driverid) - return cards[i].cs; - return NULL; -} - -/* - * Find card with given card number - */ -#if 0 -struct IsdnCardState *hisax_get_card(int cardnr) -{ - if ((cardnr <= nrcards) && (cardnr > 0)) - if (cards[cardnr - 1].cs) - return cards[cardnr - 1].cs; - return NULL; -} -#endif /* 0 */ - -static int HiSax_readstatus(u_char __user *buf, int len, int id, int channel) -{ - int count, cnt; - u_char __user *p = buf; - struct IsdnCardState *cs = hisax_findcard(id); - - if (cs) { - if (len > HISAX_STATUS_BUFSIZE) { - printk(KERN_WARNING - "HiSax: status overflow readstat %d/%d\n", - len, HISAX_STATUS_BUFSIZE); - } - count = cs->status_end - cs->status_read + 1; - if (count >= len) - count = len; - if (copy_to_user(p, cs->status_read, count)) - return -EFAULT; - cs->status_read += count; - if (cs->status_read > cs->status_end) - cs->status_read = cs->status_buf; - p += count; - count = len - count; - while (count) { - if (count > HISAX_STATUS_BUFSIZE) - cnt = HISAX_STATUS_BUFSIZE; - else - cnt = count; - if (copy_to_user(p, cs->status_read, cnt)) - return -EFAULT; - p += cnt; - cs->status_read += cnt % HISAX_STATUS_BUFSIZE; - count -= cnt; - } - return len; - } else { - printk(KERN_ERR - "HiSax: if_readstatus called with invalid driverId!\n"); - return -ENODEV; - } -} - -int jiftime(char *s, long mark) -{ - s += 8; - - *s-- = '\0'; - *s-- = mark % 10 + '0'; - mark /= 10; - *s-- = mark % 10 + '0'; - mark /= 10; - *s-- = '.'; - *s-- = mark % 10 + '0'; - mark /= 10; - *s-- = mark % 6 + '0'; - mark /= 6; - *s-- = ':'; - *s-- = mark % 10 + '0'; - mark /= 10; - *s-- = mark % 10 + '0'; - return 8; -} - -static u_char tmpbuf[HISAX_STATUS_BUFSIZE]; - -void VHiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, - va_list args) -{ - /* if head == NULL the fmt contains the full info */ - - u_long flags; - int count, i; - u_char *p; - isdn_ctrl ic; - int len; - const u_char *data; - - if (!cs) { - printk(KERN_WARNING "HiSax: No CardStatus for message"); - return; - } - spin_lock_irqsave(&cs->statlock, flags); - if (head) { - p = tmpbuf; - p += jiftime(p, jiffies); - p += sprintf(p, " %s", head); - p += vsprintf(p, fmt, args); - *p++ = '\n'; - *p = 0; - len = p - tmpbuf; - data = tmpbuf; - } else { - data = fmt; - len = strlen(fmt); - } - if (len > HISAX_STATUS_BUFSIZE) { - spin_unlock_irqrestore(&cs->statlock, flags); - printk(KERN_WARNING "HiSax: status overflow %d/%d\n", - len, HISAX_STATUS_BUFSIZE); - return; - } - count = len; - i = cs->status_end - cs->status_write + 1; - if (i >= len) - i = len; - len -= i; - memcpy(cs->status_write, data, i); - cs->status_write += i; - if (cs->status_write > cs->status_end) - cs->status_write = cs->status_buf; - if (len) { - memcpy(cs->status_write, data + i, len); - cs->status_write += len; - } -#ifdef KERNELSTACK_DEBUG - i = (ulong) & len - current->kernel_stack_page; - sprintf(tmpbuf, "kstack %s %lx use %ld\n", current->comm, - current->kernel_stack_page, i); - len = strlen(tmpbuf); - for (p = tmpbuf, i = len; i > 0; i--, p++) { - *cs->status_write++ = *p; - if (cs->status_write > cs->status_end) - cs->status_write = cs->status_buf; - count++; - } -#endif - spin_unlock_irqrestore(&cs->statlock, flags); - if (count) { - ic.command = ISDN_STAT_STAVAIL; - ic.driver = cs->myid; - ic.arg = count; - cs->iif.statcallb(&ic); - } -} - -void HiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - VHiSax_putstatus(cs, head, fmt, args); - va_end(args); -} - -int ll_run(struct IsdnCardState *cs, int addfeatures) -{ - isdn_ctrl ic; - - ic.driver = cs->myid; - ic.command = ISDN_STAT_RUN; - cs->iif.features |= addfeatures; - cs->iif.statcallb(&ic); - return 0; -} - -static void ll_stop(struct IsdnCardState *cs) -{ - isdn_ctrl ic; - - ic.command = ISDN_STAT_STOP; - ic.driver = cs->myid; - cs->iif.statcallb(&ic); - // CallcFreeChan(cs); -} - -static void ll_unload(struct IsdnCardState *cs) -{ - isdn_ctrl ic; - - ic.command = ISDN_STAT_UNLOAD; - ic.driver = cs->myid; - cs->iif.statcallb(&ic); - kfree(cs->status_buf); - cs->status_read = NULL; - cs->status_write = NULL; - cs->status_end = NULL; - kfree(cs->dlog); - cs->dlog = NULL; -} - -static void closecard(int cardnr) -{ - struct IsdnCardState *csta = cards[cardnr].cs; - - if (csta->bcs->BC_Close != NULL) { - csta->bcs->BC_Close(csta->bcs + 1); - csta->bcs->BC_Close(csta->bcs); - } - - skb_queue_purge(&csta->rq); - skb_queue_purge(&csta->sq); - kfree(csta->rcvbuf); - csta->rcvbuf = NULL; - if (csta->tx_skb) { - dev_kfree_skb(csta->tx_skb); - csta->tx_skb = NULL; - } - if (csta->DC_Close != NULL) { - csta->DC_Close(csta); - } - if (csta->cardmsg) - csta->cardmsg(csta, CARD_RELEASE, NULL); - if (csta->dbusytimer.function != NULL) // FIXME? - del_timer(&csta->dbusytimer); - ll_unload(csta); -} - -static irqreturn_t card_irq(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - irqreturn_t ret = cs->irq_func(intno, cs); - - if (ret == IRQ_HANDLED) - cs->irq_cnt++; - return ret; -} - -static int init_card(struct IsdnCardState *cs) -{ - int irq_cnt, cnt = 3, ret; - - if (!cs->irq) { - ret = cs->cardmsg(cs, CARD_INIT, NULL); - return (ret); - } - irq_cnt = cs->irq_cnt = 0; - printk(KERN_INFO "%s: IRQ %d count %d\n", CardType[cs->typ], - cs->irq, irq_cnt); - if (request_irq(cs->irq, card_irq, cs->irq_flags, "HiSax", cs)) { - printk(KERN_WARNING "HiSax: couldn't get interrupt %d\n", - cs->irq); - return 1; - } - while (cnt) { - cs->cardmsg(cs, CARD_INIT, NULL); - /* Timeout 10ms */ - msleep(10); - printk(KERN_INFO "%s: IRQ %d count %d\n", - CardType[cs->typ], cs->irq, cs->irq_cnt); - if (cs->irq_cnt == irq_cnt) { - printk(KERN_WARNING - "%s: IRQ(%d) getting no interrupts during init %d\n", - CardType[cs->typ], cs->irq, 4 - cnt); - if (cnt == 1) { - free_irq(cs->irq, cs); - return 2; - } else { - cs->cardmsg(cs, CARD_RESET, NULL); - cnt--; - } - } else { - cs->cardmsg(cs, CARD_TEST, NULL); - return 0; - } - } - return 3; -} - -static int hisax_cs_setup_card(struct IsdnCard *card) -{ - int ret; - - switch (card->typ) { -#if CARD_TELES0 - case ISDN_CTYPE_16_0: - case ISDN_CTYPE_8_0: - ret = setup_teles0(card); - break; -#endif -#if CARD_TELES3 - case ISDN_CTYPE_16_3: - case ISDN_CTYPE_PNP: - case ISDN_CTYPE_TELESPCMCIA: - case ISDN_CTYPE_COMPAQ_ISA: - ret = setup_teles3(card); - break; -#endif -#if CARD_S0BOX - case ISDN_CTYPE_S0BOX: - ret = setup_s0box(card); - break; -#endif -#if CARD_TELESPCI - case ISDN_CTYPE_TELESPCI: - ret = setup_telespci(card); - break; -#endif -#if CARD_AVM_A1 - case ISDN_CTYPE_A1: - ret = setup_avm_a1(card); - break; -#endif -#if CARD_AVM_A1_PCMCIA - case ISDN_CTYPE_A1_PCMCIA: - ret = setup_avm_a1_pcmcia(card); - break; -#endif -#if CARD_FRITZPCI - case ISDN_CTYPE_FRITZPCI: - ret = setup_avm_pcipnp(card); - break; -#endif -#if CARD_ELSA - case ISDN_CTYPE_ELSA: - case ISDN_CTYPE_ELSA_PNP: - case ISDN_CTYPE_ELSA_PCMCIA: - case ISDN_CTYPE_ELSA_PCI: - ret = setup_elsa(card); - break; -#endif -#if CARD_IX1MICROR2 - case ISDN_CTYPE_IX1MICROR2: - ret = setup_ix1micro(card); - break; -#endif -#if CARD_DIEHLDIVA - case ISDN_CTYPE_DIEHLDIVA: - ret = setup_diva(card); - break; -#endif -#if CARD_ASUSCOM - case ISDN_CTYPE_ASUSCOM: - ret = setup_asuscom(card); - break; -#endif -#if CARD_TELEINT - case ISDN_CTYPE_TELEINT: - ret = setup_TeleInt(card); - break; -#endif -#if CARD_SEDLBAUER - case ISDN_CTYPE_SEDLBAUER: - case ISDN_CTYPE_SEDLBAUER_PCMCIA: - case ISDN_CTYPE_SEDLBAUER_FAX: - ret = setup_sedlbauer(card); - break; -#endif -#if CARD_SPORTSTER - case ISDN_CTYPE_SPORTSTER: - ret = setup_sportster(card); - break; -#endif -#if CARD_MIC - case ISDN_CTYPE_MIC: - ret = setup_mic(card); - break; -#endif -#if CARD_NETJET_S - case ISDN_CTYPE_NETJET_S: - ret = setup_netjet_s(card); - break; -#endif -#if CARD_HFCS - case ISDN_CTYPE_TELES3C: - case ISDN_CTYPE_ACERP10: - ret = setup_hfcs(card); - break; -#endif -#if CARD_HFC_PCI - case ISDN_CTYPE_HFC_PCI: - ret = setup_hfcpci(card); - break; -#endif -#if CARD_HFC_SX - case ISDN_CTYPE_HFC_SX: - ret = setup_hfcsx(card); - break; -#endif -#if CARD_NICCY - case ISDN_CTYPE_NICCY: - ret = setup_niccy(card); - break; -#endif -#if CARD_ISURF - case ISDN_CTYPE_ISURF: - ret = setup_isurf(card); - break; -#endif -#if CARD_HSTSAPHIR - case ISDN_CTYPE_HSTSAPHIR: - ret = setup_saphir(card); - break; -#endif -#if CARD_BKM_A4T - case ISDN_CTYPE_BKM_A4T: - ret = setup_bkm_a4t(card); - break; -#endif -#if CARD_SCT_QUADRO - case ISDN_CTYPE_SCT_QUADRO: - ret = setup_sct_quadro(card); - break; -#endif -#if CARD_GAZEL - case ISDN_CTYPE_GAZEL: - ret = setup_gazel(card); - break; -#endif -#if CARD_W6692 - case ISDN_CTYPE_W6692: - ret = setup_w6692(card); - break; -#endif -#if CARD_NETJET_U - case ISDN_CTYPE_NETJET_U: - ret = setup_netjet_u(card); - break; -#endif -#if CARD_FN_ENTERNOW_PCI - case ISDN_CTYPE_ENTERNOW: - ret = setup_enternow_pci(card); - break; -#endif - case ISDN_CTYPE_DYNAMIC: - ret = 2; - break; - default: - printk(KERN_WARNING - "HiSax: Support for %s Card not selected\n", - CardType[card->typ]); - ret = 0; - break; - } - - return ret; -} - -static int hisax_cs_new(int cardnr, char *id, struct IsdnCard *card, - struct IsdnCardState **cs_out, int *busy_flag, - struct module *lockowner) -{ - struct IsdnCardState *cs; - - *cs_out = NULL; - - cs = kzalloc(sizeof(struct IsdnCardState), GFP_KERNEL); - if (!cs) { - printk(KERN_WARNING - "HiSax: No memory for IsdnCardState(card %d)\n", - cardnr + 1); - goto out; - } - card->cs = cs; - spin_lock_init(&cs->statlock); - spin_lock_init(&cs->lock); - cs->chanlimit = 2; /* maximum B-channel number */ - cs->logecho = 0; /* No echo logging */ - cs->cardnr = cardnr; - cs->debug = L1_DEB_WARN; - cs->HW_Flags = 0; - cs->busy_flag = busy_flag; - cs->irq_flags = I4L_IRQ_FLAG; -#if TEI_PER_CARD - if (card->protocol == ISDN_PTYPE_NI1) - test_and_set_bit(FLG_TWO_DCHAN, &cs->HW_Flags); -#else - test_and_set_bit(FLG_TWO_DCHAN, &cs->HW_Flags); -#endif - cs->protocol = card->protocol; - - if (card->typ <= 0 || card->typ > ISDN_CTYPE_COUNT) { - printk(KERN_WARNING - "HiSax: Card Type %d out of range\n", card->typ); - goto outf_cs; - } - if (!(cs->dlog = kmalloc(MAX_DLOG_SPACE, GFP_KERNEL))) { - printk(KERN_WARNING - "HiSax: No memory for dlog(card %d)\n", cardnr + 1); - goto outf_cs; - } - if (!(cs->status_buf = kmalloc(HISAX_STATUS_BUFSIZE, GFP_KERNEL))) { - printk(KERN_WARNING - "HiSax: No memory for status_buf(card %d)\n", - cardnr + 1); - goto outf_dlog; - } - cs->stlist = NULL; - cs->status_read = cs->status_buf; - cs->status_write = cs->status_buf; - cs->status_end = cs->status_buf + HISAX_STATUS_BUFSIZE - 1; - cs->typ = card->typ; -#ifdef MODULE - cs->iif.owner = lockowner; -#endif - strcpy(cs->iif.id, id); - cs->iif.channels = 2; - cs->iif.maxbufsize = MAX_DATA_SIZE; - cs->iif.hl_hdrlen = MAX_HEADER_LEN; - cs->iif.features = - ISDN_FEATURE_L2_X75I | - ISDN_FEATURE_L2_HDLC | - ISDN_FEATURE_L2_HDLC_56K | - ISDN_FEATURE_L2_TRANS | - ISDN_FEATURE_L3_TRANS | -#ifdef CONFIG_HISAX_1TR6 - ISDN_FEATURE_P_1TR6 | -#endif -#ifdef CONFIG_HISAX_EURO - ISDN_FEATURE_P_EURO | -#endif -#ifdef CONFIG_HISAX_NI1 - ISDN_FEATURE_P_NI1 | -#endif - 0; - - cs->iif.command = HiSax_command; - cs->iif.writecmd = NULL; - cs->iif.writebuf_skb = HiSax_writebuf_skb; - cs->iif.readstat = HiSax_readstatus; - register_isdn(&cs->iif); - cs->myid = cs->iif.channels; - - *cs_out = cs; - return 1; /* success */ - -outf_dlog: - kfree(cs->dlog); -outf_cs: - kfree(cs); - card->cs = NULL; -out: - return 0; /* error */ -} - -static int hisax_cs_setup(int cardnr, struct IsdnCard *card, - struct IsdnCardState *cs) -{ - int ret; - - if (!(cs->rcvbuf = kmalloc(MAX_DFRAME_LEN_L1, GFP_KERNEL))) { - printk(KERN_WARNING "HiSax: No memory for isac rcvbuf\n"); - ll_unload(cs); - goto outf_cs; - } - cs->rcvidx = 0; - cs->tx_skb = NULL; - cs->tx_cnt = 0; - cs->event = 0; - - skb_queue_head_init(&cs->rq); - skb_queue_head_init(&cs->sq); - - init_bcstate(cs, 0); - init_bcstate(cs, 1); - - /* init_card only handles interrupts which are not */ - /* used here for the loadable driver */ - switch (card->typ) { - case ISDN_CTYPE_DYNAMIC: - ret = 0; - break; - default: - ret = init_card(cs); - break; - } - if (ret) { - closecard(cardnr); - goto outf_cs; - } - init_tei(cs, cs->protocol); - ret = CallcNewChan(cs); - if (ret) { - closecard(cardnr); - goto outf_cs; - } - /* ISAR needs firmware download first */ - if (!test_bit(HW_ISAR, &cs->HW_Flags)) - ll_run(cs, 0); - - return 1; - -outf_cs: - kfree(cs); - card->cs = NULL; - return 0; -} - -static int checkcard(int cardnr, char *id, int *busy_flag, - struct module *lockowner, hisax_setup_func_t card_setup) -{ - int ret; - struct IsdnCard *card = cards + cardnr; - struct IsdnCardState *cs; - - ret = hisax_cs_new(cardnr, id, card, &cs, busy_flag, lockowner); - if (!ret) - return 0; - - printk(KERN_INFO - "HiSax: Card %d Protocol %s Id=%s (%d)\n", cardnr + 1, - (card->protocol == ISDN_PTYPE_1TR6) ? "1TR6" : - (card->protocol == ISDN_PTYPE_EURO) ? "EDSS1" : - (card->protocol == ISDN_PTYPE_LEASED) ? "LEASED" : - (card->protocol == ISDN_PTYPE_NI1) ? "NI1" : - "NONE", cs->iif.id, cs->myid); - - ret = card_setup(card); - if (!ret) { - ll_unload(cs); - goto outf_cs; - } - - ret = hisax_cs_setup(cardnr, card, cs); - goto out; - -outf_cs: - kfree(cs); - card->cs = NULL; -out: - return ret; -} - -static void HiSax_shiftcards(int idx) -{ - int i; - - for (i = idx; i < (HISAX_MAX_CARDS - 1); i++) - memcpy(&cards[i], &cards[i + 1], sizeof(cards[i])); -} - -static int __init HiSax_inithardware(int *busy_flag) -{ - int foundcards = 0; - int i = 0; - int t = ','; - int flg = 0; - char *id; - char *next_id = HiSax_id; - char ids[20]; - - if (strchr(HiSax_id, ',')) - t = ','; - else if (strchr(HiSax_id, '%')) - t = '%'; - - while (i < nrcards) { - if (cards[i].typ < 1) - break; - id = next_id; - if ((next_id = strchr(id, t))) { - *next_id++ = 0; - strcpy(ids, id); - flg = i + 1; - } else { - next_id = id; - if (flg >= i) - strcpy(ids, id); - else - sprintf(ids, "%s%d", id, i); - } - if (checkcard(i, ids, busy_flag, THIS_MODULE, - hisax_cs_setup_card)) { - foundcards++; - i++; - } else { - /* make sure we don't oops the module */ - if (cards[i].typ > 0 && cards[i].typ <= ISDN_CTYPE_COUNT) { - printk(KERN_WARNING - "HiSax: Card %s not installed !\n", - CardType[cards[i].typ]); - } - HiSax_shiftcards(i); - nrcards--; - } - } - return foundcards; -} - -void HiSax_closecard(int cardnr) -{ - int i, last = nrcards - 1; - - if (cardnr > last || cardnr < 0) - return; - if (cards[cardnr].cs) { - ll_stop(cards[cardnr].cs); - release_tei(cards[cardnr].cs); - CallcFreeChan(cards[cardnr].cs); - - closecard(cardnr); - if (cards[cardnr].cs->irq) - free_irq(cards[cardnr].cs->irq, cards[cardnr].cs); - kfree((void *) cards[cardnr].cs); - cards[cardnr].cs = NULL; - } - i = cardnr; - while (i <= last) { - cards[i] = cards[i + 1]; - i++; - } - nrcards--; -} - -void HiSax_reportcard(int cardnr, int sel) -{ - struct IsdnCardState *cs = cards[cardnr].cs; - - printk(KERN_DEBUG "HiSax: reportcard No %d\n", cardnr + 1); - printk(KERN_DEBUG "HiSax: Type %s\n", CardType[cs->typ]); - printk(KERN_DEBUG "HiSax: debuglevel %x\n", cs->debug); - printk(KERN_DEBUG "HiSax: HiSax_reportcard address 0x%px\n", - HiSax_reportcard); - printk(KERN_DEBUG "HiSax: cs 0x%px\n", cs); - printk(KERN_DEBUG "HiSax: HW_Flags %lx bc0 flg %lx bc1 flg %lx\n", - cs->HW_Flags, cs->bcs[0].Flag, cs->bcs[1].Flag); - printk(KERN_DEBUG "HiSax: bcs 0 mode %d ch%d\n", - cs->bcs[0].mode, cs->bcs[0].channel); - printk(KERN_DEBUG "HiSax: bcs 1 mode %d ch%d\n", - cs->bcs[1].mode, cs->bcs[1].channel); -#ifdef ERROR_STATISTIC - printk(KERN_DEBUG "HiSax: dc errors(rx,crc,tx) %d,%d,%d\n", - cs->err_rx, cs->err_crc, cs->err_tx); - printk(KERN_DEBUG - "HiSax: bc0 errors(inv,rdo,crc,tx) %d,%d,%d,%d\n", - cs->bcs[0].err_inv, cs->bcs[0].err_rdo, cs->bcs[0].err_crc, - cs->bcs[0].err_tx); - printk(KERN_DEBUG - "HiSax: bc1 errors(inv,rdo,crc,tx) %d,%d,%d,%d\n", - cs->bcs[1].err_inv, cs->bcs[1].err_rdo, cs->bcs[1].err_crc, - cs->bcs[1].err_tx); - if (sel == 99) { - cs->err_rx = 0; - cs->err_crc = 0; - cs->err_tx = 0; - cs->bcs[0].err_inv = 0; - cs->bcs[0].err_rdo = 0; - cs->bcs[0].err_crc = 0; - cs->bcs[0].err_tx = 0; - cs->bcs[1].err_inv = 0; - cs->bcs[1].err_rdo = 0; - cs->bcs[1].err_crc = 0; - cs->bcs[1].err_tx = 0; - } -#endif -} - -static int __init HiSax_init(void) -{ - int i, retval; -#ifdef MODULE - int j; - int nzproto = 0; -#endif - - HiSaxVersion(); - retval = CallcNew(); - if (retval) - goto out; - retval = Isdnl3New(); - if (retval) - goto out_callc; - retval = Isdnl2New(); - if (retval) - goto out_isdnl3; - retval = TeiNew(); - if (retval) - goto out_isdnl2; - retval = Isdnl1New(); - if (retval) - goto out_tei; - -#ifdef MODULE - if (!type[0]) { - /* We 'll register drivers later, but init basic functions */ - for (i = 0; i < HISAX_MAX_CARDS; i++) - cards[i].typ = 0; - return 0; - } -#ifdef CONFIG_HISAX_ELSA - if (type[0] == ISDN_CTYPE_ELSA_PCMCIA) { - /* we have exported and return in this case */ - return 0; - } -#endif -#ifdef CONFIG_HISAX_SEDLBAUER - if (type[0] == ISDN_CTYPE_SEDLBAUER_PCMCIA) { - /* we have to export and return in this case */ - return 0; - } -#endif -#ifdef CONFIG_HISAX_AVM_A1_PCMCIA - if (type[0] == ISDN_CTYPE_A1_PCMCIA) { - /* we have to export and return in this case */ - return 0; - } -#endif -#ifdef CONFIG_HISAX_HFC_SX - if (type[0] == ISDN_CTYPE_HFC_SP_PCMCIA) { - /* we have to export and return in this case */ - return 0; - } -#endif -#endif - nrcards = 0; -#ifdef MODULE - if (id) /* If id= string used */ - HiSax_id = id; - for (i = j = 0; j < HISAX_MAX_CARDS; i++) { - cards[j].typ = type[i]; - if (protocol[i]) { - cards[j].protocol = protocol[i]; - nzproto++; - } else { - cards[j].protocol = DEFAULT_PROTO; - } - switch (type[i]) { - case ISDN_CTYPE_16_0: - cards[j].para[0] = irq[i]; - cards[j].para[1] = mem[i]; - cards[j].para[2] = io[i]; - break; - - case ISDN_CTYPE_8_0: - cards[j].para[0] = irq[i]; - cards[j].para[1] = mem[i]; - break; - -#ifdef IO0_IO1 - case ISDN_CTYPE_PNP: - case ISDN_CTYPE_NICCY: - cards[j].para[0] = irq[i]; - cards[j].para[1] = io0[i]; - cards[j].para[2] = io1[i]; - break; - case ISDN_CTYPE_COMPAQ_ISA: - cards[j].para[0] = irq[i]; - cards[j].para[1] = io0[i]; - cards[j].para[2] = io1[i]; - cards[j].para[3] = io[i]; - break; -#endif - case ISDN_CTYPE_ELSA: - case ISDN_CTYPE_HFC_PCI: - cards[j].para[0] = io[i]; - break; - case ISDN_CTYPE_16_3: - case ISDN_CTYPE_TELESPCMCIA: - case ISDN_CTYPE_A1: - case ISDN_CTYPE_A1_PCMCIA: - case ISDN_CTYPE_ELSA_PNP: - case ISDN_CTYPE_ELSA_PCMCIA: - case ISDN_CTYPE_IX1MICROR2: - case ISDN_CTYPE_DIEHLDIVA: - case ISDN_CTYPE_ASUSCOM: - case ISDN_CTYPE_TELEINT: - case ISDN_CTYPE_SEDLBAUER: - case ISDN_CTYPE_SEDLBAUER_PCMCIA: - case ISDN_CTYPE_SEDLBAUER_FAX: - case ISDN_CTYPE_SPORTSTER: - case ISDN_CTYPE_MIC: - case ISDN_CTYPE_TELES3C: - case ISDN_CTYPE_ACERP10: - case ISDN_CTYPE_S0BOX: - case ISDN_CTYPE_FRITZPCI: - case ISDN_CTYPE_HSTSAPHIR: - case ISDN_CTYPE_GAZEL: - case ISDN_CTYPE_HFC_SX: - case ISDN_CTYPE_HFC_SP_PCMCIA: - cards[j].para[0] = irq[i]; - cards[j].para[1] = io[i]; - break; - case ISDN_CTYPE_ISURF: - cards[j].para[0] = irq[i]; - cards[j].para[1] = io[i]; - cards[j].para[2] = mem[i]; - break; - case ISDN_CTYPE_ELSA_PCI: - case ISDN_CTYPE_NETJET_S: - case ISDN_CTYPE_TELESPCI: - case ISDN_CTYPE_W6692: - case ISDN_CTYPE_NETJET_U: - break; - case ISDN_CTYPE_BKM_A4T: - break; - case ISDN_CTYPE_SCT_QUADRO: - if (irq[i]) { - cards[j].para[0] = irq[i]; - } else { - /* QUADRO is a 4 BRI card */ - cards[j++].para[0] = 1; - /* we need to check if further cards can be added */ - if (j < HISAX_MAX_CARDS) { - cards[j].typ = ISDN_CTYPE_SCT_QUADRO; - cards[j].protocol = protocol[i]; - cards[j++].para[0] = 2; - } - if (j < HISAX_MAX_CARDS) { - cards[j].typ = ISDN_CTYPE_SCT_QUADRO; - cards[j].protocol = protocol[i]; - cards[j++].para[0] = 3; - } - if (j < HISAX_MAX_CARDS) { - cards[j].typ = ISDN_CTYPE_SCT_QUADRO; - cards[j].protocol = protocol[i]; - cards[j].para[0] = 4; - } - } - break; - } - j++; - } - if (!nzproto) { - printk(KERN_WARNING - "HiSax: Warning - no protocol specified\n"); - printk(KERN_WARNING "HiSax: using protocol %s\n", - DEFAULT_PROTO_NAME); - } -#endif - if (!HiSax_id) - HiSax_id = HiSaxID; - if (!HiSaxID[0]) - strcpy(HiSaxID, "HiSax"); - for (i = 0; i < HISAX_MAX_CARDS; i++) - if (cards[i].typ > 0) - nrcards++; - printk(KERN_DEBUG "HiSax: Total %d card%s defined\n", - nrcards, (nrcards > 1) ? "s" : ""); - - /* Install only, if at least one card found */ - if (!HiSax_inithardware(NULL)) - return -ENODEV; - return 0; - -out_tei: - TeiFree(); -out_isdnl2: - Isdnl2Free(); -out_isdnl3: - Isdnl3Free(); -out_callc: - CallcFree(); -out: - return retval; -} - -static void __exit HiSax_exit(void) -{ - int cardnr = nrcards - 1; - - while (cardnr >= 0) - HiSax_closecard(cardnr--); - Isdnl1Free(); - TeiFree(); - Isdnl2Free(); - Isdnl3Free(); - CallcFree(); - printk(KERN_INFO "HiSax module removed\n"); -} - -int hisax_init_pcmcia(void *pcm_iob, int *busy_flag, struct IsdnCard *card) -{ - u_char ids[16]; - int ret = -1; - - cards[nrcards] = *card; - if (nrcards) - sprintf(ids, "HiSax%d", nrcards); - else - sprintf(ids, "HiSax"); - if (!checkcard(nrcards, ids, busy_flag, THIS_MODULE, - hisax_cs_setup_card)) - goto error; - - ret = nrcards; - nrcards++; -error: - return ret; -} -EXPORT_SYMBOL(hisax_init_pcmcia); - -EXPORT_SYMBOL(HiSax_closecard); - -#include "hisax_if.h" - -EXPORT_SYMBOL(hisax_register); -EXPORT_SYMBOL(hisax_unregister); - -static void hisax_d_l1l2(struct hisax_if *ifc, int pr, void *arg); -static void hisax_b_l1l2(struct hisax_if *ifc, int pr, void *arg); -static void hisax_d_l2l1(struct PStack *st, int pr, void *arg); -static void hisax_b_l2l1(struct PStack *st, int pr, void *arg); -static int hisax_cardmsg(struct IsdnCardState *cs, int mt, void *arg); -static int hisax_bc_setstack(struct PStack *st, struct BCState *bcs); -static void hisax_bc_close(struct BCState *bcs); -static void hisax_bh(struct work_struct *work); -static void EChannel_proc_rcv(struct hisax_d_if *d_if); - -static int hisax_setup_card_dynamic(struct IsdnCard *card) -{ - return 2; -} - -int hisax_register(struct hisax_d_if *hisax_d_if, struct hisax_b_if *b_if[], - char *name, int protocol) -{ - int i, retval; - char id[20]; - struct IsdnCardState *cs; - - for (i = 0; i < HISAX_MAX_CARDS; i++) { - if (!cards[i].typ) - break; - } - - if (i >= HISAX_MAX_CARDS) - return -EBUSY; - - cards[i].typ = ISDN_CTYPE_DYNAMIC; - cards[i].protocol = protocol; - sprintf(id, "%s%d", name, i); - nrcards++; - retval = checkcard(i, id, NULL, hisax_d_if->owner, - hisax_setup_card_dynamic); - if (retval == 0) { // yuck - cards[i].typ = 0; - nrcards--; - return -EINVAL; - } - cs = cards[i].cs; - hisax_d_if->cs = cs; - cs->hw.hisax_d_if = hisax_d_if; - cs->cardmsg = hisax_cardmsg; - INIT_WORK(&cs->tqueue, hisax_bh); - cs->channel[0].d_st->l2.l2l1 = hisax_d_l2l1; - for (i = 0; i < 2; i++) { - cs->bcs[i].BC_SetStack = hisax_bc_setstack; - cs->bcs[i].BC_Close = hisax_bc_close; - - b_if[i]->ifc.l1l2 = hisax_b_l1l2; - - hisax_d_if->b_if[i] = b_if[i]; - } - hisax_d_if->ifc.l1l2 = hisax_d_l1l2; - skb_queue_head_init(&hisax_d_if->erq); - clear_bit(0, &hisax_d_if->ph_state); - - return 0; -} - -void hisax_unregister(struct hisax_d_if *hisax_d_if) -{ - cards[hisax_d_if->cs->cardnr].typ = 0; - HiSax_closecard(hisax_d_if->cs->cardnr); - skb_queue_purge(&hisax_d_if->erq); -} - -#include "isdnl1.h" - -static void hisax_sched_event(struct IsdnCardState *cs, int event) -{ - test_and_set_bit(event, &cs->event); - schedule_work(&cs->tqueue); -} - -static void hisax_bh(struct work_struct *work) -{ - struct IsdnCardState *cs = - container_of(work, struct IsdnCardState, tqueue); - struct PStack *st; - int pr; - - if (test_and_clear_bit(D_RCVBUFREADY, &cs->event)) - DChannel_proc_rcv(cs); - if (test_and_clear_bit(E_RCVBUFREADY, &cs->event)) - EChannel_proc_rcv(cs->hw.hisax_d_if); - if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) { - if (test_bit(0, &cs->hw.hisax_d_if->ph_state)) - pr = PH_ACTIVATE | INDICATION; - else - pr = PH_DEACTIVATE | INDICATION; - for (st = cs->stlist; st; st = st->next) - st->l1.l1l2(st, pr, NULL); - - } -} - -static void hisax_b_sched_event(struct BCState *bcs, int event) -{ - test_and_set_bit(event, &bcs->event); - schedule_work(&bcs->tqueue); -} - -static inline void D_L2L1(struct hisax_d_if *d_if, int pr, void *arg) -{ - struct hisax_if *ifc = (struct hisax_if *) d_if; - ifc->l2l1(ifc, pr, arg); -} - -static inline void B_L2L1(struct hisax_b_if *b_if, int pr, void *arg) -{ - struct hisax_if *ifc = (struct hisax_if *) b_if; - ifc->l2l1(ifc, pr, arg); -} - -static void hisax_d_l1l2(struct hisax_if *ifc, int pr, void *arg) -{ - struct hisax_d_if *d_if = (struct hisax_d_if *) ifc; - struct IsdnCardState *cs = d_if->cs; - struct PStack *st; - struct sk_buff *skb; - - switch (pr) { - case PH_ACTIVATE | INDICATION: - set_bit(0, &d_if->ph_state); - hisax_sched_event(cs, D_L1STATECHANGE); - break; - case PH_DEACTIVATE | INDICATION: - clear_bit(0, &d_if->ph_state); - hisax_sched_event(cs, D_L1STATECHANGE); - break; - case PH_DATA | INDICATION: - skb_queue_tail(&cs->rq, arg); - hisax_sched_event(cs, D_RCVBUFREADY); - break; - case PH_DATA | CONFIRM: - skb = skb_dequeue(&cs->sq); - if (skb) { - D_L2L1(d_if, PH_DATA | REQUEST, skb); - break; - } - clear_bit(FLG_L1_DBUSY, &cs->HW_Flags); - for (st = cs->stlist; st; st = st->next) { - if (test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags)) { - st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); - break; - } - } - break; - case PH_DATA_E | INDICATION: - skb_queue_tail(&d_if->erq, arg); - hisax_sched_event(cs, E_RCVBUFREADY); - break; - default: - printk("pr %#x\n", pr); - break; - } -} - -static void hisax_b_l1l2(struct hisax_if *ifc, int pr, void *arg) -{ - struct hisax_b_if *b_if = (struct hisax_b_if *) ifc; - struct BCState *bcs = b_if->bcs; - struct PStack *st = bcs->st; - struct sk_buff *skb; - - // FIXME use isdnl1? - switch (pr) { - case PH_ACTIVATE | INDICATION: - st->l1.l1l2(st, pr, NULL); - break; - case PH_DEACTIVATE | INDICATION: - st->l1.l1l2(st, pr, NULL); - clear_bit(BC_FLG_BUSY, &bcs->Flag); - skb_queue_purge(&bcs->squeue); - bcs->hw.b_if = NULL; - break; - case PH_DATA | INDICATION: - skb_queue_tail(&bcs->rqueue, arg); - hisax_b_sched_event(bcs, B_RCVBUFREADY); - break; - case PH_DATA | CONFIRM: - bcs->tx_cnt -= (long)arg; - if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag)) { - u_long flags; - spin_lock_irqsave(&bcs->aclock, flags); - bcs->ackcnt += (long)arg; - spin_unlock_irqrestore(&bcs->aclock, flags); - schedule_event(bcs, B_ACKPENDING); - } - skb = skb_dequeue(&bcs->squeue); - if (skb) { - B_L2L1(b_if, PH_DATA | REQUEST, skb); - break; - } - clear_bit(BC_FLG_BUSY, &bcs->Flag); - if (test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags)) { - st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); - } - break; - default: - printk("hisax_b_l1l2 pr %#x\n", pr); - break; - } -} - -static void hisax_d_l2l1(struct PStack *st, int pr, void *arg) -{ - struct IsdnCardState *cs = st->l1.hardware; - struct hisax_d_if *hisax_d_if = cs->hw.hisax_d_if; - struct sk_buff *skb = arg; - - switch (pr) { - case PH_DATA | REQUEST: - case PH_PULL | INDICATION: - if (cs->debug & DEB_DLOG_HEX) - LogFrame(cs, skb->data, skb->len); - if (cs->debug & DEB_DLOG_VERBOSE) - dlogframe(cs, skb, 0); - Logl2Frame(cs, skb, "PH_DATA_REQ", 0); - // FIXME lock? - if (!test_and_set_bit(FLG_L1_DBUSY, &cs->HW_Flags)) - D_L2L1(hisax_d_if, PH_DATA | REQUEST, skb); - else - skb_queue_tail(&cs->sq, skb); - break; - case PH_PULL | REQUEST: - if (!test_bit(FLG_L1_DBUSY, &cs->HW_Flags)) - st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); - else - set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - break; - default: - D_L2L1(hisax_d_if, pr, arg); - break; - } -} - -static int hisax_cardmsg(struct IsdnCardState *cs, int mt, void *arg) -{ - return 0; -} - -static void hisax_b_l2l1(struct PStack *st, int pr, void *arg) -{ - struct BCState *bcs = st->l1.bcs; - struct hisax_b_if *b_if = bcs->hw.b_if; - - switch (pr) { - case PH_ACTIVATE | REQUEST: - B_L2L1(b_if, pr, (void *)(unsigned long)st->l1.mode); - break; - case PH_DATA | REQUEST: - case PH_PULL | INDICATION: - // FIXME lock? - if (!test_and_set_bit(BC_FLG_BUSY, &bcs->Flag)) { - B_L2L1(b_if, PH_DATA | REQUEST, arg); - } else { - skb_queue_tail(&bcs->squeue, arg); - } - break; - case PH_PULL | REQUEST: - if (!test_bit(BC_FLG_BUSY, &bcs->Flag)) - st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); - else - set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - break; - case PH_DEACTIVATE | REQUEST: - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - skb_queue_purge(&bcs->squeue); - /* fall through */ - default: - B_L2L1(b_if, pr, arg); - break; - } -} - -static int hisax_bc_setstack(struct PStack *st, struct BCState *bcs) -{ - struct IsdnCardState *cs = st->l1.hardware; - struct hisax_d_if *hisax_d_if = cs->hw.hisax_d_if; - - bcs->channel = st->l1.bc; - - bcs->hw.b_if = hisax_d_if->b_if[st->l1.bc]; - hisax_d_if->b_if[st->l1.bc]->bcs = bcs; - - st->l1.bcs = bcs; - st->l2.l2l1 = hisax_b_l2l1; - setstack_manager(st); - bcs->st = st; - setstack_l1_B(st); - skb_queue_head_init(&bcs->rqueue); - skb_queue_head_init(&bcs->squeue); - return 0; -} - -static void hisax_bc_close(struct BCState *bcs) -{ - struct hisax_b_if *b_if = bcs->hw.b_if; - - if (b_if) - B_L2L1(b_if, PH_DEACTIVATE | REQUEST, NULL); -} - -static void EChannel_proc_rcv(struct hisax_d_if *d_if) -{ - struct IsdnCardState *cs = d_if->cs; - u_char *ptr; - struct sk_buff *skb; - - while ((skb = skb_dequeue(&d_if->erq)) != NULL) { - if (cs->debug & DEB_DLOG_HEX) { - ptr = cs->dlog; - if ((skb->len) < MAX_DLOG_SPACE / 3 - 10) { - *ptr++ = 'E'; - *ptr++ = 'C'; - *ptr++ = 'H'; - *ptr++ = 'O'; - *ptr++ = ':'; - ptr += QuickHex(ptr, skb->data, skb->len); - ptr--; - *ptr++ = '\n'; - *ptr = 0; - HiSax_putstatus(cs, NULL, cs->dlog); - } else - HiSax_putstatus(cs, "LogEcho: ", - "warning Frame too big (%d)", - skb->len); - } - dev_kfree_skb_any(skb); - } -} - -#ifdef CONFIG_PCI -#include <linux/pci.h> - -static const struct pci_device_id hisax_pci_tbl[] __used = { -#ifdef CONFIG_HISAX_FRITZPCI - {PCI_VDEVICE(AVM, PCI_DEVICE_ID_AVM_A1) }, -#endif -#ifdef CONFIG_HISAX_DIEHLDIVA - {PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA20) }, - {PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA20_U) }, - {PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA201) }, -/*##########################################################################*/ - {PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA202) }, -/*##########################################################################*/ -#endif -#ifdef CONFIG_HISAX_ELSA - {PCI_VDEVICE(ELSA, PCI_DEVICE_ID_ELSA_MICROLINK) }, - {PCI_VDEVICE(ELSA, PCI_DEVICE_ID_ELSA_QS3000) }, -#endif -#ifdef CONFIG_HISAX_GAZEL - {PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_R685) }, - {PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_R753) }, - {PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_DJINN_ITOO) }, - {PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_OLITEC) }, -#endif -#ifdef CONFIG_HISAX_SCT_QUADRO - {PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_9050) }, -#endif -#ifdef CONFIG_HISAX_NICCY - {PCI_VDEVICE(SATSAGEM, PCI_DEVICE_ID_SATSAGEM_NICCY) }, -#endif -#ifdef CONFIG_HISAX_SEDLBAUER - {PCI_VDEVICE(TIGERJET, PCI_DEVICE_ID_TIGERJET_100) }, -#endif -#if defined(CONFIG_HISAX_NETJET) || defined(CONFIG_HISAX_NETJET_U) - {PCI_VDEVICE(TIGERJET, PCI_DEVICE_ID_TIGERJET_300) }, -#endif -#if defined(CONFIG_HISAX_TELESPCI) || defined(CONFIG_HISAX_SCT_QUADRO) - {PCI_VDEVICE(ZORAN, PCI_DEVICE_ID_ZORAN_36120) }, -#endif -#ifdef CONFIG_HISAX_W6692 - {PCI_VDEVICE(DYNALINK, PCI_DEVICE_ID_DYNALINK_IS64PH) }, - {PCI_VDEVICE(WINBOND2, PCI_DEVICE_ID_WINBOND2_6692) }, -#endif -#ifdef CONFIG_HISAX_HFC_PCI - {PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_2BD0) }, - {PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B000) }, - {PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B006) }, - {PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B007) }, - {PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B008) }, - {PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B009) }, - {PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B00A) }, - {PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B00B) }, - {PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B00C) }, - {PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B100) }, - {PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B700) }, - {PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B701) }, - {PCI_VDEVICE(ABOCOM, PCI_DEVICE_ID_ABOCOM_2BD1) }, - {PCI_VDEVICE(ASUSTEK, PCI_DEVICE_ID_ASUSTEK_0675) }, - {PCI_VDEVICE(BERKOM, PCI_DEVICE_ID_BERKOM_T_CONCEPT) }, - {PCI_VDEVICE(BERKOM, PCI_DEVICE_ID_BERKOM_A1T) }, - {PCI_VDEVICE(ANIGMA, PCI_DEVICE_ID_ANIGMA_MC145575) }, - {PCI_VDEVICE(ZOLTRIX, PCI_DEVICE_ID_ZOLTRIX_2BD0) }, - {PCI_VDEVICE(DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_E) }, - {PCI_VDEVICE(DIGI, PCI_DEVICE_ID_DIGI_DF_M_E) }, - {PCI_VDEVICE(DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_A) }, - {PCI_VDEVICE(DIGI, PCI_DEVICE_ID_DIGI_DF_M_A) }, -#endif - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE(pci, hisax_pci_tbl); -#endif /* CONFIG_PCI */ - -module_init(HiSax_init); -module_exit(HiSax_exit); - -EXPORT_SYMBOL(FsmNew); -EXPORT_SYMBOL(FsmFree); -EXPORT_SYMBOL(FsmEvent); -EXPORT_SYMBOL(FsmChangeState); -EXPORT_SYMBOL(FsmInitTimer); -EXPORT_SYMBOL(FsmDelTimer); -EXPORT_SYMBOL(FsmRestartTimer); diff --git a/drivers/isdn/hisax/diva.c b/drivers/isdn/hisax/diva.c deleted file mode 100644 index d23df7a7784d..000000000000 --- a/drivers/isdn/hisax/diva.c +++ /dev/null @@ -1,1282 +0,0 @@ -/* $Id: diva.c,v 1.33.2.6 2004/02/11 13:21:33 keil Exp $ - * - * low level stuff for Eicon.Diehl Diva Family ISDN cards - * - * Author Karsten Keil - * Copyright by Karsten Keil <keil@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * For changes and modifications please read - * Documentation/isdn/HiSax.cert - * - * Thanks to Eicon Technology for documents and information - * - */ - -#include <linux/init.h> -#include "hisax.h" -#include "isac.h" -#include "hscx.h" -#include "ipac.h" -#include "ipacx.h" -#include "isdnl1.h" -#include <linux/pci.h> -#include <linux/isapnp.h> - -static const char *Diva_revision = "$Revision: 1.33.2.6 $"; - -#define byteout(addr, val) outb(val, addr) -#define bytein(addr) inb(addr) - -#define DIVA_HSCX_DATA 0 -#define DIVA_HSCX_ADR 4 -#define DIVA_ISA_ISAC_DATA 2 -#define DIVA_ISA_ISAC_ADR 6 -#define DIVA_ISA_CTRL 7 -#define DIVA_IPAC_ADR 0 -#define DIVA_IPAC_DATA 1 - -#define DIVA_PCI_ISAC_DATA 8 -#define DIVA_PCI_ISAC_ADR 0xc -#define DIVA_PCI_CTRL 0x10 - -/* SUB Types */ -#define DIVA_ISA 1 -#define DIVA_PCI 2 -#define DIVA_IPAC_ISA 3 -#define DIVA_IPAC_PCI 4 -#define DIVA_IPACX_PCI 5 - -/* CTRL (Read) */ -#define DIVA_IRQ_STAT 0x01 -#define DIVA_EEPROM_SDA 0x02 - -/* CTRL (Write) */ -#define DIVA_IRQ_REQ 0x01 -#define DIVA_RESET 0x08 -#define DIVA_EEPROM_CLK 0x40 -#define DIVA_PCI_LED_A 0x10 -#define DIVA_PCI_LED_B 0x20 -#define DIVA_ISA_LED_A 0x20 -#define DIVA_ISA_LED_B 0x40 -#define DIVA_IRQ_CLR 0x80 - -/* Siemens PITA */ -#define PITA_MISC_REG 0x1c -#ifdef __BIG_ENDIAN -#define PITA_PARA_SOFTRESET 0x00000001 -#define PITA_SER_SOFTRESET 0x00000002 -#define PITA_PARA_MPX_MODE 0x00000004 -#define PITA_INT0_ENABLE 0x00000200 -#else -#define PITA_PARA_SOFTRESET 0x01000000 -#define PITA_SER_SOFTRESET 0x02000000 -#define PITA_PARA_MPX_MODE 0x04000000 -#define PITA_INT0_ENABLE 0x00020000 -#endif -#define PITA_INT0_STATUS 0x02 - -static inline u_char -readreg(unsigned int ale, unsigned int adr, u_char off) -{ - register u_char ret; - - byteout(ale, off); - ret = bytein(adr); - return (ret); -} - -static inline void -readfifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size) -{ - byteout(ale, off); - insb(adr, data, size); -} - - -static inline void -writereg(unsigned int ale, unsigned int adr, u_char off, u_char data) -{ - byteout(ale, off); - byteout(adr, data); -} - -static inline void -writefifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size) -{ - byteout(ale, off); - outsb(adr, data, size); -} - -static inline u_char -memreadreg(unsigned long adr, u_char off) -{ - return (*((unsigned char *) - (((unsigned int *)adr) + off))); -} - -static inline void -memwritereg(unsigned long adr, u_char off, u_char data) -{ - register u_char *p; - - p = (unsigned char *)(((unsigned int *)adr) + off); - *p = data; -} - -/* Interface functions */ - -static u_char -ReadISAC(struct IsdnCardState *cs, u_char offset) -{ - return (readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset)); -} - -static void -WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value) -{ - writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset, value); -} - -static void -ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - readfifo(cs->hw.diva.isac_adr, cs->hw.diva.isac, 0, data, size); -} - -static void -WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - writefifo(cs->hw.diva.isac_adr, cs->hw.diva.isac, 0, data, size); -} - -static u_char -ReadISAC_IPAC(struct IsdnCardState *cs, u_char offset) -{ - return (readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset + 0x80)); -} - -static void -WriteISAC_IPAC(struct IsdnCardState *cs, u_char offset, u_char value) -{ - writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset | 0x80, value); -} - -static void -ReadISACfifo_IPAC(struct IsdnCardState *cs, u_char *data, int size) -{ - readfifo(cs->hw.diva.isac_adr, cs->hw.diva.isac, 0x80, data, size); -} - -static void -WriteISACfifo_IPAC(struct IsdnCardState *cs, u_char *data, int size) -{ - writefifo(cs->hw.diva.isac_adr, cs->hw.diva.isac, 0x80, data, size); -} - -static u_char -ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset) -{ - return (readreg(cs->hw.diva.hscx_adr, - cs->hw.diva.hscx, offset + (hscx ? 0x40 : 0))); -} - -static void -WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) -{ - writereg(cs->hw.diva.hscx_adr, - cs->hw.diva.hscx, offset + (hscx ? 0x40 : 0), value); -} - -static u_char -MemReadISAC_IPAC(struct IsdnCardState *cs, u_char offset) -{ - return (memreadreg(cs->hw.diva.cfg_reg, offset + 0x80)); -} - -static void -MemWriteISAC_IPAC(struct IsdnCardState *cs, u_char offset, u_char value) -{ - memwritereg(cs->hw.diva.cfg_reg, offset | 0x80, value); -} - -static void -MemReadISACfifo_IPAC(struct IsdnCardState *cs, u_char *data, int size) -{ - while (size--) - *data++ = memreadreg(cs->hw.diva.cfg_reg, 0x80); -} - -static void -MemWriteISACfifo_IPAC(struct IsdnCardState *cs, u_char *data, int size) -{ - while (size--) - memwritereg(cs->hw.diva.cfg_reg, 0x80, *data++); -} - -static u_char -MemReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset) -{ - return (memreadreg(cs->hw.diva.cfg_reg, offset + (hscx ? 0x40 : 0))); -} - -static void -MemWriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) -{ - memwritereg(cs->hw.diva.cfg_reg, offset + (hscx ? 0x40 : 0), value); -} - -/* IO-Functions for IPACX type cards */ -static u_char -MemReadISAC_IPACX(struct IsdnCardState *cs, u_char offset) -{ - return (memreadreg(cs->hw.diva.cfg_reg, offset)); -} - -static void -MemWriteISAC_IPACX(struct IsdnCardState *cs, u_char offset, u_char value) -{ - memwritereg(cs->hw.diva.cfg_reg, offset, value); -} - -static void -MemReadISACfifo_IPACX(struct IsdnCardState *cs, u_char *data, int size) -{ - while (size--) - *data++ = memreadreg(cs->hw.diva.cfg_reg, 0); -} - -static void -MemWriteISACfifo_IPACX(struct IsdnCardState *cs, u_char *data, int size) -{ - while (size--) - memwritereg(cs->hw.diva.cfg_reg, 0, *data++); -} - -static u_char -MemReadHSCX_IPACX(struct IsdnCardState *cs, int hscx, u_char offset) -{ - return (memreadreg(cs->hw.diva.cfg_reg, offset + - (hscx ? IPACX_OFF_B2 : IPACX_OFF_B1))); -} - -static void -MemWriteHSCX_IPACX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) -{ - memwritereg(cs->hw.diva.cfg_reg, offset + - (hscx ? IPACX_OFF_B2 : IPACX_OFF_B1), value); -} - -/* - * fast interrupt HSCX stuff goes here - */ - -#define READHSCX(cs, nr, reg) readreg(cs->hw.diva.hscx_adr, \ - cs->hw.diva.hscx, reg + (nr ? 0x40 : 0)) -#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.diva.hscx_adr, \ - cs->hw.diva.hscx, reg + (nr ? 0x40 : 0), data) - -#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.diva.hscx_adr, \ - cs->hw.diva.hscx, (nr ? 0x40 : 0), ptr, cnt) - -#define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.diva.hscx_adr, \ - cs->hw.diva.hscx, (nr ? 0x40 : 0), ptr, cnt) - -#include "hscx_irq.c" - -static irqreturn_t -diva_interrupt(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - u_char val, sval; - u_long flags; - int cnt = 5; - - spin_lock_irqsave(&cs->lock, flags); - while (((sval = bytein(cs->hw.diva.ctrl)) & DIVA_IRQ_REQ) && cnt) { - val = readreg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_ISTA + 0x40); - if (val) - hscx_int_main(cs, val); - val = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, ISAC_ISTA); - if (val) - isac_interrupt(cs, val); - cnt--; - } - if (!cnt) - printk(KERN_WARNING "Diva: IRQ LOOP\n"); - writereg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_MASK, 0xFF); - writereg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_MASK + 0x40, 0xFF); - writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, ISAC_MASK, 0xFF); - writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, ISAC_MASK, 0x0); - writereg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_MASK, 0x0); - writereg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_MASK + 0x40, 0x0); - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -static irqreturn_t -diva_irq_ipac_isa(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - u_char ista, val; - u_long flags; - int icnt = 5; - - spin_lock_irqsave(&cs->lock, flags); - ista = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_ISTA); -Start_IPACISA: - if (cs->debug & L1_DEB_IPAC) - debugl1(cs, "IPAC ISTA %02X", ista); - if (ista & 0x0f) { - val = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, HSCX_ISTA + 0x40); - if (ista & 0x01) - val |= 0x01; - if (ista & 0x04) - val |= 0x02; - if (ista & 0x08) - val |= 0x04; - if (val) - hscx_int_main(cs, val); - } - if (ista & 0x20) { - val = 0xfe & readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, ISAC_ISTA + 0x80); - if (val) { - isac_interrupt(cs, val); - } - } - if (ista & 0x10) { - val = 0x01; - isac_interrupt(cs, val); - } - ista = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_ISTA); - if ((ista & 0x3f) && icnt) { - icnt--; - goto Start_IPACISA; - } - if (!icnt) - printk(KERN_WARNING "DIVA IPAC IRQ LOOP\n"); - writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_MASK, 0xFF); - writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_MASK, 0xC0); - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -static inline void -MemwaitforCEC(struct IsdnCardState *cs, int hscx) -{ - int to = 50; - - while ((MemReadHSCX(cs, hscx, HSCX_STAR) & 0x04) && to) { - udelay(1); - to--; - } - if (!to) - printk(KERN_WARNING "HiSax: waitforCEC timeout\n"); -} - - -static inline void -MemwaitforXFW(struct IsdnCardState *cs, int hscx) -{ - int to = 50; - - while (((MemReadHSCX(cs, hscx, HSCX_STAR) & 0x44) != 0x40) && to) { - udelay(1); - to--; - } - if (!to) - printk(KERN_WARNING "HiSax: waitforXFW timeout\n"); -} - -static inline void -MemWriteHSCXCMDR(struct IsdnCardState *cs, int hscx, u_char data) -{ - MemwaitforCEC(cs, hscx); - MemWriteHSCX(cs, hscx, HSCX_CMDR, data); -} - -static void -Memhscx_empty_fifo(struct BCState *bcs, int count) -{ - u_char *ptr; - struct IsdnCardState *cs = bcs->cs; - int cnt; - - if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) - debugl1(cs, "hscx_empty_fifo"); - - if (bcs->hw.hscx.rcvidx + count > HSCX_BUFMAX) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "hscx_empty_fifo: incoming packet too large"); - MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x80); - bcs->hw.hscx.rcvidx = 0; - return; - } - ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx; - cnt = count; - while (cnt--) - *ptr++ = memreadreg(cs->hw.diva.cfg_reg, bcs->hw.hscx.hscx ? 0x40 : 0); - MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x80); - ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx; - bcs->hw.hscx.rcvidx += count; - if (cs->debug & L1_DEB_HSCX_FIFO) { - char *t = bcs->blog; - - t += sprintf(t, "hscx_empty_fifo %c cnt %d", - bcs->hw.hscx.hscx ? 'B' : 'A', count); - QuickHex(t, ptr, count); - debugl1(cs, "%s", bcs->blog); - } -} - -static void -Memhscx_fill_fifo(struct BCState *bcs) -{ - struct IsdnCardState *cs = bcs->cs; - int more, count, cnt; - int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags) ? 64 : 32; - u_char *ptr, *p; - - if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) - debugl1(cs, "hscx_fill_fifo"); - - if (!bcs->tx_skb) - return; - if (bcs->tx_skb->len <= 0) - return; - - more = (bcs->mode == L1_MODE_TRANS) ? 1 : 0; - if (bcs->tx_skb->len > fifo_size) { - more = !0; - count = fifo_size; - } else - count = bcs->tx_skb->len; - cnt = count; - MemwaitforXFW(cs, bcs->hw.hscx.hscx); - p = ptr = bcs->tx_skb->data; - skb_pull(bcs->tx_skb, count); - bcs->tx_cnt -= count; - bcs->hw.hscx.count += count; - while (cnt--) - memwritereg(cs->hw.diva.cfg_reg, bcs->hw.hscx.hscx ? 0x40 : 0, - *p++); - MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, more ? 0x8 : 0xa); - if (cs->debug & L1_DEB_HSCX_FIFO) { - char *t = bcs->blog; - - t += sprintf(t, "hscx_fill_fifo %c cnt %d", - bcs->hw.hscx.hscx ? 'B' : 'A', count); - QuickHex(t, ptr, count); - debugl1(cs, "%s", bcs->blog); - } -} - -static void -Memhscx_interrupt(struct IsdnCardState *cs, u_char val, u_char hscx) -{ - u_char r; - struct BCState *bcs = cs->bcs + hscx; - struct sk_buff *skb; - int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags) ? 64 : 32; - int count; - - if (!test_bit(BC_FLG_INIT, &bcs->Flag)) - return; - - if (val & 0x80) { /* RME */ - r = MemReadHSCX(cs, hscx, HSCX_RSTA); - if ((r & 0xf0) != 0xa0) { - if (!(r & 0x80)) - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "HSCX invalid frame"); - if ((r & 0x40) && bcs->mode) - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "HSCX RDO mode=%d", - bcs->mode); - if (!(r & 0x20)) - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "HSCX CRC error"); - MemWriteHSCXCMDR(cs, hscx, 0x80); - } else { - count = MemReadHSCX(cs, hscx, HSCX_RBCL) & ( - test_bit(HW_IPAC, &cs->HW_Flags) ? 0x3f : 0x1f); - if (count == 0) - count = fifo_size; - Memhscx_empty_fifo(bcs, count); - if ((count = bcs->hw.hscx.rcvidx - 1) > 0) { - if (cs->debug & L1_DEB_HSCX_FIFO) - debugl1(cs, "HX Frame %d", count); - if (!(skb = dev_alloc_skb(count))) - printk(KERN_WARNING "HSCX: receive out of memory\n"); - else { - skb_put_data(skb, bcs->hw.hscx.rcvbuf, - count); - skb_queue_tail(&bcs->rqueue, skb); - } - } - } - bcs->hw.hscx.rcvidx = 0; - schedule_event(bcs, B_RCVBUFREADY); - } - if (val & 0x40) { /* RPF */ - Memhscx_empty_fifo(bcs, fifo_size); - if (bcs->mode == L1_MODE_TRANS) { - /* receive audio data */ - if (!(skb = dev_alloc_skb(fifo_size))) - printk(KERN_WARNING "HiSax: receive out of memory\n"); - else { - skb_put_data(skb, bcs->hw.hscx.rcvbuf, - fifo_size); - skb_queue_tail(&bcs->rqueue, skb); - } - bcs->hw.hscx.rcvidx = 0; - schedule_event(bcs, B_RCVBUFREADY); - } - } - if (val & 0x10) { /* XPR */ - if (bcs->tx_skb) { - if (bcs->tx_skb->len) { - Memhscx_fill_fifo(bcs); - return; - } else { - if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) && - (PACKET_NOACK != bcs->tx_skb->pkt_type)) { - u_long flags; - spin_lock_irqsave(&bcs->aclock, flags); - bcs->ackcnt += bcs->hw.hscx.count; - spin_unlock_irqrestore(&bcs->aclock, flags); - schedule_event(bcs, B_ACKPENDING); - } - dev_kfree_skb_irq(bcs->tx_skb); - bcs->hw.hscx.count = 0; - bcs->tx_skb = NULL; - } - } - if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) { - bcs->hw.hscx.count = 0; - test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); - Memhscx_fill_fifo(bcs); - } else { - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - schedule_event(bcs, B_XMTBUFREADY); - } - } -} - -static inline void -Memhscx_int_main(struct IsdnCardState *cs, u_char val) -{ - - u_char exval; - struct BCState *bcs; - - if (val & 0x01) { // EXB - bcs = cs->bcs + 1; - exval = MemReadHSCX(cs, 1, HSCX_EXIR); - if (exval & 0x40) { - if (bcs->mode == 1) - Memhscx_fill_fifo(bcs); - else { - /* Here we lost an TX interrupt, so - * restart transmitting the whole frame. - */ - if (bcs->tx_skb) { - skb_push(bcs->tx_skb, bcs->hw.hscx.count); - bcs->tx_cnt += bcs->hw.hscx.count; - bcs->hw.hscx.count = 0; - } - MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x01); - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "HSCX B EXIR %x Lost TX", exval); - } - } else if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "HSCX B EXIR %x", exval); - } - if (val & 0xf8) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "HSCX B interrupt %x", val); - Memhscx_interrupt(cs, val, 1); - } - if (val & 0x02) { // EXA - bcs = cs->bcs; - exval = MemReadHSCX(cs, 0, HSCX_EXIR); - if (exval & 0x40) { - if (bcs->mode == L1_MODE_TRANS) - Memhscx_fill_fifo(bcs); - else { - /* Here we lost an TX interrupt, so - * restart transmitting the whole frame. - */ - if (bcs->tx_skb) { - skb_push(bcs->tx_skb, bcs->hw.hscx.count); - bcs->tx_cnt += bcs->hw.hscx.count; - bcs->hw.hscx.count = 0; - } - MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x01); - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "HSCX A EXIR %x Lost TX", exval); - } - } else if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "HSCX A EXIR %x", exval); - } - if (val & 0x04) { // ICA - exval = MemReadHSCX(cs, 0, HSCX_ISTA); - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "HSCX A interrupt %x", exval); - Memhscx_interrupt(cs, exval, 0); - } -} - -static irqreturn_t -diva_irq_ipac_pci(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - u_char ista, val; - int icnt = 5; - u_char *cfg; - u_long flags; - - spin_lock_irqsave(&cs->lock, flags); - cfg = (u_char *) cs->hw.diva.pci_cfg; - val = *cfg; - if (!(val & PITA_INT0_STATUS)) { - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_NONE; /* other shared IRQ */ - } - *cfg = PITA_INT0_STATUS; /* Reset pending INT0 */ - ista = memreadreg(cs->hw.diva.cfg_reg, IPAC_ISTA); -Start_IPACPCI: - if (cs->debug & L1_DEB_IPAC) - debugl1(cs, "IPAC ISTA %02X", ista); - if (ista & 0x0f) { - val = memreadreg(cs->hw.diva.cfg_reg, HSCX_ISTA + 0x40); - if (ista & 0x01) - val |= 0x01; - if (ista & 0x04) - val |= 0x02; - if (ista & 0x08) - val |= 0x04; - if (val) - Memhscx_int_main(cs, val); - } - if (ista & 0x20) { - val = 0xfe & memreadreg(cs->hw.diva.cfg_reg, ISAC_ISTA + 0x80); - if (val) { - isac_interrupt(cs, val); - } - } - if (ista & 0x10) { - val = 0x01; - isac_interrupt(cs, val); - } - ista = memreadreg(cs->hw.diva.cfg_reg, IPAC_ISTA); - if ((ista & 0x3f) && icnt) { - icnt--; - goto Start_IPACPCI; - } - if (!icnt) - printk(KERN_WARNING "DIVA IPAC PCI IRQ LOOP\n"); - memwritereg(cs->hw.diva.cfg_reg, IPAC_MASK, 0xFF); - memwritereg(cs->hw.diva.cfg_reg, IPAC_MASK, 0xC0); - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -static irqreturn_t -diva_irq_ipacx_pci(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - u_char val; - u_char *cfg; - u_long flags; - - spin_lock_irqsave(&cs->lock, flags); - cfg = (u_char *) cs->hw.diva.pci_cfg; - val = *cfg; - if (!(val & PITA_INT0_STATUS)) { - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_NONE; // other shared IRQ - } - interrupt_ipacx(cs); // handler for chip - *cfg = PITA_INT0_STATUS; // Reset PLX interrupt - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -static void -release_io_diva(struct IsdnCardState *cs) -{ - int bytecnt; - - if ((cs->subtyp == DIVA_IPAC_PCI) || - (cs->subtyp == DIVA_IPACX_PCI)) { - u_int *cfg = (unsigned int *)cs->hw.diva.pci_cfg; - - *cfg = 0; /* disable INT0/1 */ - *cfg = 2; /* reset pending INT0 */ - if (cs->hw.diva.cfg_reg) - iounmap((void *)cs->hw.diva.cfg_reg); - if (cs->hw.diva.pci_cfg) - iounmap((void *)cs->hw.diva.pci_cfg); - return; - } else if (cs->subtyp != DIVA_IPAC_ISA) { - del_timer(&cs->hw.diva.tl); - if (cs->hw.diva.cfg_reg) - byteout(cs->hw.diva.ctrl, 0); /* LED off, Reset */ - } - if ((cs->subtyp == DIVA_ISA) || (cs->subtyp == DIVA_IPAC_ISA)) - bytecnt = 8; - else - bytecnt = 32; - if (cs->hw.diva.cfg_reg) { - release_region(cs->hw.diva.cfg_reg, bytecnt); - } -} - -static void -iounmap_diva(struct IsdnCardState *cs) -{ - if ((cs->subtyp == DIVA_IPAC_PCI) || (cs->subtyp == DIVA_IPACX_PCI)) { - if (cs->hw.diva.cfg_reg) { - iounmap((void *)cs->hw.diva.cfg_reg); - cs->hw.diva.cfg_reg = 0; - } - if (cs->hw.diva.pci_cfg) { - iounmap((void *)cs->hw.diva.pci_cfg); - cs->hw.diva.pci_cfg = 0; - } - } - - return; -} - -static void -reset_diva(struct IsdnCardState *cs) -{ - if (cs->subtyp == DIVA_IPAC_ISA) { - writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_POTA2, 0x20); - mdelay(10); - writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_POTA2, 0x00); - mdelay(10); - writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_MASK, 0xc0); - } else if (cs->subtyp == DIVA_IPAC_PCI) { - unsigned int *ireg = (unsigned int *)(cs->hw.diva.pci_cfg + - PITA_MISC_REG); - *ireg = PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE; - mdelay(10); - *ireg = PITA_PARA_MPX_MODE; - mdelay(10); - memwritereg(cs->hw.diva.cfg_reg, IPAC_MASK, 0xc0); - } else if (cs->subtyp == DIVA_IPACX_PCI) { - unsigned int *ireg = (unsigned int *)(cs->hw.diva.pci_cfg + - PITA_MISC_REG); - *ireg = PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE; - mdelay(10); - *ireg = PITA_PARA_MPX_MODE | PITA_SER_SOFTRESET; - mdelay(10); - MemWriteISAC_IPACX(cs, IPACX_MASK, 0xff); // Interrupts off - } else { /* DIVA 2.0 */ - cs->hw.diva.ctrl_reg = 0; /* Reset On */ - byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg); - mdelay(10); - cs->hw.diva.ctrl_reg |= DIVA_RESET; /* Reset Off */ - byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg); - mdelay(10); - if (cs->subtyp == DIVA_ISA) - cs->hw.diva.ctrl_reg |= DIVA_ISA_LED_A; - else { - /* Workaround PCI9060 */ - byteout(cs->hw.diva.pci_cfg + 0x69, 9); - cs->hw.diva.ctrl_reg |= DIVA_PCI_LED_A; - } - byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg); - } -} - -#define DIVA_ASSIGN 1 - -static void -diva_led_handler(struct timer_list *t) -{ - struct IsdnCardState *cs = from_timer(cs, t, hw.diva.tl); - int blink = 0; - - if ((cs->subtyp == DIVA_IPAC_ISA) || - (cs->subtyp == DIVA_IPAC_PCI) || - (cs->subtyp == DIVA_IPACX_PCI)) - return; - del_timer(&cs->hw.diva.tl); - if (cs->hw.diva.status & DIVA_ASSIGN) - cs->hw.diva.ctrl_reg |= (DIVA_ISA == cs->subtyp) ? - DIVA_ISA_LED_A : DIVA_PCI_LED_A; - else { - cs->hw.diva.ctrl_reg ^= (DIVA_ISA == cs->subtyp) ? - DIVA_ISA_LED_A : DIVA_PCI_LED_A; - blink = 250; - } - if (cs->hw.diva.status & 0xf000) - cs->hw.diva.ctrl_reg |= (DIVA_ISA == cs->subtyp) ? - DIVA_ISA_LED_B : DIVA_PCI_LED_B; - else if (cs->hw.diva.status & 0x0f00) { - cs->hw.diva.ctrl_reg ^= (DIVA_ISA == cs->subtyp) ? - DIVA_ISA_LED_B : DIVA_PCI_LED_B; - blink = 500; - } else - cs->hw.diva.ctrl_reg &= ~((DIVA_ISA == cs->subtyp) ? - DIVA_ISA_LED_B : DIVA_PCI_LED_B); - - byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg); - if (blink) { - cs->hw.diva.tl.expires = jiffies + ((blink * HZ) / 1000); - add_timer(&cs->hw.diva.tl); - } -} - -static int -Diva_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - u_int *ireg; - u_long flags; - - switch (mt) { - case CARD_RESET: - spin_lock_irqsave(&cs->lock, flags); - reset_diva(cs); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_RELEASE: - release_io_diva(cs); - return (0); - case CARD_INIT: - spin_lock_irqsave(&cs->lock, flags); - reset_diva(cs); - if (cs->subtyp == DIVA_IPACX_PCI) { - ireg = (unsigned int *)cs->hw.diva.pci_cfg; - *ireg = PITA_INT0_ENABLE; - init_ipacx(cs, 3); // init chip and enable interrupts - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - } - if (cs->subtyp == DIVA_IPAC_PCI) { - ireg = (unsigned int *)cs->hw.diva.pci_cfg; - *ireg = PITA_INT0_ENABLE; - } - inithscxisac(cs, 3); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_TEST: - return (0); - case (MDL_REMOVE | REQUEST): - cs->hw.diva.status = 0; - break; - case (MDL_ASSIGN | REQUEST): - cs->hw.diva.status |= DIVA_ASSIGN; - break; - case MDL_INFO_SETUP: - if ((long)arg) - cs->hw.diva.status |= 0x0200; - else - cs->hw.diva.status |= 0x0100; - break; - case MDL_INFO_CONN: - if ((long)arg) - cs->hw.diva.status |= 0x2000; - else - cs->hw.diva.status |= 0x1000; - break; - case MDL_INFO_REL: - if ((long)arg) { - cs->hw.diva.status &= ~0x2000; - cs->hw.diva.status &= ~0x0200; - } else { - cs->hw.diva.status &= ~0x1000; - cs->hw.diva.status &= ~0x0100; - } - break; - } - if ((cs->subtyp != DIVA_IPAC_ISA) && - (cs->subtyp != DIVA_IPAC_PCI) && - (cs->subtyp != DIVA_IPACX_PCI)) { - spin_lock_irqsave(&cs->lock, flags); - diva_led_handler(&cs->hw.diva.tl); - spin_unlock_irqrestore(&cs->lock, flags); - } - return (0); -} - -static int setup_diva_common(struct IsdnCardState *cs) -{ - int bytecnt; - u_char val; - - if ((cs->subtyp == DIVA_ISA) || (cs->subtyp == DIVA_IPAC_ISA)) - bytecnt = 8; - else - bytecnt = 32; - - printk(KERN_INFO - "Diva: %s card configured at %#lx IRQ %d\n", - (cs->subtyp == DIVA_PCI) ? "PCI" : - (cs->subtyp == DIVA_ISA) ? "ISA" : - (cs->subtyp == DIVA_IPAC_ISA) ? "IPAC ISA" : - (cs->subtyp == DIVA_IPAC_PCI) ? "IPAC PCI" : "IPACX PCI", - cs->hw.diva.cfg_reg, cs->irq); - if ((cs->subtyp == DIVA_IPAC_PCI) || - (cs->subtyp == DIVA_IPACX_PCI) || - (cs->subtyp == DIVA_PCI)) - printk(KERN_INFO "Diva: %s space at %#lx\n", - (cs->subtyp == DIVA_PCI) ? "PCI" : - (cs->subtyp == DIVA_IPAC_PCI) ? "IPAC PCI" : "IPACX PCI", - cs->hw.diva.pci_cfg); - if ((cs->subtyp != DIVA_IPAC_PCI) && - (cs->subtyp != DIVA_IPACX_PCI)) { - if (!request_region(cs->hw.diva.cfg_reg, bytecnt, "diva isdn")) { - printk(KERN_WARNING - "HiSax: %s config port %lx-%lx already in use\n", - "diva", - cs->hw.diva.cfg_reg, - cs->hw.diva.cfg_reg + bytecnt); - iounmap_diva(cs); - return (0); - } - } - cs->BC_Read_Reg = &ReadHSCX; - cs->BC_Write_Reg = &WriteHSCX; - cs->BC_Send_Data = &hscx_fill_fifo; - cs->cardmsg = &Diva_card_msg; - setup_isac(cs); - if (cs->subtyp == DIVA_IPAC_ISA) { - cs->readisac = &ReadISAC_IPAC; - cs->writeisac = &WriteISAC_IPAC; - cs->readisacfifo = &ReadISACfifo_IPAC; - cs->writeisacfifo = &WriteISACfifo_IPAC; - cs->irq_func = &diva_irq_ipac_isa; - val = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_ID); - printk(KERN_INFO "Diva: IPAC version %x\n", val); - } else if (cs->subtyp == DIVA_IPAC_PCI) { - cs->readisac = &MemReadISAC_IPAC; - cs->writeisac = &MemWriteISAC_IPAC; - cs->readisacfifo = &MemReadISACfifo_IPAC; - cs->writeisacfifo = &MemWriteISACfifo_IPAC; - cs->BC_Read_Reg = &MemReadHSCX; - cs->BC_Write_Reg = &MemWriteHSCX; - cs->BC_Send_Data = &Memhscx_fill_fifo; - cs->irq_func = &diva_irq_ipac_pci; - val = memreadreg(cs->hw.diva.cfg_reg, IPAC_ID); - printk(KERN_INFO "Diva: IPAC version %x\n", val); - } else if (cs->subtyp == DIVA_IPACX_PCI) { - cs->readisac = &MemReadISAC_IPACX; - cs->writeisac = &MemWriteISAC_IPACX; - cs->readisacfifo = &MemReadISACfifo_IPACX; - cs->writeisacfifo = &MemWriteISACfifo_IPACX; - cs->BC_Read_Reg = &MemReadHSCX_IPACX; - cs->BC_Write_Reg = &MemWriteHSCX_IPACX; - cs->BC_Send_Data = NULL; // function located in ipacx module - cs->irq_func = &diva_irq_ipacx_pci; - printk(KERN_INFO "Diva: IPACX Design Id: %x\n", - MemReadISAC_IPACX(cs, IPACX_ID) & 0x3F); - } else { /* DIVA 2.0 */ - timer_setup(&cs->hw.diva.tl, diva_led_handler, 0); - cs->readisac = &ReadISAC; - cs->writeisac = &WriteISAC; - cs->readisacfifo = &ReadISACfifo; - cs->writeisacfifo = &WriteISACfifo; - cs->irq_func = &diva_interrupt; - ISACVersion(cs, "Diva:"); - if (HscxVersion(cs, "Diva:")) { - printk(KERN_WARNING - "Diva: wrong HSCX versions check IO address\n"); - release_io_diva(cs); - return (0); - } - } - return (1); -} - -#ifdef CONFIG_ISA - -static int setup_diva_isa(struct IsdnCard *card) -{ - struct IsdnCardState *cs = card->cs; - u_char val; - - if (!card->para[1]) - return (-1); /* card not found; continue search */ - - cs->hw.diva.ctrl_reg = 0; - cs->hw.diva.cfg_reg = card->para[1]; - val = readreg(cs->hw.diva.cfg_reg + DIVA_IPAC_ADR, - cs->hw.diva.cfg_reg + DIVA_IPAC_DATA, IPAC_ID); - printk(KERN_INFO "Diva: IPAC version %x\n", val); - if ((val == 1) || (val == 2)) { - cs->subtyp = DIVA_IPAC_ISA; - cs->hw.diva.ctrl = 0; - cs->hw.diva.isac = card->para[1] + DIVA_IPAC_DATA; - cs->hw.diva.hscx = card->para[1] + DIVA_IPAC_DATA; - cs->hw.diva.isac_adr = card->para[1] + DIVA_IPAC_ADR; - cs->hw.diva.hscx_adr = card->para[1] + DIVA_IPAC_ADR; - test_and_set_bit(HW_IPAC, &cs->HW_Flags); - } else { - cs->subtyp = DIVA_ISA; - cs->hw.diva.ctrl = card->para[1] + DIVA_ISA_CTRL; - cs->hw.diva.isac = card->para[1] + DIVA_ISA_ISAC_DATA; - cs->hw.diva.hscx = card->para[1] + DIVA_HSCX_DATA; - cs->hw.diva.isac_adr = card->para[1] + DIVA_ISA_ISAC_ADR; - cs->hw.diva.hscx_adr = card->para[1] + DIVA_HSCX_ADR; - } - cs->irq = card->para[0]; - - return (1); /* card found */ -} - -#else /* if !CONFIG_ISA */ - -static int setup_diva_isa(struct IsdnCard *card) -{ - return (-1); /* card not found; continue search */ -} - -#endif /* CONFIG_ISA */ - -#ifdef __ISAPNP__ -static struct isapnp_device_id diva_ids[] = { - { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51), - ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51), - (unsigned long) "Diva picola" }, - { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51), - ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0x51), - (unsigned long) "Diva picola" }, - { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71), - ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71), - (unsigned long) "Diva 2.0" }, - { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71), - ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0x71), - (unsigned long) "Diva 2.0" }, - { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1), - ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1), - (unsigned long) "Diva 2.01" }, - { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1), - ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0xA1), - (unsigned long) "Diva 2.01" }, - { 0, } -}; - -static struct isapnp_device_id *ipid = &diva_ids[0]; -static struct pnp_card *pnp_c = NULL; - -static int setup_diva_isapnp(struct IsdnCard *card) -{ - struct IsdnCardState *cs = card->cs; - struct pnp_dev *pnp_d; - - if (!isapnp_present()) - return (-1); /* card not found; continue search */ - - while (ipid->card_vendor) { - if ((pnp_c = pnp_find_card(ipid->card_vendor, - ipid->card_device, pnp_c))) { - pnp_d = NULL; - if ((pnp_d = pnp_find_dev(pnp_c, - ipid->vendor, ipid->function, pnp_d))) { - int err; - - printk(KERN_INFO "HiSax: %s detected\n", - (char *)ipid->driver_data); - pnp_disable_dev(pnp_d); - err = pnp_activate_dev(pnp_d); - if (err < 0) { - printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n", - __func__, err); - return (0); - } - card->para[1] = pnp_port_start(pnp_d, 0); - card->para[0] = pnp_irq(pnp_d, 0); - if (card->para[0] == -1 || !card->para[1]) { - printk(KERN_ERR "Diva PnP:some resources are missing %ld/%lx\n", - card->para[0], card->para[1]); - pnp_disable_dev(pnp_d); - return (0); - } - cs->hw.diva.cfg_reg = card->para[1]; - cs->irq = card->para[0]; - if (ipid->function == ISAPNP_FUNCTION(0xA1)) { - cs->subtyp = DIVA_IPAC_ISA; - cs->hw.diva.ctrl = 0; - cs->hw.diva.isac = - card->para[1] + DIVA_IPAC_DATA; - cs->hw.diva.hscx = - card->para[1] + DIVA_IPAC_DATA; - cs->hw.diva.isac_adr = - card->para[1] + DIVA_IPAC_ADR; - cs->hw.diva.hscx_adr = - card->para[1] + DIVA_IPAC_ADR; - test_and_set_bit(HW_IPAC, &cs->HW_Flags); - } else { - cs->subtyp = DIVA_ISA; - cs->hw.diva.ctrl = - card->para[1] + DIVA_ISA_CTRL; - cs->hw.diva.isac = - card->para[1] + DIVA_ISA_ISAC_DATA; - cs->hw.diva.hscx = - card->para[1] + DIVA_HSCX_DATA; - cs->hw.diva.isac_adr = - card->para[1] + DIVA_ISA_ISAC_ADR; - cs->hw.diva.hscx_adr = - card->para[1] + DIVA_HSCX_ADR; - } - return (1); /* card found */ - } else { - printk(KERN_ERR "Diva PnP: PnP error card found, no device\n"); - return (0); - } - } - ipid++; - pnp_c = NULL; - } - - return (-1); /* card not found; continue search */ -} - -#else /* if !ISAPNP */ - -static int setup_diva_isapnp(struct IsdnCard *card) -{ - return (-1); /* card not found; continue search */ -} - -#endif /* ISAPNP */ - -#ifdef CONFIG_PCI -static struct pci_dev *dev_diva = NULL; -static struct pci_dev *dev_diva_u = NULL; -static struct pci_dev *dev_diva201 = NULL; -static struct pci_dev *dev_diva202 = NULL; - -static int setup_diva_pci(struct IsdnCard *card) -{ - struct IsdnCardState *cs = card->cs; - - cs->subtyp = 0; - if ((dev_diva = hisax_find_pci_device(PCI_VENDOR_ID_EICON, - PCI_DEVICE_ID_EICON_DIVA20, dev_diva))) { - if (pci_enable_device(dev_diva)) - return (0); - cs->subtyp = DIVA_PCI; - cs->irq = dev_diva->irq; - cs->hw.diva.cfg_reg = pci_resource_start(dev_diva, 2); - } else if ((dev_diva_u = hisax_find_pci_device(PCI_VENDOR_ID_EICON, - PCI_DEVICE_ID_EICON_DIVA20_U, dev_diva_u))) { - if (pci_enable_device(dev_diva_u)) - return (0); - cs->subtyp = DIVA_PCI; - cs->irq = dev_diva_u->irq; - cs->hw.diva.cfg_reg = pci_resource_start(dev_diva_u, 2); - } else if ((dev_diva201 = hisax_find_pci_device(PCI_VENDOR_ID_EICON, - PCI_DEVICE_ID_EICON_DIVA201, dev_diva201))) { - if (pci_enable_device(dev_diva201)) - return (0); - cs->subtyp = DIVA_IPAC_PCI; - cs->irq = dev_diva201->irq; - cs->hw.diva.pci_cfg = - (ulong) ioremap(pci_resource_start(dev_diva201, 0), 4096); - cs->hw.diva.cfg_reg = - (ulong) ioremap(pci_resource_start(dev_diva201, 1), 4096); - } else if ((dev_diva202 = hisax_find_pci_device(PCI_VENDOR_ID_EICON, - PCI_DEVICE_ID_EICON_DIVA202, dev_diva202))) { - if (pci_enable_device(dev_diva202)) - return (0); - cs->subtyp = DIVA_IPACX_PCI; - cs->irq = dev_diva202->irq; - cs->hw.diva.pci_cfg = - (ulong) ioremap(pci_resource_start(dev_diva202, 0), 4096); - cs->hw.diva.cfg_reg = - (ulong) ioremap(pci_resource_start(dev_diva202, 1), 4096); - } else { - return (-1); /* card not found; continue search */ - } - - if (!cs->irq) { - printk(KERN_WARNING "Diva: No IRQ for PCI card found\n"); - iounmap_diva(cs); - return (0); - } - - if (!cs->hw.diva.cfg_reg) { - printk(KERN_WARNING "Diva: No IO-Adr for PCI card found\n"); - iounmap_diva(cs); - return (0); - } - cs->irq_flags |= IRQF_SHARED; - - if ((cs->subtyp == DIVA_IPAC_PCI) || - (cs->subtyp == DIVA_IPACX_PCI)) { - cs->hw.diva.ctrl = 0; - cs->hw.diva.isac = 0; - cs->hw.diva.hscx = 0; - cs->hw.diva.isac_adr = 0; - cs->hw.diva.hscx_adr = 0; - test_and_set_bit(HW_IPAC, &cs->HW_Flags); - } else { - cs->hw.diva.ctrl = cs->hw.diva.cfg_reg + DIVA_PCI_CTRL; - cs->hw.diva.isac = cs->hw.diva.cfg_reg + DIVA_PCI_ISAC_DATA; - cs->hw.diva.hscx = cs->hw.diva.cfg_reg + DIVA_HSCX_DATA; - cs->hw.diva.isac_adr = cs->hw.diva.cfg_reg + DIVA_PCI_ISAC_ADR; - cs->hw.diva.hscx_adr = cs->hw.diva.cfg_reg + DIVA_HSCX_ADR; - } - - return (1); /* card found */ -} - -#else /* if !CONFIG_PCI */ - -static int setup_diva_pci(struct IsdnCard *card) -{ - return (-1); /* card not found; continue search */ -} - -#endif /* CONFIG_PCI */ - -int setup_diva(struct IsdnCard *card) -{ - int rc, have_card = 0; - struct IsdnCardState *cs = card->cs; - char tmp[64]; - - strcpy(tmp, Diva_revision); - printk(KERN_INFO "HiSax: Eicon.Diehl Diva driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_DIEHLDIVA) - return (0); - cs->hw.diva.status = 0; - - rc = setup_diva_isa(card); - if (!rc) - return rc; - if (rc > 0) { - have_card = 1; - goto ready; - } - - rc = setup_diva_isapnp(card); - if (!rc) - return rc; - if (rc > 0) { - have_card = 1; - goto ready; - } - - rc = setup_diva_pci(card); - if (!rc) - return rc; - if (rc > 0) - have_card = 1; - -ready: - if (!have_card) { - printk(KERN_WARNING "Diva: No ISA, ISAPNP or PCI card found\n"); - return (0); - } - - return setup_diva_common(card->cs); -} diff --git a/drivers/isdn/hisax/elsa.c b/drivers/isdn/hisax/elsa.c deleted file mode 100644 index 0754c0743790..000000000000 --- a/drivers/isdn/hisax/elsa.c +++ /dev/null @@ -1,1245 +0,0 @@ -/* $Id: elsa.c,v 2.32.2.4 2004/01/24 20:47:21 keil Exp $ - * - * low level stuff for Elsa isdn cards - * - * Author Karsten Keil - * Copyright by Karsten Keil <keil@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * For changes and modifications please read - * Documentation/isdn/HiSax.cert - * - * Thanks to Elsa GmbH for documents and information - * - * Klaus Lichtenwalder (Klaus.Lichtenwalder@WebForum.DE) - * for ELSA PCMCIA support - * - */ - -#include <linux/init.h> -#include <linux/slab.h> -#include "hisax.h" -#include "arcofi.h" -#include "isac.h" -#include "ipac.h" -#include "hscx.h" -#include "isdnl1.h" -#include <linux/pci.h> -#include <linux/isapnp.h> -#include <linux/serial.h> -#include <linux/serial_reg.h> - -static const char *Elsa_revision = "$Revision: 2.32.2.4 $"; -static const char *Elsa_Types[] = -{"None", "PC", "PCC-8", "PCC-16", "PCF", "PCF-Pro", - "PCMCIA", "QS 1000", "QS 3000", "Microlink PCI", "QS 3000 PCI", - "PCMCIA-IPAC" }; - -static const char *ITACVer[] = -{"?0?", "?1?", "?2?", "?3?", "?4?", "V2.2", - "B1", "A1"}; - -#define byteout(addr, val) outb(val, addr) -#define bytein(addr) inb(addr) - -#define ELSA_ISAC 0 -#define ELSA_ISAC_PCM 1 -#define ELSA_ITAC 1 -#define ELSA_HSCX 2 -#define ELSA_ALE 3 -#define ELSA_ALE_PCM 4 -#define ELSA_CONTROL 4 -#define ELSA_CONFIG 5 -#define ELSA_START_TIMER 6 -#define ELSA_TRIG_IRQ 7 - -#define ELSA_PC 1 -#define ELSA_PCC8 2 -#define ELSA_PCC16 3 -#define ELSA_PCF 4 -#define ELSA_PCFPRO 5 -#define ELSA_PCMCIA 6 -#define ELSA_QS1000 7 -#define ELSA_QS3000 8 -#define ELSA_QS1000PCI 9 -#define ELSA_QS3000PCI 10 -#define ELSA_PCMCIA_IPAC 11 - -/* PCI stuff */ -#define ELSA_PCI_IRQ_MASK 0x04 - -/* ITAC Registeradressen (only Microlink PC) */ -#define ITAC_SYS 0x34 -#define ITAC_ISEN 0x48 -#define ITAC_RFIE 0x4A -#define ITAC_XFIE 0x4C -#define ITAC_SCIE 0x4E -#define ITAC_STIE 0x46 - -/*** *** - *** Makros als Befehle fuer die Kartenregister *** - *** (mehrere Befehle werden durch Bit-Oderung kombiniert) *** - *** ***/ - -/* Config-Register (Read) */ -#define ELIRQF_TIMER_RUN 0x02 /* Bit 1 des Config-Reg */ -#define ELIRQF_TIMER_RUN_PCC8 0x01 /* Bit 0 des Config-Reg bei PCC */ -#define ELSA_IRQ_IDX 0x38 /* Bit 3,4,5 des Config-Reg */ -#define ELSA_IRQ_IDX_PCC8 0x30 /* Bit 4,5 des Config-Reg */ -#define ELSA_IRQ_IDX_PC 0x0c /* Bit 2,3 des Config-Reg */ - -/* Control-Register (Write) */ -#define ELSA_LINE_LED 0x02 /* Bit 1 Gelbe LED */ -#define ELSA_STAT_LED 0x08 /* Bit 3 Gruene LED */ -#define ELSA_ISDN_RESET 0x20 /* Bit 5 Reset-Leitung */ -#define ELSA_ENA_TIMER_INT 0x80 /* Bit 7 Freigabe Timer Interrupt */ - -/* ALE-Register (Read) */ -#define ELSA_HW_RELEASE 0x07 /* Bit 0-2 Hardwarerkennung */ -#define ELSA_S0_POWER_BAD 0x08 /* Bit 3 S0-Bus Spannung fehlt */ - -/* Status Flags */ -#define ELIRQF_TIMER_AKTIV 1 -#define ELSA_BAD_PWR 2 -#define ELSA_ASSIGN 4 - -#define RS_ISR_PASS_LIMIT 256 -#define FLG_MODEM_ACTIVE 1 -/* IPAC AUX */ -#define ELSA_IPAC_LINE_LED 0x40 /* Bit 6 Gelbe LED */ -#define ELSA_IPAC_STAT_LED 0x80 /* Bit 7 Gruene LED */ - -#if ARCOFI_USE -static struct arcofi_msg ARCOFI_XOP_F = -{NULL,0,2,{0xa1,0x3f,0,0,0,0,0,0,0,0}}; /* Normal OP */ -static struct arcofi_msg ARCOFI_XOP_1 = -{&ARCOFI_XOP_F,0,2,{0xa1,0x31,0,0,0,0,0,0,0,0}}; /* PWR UP */ -static struct arcofi_msg ARCOFI_SOP_F = -{&ARCOFI_XOP_1,0,10,{0xa1,0x1f,0x00,0x50,0x10,0x00,0x00,0x80,0x02,0x12}}; -static struct arcofi_msg ARCOFI_COP_9 = -{&ARCOFI_SOP_F,0,10,{0xa1,0x29,0x80,0xcb,0xe9,0x88,0x00,0xc8,0xd8,0x80}}; /* RX */ -static struct arcofi_msg ARCOFI_COP_8 = -{&ARCOFI_COP_9,0,10,{0xa1,0x28,0x49,0x31,0x8,0x13,0x6e,0x88,0x2a,0x61}}; /* TX */ -static struct arcofi_msg ARCOFI_COP_7 = -{&ARCOFI_COP_8,0,4,{0xa1,0x27,0x80,0x80,0,0,0,0,0,0}}; /* GZ */ -static struct arcofi_msg ARCOFI_COP_6 = -{&ARCOFI_COP_7,0,6,{0xa1,0x26,0,0,0x82,0x7c,0,0,0,0}}; /* GRL GRH */ -static struct arcofi_msg ARCOFI_COP_5 = -{&ARCOFI_COP_6,0,4,{0xa1,0x25,0xbb,0x4a,0,0,0,0,0,0}}; /* GTX */ -static struct arcofi_msg ARCOFI_VERSION = -{NULL,1,2,{0xa0,0,0,0,0,0,0,0,0,0}}; -static struct arcofi_msg ARCOFI_XOP_0 = -{NULL,0,2,{0xa1,0x30,0,0,0,0,0,0,0,0}}; /* PWR Down */ - -static void set_arcofi(struct IsdnCardState *cs, int bc); - -#include "elsa_ser.c" -#endif /* ARCOFI_USE */ - -static inline u_char -readreg(unsigned int ale, unsigned int adr, u_char off) -{ - register u_char ret; - - byteout(ale, off); - ret = bytein(adr); - return (ret); -} - -static inline void -readfifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size) -{ - byteout(ale, off); - insb(adr, data, size); -} - - -static inline void -writereg(unsigned int ale, unsigned int adr, u_char off, u_char data) -{ - byteout(ale, off); - byteout(adr, data); -} - -static inline void -writefifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size) -{ - byteout(ale, off); - outsb(adr, data, size); -} - -/* Interface functions */ - -static u_char -ReadISAC(struct IsdnCardState *cs, u_char offset) -{ - return (readreg(cs->hw.elsa.ale, cs->hw.elsa.isac, offset)); -} - -static void -WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value) -{ - writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, offset, value); -} - -static void -ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - readfifo(cs->hw.elsa.ale, cs->hw.elsa.isac, 0, data, size); -} - -static void -WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - writefifo(cs->hw.elsa.ale, cs->hw.elsa.isac, 0, data, size); -} - -static u_char -ReadISAC_IPAC(struct IsdnCardState *cs, u_char offset) -{ - return (readreg(cs->hw.elsa.ale, cs->hw.elsa.isac, offset + 0x80)); -} - -static void -WriteISAC_IPAC(struct IsdnCardState *cs, u_char offset, u_char value) -{ - writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, offset | 0x80, value); -} - -static void -ReadISACfifo_IPAC(struct IsdnCardState *cs, u_char *data, int size) -{ - readfifo(cs->hw.elsa.ale, cs->hw.elsa.isac, 0x80, data, size); -} - -static void -WriteISACfifo_IPAC(struct IsdnCardState *cs, u_char *data, int size) -{ - writefifo(cs->hw.elsa.ale, cs->hw.elsa.isac, 0x80, data, size); -} - -static u_char -ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset) -{ - return (readreg(cs->hw.elsa.ale, - cs->hw.elsa.hscx, offset + (hscx ? 0x40 : 0))); -} - -static void -WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) -{ - writereg(cs->hw.elsa.ale, - cs->hw.elsa.hscx, offset + (hscx ? 0x40 : 0), value); -} - -static inline u_char -readitac(struct IsdnCardState *cs, u_char off) -{ - register u_char ret; - - byteout(cs->hw.elsa.ale, off); - ret = bytein(cs->hw.elsa.itac); - return (ret); -} - -static inline void -writeitac(struct IsdnCardState *cs, u_char off, u_char data) -{ - byteout(cs->hw.elsa.ale, off); - byteout(cs->hw.elsa.itac, data); -} - -static inline int -TimerRun(struct IsdnCardState *cs) -{ - register u_char v; - - v = bytein(cs->hw.elsa.cfg); - if ((cs->subtyp == ELSA_QS1000) || (cs->subtyp == ELSA_QS3000)) - return (0 == (v & ELIRQF_TIMER_RUN)); - else if (cs->subtyp == ELSA_PCC8) - return (v & ELIRQF_TIMER_RUN_PCC8); - return (v & ELIRQF_TIMER_RUN); -} -/* - * fast interrupt HSCX stuff goes here - */ - -#define READHSCX(cs, nr, reg) readreg(cs->hw.elsa.ale, \ - cs->hw.elsa.hscx, reg + (nr ? 0x40 : 0)) -#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.elsa.ale, \ - cs->hw.elsa.hscx, reg + (nr ? 0x40 : 0), data) - -#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.elsa.ale, \ - cs->hw.elsa.hscx, (nr ? 0x40 : 0), ptr, cnt) - -#define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.elsa.ale, \ - cs->hw.elsa.hscx, (nr ? 0x40 : 0), ptr, cnt) - -#include "hscx_irq.c" - -static irqreturn_t -elsa_interrupt(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - u_long flags; - u_char val; - int icnt = 5; - - if ((cs->typ == ISDN_CTYPE_ELSA_PCMCIA) && (*cs->busy_flag == 1)) { - /* The card tends to generate interrupts while being removed - causing us to just crash the kernel. bad. */ - printk(KERN_WARNING "Elsa: card not available!\n"); - return IRQ_NONE; - } - spin_lock_irqsave(&cs->lock, flags); -#if ARCOFI_USE - if (cs->hw.elsa.MFlag) { - val = serial_inp(cs, UART_IIR); - if (!(val & UART_IIR_NO_INT)) { - debugl1(cs, "IIR %02x", val); - rs_interrupt_elsa(cs); - } - } -#endif - val = readreg(cs->hw.elsa.ale, cs->hw.elsa.hscx, HSCX_ISTA + 0x40); -Start_HSCX: - if (val) { - hscx_int_main(cs, val); - } - val = readreg(cs->hw.elsa.ale, cs->hw.elsa.isac, ISAC_ISTA); -Start_ISAC: - if (val) { - isac_interrupt(cs, val); - } - val = readreg(cs->hw.elsa.ale, cs->hw.elsa.hscx, HSCX_ISTA + 0x40); - if (val && icnt) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "HSCX IntStat after IntRoutine"); - icnt--; - goto Start_HSCX; - } - val = readreg(cs->hw.elsa.ale, cs->hw.elsa.isac, ISAC_ISTA); - if (val && icnt) { - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "ISAC IntStat after IntRoutine"); - icnt--; - goto Start_ISAC; - } - if (!icnt) - printk(KERN_WARNING"ELSA IRQ LOOP\n"); - writereg(cs->hw.elsa.ale, cs->hw.elsa.hscx, HSCX_MASK, 0xFF); - writereg(cs->hw.elsa.ale, cs->hw.elsa.hscx, HSCX_MASK + 0x40, 0xFF); - writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, ISAC_MASK, 0xFF); - if (cs->hw.elsa.status & ELIRQF_TIMER_AKTIV) { - if (!TimerRun(cs)) { - /* Timer Restart */ - byteout(cs->hw.elsa.timer, 0); - cs->hw.elsa.counter++; - } - } -#if ARCOFI_USE - if (cs->hw.elsa.MFlag) { - val = serial_inp(cs, UART_MCR); - val ^= 0x8; - serial_outp(cs, UART_MCR, val); - val = serial_inp(cs, UART_MCR); - val ^= 0x8; - serial_outp(cs, UART_MCR, val); - } -#endif - if (cs->hw.elsa.trig) - byteout(cs->hw.elsa.trig, 0x00); - writereg(cs->hw.elsa.ale, cs->hw.elsa.hscx, HSCX_MASK, 0x0); - writereg(cs->hw.elsa.ale, cs->hw.elsa.hscx, HSCX_MASK + 0x40, 0x0); - writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, ISAC_MASK, 0x0); - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -static irqreturn_t -elsa_interrupt_ipac(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - u_long flags; - u_char ista, val; - int icnt = 5; - - spin_lock_irqsave(&cs->lock, flags); - if (cs->subtyp == ELSA_QS1000PCI || cs->subtyp == ELSA_QS3000PCI) { - val = bytein(cs->hw.elsa.cfg + 0x4c); /* PCI IRQ */ - if (!(val & ELSA_PCI_IRQ_MASK)) { - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_NONE; - } - } -#if ARCOFI_USE - if (cs->hw.elsa.MFlag) { - val = serial_inp(cs, UART_IIR); - if (!(val & UART_IIR_NO_INT)) { - debugl1(cs, "IIR %02x", val); - rs_interrupt_elsa(cs); - } - } -#endif - ista = readreg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_ISTA); -Start_IPAC: - if (cs->debug & L1_DEB_IPAC) - debugl1(cs, "IPAC ISTA %02X", ista); - if (ista & 0x0f) { - val = readreg(cs->hw.elsa.ale, cs->hw.elsa.hscx, HSCX_ISTA + 0x40); - if (ista & 0x01) - val |= 0x01; - if (ista & 0x04) - val |= 0x02; - if (ista & 0x08) - val |= 0x04; - if (val) - hscx_int_main(cs, val); - } - if (ista & 0x20) { - val = 0xfe & readreg(cs->hw.elsa.ale, cs->hw.elsa.isac, ISAC_ISTA + 0x80); - if (val) { - isac_interrupt(cs, val); - } - } - if (ista & 0x10) { - val = 0x01; - isac_interrupt(cs, val); - } - ista = readreg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_ISTA); - if ((ista & 0x3f) && icnt) { - icnt--; - goto Start_IPAC; - } - if (!icnt) - printk(KERN_WARNING "ELSA IRQ LOOP\n"); - writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_MASK, 0xFF); - writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_MASK, 0xC0); - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -static void -release_io_elsa(struct IsdnCardState *cs) -{ - int bytecnt = 8; - - del_timer(&cs->hw.elsa.tl); -#if ARCOFI_USE - clear_arcofi(cs); -#endif - if (cs->hw.elsa.ctrl) - byteout(cs->hw.elsa.ctrl, 0); /* LEDs Out */ - if (cs->subtyp == ELSA_QS1000PCI) { - byteout(cs->hw.elsa.cfg + 0x4c, 0x01); /* disable IRQ */ - writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_ATX, 0xff); - bytecnt = 2; - release_region(cs->hw.elsa.cfg, 0x80); - } - if (cs->subtyp == ELSA_QS3000PCI) { - byteout(cs->hw.elsa.cfg + 0x4c, 0x03); /* disable ELSA PCI IRQ */ - writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_ATX, 0xff); - release_region(cs->hw.elsa.cfg, 0x80); - } - if (cs->subtyp == ELSA_PCMCIA_IPAC) { - writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_ATX, 0xff); - } - if ((cs->subtyp == ELSA_PCFPRO) || - (cs->subtyp == ELSA_QS3000) || - (cs->subtyp == ELSA_PCF) || - (cs->subtyp == ELSA_QS3000PCI)) { - bytecnt = 16; -#if ARCOFI_USE - release_modem(cs); -#endif - } - if (cs->hw.elsa.base) - release_region(cs->hw.elsa.base, bytecnt); -} - -static void -reset_elsa(struct IsdnCardState *cs) -{ - if (cs->hw.elsa.timer) { - /* Wait 1 Timer */ - byteout(cs->hw.elsa.timer, 0); - while (TimerRun(cs)); - cs->hw.elsa.ctrl_reg |= 0x50; - cs->hw.elsa.ctrl_reg &= ~ELSA_ISDN_RESET; /* Reset On */ - byteout(cs->hw.elsa.ctrl, cs->hw.elsa.ctrl_reg); - /* Wait 1 Timer */ - byteout(cs->hw.elsa.timer, 0); - while (TimerRun(cs)); - cs->hw.elsa.ctrl_reg |= ELSA_ISDN_RESET; /* Reset Off */ - byteout(cs->hw.elsa.ctrl, cs->hw.elsa.ctrl_reg); - /* Wait 1 Timer */ - byteout(cs->hw.elsa.timer, 0); - while (TimerRun(cs)); - if (cs->hw.elsa.trig) - byteout(cs->hw.elsa.trig, 0xff); - } - if ((cs->subtyp == ELSA_QS1000PCI) || (cs->subtyp == ELSA_QS3000PCI) || (cs->subtyp == ELSA_PCMCIA_IPAC)) { - writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_POTA2, 0x20); - mdelay(10); - writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_POTA2, 0x00); - writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_MASK, 0xc0); - mdelay(10); - if (cs->subtyp != ELSA_PCMCIA_IPAC) { - writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_ACFG, 0x0); - writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_AOE, 0x3c); - } else { - writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_PCFG, 0x10); - writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_ACFG, 0x4); - writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_AOE, 0xf8); - } - writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_ATX, 0xff); - if (cs->subtyp == ELSA_QS1000PCI) - byteout(cs->hw.elsa.cfg + 0x4c, 0x41); /* enable ELSA PCI IRQ */ - else if (cs->subtyp == ELSA_QS3000PCI) - byteout(cs->hw.elsa.cfg + 0x4c, 0x43); /* enable ELSA PCI IRQ */ - } -} - -#if ARCOFI_USE - -static void -set_arcofi(struct IsdnCardState *cs, int bc) { - cs->dc.isac.arcofi_bc = bc; - arcofi_fsm(cs, ARCOFI_START, &ARCOFI_COP_5); - wait_event_interruptible(cs->dc.isac.arcofi_wait, - cs->dc.isac.arcofi_state == ARCOFI_NOP); -} - -static int -check_arcofi(struct IsdnCardState *cs) -{ - int arcofi_present = 0; - char tmp[40]; - char *t; - u_char *p; - - if (!cs->dc.isac.mon_tx) - if (!(cs->dc.isac.mon_tx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC))) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "ISAC MON TX out of buffers!"); - return (0); - } - cs->dc.isac.arcofi_bc = 0; - arcofi_fsm(cs, ARCOFI_START, &ARCOFI_VERSION); - wait_event_interruptible(cs->dc.isac.arcofi_wait, - cs->dc.isac.arcofi_state == ARCOFI_NOP); - if (!test_and_clear_bit(FLG_ARCOFI_ERROR, &cs->HW_Flags)) { - debugl1(cs, "Arcofi response received %d bytes", cs->dc.isac.mon_rxp); - p = cs->dc.isac.mon_rx; - t = tmp; - t += sprintf(tmp, "Arcofi data"); - QuickHex(t, p, cs->dc.isac.mon_rxp); - debugl1(cs, "%s", tmp); - if ((cs->dc.isac.mon_rxp == 2) && (cs->dc.isac.mon_rx[0] == 0xa0)) { - switch (cs->dc.isac.mon_rx[1]) { - case 0x80: - debugl1(cs, "Arcofi 2160 detected"); - arcofi_present = 1; - break; - case 0x82: - debugl1(cs, "Arcofi 2165 detected"); - arcofi_present = 2; - break; - case 0x84: - debugl1(cs, "Arcofi 2163 detected"); - arcofi_present = 3; - break; - default: - debugl1(cs, "unknown Arcofi response"); - break; - } - } else - debugl1(cs, "undefined Monitor response"); - cs->dc.isac.mon_rxp = 0; - } else if (cs->dc.isac.mon_tx) { - debugl1(cs, "Arcofi not detected"); - } - if (arcofi_present) { - if (cs->subtyp == ELSA_QS1000) { - cs->subtyp = ELSA_QS3000; - printk(KERN_INFO - "Elsa: %s detected modem at 0x%lx\n", - Elsa_Types[cs->subtyp], - cs->hw.elsa.base + 8); - release_region(cs->hw.elsa.base, 8); - if (!request_region(cs->hw.elsa.base, 16, "elsa isdn modem")) { - printk(KERN_WARNING - "HiSax: %s config port %lx-%lx already in use\n", - Elsa_Types[cs->subtyp], - cs->hw.elsa.base + 8, - cs->hw.elsa.base + 16); - } - } else if (cs->subtyp == ELSA_PCC16) { - cs->subtyp = ELSA_PCF; - printk(KERN_INFO - "Elsa: %s detected modem at 0x%lx\n", - Elsa_Types[cs->subtyp], - cs->hw.elsa.base + 8); - release_region(cs->hw.elsa.base, 8); - if (!request_region(cs->hw.elsa.base, 16, "elsa isdn modem")) { - printk(KERN_WARNING - "HiSax: %s config port %lx-%lx already in use\n", - Elsa_Types[cs->subtyp], - cs->hw.elsa.base + 8, - cs->hw.elsa.base + 16); - } - } else - printk(KERN_INFO - "Elsa: %s detected modem at 0x%lx\n", - Elsa_Types[cs->subtyp], - cs->hw.elsa.base + 8); - arcofi_fsm(cs, ARCOFI_START, &ARCOFI_XOP_0); - wait_event_interruptible(cs->dc.isac.arcofi_wait, - cs->dc.isac.arcofi_state == ARCOFI_NOP); - return (1); - } - return (0); -} -#endif /* ARCOFI_USE */ - -static void -elsa_led_handler(struct timer_list *t) -{ - struct IsdnCardState *cs = from_timer(cs, t, hw.elsa.tl); - int blink = 0; - - if (cs->subtyp == ELSA_PCMCIA || cs->subtyp == ELSA_PCMCIA_IPAC) - return; - del_timer(&cs->hw.elsa.tl); - if (cs->hw.elsa.status & ELSA_ASSIGN) - cs->hw.elsa.ctrl_reg |= ELSA_STAT_LED; - else if (cs->hw.elsa.status & ELSA_BAD_PWR) - cs->hw.elsa.ctrl_reg &= ~ELSA_STAT_LED; - else { - cs->hw.elsa.ctrl_reg ^= ELSA_STAT_LED; - blink = 250; - } - if (cs->hw.elsa.status & 0xf000) - cs->hw.elsa.ctrl_reg |= ELSA_LINE_LED; - else if (cs->hw.elsa.status & 0x0f00) { - cs->hw.elsa.ctrl_reg ^= ELSA_LINE_LED; - blink = 500; - } else - cs->hw.elsa.ctrl_reg &= ~ELSA_LINE_LED; - - if ((cs->subtyp == ELSA_QS1000PCI) || - (cs->subtyp == ELSA_QS3000PCI)) { - u_char led = 0xff; - if (cs->hw.elsa.ctrl_reg & ELSA_LINE_LED) - led ^= ELSA_IPAC_LINE_LED; - if (cs->hw.elsa.ctrl_reg & ELSA_STAT_LED) - led ^= ELSA_IPAC_STAT_LED; - writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_ATX, led); - } else - byteout(cs->hw.elsa.ctrl, cs->hw.elsa.ctrl_reg); - if (blink) { - cs->hw.elsa.tl.expires = jiffies + ((blink * HZ) / 1000); - add_timer(&cs->hw.elsa.tl); - } -} - -static int -Elsa_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - int ret = 0; - u_long flags; - - switch (mt) { - case CARD_RESET: - spin_lock_irqsave(&cs->lock, flags); - reset_elsa(cs); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_RELEASE: - release_io_elsa(cs); - return (0); - case CARD_INIT: - spin_lock_irqsave(&cs->lock, flags); - cs->debug |= L1_DEB_IPAC; - reset_elsa(cs); - inithscxisac(cs, 1); - if ((cs->subtyp == ELSA_QS1000) || - (cs->subtyp == ELSA_QS3000)) - { - byteout(cs->hw.elsa.timer, 0); - } - if (cs->hw.elsa.trig) - byteout(cs->hw.elsa.trig, 0xff); - inithscxisac(cs, 2); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_TEST: - if ((cs->subtyp == ELSA_PCMCIA) || - (cs->subtyp == ELSA_PCMCIA_IPAC) || - (cs->subtyp == ELSA_QS1000PCI)) { - return (0); - } else if (cs->subtyp == ELSA_QS3000PCI) { - ret = 0; - } else { - spin_lock_irqsave(&cs->lock, flags); - cs->hw.elsa.counter = 0; - cs->hw.elsa.ctrl_reg |= ELSA_ENA_TIMER_INT; - cs->hw.elsa.status |= ELIRQF_TIMER_AKTIV; - byteout(cs->hw.elsa.ctrl, cs->hw.elsa.ctrl_reg); - byteout(cs->hw.elsa.timer, 0); - spin_unlock_irqrestore(&cs->lock, flags); - msleep(110); - spin_lock_irqsave(&cs->lock, flags); - cs->hw.elsa.ctrl_reg &= ~ELSA_ENA_TIMER_INT; - byteout(cs->hw.elsa.ctrl, cs->hw.elsa.ctrl_reg); - cs->hw.elsa.status &= ~ELIRQF_TIMER_AKTIV; - spin_unlock_irqrestore(&cs->lock, flags); - printk(KERN_INFO "Elsa: %d timer tics in 110 msek\n", - cs->hw.elsa.counter); - if ((cs->hw.elsa.counter > 10) && - (cs->hw.elsa.counter < 16)) { - printk(KERN_INFO "Elsa: timer and irq OK\n"); - ret = 0; - } else { - printk(KERN_WARNING - "Elsa: timer tic problem (%d/12) maybe an IRQ(%d) conflict\n", - cs->hw.elsa.counter, cs->irq); - ret = 1; - } - } -#if ARCOFI_USE - if (check_arcofi(cs)) { - init_modem(cs); - } -#endif - elsa_led_handler(&cs->hw.elsa.tl); - return (ret); - case (MDL_REMOVE | REQUEST): - cs->hw.elsa.status &= 0; - break; - case (MDL_ASSIGN | REQUEST): - cs->hw.elsa.status |= ELSA_ASSIGN; - break; - case MDL_INFO_SETUP: - if ((long) arg) - cs->hw.elsa.status |= 0x0200; - else - cs->hw.elsa.status |= 0x0100; - break; - case MDL_INFO_CONN: - if ((long) arg) - cs->hw.elsa.status |= 0x2000; - else - cs->hw.elsa.status |= 0x1000; - break; - case MDL_INFO_REL: - if ((long) arg) { - cs->hw.elsa.status &= ~0x2000; - cs->hw.elsa.status &= ~0x0200; - } else { - cs->hw.elsa.status &= ~0x1000; - cs->hw.elsa.status &= ~0x0100; - } - break; -#if ARCOFI_USE - case CARD_AUX_IND: - if (cs->hw.elsa.MFlag) { - int len; - u_char *msg; - - if (!arg) - return (0); - msg = arg; - len = *msg; - msg++; - modem_write_cmd(cs, msg, len); - } - break; -#endif - } - if (cs->typ == ISDN_CTYPE_ELSA) { - int pwr = bytein(cs->hw.elsa.ale); - if (pwr & 0x08) - cs->hw.elsa.status |= ELSA_BAD_PWR; - else - cs->hw.elsa.status &= ~ELSA_BAD_PWR; - } - elsa_led_handler(&cs->hw.elsa.tl); - return (ret); -} - -static unsigned char -probe_elsa_adr(unsigned int adr, int typ) -{ - int i, in1, in2, p16_1 = 0, p16_2 = 0, p8_1 = 0, p8_2 = 0, pc_1 = 0, - pc_2 = 0, pfp_1 = 0, pfp_2 = 0; - - /* In case of the elsa pcmcia card, this region is in use, - reserved for us by the card manager. So we do not check it - here, it would fail. */ - if (typ != ISDN_CTYPE_ELSA_PCMCIA) { - if (request_region(adr, 8, "elsa card")) { - release_region(adr, 8); - } else { - printk(KERN_WARNING - "Elsa: Probing Port 0x%x: already in use\n", adr); - return (0); - } - } - for (i = 0; i < 16; i++) { - in1 = inb(adr + ELSA_CONFIG); /* 'toggelt' bei */ - in2 = inb(adr + ELSA_CONFIG); /* jedem Zugriff */ - p16_1 += 0x04 & in1; - p16_2 += 0x04 & in2; - p8_1 += 0x02 & in1; - p8_2 += 0x02 & in2; - pc_1 += 0x01 & in1; - pc_2 += 0x01 & in2; - pfp_1 += 0x40 & in1; - pfp_2 += 0x40 & in2; - } - printk(KERN_INFO "Elsa: Probing IO 0x%x", adr); - if (65 == ++p16_1 * ++p16_2) { - printk(" PCC-16/PCF found\n"); - return (ELSA_PCC16); - } else if (1025 == ++pfp_1 * ++pfp_2) { - printk(" PCF-Pro found\n"); - return (ELSA_PCFPRO); - } else if (33 == ++p8_1 * ++p8_2) { - printk(" PCC8 found\n"); - return (ELSA_PCC8); - } else if (17 == ++pc_1 * ++pc_2) { - printk(" PC found\n"); - return (ELSA_PC); - } else { - printk(" failed\n"); - return (0); - } -} - -static unsigned int -probe_elsa(struct IsdnCardState *cs) -{ - int i; - unsigned int CARD_portlist[] = - {0x160, 0x170, 0x260, 0x360, 0}; - - for (i = 0; CARD_portlist[i]; i++) { - if ((cs->subtyp = probe_elsa_adr(CARD_portlist[i], cs->typ))) - break; - } - return (CARD_portlist[i]); -} - -static int setup_elsa_isa(struct IsdnCard *card) -{ - struct IsdnCardState *cs = card->cs; - u_char val; - - cs->hw.elsa.base = card->para[0]; - printk(KERN_INFO "Elsa: Microlink IO probing\n"); - if (cs->hw.elsa.base) { - if (!(cs->subtyp = probe_elsa_adr(cs->hw.elsa.base, - cs->typ))) { - printk(KERN_WARNING - "Elsa: no Elsa Microlink at %#lx\n", - cs->hw.elsa.base); - return (0); - } - } else - cs->hw.elsa.base = probe_elsa(cs); - - if (!cs->hw.elsa.base) { - printk(KERN_WARNING - "No Elsa Microlink found\n"); - return (0); - } - - cs->hw.elsa.cfg = cs->hw.elsa.base + ELSA_CONFIG; - cs->hw.elsa.ctrl = cs->hw.elsa.base + ELSA_CONTROL; - cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE; - cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC; - cs->hw.elsa.itac = cs->hw.elsa.base + ELSA_ITAC; - cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX; - cs->hw.elsa.trig = cs->hw.elsa.base + ELSA_TRIG_IRQ; - cs->hw.elsa.timer = cs->hw.elsa.base + ELSA_START_TIMER; - val = bytein(cs->hw.elsa.cfg); - if (cs->subtyp == ELSA_PC) { - const u_char CARD_IrqTab[8] = - {7, 3, 5, 9, 0, 0, 0, 0}; - cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX_PC) >> 2]; - } else if (cs->subtyp == ELSA_PCC8) { - const u_char CARD_IrqTab[8] = - {7, 3, 5, 9, 0, 0, 0, 0}; - cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX_PCC8) >> 4]; - } else { - const u_char CARD_IrqTab[8] = - {15, 10, 15, 3, 11, 5, 11, 9}; - cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX) >> 3]; - } - val = bytein(cs->hw.elsa.ale) & ELSA_HW_RELEASE; - if (val < 3) - val |= 8; - val += 'A' - 3; - if (val == 'B' || val == 'C') - val ^= 1; - if ((cs->subtyp == ELSA_PCFPRO) && (val == 'G')) - val = 'C'; - printk(KERN_INFO - "Elsa: %s found at %#lx Rev.:%c IRQ %d\n", - Elsa_Types[cs->subtyp], - cs->hw.elsa.base, - val, cs->irq); - val = bytein(cs->hw.elsa.ale) & ELSA_S0_POWER_BAD; - if (val) { - printk(KERN_WARNING - "Elsa: Microlink S0 bus power bad\n"); - cs->hw.elsa.status |= ELSA_BAD_PWR; - } - - return (1); -} - -#ifdef __ISAPNP__ -static struct isapnp_device_id elsa_ids[] = { - { ISAPNP_VENDOR('E', 'L', 'S'), ISAPNP_FUNCTION(0x0133), - ISAPNP_VENDOR('E', 'L', 'S'), ISAPNP_FUNCTION(0x0133), - (unsigned long) "Elsa QS1000" }, - { ISAPNP_VENDOR('E', 'L', 'S'), ISAPNP_FUNCTION(0x0134), - ISAPNP_VENDOR('E', 'L', 'S'), ISAPNP_FUNCTION(0x0134), - (unsigned long) "Elsa QS3000" }, - { 0, } -}; - -static struct isapnp_device_id *ipid = &elsa_ids[0]; -static struct pnp_card *pnp_c = NULL; -#endif /* __ISAPNP__ */ - -static int setup_elsa_isapnp(struct IsdnCard *card) -{ - struct IsdnCardState *cs = card->cs; - -#ifdef __ISAPNP__ - if (!card->para[1] && isapnp_present()) { - struct pnp_dev *pnp_d; - while (ipid->card_vendor) { - if ((pnp_c = pnp_find_card(ipid->card_vendor, - ipid->card_device, pnp_c))) { - pnp_d = NULL; - if ((pnp_d = pnp_find_dev(pnp_c, - ipid->vendor, ipid->function, pnp_d))) { - int err; - - printk(KERN_INFO "HiSax: %s detected\n", - (char *)ipid->driver_data); - pnp_disable_dev(pnp_d); - err = pnp_activate_dev(pnp_d); - if (err < 0) { - printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n", - __func__, err); - return (0); - } - card->para[1] = pnp_port_start(pnp_d, 0); - card->para[0] = pnp_irq(pnp_d, 0); - - if (card->para[0] == -1 || !card->para[1]) { - printk(KERN_ERR "Elsa PnP:some resources are missing %ld/%lx\n", - card->para[0], card->para[1]); - pnp_disable_dev(pnp_d); - return (0); - } - if (ipid->function == ISAPNP_FUNCTION(0x133)) - cs->subtyp = ELSA_QS1000; - else - cs->subtyp = ELSA_QS3000; - break; - } else { - printk(KERN_ERR "Elsa PnP: PnP error card found, no device\n"); - return (0); - } - } - ipid++; - pnp_c = NULL; - } - if (!ipid->card_vendor) { - printk(KERN_INFO "Elsa PnP: no ISAPnP card found\n"); - return (0); - } - } -#endif /* __ISAPNP__ */ - - if (card->para[1] && card->para[0]) { - cs->hw.elsa.base = card->para[1]; - cs->irq = card->para[0]; - if (!cs->subtyp) - cs->subtyp = ELSA_QS1000; - } else { - printk(KERN_ERR "Elsa PnP: no parameter\n"); - } - cs->hw.elsa.cfg = cs->hw.elsa.base + ELSA_CONFIG; - cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE; - cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC; - cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX; - cs->hw.elsa.trig = cs->hw.elsa.base + ELSA_TRIG_IRQ; - cs->hw.elsa.timer = cs->hw.elsa.base + ELSA_START_TIMER; - cs->hw.elsa.ctrl = cs->hw.elsa.base + ELSA_CONTROL; - printk(KERN_INFO - "Elsa: %s defined at %#lx IRQ %d\n", - Elsa_Types[cs->subtyp], - cs->hw.elsa.base, - cs->irq); - - return (1); -} - -static void setup_elsa_pcmcia(struct IsdnCard *card) -{ - struct IsdnCardState *cs = card->cs; - u_char val; - - cs->hw.elsa.base = card->para[1]; - cs->irq = card->para[0]; - val = readreg(cs->hw.elsa.base + 0, cs->hw.elsa.base + 2, IPAC_ID); - if ((val == 1) || (val == 2)) { /* IPAC version 1.1/1.2 */ - cs->subtyp = ELSA_PCMCIA_IPAC; - cs->hw.elsa.ale = cs->hw.elsa.base + 0; - cs->hw.elsa.isac = cs->hw.elsa.base + 2; - cs->hw.elsa.hscx = cs->hw.elsa.base + 2; - test_and_set_bit(HW_IPAC, &cs->HW_Flags); - } else { - cs->subtyp = ELSA_PCMCIA; - cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE_PCM; - cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC_PCM; - cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX; - } - cs->hw.elsa.timer = 0; - cs->hw.elsa.trig = 0; - cs->hw.elsa.ctrl = 0; - cs->irq_flags |= IRQF_SHARED; - printk(KERN_INFO - "Elsa: %s defined at %#lx IRQ %d\n", - Elsa_Types[cs->subtyp], - cs->hw.elsa.base, - cs->irq); -} - -#ifdef CONFIG_PCI -static struct pci_dev *dev_qs1000 = NULL; -static struct pci_dev *dev_qs3000 = NULL; - -static int setup_elsa_pci(struct IsdnCard *card) -{ - struct IsdnCardState *cs = card->cs; - - cs->subtyp = 0; - if ((dev_qs1000 = hisax_find_pci_device(PCI_VENDOR_ID_ELSA, - PCI_DEVICE_ID_ELSA_MICROLINK, dev_qs1000))) { - if (pci_enable_device(dev_qs1000)) - return (0); - cs->subtyp = ELSA_QS1000PCI; - cs->irq = dev_qs1000->irq; - cs->hw.elsa.cfg = pci_resource_start(dev_qs1000, 1); - cs->hw.elsa.base = pci_resource_start(dev_qs1000, 3); - } else if ((dev_qs3000 = hisax_find_pci_device(PCI_VENDOR_ID_ELSA, - PCI_DEVICE_ID_ELSA_QS3000, dev_qs3000))) { - if (pci_enable_device(dev_qs3000)) - return (0); - cs->subtyp = ELSA_QS3000PCI; - cs->irq = dev_qs3000->irq; - cs->hw.elsa.cfg = pci_resource_start(dev_qs3000, 1); - cs->hw.elsa.base = pci_resource_start(dev_qs3000, 3); - } else { - printk(KERN_WARNING "Elsa: No PCI card found\n"); - return (0); - } - if (!cs->irq) { - printk(KERN_WARNING "Elsa: No IRQ for PCI card found\n"); - return (0); - } - - if (!(cs->hw.elsa.base && cs->hw.elsa.cfg)) { - printk(KERN_WARNING "Elsa: No IO-Adr for PCI card found\n"); - return (0); - } - if ((cs->hw.elsa.cfg & 0xff) || (cs->hw.elsa.base & 0xf)) { - printk(KERN_WARNING "Elsa: You may have a wrong PCI bios\n"); - printk(KERN_WARNING "Elsa: If your system hangs now, read\n"); - printk(KERN_WARNING "Elsa: Documentation/isdn/README.HiSax\n"); - } - cs->hw.elsa.ale = cs->hw.elsa.base; - cs->hw.elsa.isac = cs->hw.elsa.base + 1; - cs->hw.elsa.hscx = cs->hw.elsa.base + 1; - test_and_set_bit(HW_IPAC, &cs->HW_Flags); - cs->hw.elsa.timer = 0; - cs->hw.elsa.trig = 0; - cs->irq_flags |= IRQF_SHARED; - printk(KERN_INFO - "Elsa: %s defined at %#lx/0x%x IRQ %d\n", - Elsa_Types[cs->subtyp], - cs->hw.elsa.base, - cs->hw.elsa.cfg, - cs->irq); - - return (1); -} - -#else - -static int setup_elsa_pci(struct IsdnCard *card) -{ - return (1); -} -#endif /* CONFIG_PCI */ - -static int setup_elsa_common(struct IsdnCard *card) -{ - struct IsdnCardState *cs = card->cs; - u_char val; - int bytecnt; - - switch (cs->subtyp) { - case ELSA_PC: - case ELSA_PCC8: - case ELSA_PCC16: - case ELSA_QS1000: - case ELSA_PCMCIA: - case ELSA_PCMCIA_IPAC: - bytecnt = 8; - break; - case ELSA_PCFPRO: - case ELSA_PCF: - case ELSA_QS3000: - case ELSA_QS3000PCI: - bytecnt = 16; - break; - case ELSA_QS1000PCI: - bytecnt = 2; - break; - default: - printk(KERN_WARNING - "Unknown ELSA subtype %d\n", cs->subtyp); - return (0); - } - /* In case of the elsa pcmcia card, this region is in use, - reserved for us by the card manager. So we do not check it - here, it would fail. */ - if (cs->typ != ISDN_CTYPE_ELSA_PCMCIA && !request_region(cs->hw.elsa.base, bytecnt, "elsa isdn")) { - printk(KERN_WARNING - "HiSax: ELSA config port %#lx-%#lx already in use\n", - cs->hw.elsa.base, - cs->hw.elsa.base + bytecnt); - return (0); - } - if ((cs->subtyp == ELSA_QS1000PCI) || (cs->subtyp == ELSA_QS3000PCI)) { - if (!request_region(cs->hw.elsa.cfg, 0x80, "elsa isdn pci")) { - printk(KERN_WARNING - "HiSax: ELSA pci port %x-%x already in use\n", - cs->hw.elsa.cfg, - cs->hw.elsa.cfg + 0x80); - release_region(cs->hw.elsa.base, bytecnt); - return (0); - } - } -#if ARCOFI_USE - init_arcofi(cs); -#endif - setup_isac(cs); - timer_setup(&cs->hw.elsa.tl, elsa_led_handler, 0); - /* Teste Timer */ - if (cs->hw.elsa.timer) { - byteout(cs->hw.elsa.trig, 0xff); - byteout(cs->hw.elsa.timer, 0); - if (!TimerRun(cs)) { - byteout(cs->hw.elsa.timer, 0); /* 2. Versuch */ - if (!TimerRun(cs)) { - printk(KERN_WARNING - "Elsa: timer do not start\n"); - release_io_elsa(cs); - return (0); - } - } - HZDELAY((HZ / 100) + 1); /* wait >=10 ms */ - if (TimerRun(cs)) { - printk(KERN_WARNING "Elsa: timer do not run down\n"); - release_io_elsa(cs); - return (0); - } - printk(KERN_INFO "Elsa: timer OK; resetting card\n"); - } - cs->BC_Read_Reg = &ReadHSCX; - cs->BC_Write_Reg = &WriteHSCX; - cs->BC_Send_Data = &hscx_fill_fifo; - cs->cardmsg = &Elsa_card_msg; - if ((cs->subtyp == ELSA_QS1000PCI) || (cs->subtyp == ELSA_QS3000PCI) || (cs->subtyp == ELSA_PCMCIA_IPAC)) { - cs->readisac = &ReadISAC_IPAC; - cs->writeisac = &WriteISAC_IPAC; - cs->readisacfifo = &ReadISACfifo_IPAC; - cs->writeisacfifo = &WriteISACfifo_IPAC; - cs->irq_func = &elsa_interrupt_ipac; - val = readreg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_ID); - printk(KERN_INFO "Elsa: IPAC version %x\n", val); - } else { - cs->readisac = &ReadISAC; - cs->writeisac = &WriteISAC; - cs->readisacfifo = &ReadISACfifo; - cs->writeisacfifo = &WriteISACfifo; - cs->irq_func = &elsa_interrupt; - ISACVersion(cs, "Elsa:"); - if (HscxVersion(cs, "Elsa:")) { - printk(KERN_WARNING - "Elsa: wrong HSCX versions check IO address\n"); - release_io_elsa(cs); - return (0); - } - } - if (cs->subtyp == ELSA_PC) { - val = readitac(cs, ITAC_SYS); - printk(KERN_INFO "Elsa: ITAC version %s\n", ITACVer[val & 7]); - writeitac(cs, ITAC_ISEN, 0); - writeitac(cs, ITAC_RFIE, 0); - writeitac(cs, ITAC_XFIE, 0); - writeitac(cs, ITAC_SCIE, 0); - writeitac(cs, ITAC_STIE, 0); - } - return (1); -} - -int setup_elsa(struct IsdnCard *card) -{ - int rc; - struct IsdnCardState *cs = card->cs; - char tmp[64]; - - strcpy(tmp, Elsa_revision); - printk(KERN_INFO "HiSax: Elsa driver Rev. %s\n", HiSax_getrev(tmp)); - cs->hw.elsa.ctrl_reg = 0; - cs->hw.elsa.status = 0; - cs->hw.elsa.MFlag = 0; - cs->subtyp = 0; - - if (cs->typ == ISDN_CTYPE_ELSA) { - rc = setup_elsa_isa(card); - if (!rc) - return (0); - - } else if (cs->typ == ISDN_CTYPE_ELSA_PNP) { - rc = setup_elsa_isapnp(card); - if (!rc) - return (0); - - } else if (cs->typ == ISDN_CTYPE_ELSA_PCMCIA) - setup_elsa_pcmcia(card); - - else if (cs->typ == ISDN_CTYPE_ELSA_PCI) { - rc = setup_elsa_pci(card); - if (!rc) - return (0); - - } else - return (0); - - return setup_elsa_common(card); -} diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c deleted file mode 100644 index 40f6fad79de3..000000000000 --- a/drivers/isdn/hisax/elsa_cs.c +++ /dev/null @@ -1,218 +0,0 @@ -/*====================================================================== - - An elsa_cs PCMCIA client driver - - This driver is for the Elsa PCM ISDN Cards, i.e. the MicroLink - - - The contents of this file are subject to the Mozilla Public - License Version 1.1 (the "License"); you may not use this file - except in compliance with the License. You may obtain a copy of - the License at http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS - IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - implied. See the License for the specific language governing - rights and limitations under the License. - - The initial developer of the original code is David A. Hinds - <dahinds@users.sourceforge.net>. Portions created by David A. Hinds - are Copyright (C) 1999 David A. Hinds. All Rights Reserved. - - Modifications from dummy_cs.c are Copyright (C) 1999-2001 Klaus - Lichtenwalder <Lichtenwalder@ACM.org>. All Rights Reserved. - - Alternatively, the contents of this file may be used under the - terms of the GNU General Public License version 2 (the "GPL"), in - which case the provisions of the GPL are applicable instead of the - above. If you wish to allow the use of your version of this file - only under the terms of the GPL and not to allow others to use - your version of this file under the MPL, indicate your decision - by deleting the provisions above and replace them with the notice - and other provisions required by the GPL. If you do not delete - the provisions above, a recipient may use your version of this - file under either the MPL or the GPL. - - ======================================================================*/ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/ptrace.h> -#include <linux/slab.h> -#include <linux/string.h> -#include <linux/timer.h> -#include <linux/ioport.h> -#include <asm/io.h> - -#include <pcmcia/cistpl.h> -#include <pcmcia/cisreg.h> -#include <pcmcia/ds.h> -#include "hisax_cfg.h" - -MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Elsa PCM cards"); -MODULE_AUTHOR("Klaus Lichtenwalder"); -MODULE_LICENSE("Dual MPL/GPL"); - - -/*====================================================================*/ - -/* Parameters that can be set with 'insmod' */ - -static int protocol = 2; /* EURO-ISDN Default */ -module_param(protocol, int, 0); - -static int elsa_cs_config(struct pcmcia_device *link); -static void elsa_cs_release(struct pcmcia_device *link); -static void elsa_cs_detach(struct pcmcia_device *p_dev); - -typedef struct local_info_t { - struct pcmcia_device *p_dev; - int busy; - int cardnr; -} local_info_t; - -static int elsa_cs_probe(struct pcmcia_device *link) -{ - local_info_t *local; - - dev_dbg(&link->dev, "elsa_cs_attach()\n"); - - /* Allocate space for private device-specific data */ - local = kzalloc(sizeof(local_info_t), GFP_KERNEL); - if (!local) return -ENOMEM; - - local->p_dev = link; - link->priv = local; - - local->cardnr = -1; - - return elsa_cs_config(link); -} /* elsa_cs_attach */ - -static void elsa_cs_detach(struct pcmcia_device *link) -{ - local_info_t *info = link->priv; - - dev_dbg(&link->dev, "elsa_cs_detach(0x%p)\n", link); - - info->busy = 1; - elsa_cs_release(link); - - kfree(info); -} /* elsa_cs_detach */ - -static int elsa_cs_configcheck(struct pcmcia_device *p_dev, void *priv_data) -{ - int j; - - p_dev->io_lines = 3; - p_dev->resource[0]->end = 8; - p_dev->resource[0]->flags &= IO_DATA_PATH_WIDTH; - p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; - - if ((p_dev->resource[0]->end) && p_dev->resource[0]->start) { - printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n"); - if (!pcmcia_request_io(p_dev)) - return 0; - } else { - printk(KERN_INFO "(elsa_cs: looks like the 97 model)\n"); - for (j = 0x2f0; j > 0x100; j -= 0x10) { - p_dev->resource[0]->start = j; - if (!pcmcia_request_io(p_dev)) - return 0; - } - } - return -ENODEV; -} - -static int elsa_cs_config(struct pcmcia_device *link) -{ - int i; - IsdnCard_t icard; - - dev_dbg(&link->dev, "elsa_config(0x%p)\n", link); - - link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; - - i = pcmcia_loop_config(link, elsa_cs_configcheck, NULL); - if (i != 0) - goto failed; - - if (!link->irq) - goto failed; - - i = pcmcia_enable_device(link); - if (i != 0) - goto failed; - - icard.para[0] = link->irq; - icard.para[1] = link->resource[0]->start; - icard.protocol = protocol; - icard.typ = ISDN_CTYPE_ELSA_PCMCIA; - - i = hisax_init_pcmcia(link, &(((local_info_t *)link->priv)->busy), &icard); - if (i < 0) { - printk(KERN_ERR "elsa_cs: failed to initialize Elsa " - "PCMCIA %d with %pR\n", i, link->resource[0]); - elsa_cs_release(link); - } else - ((local_info_t *)link->priv)->cardnr = i; - - return 0; -failed: - elsa_cs_release(link); - return -ENODEV; -} /* elsa_cs_config */ - -static void elsa_cs_release(struct pcmcia_device *link) -{ - local_info_t *local = link->priv; - - dev_dbg(&link->dev, "elsa_cs_release(0x%p)\n", link); - - if (local) { - if (local->cardnr >= 0) { - /* no unregister function with hisax */ - HiSax_closecard(local->cardnr); - } - } - - pcmcia_disable_device(link); -} /* elsa_cs_release */ - -static int elsa_suspend(struct pcmcia_device *link) -{ - local_info_t *dev = link->priv; - - dev->busy = 1; - - return 0; -} - -static int elsa_resume(struct pcmcia_device *link) -{ - local_info_t *dev = link->priv; - - dev->busy = 0; - - return 0; -} - -static const struct pcmcia_device_id elsa_ids[] = { - PCMCIA_DEVICE_PROD_ID12("ELSA AG (Aachen, Germany)", "MicroLink ISDN/MC ", 0x983de2c4, 0x333ba257), - PCMCIA_DEVICE_PROD_ID12("ELSA GmbH, Aachen", "MicroLink ISDN/MC ", 0x639e5718, 0x333ba257), - PCMCIA_DEVICE_NULL -}; -MODULE_DEVICE_TABLE(pcmcia, elsa_ids); - -static struct pcmcia_driver elsa_cs_driver = { - .owner = THIS_MODULE, - .name = "elsa_cs", - .probe = elsa_cs_probe, - .remove = elsa_cs_detach, - .id_table = elsa_ids, - .suspend = elsa_suspend, - .resume = elsa_resume, -}; -module_pcmcia_driver(elsa_cs_driver); diff --git a/drivers/isdn/hisax/elsa_ser.c b/drivers/isdn/hisax/elsa_ser.c deleted file mode 100644 index 999effd7a276..000000000000 --- a/drivers/isdn/hisax/elsa_ser.c +++ /dev/null @@ -1,659 +0,0 @@ -/* $Id: elsa_ser.c,v 2.14.2.3 2004/02/11 13:21:33 keil Exp $ - * - * stuff for the serial modem on ELSA cards - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#include <linux/serial.h> -#include <linux/serial_reg.h> -#include <linux/slab.h> - -#define MAX_MODEM_BUF 256 -#define WAKEUP_CHARS (MAX_MODEM_BUF / 2) -#define RS_ISR_PASS_LIMIT 256 -#define BASE_BAUD (1843200 / 16) - -//#define SERIAL_DEBUG_OPEN 1 -//#define SERIAL_DEBUG_INTR 1 -//#define SERIAL_DEBUG_FLOW 1 -#undef SERIAL_DEBUG_OPEN -#undef SERIAL_DEBUG_INTR -#undef SERIAL_DEBUG_FLOW -#undef SERIAL_DEBUG_REG -//#define SERIAL_DEBUG_REG 1 - -#ifdef SERIAL_DEBUG_REG -static u_char deb[32]; -const char *ModemIn[] = {"RBR", "IER", "IIR", "LCR", "MCR", "LSR", "MSR", "SCR"}; -const char *ModemOut[] = {"THR", "IER", "FCR", "LCR", "MCR", "LSR", "MSR", "SCR"}; -#endif - -static char *MInit_1 = "AT&F&C1E0&D2\r\0"; -static char *MInit_2 = "ATL2M1S64=13\r\0"; -static char *MInit_3 = "AT+FCLASS=0\r\0"; -static char *MInit_4 = "ATV1S2=128X1\r\0"; -static char *MInit_5 = "AT\\V8\\N3\r\0"; -static char *MInit_6 = "ATL0M0&G0%E1\r\0"; -static char *MInit_7 = "AT%L1%M0%C3\r\0"; - -static char *MInit_speed28800 = "AT%G0%B28800\r\0"; - -static char *MInit_dialout = "ATs7=60 x1 d\r\0"; -static char *MInit_dialin = "ATs7=60 x1 a\r\0"; - - -static inline unsigned int serial_in(struct IsdnCardState *cs, int offset) -{ -#ifdef SERIAL_DEBUG_REG - u_int val = inb(cs->hw.elsa.base + 8 + offset); - debugl1(cs, "in %s %02x", ModemIn[offset], val); - return (val); -#else - return inb(cs->hw.elsa.base + 8 + offset); -#endif -} - -static inline unsigned int serial_inp(struct IsdnCardState *cs, int offset) -{ -#ifdef SERIAL_DEBUG_REG -#ifdef ELSA_SERIAL_NOPAUSE_IO - u_int val = inb(cs->hw.elsa.base + 8 + offset); - debugl1(cs, "inp %s %02x", ModemIn[offset], val); -#else - u_int val = inb_p(cs->hw.elsa.base + 8 + offset); - debugl1(cs, "inP %s %02x", ModemIn[offset], val); -#endif - return (val); -#else -#ifdef ELSA_SERIAL_NOPAUSE_IO - return inb(cs->hw.elsa.base + 8 + offset); -#else - return inb_p(cs->hw.elsa.base + 8 + offset); -#endif -#endif -} - -static inline void serial_out(struct IsdnCardState *cs, int offset, int value) -{ -#ifdef SERIAL_DEBUG_REG - debugl1(cs, "out %s %02x", ModemOut[offset], value); -#endif - outb(value, cs->hw.elsa.base + 8 + offset); -} - -static inline void serial_outp(struct IsdnCardState *cs, int offset, - int value) -{ -#ifdef SERIAL_DEBUG_REG -#ifdef ELSA_SERIAL_NOPAUSE_IO - debugl1(cs, "outp %s %02x", ModemOut[offset], value); -#else - debugl1(cs, "outP %s %02x", ModemOut[offset], value); -#endif -#endif -#ifdef ELSA_SERIAL_NOPAUSE_IO - outb(value, cs->hw.elsa.base + 8 + offset); -#else - outb_p(value, cs->hw.elsa.base + 8 + offset); -#endif -} - -/* - * This routine is called to set the UART divisor registers to match - * the specified baud rate for a serial port. - */ -static void change_speed(struct IsdnCardState *cs, int baud) -{ - int quot = 0, baud_base; - unsigned cval, fcr = 0; - - - /* byte size and parity */ - cval = 0x03; - /* Determine divisor based on baud rate */ - baud_base = BASE_BAUD; - quot = baud_base / baud; - /* If the quotient is ever zero, default to 9600 bps */ - if (!quot) - quot = baud_base / 9600; - - /* Set up FIFO's */ - if ((baud_base / quot) < 2400) - fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1; - else - fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_8; - serial_outp(cs, UART_FCR, fcr); - /* CTS flow control flag and modem status interrupts */ - cs->hw.elsa.IER &= ~UART_IER_MSI; - cs->hw.elsa.IER |= UART_IER_MSI; - serial_outp(cs, UART_IER, cs->hw.elsa.IER); - - debugl1(cs, "modem quot=0x%x", quot); - serial_outp(cs, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */ - serial_outp(cs, UART_DLL, quot & 0xff); /* LS of divisor */ - serial_outp(cs, UART_DLM, quot >> 8); /* MS of divisor */ - serial_outp(cs, UART_LCR, cval); /* reset DLAB */ - serial_inp(cs, UART_RX); -} - -static int mstartup(struct IsdnCardState *cs) -{ - int retval = 0; - - /* - * Clear the FIFO buffers and disable them - * (they will be reenabled in change_speed()) - */ - serial_outp(cs, UART_FCR, (UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT)); - - /* - * At this point there's no way the LSR could still be 0xFF; - * if it is, then bail out, because there's likely no UART - * here. - */ - if (serial_inp(cs, UART_LSR) == 0xff) { - retval = -ENODEV; - goto errout; - } - - /* - * Clear the interrupt registers. - */ - (void) serial_inp(cs, UART_RX); - (void) serial_inp(cs, UART_IIR); - (void) serial_inp(cs, UART_MSR); - - /* - * Now, initialize the UART - */ - serial_outp(cs, UART_LCR, UART_LCR_WLEN8); /* reset DLAB */ - - cs->hw.elsa.MCR = 0; - cs->hw.elsa.MCR = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2; - serial_outp(cs, UART_MCR, cs->hw.elsa.MCR); - - /* - * Finally, enable interrupts - */ - cs->hw.elsa.IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI; - serial_outp(cs, UART_IER, cs->hw.elsa.IER); /* enable interrupts */ - - /* - * And clear the interrupt registers again for luck. - */ - (void)serial_inp(cs, UART_LSR); - (void)serial_inp(cs, UART_RX); - (void)serial_inp(cs, UART_IIR); - (void)serial_inp(cs, UART_MSR); - - cs->hw.elsa.transcnt = cs->hw.elsa.transp = 0; - cs->hw.elsa.rcvcnt = cs->hw.elsa.rcvp = 0; - - /* - * and set the speed of the serial port - */ - change_speed(cs, BASE_BAUD); - cs->hw.elsa.MFlag = 1; -errout: - return retval; -} - -/* - * This routine will shutdown a serial port; interrupts are disabled, and - * DTR is dropped if the hangup on close termio flag is on. - */ -static void mshutdown(struct IsdnCardState *cs) -{ - -#ifdef SERIAL_DEBUG_OPEN - printk(KERN_DEBUG"Shutting down serial ...."); -#endif - - /* - * clear delta_msr_wait queue to avoid mem leaks: we may free the irq - * here so the queue might never be waken up - */ - - cs->hw.elsa.IER = 0; - serial_outp(cs, UART_IER, 0x00); /* disable all intrs */ - cs->hw.elsa.MCR &= ~UART_MCR_OUT2; - - /* disable break condition */ - serial_outp(cs, UART_LCR, serial_inp(cs, UART_LCR) & ~UART_LCR_SBC); - - cs->hw.elsa.MCR &= ~(UART_MCR_DTR | UART_MCR_RTS); - serial_outp(cs, UART_MCR, cs->hw.elsa.MCR); - - /* disable FIFO's */ - serial_outp(cs, UART_FCR, (UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT)); - serial_inp(cs, UART_RX); /* read data port to reset things */ - -#ifdef SERIAL_DEBUG_OPEN - printk(" done\n"); -#endif -} - -static inline int -write_modem(struct BCState *bcs) { - int ret = 0; - struct IsdnCardState *cs = bcs->cs; - int count, len, fp; - - if (!bcs->tx_skb) - return 0; - if (bcs->tx_skb->len <= 0) - return 0; - len = bcs->tx_skb->len; - if (len > MAX_MODEM_BUF - cs->hw.elsa.transcnt) - len = MAX_MODEM_BUF - cs->hw.elsa.transcnt; - fp = cs->hw.elsa.transcnt + cs->hw.elsa.transp; - fp &= (MAX_MODEM_BUF - 1); - count = len; - if (count > MAX_MODEM_BUF - fp) { - count = MAX_MODEM_BUF - fp; - skb_copy_from_linear_data(bcs->tx_skb, - cs->hw.elsa.transbuf + fp, count); - skb_pull(bcs->tx_skb, count); - cs->hw.elsa.transcnt += count; - ret = count; - count = len - count; - fp = 0; - } - skb_copy_from_linear_data(bcs->tx_skb, - cs->hw.elsa.transbuf + fp, count); - skb_pull(bcs->tx_skb, count); - cs->hw.elsa.transcnt += count; - ret += count; - - if (cs->hw.elsa.transcnt && - !(cs->hw.elsa.IER & UART_IER_THRI)) { - cs->hw.elsa.IER |= UART_IER_THRI; - serial_outp(cs, UART_IER, cs->hw.elsa.IER); - } - return (ret); -} - -static inline void -modem_fill(struct BCState *bcs) { - - if (bcs->tx_skb) { - if (bcs->tx_skb->len) { - write_modem(bcs); - return; - } else { - if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) && - (PACKET_NOACK != bcs->tx_skb->pkt_type)) { - u_long flags; - spin_lock_irqsave(&bcs->aclock, flags); - bcs->ackcnt += bcs->hw.hscx.count; - spin_unlock_irqrestore(&bcs->aclock, flags); - schedule_event(bcs, B_ACKPENDING); - } - dev_kfree_skb_any(bcs->tx_skb); - bcs->tx_skb = NULL; - } - } - if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) { - bcs->hw.hscx.count = 0; - test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); - write_modem(bcs); - } else { - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - schedule_event(bcs, B_XMTBUFREADY); - } -} - -static inline void receive_chars(struct IsdnCardState *cs, - int *status) -{ - unsigned char ch; - struct sk_buff *skb; - - do { - ch = serial_in(cs, UART_RX); - if (cs->hw.elsa.rcvcnt >= MAX_MODEM_BUF) - break; - cs->hw.elsa.rcvbuf[cs->hw.elsa.rcvcnt++] = ch; -#ifdef SERIAL_DEBUG_INTR - printk("DR%02x:%02x...", ch, *status); -#endif - if (*status & (UART_LSR_BI | UART_LSR_PE | - UART_LSR_FE | UART_LSR_OE)) { - -#ifdef SERIAL_DEBUG_INTR - printk("handling exept...."); -#endif - } - *status = serial_inp(cs, UART_LSR); - } while (*status & UART_LSR_DR); - if (cs->hw.elsa.MFlag == 2) { - if (!(skb = dev_alloc_skb(cs->hw.elsa.rcvcnt))) - printk(KERN_WARNING "ElsaSER: receive out of memory\n"); - else { - skb_put_data(skb, cs->hw.elsa.rcvbuf, - cs->hw.elsa.rcvcnt); - skb_queue_tail(&cs->hw.elsa.bcs->rqueue, skb); - } - schedule_event(cs->hw.elsa.bcs, B_RCVBUFREADY); - } else { - char tmp[128]; - char *t = tmp; - - t += sprintf(t, "modem read cnt %d", cs->hw.elsa.rcvcnt); - QuickHex(t, cs->hw.elsa.rcvbuf, cs->hw.elsa.rcvcnt); - debugl1(cs, "%s", tmp); - } - cs->hw.elsa.rcvcnt = 0; -} - -static inline void transmit_chars(struct IsdnCardState *cs, int *intr_done) -{ - int count; - - debugl1(cs, "transmit_chars: p(%x) cnt(%x)", cs->hw.elsa.transp, - cs->hw.elsa.transcnt); - - if (cs->hw.elsa.transcnt <= 0) { - cs->hw.elsa.IER &= ~UART_IER_THRI; - serial_out(cs, UART_IER, cs->hw.elsa.IER); - return; - } - count = 16; - do { - serial_outp(cs, UART_TX, cs->hw.elsa.transbuf[cs->hw.elsa.transp++]); - if (cs->hw.elsa.transp >= MAX_MODEM_BUF) - cs->hw.elsa.transp = 0; - if (--cs->hw.elsa.transcnt <= 0) - break; - } while (--count > 0); - if ((cs->hw.elsa.transcnt < WAKEUP_CHARS) && (cs->hw.elsa.MFlag == 2)) - modem_fill(cs->hw.elsa.bcs); - -#ifdef SERIAL_DEBUG_INTR - printk("THRE..."); -#endif - if (intr_done) - *intr_done = 0; - if (cs->hw.elsa.transcnt <= 0) { - cs->hw.elsa.IER &= ~UART_IER_THRI; - serial_outp(cs, UART_IER, cs->hw.elsa.IER); - } -} - - -static void rs_interrupt_elsa(struct IsdnCardState *cs) -{ - int status, iir, msr; - int pass_counter = 0; - -#ifdef SERIAL_DEBUG_INTR - printk(KERN_DEBUG "rs_interrupt_single(%d)...", cs->irq); -#endif - - do { - status = serial_inp(cs, UART_LSR); - debugl1(cs, "rs LSR %02x", status); -#ifdef SERIAL_DEBUG_INTR - printk("status = %x...", status); -#endif - if (status & UART_LSR_DR) - receive_chars(cs, &status); - if (status & UART_LSR_THRE) - transmit_chars(cs, NULL); - if (pass_counter++ > RS_ISR_PASS_LIMIT) { - printk("rs_single loop break.\n"); - break; - } - iir = serial_inp(cs, UART_IIR); - debugl1(cs, "rs IIR %02x", iir); - if ((iir & 0xf) == 0) { - msr = serial_inp(cs, UART_MSR); - debugl1(cs, "rs MSR %02x", msr); - } - } while (!(iir & UART_IIR_NO_INT)); -#ifdef SERIAL_DEBUG_INTR - printk("end.\n"); -#endif -} - -extern int open_hscxstate(struct IsdnCardState *cs, struct BCState *bcs); -extern void modehscx(struct BCState *bcs, int mode, int bc); -extern void hscx_l2l1(struct PStack *st, int pr, void *arg); - -static void -close_elsastate(struct BCState *bcs) -{ - modehscx(bcs, 0, bcs->channel); - if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) { - if (bcs->hw.hscx.rcvbuf) { - if (bcs->mode != L1_MODE_MODEM) - kfree(bcs->hw.hscx.rcvbuf); - bcs->hw.hscx.rcvbuf = NULL; - } - skb_queue_purge(&bcs->rqueue); - skb_queue_purge(&bcs->squeue); - if (bcs->tx_skb) { - dev_kfree_skb_any(bcs->tx_skb); - bcs->tx_skb = NULL; - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - } - } -} - -static void -modem_write_cmd(struct IsdnCardState *cs, u_char *buf, int len) { - int count, fp; - u_char *msg = buf; - - if (!len) - return; - if (len > (MAX_MODEM_BUF - cs->hw.elsa.transcnt)) { - return; - } - fp = cs->hw.elsa.transcnt + cs->hw.elsa.transp; - fp &= (MAX_MODEM_BUF - 1); - count = len; - if (count > MAX_MODEM_BUF - fp) { - count = MAX_MODEM_BUF - fp; - memcpy(cs->hw.elsa.transbuf + fp, msg, count); - cs->hw.elsa.transcnt += count; - msg += count; - count = len - count; - fp = 0; - } - memcpy(cs->hw.elsa.transbuf + fp, msg, count); - cs->hw.elsa.transcnt += count; - if (cs->hw.elsa.transcnt && - !(cs->hw.elsa.IER & UART_IER_THRI)) { - cs->hw.elsa.IER |= UART_IER_THRI; - serial_outp(cs, UART_IER, cs->hw.elsa.IER); - } -} - -static void -modem_set_init(struct IsdnCardState *cs) { - int timeout; - -#define RCV_DELAY 20 - modem_write_cmd(cs, MInit_1, strlen(MInit_1)); - timeout = 1000; - while (timeout-- && cs->hw.elsa.transcnt) - udelay(1000); - debugl1(cs, "msi tout=%d", timeout); - mdelay(RCV_DELAY); - modem_write_cmd(cs, MInit_2, strlen(MInit_2)); - timeout = 1000; - while (timeout-- && cs->hw.elsa.transcnt) - udelay(1000); - debugl1(cs, "msi tout=%d", timeout); - mdelay(RCV_DELAY); - modem_write_cmd(cs, MInit_3, strlen(MInit_3)); - timeout = 1000; - while (timeout-- && cs->hw.elsa.transcnt) - udelay(1000); - debugl1(cs, "msi tout=%d", timeout); - mdelay(RCV_DELAY); - modem_write_cmd(cs, MInit_4, strlen(MInit_4)); - timeout = 1000; - while (timeout-- && cs->hw.elsa.transcnt) - udelay(1000); - debugl1(cs, "msi tout=%d", timeout); - mdelay(RCV_DELAY); - modem_write_cmd(cs, MInit_5, strlen(MInit_5)); - timeout = 1000; - while (timeout-- && cs->hw.elsa.transcnt) - udelay(1000); - debugl1(cs, "msi tout=%d", timeout); - mdelay(RCV_DELAY); - modem_write_cmd(cs, MInit_6, strlen(MInit_6)); - timeout = 1000; - while (timeout-- && cs->hw.elsa.transcnt) - udelay(1000); - debugl1(cs, "msi tout=%d", timeout); - mdelay(RCV_DELAY); - modem_write_cmd(cs, MInit_7, strlen(MInit_7)); - timeout = 1000; - while (timeout-- && cs->hw.elsa.transcnt) - udelay(1000); - debugl1(cs, "msi tout=%d", timeout); - mdelay(RCV_DELAY); -} - -static void -modem_set_dial(struct IsdnCardState *cs, int outgoing) { - int timeout; -#define RCV_DELAY 20 - - modem_write_cmd(cs, MInit_speed28800, strlen(MInit_speed28800)); - timeout = 1000; - while (timeout-- && cs->hw.elsa.transcnt) - udelay(1000); - debugl1(cs, "msi tout=%d", timeout); - mdelay(RCV_DELAY); - if (outgoing) - modem_write_cmd(cs, MInit_dialout, strlen(MInit_dialout)); - else - modem_write_cmd(cs, MInit_dialin, strlen(MInit_dialin)); - timeout = 1000; - while (timeout-- && cs->hw.elsa.transcnt) - udelay(1000); - debugl1(cs, "msi tout=%d", timeout); - mdelay(RCV_DELAY); -} - -static void -modem_l2l1(struct PStack *st, int pr, void *arg) -{ - struct BCState *bcs = st->l1.bcs; - struct sk_buff *skb = arg; - u_long flags; - - if (pr == (PH_DATA | REQUEST)) { - spin_lock_irqsave(&bcs->cs->lock, flags); - if (bcs->tx_skb) { - skb_queue_tail(&bcs->squeue, skb); - } else { - bcs->tx_skb = skb; - test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); - bcs->hw.hscx.count = 0; - write_modem(bcs); - } - spin_unlock_irqrestore(&bcs->cs->lock, flags); - } else if (pr == (PH_ACTIVATE | REQUEST)) { - test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag); - st->l1.l1l2(st, PH_ACTIVATE | CONFIRM, NULL); - set_arcofi(bcs->cs, st->l1.bc); - mstartup(bcs->cs); - modem_set_dial(bcs->cs, test_bit(FLG_ORIG, &st->l2.flag)); - bcs->cs->hw.elsa.MFlag = 2; - } else if (pr == (PH_DEACTIVATE | REQUEST)) { - test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag); - bcs->cs->dc.isac.arcofi_bc = st->l1.bc; - arcofi_fsm(bcs->cs, ARCOFI_START, &ARCOFI_XOP_0); - wait_event_interruptible(bcs->cs->dc.isac.arcofi_wait, - bcs->cs->dc.isac.arcofi_state == ARCOFI_NOP); - bcs->cs->hw.elsa.MFlag = 1; - } else { - printk(KERN_WARNING "ElsaSer: unknown pr %x\n", pr); - } -} - -static int -setstack_elsa(struct PStack *st, struct BCState *bcs) -{ - - bcs->channel = st->l1.bc; - switch (st->l1.mode) { - case L1_MODE_HDLC: - case L1_MODE_TRANS: - if (open_hscxstate(st->l1.hardware, bcs)) - return (-1); - st->l2.l2l1 = hscx_l2l1; - break; - case L1_MODE_MODEM: - bcs->mode = L1_MODE_MODEM; - if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { - bcs->hw.hscx.rcvbuf = bcs->cs->hw.elsa.rcvbuf; - skb_queue_head_init(&bcs->rqueue); - skb_queue_head_init(&bcs->squeue); - } - bcs->tx_skb = NULL; - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - bcs->event = 0; - bcs->hw.hscx.rcvidx = 0; - bcs->tx_cnt = 0; - bcs->cs->hw.elsa.bcs = bcs; - st->l2.l2l1 = modem_l2l1; - break; - } - st->l1.bcs = bcs; - setstack_manager(st); - bcs->st = st; - setstack_l1_B(st); - return (0); -} - -static void -init_modem(struct IsdnCardState *cs) { - - cs->bcs[0].BC_SetStack = setstack_elsa; - cs->bcs[1].BC_SetStack = setstack_elsa; - cs->bcs[0].BC_Close = close_elsastate; - cs->bcs[1].BC_Close = close_elsastate; - if (!(cs->hw.elsa.rcvbuf = kmalloc(MAX_MODEM_BUF, - GFP_ATOMIC))) { - printk(KERN_WARNING - "Elsa: No modem mem hw.elsa.rcvbuf\n"); - return; - } - if (!(cs->hw.elsa.transbuf = kmalloc(MAX_MODEM_BUF, - GFP_ATOMIC))) { - printk(KERN_WARNING - "Elsa: No modem mem hw.elsa.transbuf\n"); - kfree(cs->hw.elsa.rcvbuf); - cs->hw.elsa.rcvbuf = NULL; - return; - } - if (mstartup(cs)) { - printk(KERN_WARNING "Elsa: problem startup modem\n"); - } - modem_set_init(cs); -} - -static void -release_modem(struct IsdnCardState *cs) { - - cs->hw.elsa.MFlag = 0; - if (cs->hw.elsa.transbuf) { - if (cs->hw.elsa.rcvbuf) { - mshutdown(cs); - kfree(cs->hw.elsa.rcvbuf); - cs->hw.elsa.rcvbuf = NULL; - } - kfree(cs->hw.elsa.transbuf); - cs->hw.elsa.transbuf = NULL; - } -} diff --git a/drivers/isdn/hisax/enternow_pci.c b/drivers/isdn/hisax/enternow_pci.c deleted file mode 100644 index e8d431a8302d..000000000000 --- a/drivers/isdn/hisax/enternow_pci.c +++ /dev/null @@ -1,420 +0,0 @@ -/* enternow_pci.c,v 0.99 2001/10/02 - * - * enternow_pci.c Card-specific routines for - * Formula-n enter:now ISDN PCI ab - * Gerdes AG Power ISDN PCI - * Woerltronic SA 16 PCI - * (based on HiSax driver by Karsten Keil) - * - * Author Christoph Ersfeld <info@formula-n.de> - * Formula-n Europe AG (www.formula-n.com) - * previously Gerdes AG - * - * - * This file is (c) under GNU PUBLIC LICENSE - * - * Notes: - * This driver interfaces to netjet.c which performs B-channel - * processing. - * - * Version 0.99 is the first release of this driver and there are - * certainly a few bugs. - * It isn't testet on linux 2.4 yet, so consider this code to be - * beta. - * - * Please don't report me any malfunction without sending - * (compressed) debug-logs. - * It would be nearly impossible to retrace it. - * - * Log D-channel-processing as follows: - * - * 1. Load hisax with card-specific parameters, this example ist for - * Formula-n enter:now ISDN PCI and compatible - * (f.e. Gerdes Power ISDN PCI) - * - * modprobe hisax type=41 protocol=2 id=gerdes - * - * if you chose an other value for id, you need to modify the - * code below, too. - * - * 2. set debug-level - * - * hisaxctrl gerdes 1 0x3ff - * hisaxctrl gerdes 11 0x4f - * cat /dev/isdnctrl >> ~/log & - * - * Please take also a look into /var/log/messages if there is - * anything importand concerning HISAX. - * - * - * Credits: - * Programming the driver for Formula-n enter:now ISDN PCI and - * necessary the driver for the used Amd 7930 D-channel-controller - * was spnsored by Formula-n Europe AG. - * Thanks to Karsten Keil and Petr Novak, who gave me support in - * Hisax-specific questions. - * I want so say special thanks to Carl-Friedrich Braun, who had to - * answer a lot of questions about generally ISDN and about handling - * of the Amd-Chip. - * - */ - - -#include "hisax.h" -#include "isac.h" -#include "isdnl1.h" -#include "amd7930_fn.h" -#include <linux/interrupt.h> -#include <linux/ppp_defs.h> -#include <linux/pci.h> -#include <linux/init.h> -#include "netjet.h" - - - -static const char *enternow_pci_rev = "$Revision: 1.1.4.5 $"; - - -/* for PowerISDN PCI */ -#define TJ_AMD_IRQ 0x20 -#define TJ_LED1 0x40 -#define TJ_LED2 0x80 - - -/* The window to [the] AMD [chip]... - * From address hw.njet.base + TJ_AMD_PORT onwards, the AMD - * maps [consecutive/multiple] 8 bits into the TigerJet I/O space - * -> 0x01 of the AMD at hw.njet.base + 0C4 */ -#define TJ_AMD_PORT 0xC0 - - - -/* *************************** I/O-Interface functions ************************************* */ - - -/* cs->readisac, macro rByteAMD */ -static unsigned char -ReadByteAmd7930(struct IsdnCardState *cs, unsigned char offset) -{ - /* direct register */ - if (offset < 8) - return (inb(cs->hw.njet.isac + 4 * offset)); - - /* indirect register */ - else { - outb(offset, cs->hw.njet.isac + 4 * AMD_CR); - return (inb(cs->hw.njet.isac + 4 * AMD_DR)); - } -} - -/* cs->writeisac, macro wByteAMD */ -static void -WriteByteAmd7930(struct IsdnCardState *cs, unsigned char offset, unsigned char value) -{ - /* direct register */ - if (offset < 8) - outb(value, cs->hw.njet.isac + 4 * offset); - - /* indirect register */ - else { - outb(offset, cs->hw.njet.isac + 4 * AMD_CR); - outb(value, cs->hw.njet.isac + 4 * AMD_DR); - } -} - - -static void -enpci_setIrqMask(struct IsdnCardState *cs, unsigned char val) { - if (!val) - outb(0x00, cs->hw.njet.base + NETJET_IRQMASK1); - else - outb(TJ_AMD_IRQ, cs->hw.njet.base + NETJET_IRQMASK1); -} - - -static unsigned char dummyrr(struct IsdnCardState *cs, int chan, unsigned char off) -{ - return (5); -} - -static void dummywr(struct IsdnCardState *cs, int chan, unsigned char off, unsigned char value) -{ - -} - - -/* ******************************************************************************** */ - - -static void -reset_enpci(struct IsdnCardState *cs) -{ - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "enter:now PCI: reset"); - - /* Reset on, (also for AMD) */ - cs->hw.njet.ctrl_reg = 0x07; - outb(cs->hw.njet.ctrl_reg, cs->hw.njet.base + NETJET_CTRL); - mdelay(20); - /* Reset off */ - cs->hw.njet.ctrl_reg = 0x30; - outb(cs->hw.njet.ctrl_reg, cs->hw.njet.base + NETJET_CTRL); - /* 20ms delay */ - mdelay(20); - cs->hw.njet.auxd = 0; // LED-status - cs->hw.njet.dmactrl = 0; - outb(~TJ_AMD_IRQ, cs->hw.njet.base + NETJET_AUXCTRL); - outb(TJ_AMD_IRQ, cs->hw.njet.base + NETJET_IRQMASK1); - outb(cs->hw.njet.auxd, cs->hw.njet.auxa); // LED off -} - - -static int -enpci_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - u_long flags; - unsigned char *chan; - - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "enter:now PCI: card_msg: 0x%04X", mt); - - switch (mt) { - case CARD_RESET: - spin_lock_irqsave(&cs->lock, flags); - reset_enpci(cs); - Amd7930_init(cs); - spin_unlock_irqrestore(&cs->lock, flags); - break; - case CARD_RELEASE: - release_io_netjet(cs); - break; - case CARD_INIT: - reset_enpci(cs); - inittiger(cs); - /* irq must be on here */ - Amd7930_init(cs); - break; - case CARD_TEST: - break; - case MDL_ASSIGN: - /* TEI assigned, LED1 on */ - cs->hw.njet.auxd = TJ_AMD_IRQ << 1; - outb(cs->hw.njet.auxd, cs->hw.njet.base + NETJET_AUXDATA); - break; - case MDL_REMOVE: - /* TEI removed, LEDs off */ - cs->hw.njet.auxd = 0; - outb(0x00, cs->hw.njet.base + NETJET_AUXDATA); - break; - case MDL_BC_ASSIGN: - /* activate B-channel */ - chan = (unsigned char *)arg; - - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "enter:now PCI: assign phys. BC %d in AMD LMR1", *chan); - - cs->dc.amd7930.ph_command(cs, (cs->dc.amd7930.lmr1 | (*chan + 1)), "MDL_BC_ASSIGN"); - /* at least one b-channel in use, LED 2 on */ - cs->hw.njet.auxd |= TJ_AMD_IRQ << 2; - outb(cs->hw.njet.auxd, cs->hw.njet.base + NETJET_AUXDATA); - break; - case MDL_BC_RELEASE: - /* deactivate B-channel */ - chan = (unsigned char *)arg; - - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "enter:now PCI: release phys. BC %d in Amd LMR1", *chan); - - cs->dc.amd7930.ph_command(cs, (cs->dc.amd7930.lmr1 & ~(*chan + 1)), "MDL_BC_RELEASE"); - /* no b-channel active -> LED2 off */ - if (!(cs->dc.amd7930.lmr1 & 3)) { - cs->hw.njet.auxd &= ~(TJ_AMD_IRQ << 2); - outb(cs->hw.njet.auxd, cs->hw.njet.base + NETJET_AUXDATA); - } - break; - default: - break; - - } - return (0); -} - -static irqreturn_t -enpci_interrupt(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - unsigned char s0val, s1val, ir; - u_long flags; - - spin_lock_irqsave(&cs->lock, flags); - s1val = inb(cs->hw.njet.base + NETJET_IRQSTAT1); - - /* AMD threw an interrupt */ - if (!(s1val & TJ_AMD_IRQ)) { - /* read and clear interrupt-register */ - ir = ReadByteAmd7930(cs, 0x00); - Amd7930_interrupt(cs, ir); - s1val = 1; - } else - s1val = 0; - s0val = inb(cs->hw.njet.base + NETJET_IRQSTAT0); - if ((s0val | s1val) == 0) { // shared IRQ - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_NONE; - } - if (s0val) - outb(s0val, cs->hw.njet.base + NETJET_IRQSTAT0); - - /* DMA-Interrupt: B-channel-stuff */ - /* set bits in sval to indicate which page is free */ - if (inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR) < - inl(cs->hw.njet.base + NETJET_DMA_WRITE_IRQ)) - /* the 2nd write page is free */ - s0val = 0x08; - else /* the 1st write page is free */ - s0val = 0x04; - if (inl(cs->hw.njet.base + NETJET_DMA_READ_ADR) < - inl(cs->hw.njet.base + NETJET_DMA_READ_IRQ)) - /* the 2nd read page is free */ - s0val = s0val | 0x02; - else /* the 1st read page is free */ - s0val = s0val | 0x01; - if (s0val != cs->hw.njet.last_is0) /* we have a DMA interrupt */ - { - if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; - } - cs->hw.njet.irqstat0 = s0val; - if ((cs->hw.njet.irqstat0 & NETJET_IRQM0_READ) != - (cs->hw.njet.last_is0 & NETJET_IRQM0_READ)) - /* we have a read dma int */ - read_tiger(cs); - if ((cs->hw.njet.irqstat0 & NETJET_IRQM0_WRITE) != - (cs->hw.njet.last_is0 & NETJET_IRQM0_WRITE)) - /* we have a write dma int */ - write_tiger(cs); - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - } - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -static int en_pci_probe(struct pci_dev *dev_netjet, struct IsdnCardState *cs) -{ - if (pci_enable_device(dev_netjet)) - return (0); - cs->irq = dev_netjet->irq; - if (!cs->irq) { - printk(KERN_WARNING "enter:now PCI: No IRQ for PCI card found\n"); - return (0); - } - cs->hw.njet.base = pci_resource_start(dev_netjet, 0); - if (!cs->hw.njet.base) { - printk(KERN_WARNING "enter:now PCI: No IO-Adr for PCI card found\n"); - return (0); - } - /* checks Sub-Vendor ID because system crashes with Traverse-Card */ - if ((dev_netjet->subsystem_vendor != 0x55) || - (dev_netjet->subsystem_device != 0x02)) { - printk(KERN_WARNING "enter:now: You tried to load this driver with an incompatible TigerJet-card\n"); - printk(KERN_WARNING "Use type=20 for Traverse NetJet PCI Card.\n"); - return (0); - } - - return (1); -} - -static void en_cs_init(struct IsdnCard *card, struct IsdnCardState *cs) -{ - cs->hw.njet.auxa = cs->hw.njet.base + NETJET_AUXDATA; - cs->hw.njet.isac = cs->hw.njet.base + 0xC0; // Fenster zum AMD - - /* Reset an */ - cs->hw.njet.ctrl_reg = 0x07; // geändert von 0xff - outb(cs->hw.njet.ctrl_reg, cs->hw.njet.base + NETJET_CTRL); - /* 20 ms Pause */ - mdelay(20); - - cs->hw.njet.ctrl_reg = 0x30; /* Reset Off and status read clear */ - outb(cs->hw.njet.ctrl_reg, cs->hw.njet.base + NETJET_CTRL); - mdelay(10); - - cs->hw.njet.auxd = 0x00; // war 0xc0 - cs->hw.njet.dmactrl = 0; - - outb(~TJ_AMD_IRQ, cs->hw.njet.base + NETJET_AUXCTRL); - outb(TJ_AMD_IRQ, cs->hw.njet.base + NETJET_IRQMASK1); - outb(cs->hw.njet.auxd, cs->hw.njet.auxa); -} - -static int en_cs_init_rest(struct IsdnCard *card, struct IsdnCardState *cs) -{ - const int bytecnt = 256; - - printk(KERN_INFO - "enter:now PCI: PCI card configured at 0x%lx IRQ %d\n", - cs->hw.njet.base, cs->irq); - if (!request_region(cs->hw.njet.base, bytecnt, "Fn_ISDN")) { - printk(KERN_WARNING - "HiSax: enter:now config port %lx-%lx already in use\n", - cs->hw.njet.base, - cs->hw.njet.base + bytecnt); - return (0); - } - - setup_Amd7930(cs); - cs->hw.njet.last_is0 = 0; - /* macro rByteAMD */ - cs->readisac = &ReadByteAmd7930; - /* macro wByteAMD */ - cs->writeisac = &WriteByteAmd7930; - cs->dc.amd7930.setIrqMask = &enpci_setIrqMask; - - cs->BC_Read_Reg = &dummyrr; - cs->BC_Write_Reg = &dummywr; - cs->BC_Send_Data = &netjet_fill_dma; - cs->cardmsg = &enpci_card_msg; - cs->irq_func = &enpci_interrupt; - cs->irq_flags |= IRQF_SHARED; - - return (1); -} - -static struct pci_dev *dev_netjet = NULL; - -/* called by config.c */ -int setup_enternow_pci(struct IsdnCard *card) -{ - int ret; - struct IsdnCardState *cs = card->cs; - char tmp[64]; - -#ifdef __BIG_ENDIAN -#error "not running on big endian machines now" -#endif - - strcpy(tmp, enternow_pci_rev); - printk(KERN_INFO "HiSax: Formula-n Europe AG enter:now ISDN PCI driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_ENTERNOW) - return (0); - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - - for (;;) - { - if ((dev_netjet = hisax_find_pci_device(PCI_VENDOR_ID_TIGERJET, - PCI_DEVICE_ID_TIGERJET_300, dev_netjet))) { - ret = en_pci_probe(dev_netjet, cs); - if (!ret) - return (0); - } else { - printk(KERN_WARNING "enter:now PCI: No PCI card found\n"); - return (0); - } - - en_cs_init(card, cs); - break; - } - - return en_cs_init_rest(card, cs); -} diff --git a/drivers/isdn/hisax/fsm.c b/drivers/isdn/hisax/fsm.c deleted file mode 100644 index 80ba82f77c63..000000000000 --- a/drivers/isdn/hisax/fsm.c +++ /dev/null @@ -1,161 +0,0 @@ -/* $Id: fsm.c,v 1.14.6.4 2001/09/23 22:24:47 kai Exp $ - * - * Finite state machine - * - * Author Karsten Keil - * Copyright by Karsten Keil <keil@isdn4linux.de> - * by Kai Germaschewski <kai.germaschewski@gmx.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * Thanks to Jan den Ouden - * Fritz Elfert - * - */ - -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/init.h> -#include "hisax.h" - -#define FSM_TIMER_DEBUG 0 - -int -FsmNew(struct Fsm *fsm, struct FsmNode *fnlist, int fncount) -{ - int i; - - fsm->jumpmatrix = - kzalloc(array3_size(sizeof(FSMFNPTR), fsm->state_count, - fsm->event_count), - GFP_KERNEL); - if (!fsm->jumpmatrix) - return -ENOMEM; - - for (i = 0; i < fncount; i++) - if ((fnlist[i].state >= fsm->state_count) || (fnlist[i].event >= fsm->event_count)) { - printk(KERN_ERR "FsmNew Error line %d st(%ld/%ld) ev(%ld/%ld)\n", - i, (long)fnlist[i].state, (long)fsm->state_count, - (long)fnlist[i].event, (long)fsm->event_count); - } else - fsm->jumpmatrix[fsm->state_count * fnlist[i].event + - fnlist[i].state] = (FSMFNPTR)fnlist[i].routine; - return 0; -} - -void -FsmFree(struct Fsm *fsm) -{ - kfree((void *) fsm->jumpmatrix); -} - -int -FsmEvent(struct FsmInst *fi, int event, void *arg) -{ - FSMFNPTR r; - - if ((fi->state >= fi->fsm->state_count) || (event >= fi->fsm->event_count)) { - printk(KERN_ERR "FsmEvent Error st(%ld/%ld) ev(%d/%ld)\n", - (long)fi->state, (long)fi->fsm->state_count, event, (long)fi->fsm->event_count); - return (1); - } - r = fi->fsm->jumpmatrix[fi->fsm->state_count * event + fi->state]; - if (r) { - if (fi->debug) - fi->printdebug(fi, "State %s Event %s", - fi->fsm->strState[fi->state], - fi->fsm->strEvent[event]); - r(fi, event, arg); - return (0); - } else { - if (fi->debug) - fi->printdebug(fi, "State %s Event %s no routine", - fi->fsm->strState[fi->state], - fi->fsm->strEvent[event]); - return (!0); - } -} - -void -FsmChangeState(struct FsmInst *fi, int newstate) -{ - fi->state = newstate; - if (fi->debug) - fi->printdebug(fi, "ChangeState %s", - fi->fsm->strState[newstate]); -} - -static void -FsmExpireTimer(struct timer_list *t) -{ - struct FsmTimer *ft = from_timer(ft, t, tl); -#if FSM_TIMER_DEBUG - if (ft->fi->debug) - ft->fi->printdebug(ft->fi, "FsmExpireTimer %lx", (long) ft); -#endif - FsmEvent(ft->fi, ft->event, ft->arg); -} - -void -FsmInitTimer(struct FsmInst *fi, struct FsmTimer *ft) -{ - ft->fi = fi; -#if FSM_TIMER_DEBUG - if (ft->fi->debug) - ft->fi->printdebug(ft->fi, "FsmInitTimer %lx", (long) ft); -#endif - timer_setup(&ft->tl, FsmExpireTimer, 0); -} - -void -FsmDelTimer(struct FsmTimer *ft, int where) -{ -#if FSM_TIMER_DEBUG - if (ft->fi->debug) - ft->fi->printdebug(ft->fi, "FsmDelTimer %lx %d", (long) ft, where); -#endif - del_timer(&ft->tl); -} - -int -FsmAddTimer(struct FsmTimer *ft, - int millisec, int event, void *arg, int where) -{ - -#if FSM_TIMER_DEBUG - if (ft->fi->debug) - ft->fi->printdebug(ft->fi, "FsmAddTimer %lx %d %d", - (long) ft, millisec, where); -#endif - - if (timer_pending(&ft->tl)) { - printk(KERN_WARNING "FsmAddTimer: timer already active!\n"); - ft->fi->printdebug(ft->fi, "FsmAddTimer already active!"); - return -1; - } - ft->event = event; - ft->arg = arg; - ft->tl.expires = jiffies + (millisec * HZ) / 1000; - add_timer(&ft->tl); - return 0; -} - -void -FsmRestartTimer(struct FsmTimer *ft, - int millisec, int event, void *arg, int where) -{ - -#if FSM_TIMER_DEBUG - if (ft->fi->debug) - ft->fi->printdebug(ft->fi, "FsmRestartTimer %lx %d %d", - (long) ft, millisec, where); -#endif - - if (timer_pending(&ft->tl)) - del_timer(&ft->tl); - ft->event = event; - ft->arg = arg; - ft->tl.expires = jiffies + (millisec * HZ) / 1000; - add_timer(&ft->tl); -} diff --git a/drivers/isdn/hisax/fsm.h b/drivers/isdn/hisax/fsm.h deleted file mode 100644 index 8c7385619a46..000000000000 --- a/drivers/isdn/hisax/fsm.h +++ /dev/null @@ -1,61 +0,0 @@ -/* $Id: fsm.h,v 1.3.2.2 2001/09/23 22:24:47 kai Exp $ - * - * Finite state machine - * - * Author Karsten Keil - * Copyright by Karsten Keil <keil@isdn4linux.de> - * by Kai Germaschewski <kai.germaschewski@gmx.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#ifndef __FSM_H__ -#define __FSM_H__ - -#include <linux/timer.h> - -struct FsmInst; - -typedef void (*FSMFNPTR)(struct FsmInst *, int, void *); - -struct Fsm { - FSMFNPTR *jumpmatrix; - int state_count, event_count; - char **strEvent, **strState; -}; - -struct FsmInst { - struct Fsm *fsm; - int state; - int debug; - void *userdata; - int userint; - void (*printdebug) (struct FsmInst *, char *, ...); -}; - -struct FsmNode { - int state, event; - void (*routine) (struct FsmInst *, int, void *); -}; - -struct FsmTimer { - struct FsmInst *fi; - struct timer_list tl; - int event; - void *arg; -}; - -int FsmNew(struct Fsm *fsm, struct FsmNode *fnlist, int fncount); -void FsmFree(struct Fsm *fsm); -int FsmEvent(struct FsmInst *fi, int event, void *arg); -void FsmChangeState(struct FsmInst *fi, int newstate); -void FsmInitTimer(struct FsmInst *fi, struct FsmTimer *ft); -int FsmAddTimer(struct FsmTimer *ft, int millisec, int event, - void *arg, int where); -void FsmRestartTimer(struct FsmTimer *ft, int millisec, int event, - void *arg, int where); -void FsmDelTimer(struct FsmTimer *ft, int where); - -#endif diff --git a/drivers/isdn/hisax/gazel.c b/drivers/isdn/hisax/gazel.c deleted file mode 100644 index a6d8af02354a..000000000000 --- a/drivers/isdn/hisax/gazel.c +++ /dev/null @@ -1,691 +0,0 @@ -/* $Id: gazel.c,v 2.19.2.4 2004/01/14 16:04:48 keil Exp $ - * - * low level stuff for Gazel isdn cards - * - * Author BeWan Systems - * based on source code from Karsten Keil - * Copyright by BeWan Systems - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#include <linux/init.h> -#include "hisax.h" -#include "isac.h" -#include "hscx.h" -#include "isdnl1.h" -#include "ipac.h" -#include <linux/pci.h> - -static const char *gazel_revision = "$Revision: 2.19.2.4 $"; - -#define R647 1 -#define R685 2 -#define R753 3 -#define R742 4 - -#define PLX_CNTRL 0x50 /* registre de controle PLX */ -#define RESET_GAZEL 0x4 -#define RESET_9050 0x40000000 -#define PLX_INCSR 0x4C /* registre d'IT du 9050 */ -#define INT_ISAC_EN 0x8 /* 1 = enable IT isac */ -#define INT_ISAC 0x20 /* 1 = IT isac en cours */ -#define INT_HSCX_EN 0x1 /* 1 = enable IT hscx */ -#define INT_HSCX 0x4 /* 1 = IT hscx en cours */ -#define INT_PCI_EN 0x40 /* 1 = enable IT PCI */ -#define INT_IPAC_EN 0x3 /* enable IT ipac */ - - -#define byteout(addr, val) outb(val, addr) -#define bytein(addr) inb(addr) - -static inline u_char -readreg(unsigned int adr, u_short off) -{ - return bytein(adr + off); -} - -static inline void -writereg(unsigned int adr, u_short off, u_char data) -{ - byteout(adr + off, data); -} - - -static inline void -read_fifo(unsigned int adr, u_char *data, int size) -{ - insb(adr, data, size); -} - -static void -write_fifo(unsigned int adr, u_char *data, int size) -{ - outsb(adr, data, size); -} - -static inline u_char -readreg_ipac(unsigned int adr, u_short off) -{ - register u_char ret; - - byteout(adr, off); - ret = bytein(adr + 4); - return ret; -} - -static inline void -writereg_ipac(unsigned int adr, u_short off, u_char data) -{ - byteout(adr, off); - byteout(adr + 4, data); -} - - -static inline void -read_fifo_ipac(unsigned int adr, u_short off, u_char *data, int size) -{ - byteout(adr, off); - insb(adr + 4, data, size); -} - -static void -write_fifo_ipac(unsigned int adr, u_short off, u_char *data, int size) -{ - byteout(adr, off); - outsb(adr + 4, data, size); -} - -/* Interface functions */ - -static u_char -ReadISAC(struct IsdnCardState *cs, u_char offset) -{ - u_short off2 = offset; - - switch (cs->subtyp) { - case R647: - off2 = ((off2 << 8 & 0xf000) | (off2 & 0xf)); - /* fall through */ - case R685: - return (readreg(cs->hw.gazel.isac, off2)); - case R753: - case R742: - return (readreg_ipac(cs->hw.gazel.ipac, 0x80 + off2)); - } - return 0; -} - -static void -WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value) -{ - u_short off2 = offset; - - switch (cs->subtyp) { - case R647: - off2 = ((off2 << 8 & 0xf000) | (off2 & 0xf)); - /* fall through */ - case R685: - writereg(cs->hw.gazel.isac, off2, value); - break; - case R753: - case R742: - writereg_ipac(cs->hw.gazel.ipac, 0x80 + off2, value); - break; - } -} - -static void -ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - switch (cs->subtyp) { - case R647: - case R685: - read_fifo(cs->hw.gazel.isacfifo, data, size); - break; - case R753: - case R742: - read_fifo_ipac(cs->hw.gazel.ipac, 0x80, data, size); - break; - } -} - -static void -WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - switch (cs->subtyp) { - case R647: - case R685: - write_fifo(cs->hw.gazel.isacfifo, data, size); - break; - case R753: - case R742: - write_fifo_ipac(cs->hw.gazel.ipac, 0x80, data, size); - break; - } -} - -static void -ReadHSCXfifo(struct IsdnCardState *cs, int hscx, u_char *data, int size) -{ - switch (cs->subtyp) { - case R647: - case R685: - read_fifo(cs->hw.gazel.hscxfifo[hscx], data, size); - break; - case R753: - case R742: - read_fifo_ipac(cs->hw.gazel.ipac, hscx * 0x40, data, size); - break; - } -} - -static void -WriteHSCXfifo(struct IsdnCardState *cs, int hscx, u_char *data, int size) -{ - switch (cs->subtyp) { - case R647: - case R685: - write_fifo(cs->hw.gazel.hscxfifo[hscx], data, size); - break; - case R753: - case R742: - write_fifo_ipac(cs->hw.gazel.ipac, hscx * 0x40, data, size); - break; - } -} - -static u_char -ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset) -{ - u_short off2 = offset; - - switch (cs->subtyp) { - case R647: - off2 = ((off2 << 8 & 0xf000) | (off2 & 0xf)); - /* fall through */ - case R685: - return (readreg(cs->hw.gazel.hscx[hscx], off2)); - case R753: - case R742: - return (readreg_ipac(cs->hw.gazel.ipac, hscx * 0x40 + off2)); - } - return 0; -} - -static void -WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) -{ - u_short off2 = offset; - - switch (cs->subtyp) { - case R647: - off2 = ((off2 << 8 & 0xf000) | (off2 & 0xf)); - /* fall through */ - case R685: - writereg(cs->hw.gazel.hscx[hscx], off2, value); - break; - case R753: - case R742: - writereg_ipac(cs->hw.gazel.ipac, hscx * 0x40 + off2, value); - break; - } -} - -/* - * fast interrupt HSCX stuff goes here - */ - -#define READHSCX(cs, nr, reg) ReadHSCX(cs, nr, reg) -#define WRITEHSCX(cs, nr, reg, data) WriteHSCX(cs, nr, reg, data) -#define READHSCXFIFO(cs, nr, ptr, cnt) ReadHSCXfifo(cs, nr, ptr, cnt) -#define WRITEHSCXFIFO(cs, nr, ptr, cnt) WriteHSCXfifo(cs, nr, ptr, cnt) - -#include "hscx_irq.c" - -static irqreturn_t -gazel_interrupt(int intno, void *dev_id) -{ -#define MAXCOUNT 5 - struct IsdnCardState *cs = dev_id; - u_char valisac, valhscx; - int count = 0; - u_long flags; - - spin_lock_irqsave(&cs->lock, flags); - do { - valhscx = ReadHSCX(cs, 1, HSCX_ISTA); - if (valhscx) - hscx_int_main(cs, valhscx); - valisac = ReadISAC(cs, ISAC_ISTA); - if (valisac) - isac_interrupt(cs, valisac); - count++; - } while ((valhscx || valisac) && (count < MAXCOUNT)); - - WriteHSCX(cs, 0, HSCX_MASK, 0xFF); - WriteHSCX(cs, 1, HSCX_MASK, 0xFF); - WriteISAC(cs, ISAC_MASK, 0xFF); - WriteISAC(cs, ISAC_MASK, 0x0); - WriteHSCX(cs, 0, HSCX_MASK, 0x0); - WriteHSCX(cs, 1, HSCX_MASK, 0x0); - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - - -static irqreturn_t -gazel_interrupt_ipac(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - u_char ista, val; - int count = 0; - u_long flags; - - spin_lock_irqsave(&cs->lock, flags); - ista = ReadISAC(cs, IPAC_ISTA - 0x80); - do { - if (ista & 0x0f) { - val = ReadHSCX(cs, 1, HSCX_ISTA); - if (ista & 0x01) - val |= 0x01; - if (ista & 0x04) - val |= 0x02; - if (ista & 0x08) - val |= 0x04; - if (val) { - hscx_int_main(cs, val); - } - } - if (ista & 0x20) { - val = 0xfe & ReadISAC(cs, ISAC_ISTA); - if (val) { - isac_interrupt(cs, val); - } - } - if (ista & 0x10) { - val = 0x01; - isac_interrupt(cs, val); - } - ista = ReadISAC(cs, IPAC_ISTA - 0x80); - count++; - } - while ((ista & 0x3f) && (count < MAXCOUNT)); - - WriteISAC(cs, IPAC_MASK - 0x80, 0xFF); - WriteISAC(cs, IPAC_MASK - 0x80, 0xC0); - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -static void -release_io_gazel(struct IsdnCardState *cs) -{ - unsigned int i; - - switch (cs->subtyp) { - case R647: - for (i = 0x0000; i < 0xC000; i += 0x1000) - release_region(i + cs->hw.gazel.hscx[0], 16); - release_region(0xC000 + cs->hw.gazel.hscx[0], 1); - break; - - case R685: - release_region(cs->hw.gazel.hscx[0], 0x100); - release_region(cs->hw.gazel.cfg_reg, 0x80); - break; - - case R753: - release_region(cs->hw.gazel.ipac, 0x8); - release_region(cs->hw.gazel.cfg_reg, 0x80); - break; - - case R742: - release_region(cs->hw.gazel.ipac, 8); - break; - } -} - -static int -reset_gazel(struct IsdnCardState *cs) -{ - unsigned long plxcntrl, addr = cs->hw.gazel.cfg_reg; - - switch (cs->subtyp) { - case R647: - writereg(addr, 0, 0); - HZDELAY(10); - writereg(addr, 0, 1); - HZDELAY(2); - break; - case R685: - plxcntrl = inl(addr + PLX_CNTRL); - plxcntrl |= (RESET_9050 + RESET_GAZEL); - outl(plxcntrl, addr + PLX_CNTRL); - plxcntrl &= ~(RESET_9050 + RESET_GAZEL); - HZDELAY(4); - outl(plxcntrl, addr + PLX_CNTRL); - HZDELAY(10); - outb(INT_ISAC_EN + INT_HSCX_EN + INT_PCI_EN, addr + PLX_INCSR); - break; - case R753: - plxcntrl = inl(addr + PLX_CNTRL); - plxcntrl |= (RESET_9050 + RESET_GAZEL); - outl(plxcntrl, addr + PLX_CNTRL); - plxcntrl &= ~(RESET_9050 + RESET_GAZEL); - WriteISAC(cs, IPAC_POTA2 - 0x80, 0x20); - HZDELAY(4); - outl(plxcntrl, addr + PLX_CNTRL); - HZDELAY(10); - WriteISAC(cs, IPAC_POTA2 - 0x80, 0x00); - WriteISAC(cs, IPAC_ACFG - 0x80, 0xff); - WriteISAC(cs, IPAC_AOE - 0x80, 0x0); - WriteISAC(cs, IPAC_MASK - 0x80, 0xff); - WriteISAC(cs, IPAC_CONF - 0x80, 0x1); - outb(INT_IPAC_EN + INT_PCI_EN, addr + PLX_INCSR); - WriteISAC(cs, IPAC_MASK - 0x80, 0xc0); - break; - case R742: - WriteISAC(cs, IPAC_POTA2 - 0x80, 0x20); - HZDELAY(4); - WriteISAC(cs, IPAC_POTA2 - 0x80, 0x00); - WriteISAC(cs, IPAC_ACFG - 0x80, 0xff); - WriteISAC(cs, IPAC_AOE - 0x80, 0x0); - WriteISAC(cs, IPAC_MASK - 0x80, 0xff); - WriteISAC(cs, IPAC_CONF - 0x80, 0x1); - WriteISAC(cs, IPAC_MASK - 0x80, 0xc0); - break; - } - return (0); -} - -static int -Gazel_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - u_long flags; - - switch (mt) { - case CARD_RESET: - spin_lock_irqsave(&cs->lock, flags); - reset_gazel(cs); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_RELEASE: - release_io_gazel(cs); - return (0); - case CARD_INIT: - spin_lock_irqsave(&cs->lock, flags); - inithscxisac(cs, 1); - if ((cs->subtyp == R647) || (cs->subtyp == R685)) { - int i; - for (i = 0; i < (2 + MAX_WAITING_CALLS); i++) { - cs->bcs[i].hw.hscx.tsaxr0 = 0x1f; - cs->bcs[i].hw.hscx.tsaxr1 = 0x23; - } - } - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_TEST: - return (0); - } - return (0); -} - -static int -reserve_regions(struct IsdnCard *card, struct IsdnCardState *cs) -{ - unsigned int i, j, base = 0, adr = 0, len = 0; - - switch (cs->subtyp) { - case R647: - base = cs->hw.gazel.hscx[0]; - if (!request_region(adr = (0xC000 + base), len = 1, "gazel")) - goto error; - for (i = 0x0000; i < 0xC000; i += 0x1000) { - if (!request_region(adr = (i + base), len = 16, "gazel")) - goto error; - } - if (i != 0xC000) { - for (j = 0; j < i; j += 0x1000) - release_region(j + base, 16); - release_region(0xC000 + base, 1); - goto error; - } - break; - - case R685: - if (!request_region(adr = cs->hw.gazel.hscx[0], len = 0x100, "gazel")) - goto error; - if (!request_region(adr = cs->hw.gazel.cfg_reg, len = 0x80, "gazel")) { - release_region(cs->hw.gazel.hscx[0], 0x100); - goto error; - } - break; - - case R753: - if (!request_region(adr = cs->hw.gazel.ipac, len = 0x8, "gazel")) - goto error; - if (!request_region(adr = cs->hw.gazel.cfg_reg, len = 0x80, "gazel")) { - release_region(cs->hw.gazel.ipac, 8); - goto error; - } - break; - - case R742: - if (!request_region(adr = cs->hw.gazel.ipac, len = 0x8, "gazel")) - goto error; - break; - } - - return 0; - -error: - printk(KERN_WARNING "Gazel: io ports 0x%x-0x%x already in use\n", - adr, adr + len); - return 1; -} - -static int setup_gazelisa(struct IsdnCard *card, struct IsdnCardState *cs) -{ - printk(KERN_INFO "Gazel: ISA PnP card automatic recognition\n"); - // we got an irq parameter, assume it is an ISA card - // R742 decodes address even in not started... - // R647 returns FF if not present or not started - // eventually needs improvment - if (readreg_ipac(card->para[1], IPAC_ID) == 1) - cs->subtyp = R742; - else - cs->subtyp = R647; - - setup_isac(cs); - cs->hw.gazel.cfg_reg = card->para[1] + 0xC000; - cs->hw.gazel.ipac = card->para[1]; - cs->hw.gazel.isac = card->para[1] + 0x8000; - cs->hw.gazel.hscx[0] = card->para[1]; - cs->hw.gazel.hscx[1] = card->para[1] + 0x4000; - cs->irq = card->para[0]; - cs->hw.gazel.isacfifo = cs->hw.gazel.isac; - cs->hw.gazel.hscxfifo[0] = cs->hw.gazel.hscx[0]; - cs->hw.gazel.hscxfifo[1] = cs->hw.gazel.hscx[1]; - - switch (cs->subtyp) { - case R647: - printk(KERN_INFO "Gazel: Card ISA R647/R648 found\n"); - cs->dc.isac.adf2 = 0x87; - printk(KERN_INFO - "Gazel: config irq:%d isac:0x%X cfg:0x%X\n", - cs->irq, cs->hw.gazel.isac, cs->hw.gazel.cfg_reg); - printk(KERN_INFO - "Gazel: hscx A:0x%X hscx B:0x%X\n", - cs->hw.gazel.hscx[0], cs->hw.gazel.hscx[1]); - - break; - case R742: - printk(KERN_INFO "Gazel: Card ISA R742 found\n"); - test_and_set_bit(HW_IPAC, &cs->HW_Flags); - printk(KERN_INFO - "Gazel: config irq:%d ipac:0x%X\n", - cs->irq, cs->hw.gazel.ipac); - break; - } - - return (0); -} - -#ifdef CONFIG_PCI -static struct pci_dev *dev_tel = NULL; - -static int setup_gazelpci(struct IsdnCardState *cs) -{ - u_int pci_ioaddr0 = 0, pci_ioaddr1 = 0; - u_char pci_irq = 0, found; - u_int nbseek, seekcard; - - printk(KERN_WARNING "Gazel: PCI card automatic recognition\n"); - - found = 0; - seekcard = PCI_DEVICE_ID_PLX_R685; - for (nbseek = 0; nbseek < 4; nbseek++) { - if ((dev_tel = hisax_find_pci_device(PCI_VENDOR_ID_PLX, - seekcard, dev_tel))) { - if (pci_enable_device(dev_tel)) - return 1; - pci_irq = dev_tel->irq; - pci_ioaddr0 = pci_resource_start(dev_tel, 1); - pci_ioaddr1 = pci_resource_start(dev_tel, 2); - found = 1; - } - if (found) - break; - else { - switch (seekcard) { - case PCI_DEVICE_ID_PLX_R685: - seekcard = PCI_DEVICE_ID_PLX_R753; - break; - case PCI_DEVICE_ID_PLX_R753: - seekcard = PCI_DEVICE_ID_PLX_DJINN_ITOO; - break; - case PCI_DEVICE_ID_PLX_DJINN_ITOO: - seekcard = PCI_DEVICE_ID_PLX_OLITEC; - break; - } - } - } - if (!found) { - printk(KERN_WARNING "Gazel: No PCI card found\n"); - return (1); - } - if (!pci_irq) { - printk(KERN_WARNING "Gazel: No IRQ for PCI card found\n"); - return 1; - } - cs->hw.gazel.pciaddr[0] = pci_ioaddr0; - cs->hw.gazel.pciaddr[1] = pci_ioaddr1; - setup_isac(cs); - pci_ioaddr1 &= 0xfffe; - cs->hw.gazel.cfg_reg = pci_ioaddr0 & 0xfffe; - cs->hw.gazel.ipac = pci_ioaddr1; - cs->hw.gazel.isac = pci_ioaddr1 + 0x80; - cs->hw.gazel.hscx[0] = pci_ioaddr1; - cs->hw.gazel.hscx[1] = pci_ioaddr1 + 0x40; - cs->hw.gazel.isacfifo = cs->hw.gazel.isac; - cs->hw.gazel.hscxfifo[0] = cs->hw.gazel.hscx[0]; - cs->hw.gazel.hscxfifo[1] = cs->hw.gazel.hscx[1]; - cs->irq = pci_irq; - cs->irq_flags |= IRQF_SHARED; - - switch (seekcard) { - case PCI_DEVICE_ID_PLX_R685: - printk(KERN_INFO "Gazel: Card PCI R685 found\n"); - cs->subtyp = R685; - cs->dc.isac.adf2 = 0x87; - printk(KERN_INFO - "Gazel: config irq:%d isac:0x%X cfg:0x%X\n", - cs->irq, cs->hw.gazel.isac, cs->hw.gazel.cfg_reg); - printk(KERN_INFO - "Gazel: hscx A:0x%X hscx B:0x%X\n", - cs->hw.gazel.hscx[0], cs->hw.gazel.hscx[1]); - break; - case PCI_DEVICE_ID_PLX_R753: - case PCI_DEVICE_ID_PLX_DJINN_ITOO: - case PCI_DEVICE_ID_PLX_OLITEC: - printk(KERN_INFO "Gazel: Card PCI R753 found\n"); - cs->subtyp = R753; - test_and_set_bit(HW_IPAC, &cs->HW_Flags); - printk(KERN_INFO - "Gazel: config irq:%d ipac:0x%X cfg:0x%X\n", - cs->irq, cs->hw.gazel.ipac, cs->hw.gazel.cfg_reg); - break; - } - - return (0); -} -#endif /* CONFIG_PCI */ - -int setup_gazel(struct IsdnCard *card) -{ - struct IsdnCardState *cs = card->cs; - char tmp[64]; - u_char val; - - strcpy(tmp, gazel_revision); - printk(KERN_INFO "Gazel: Driver Revision %s\n", HiSax_getrev(tmp)); - - if (cs->typ != ISDN_CTYPE_GAZEL) - return (0); - - if (card->para[0]) { - if (setup_gazelisa(card, cs)) - return (0); - } else { - -#ifdef CONFIG_PCI - if (setup_gazelpci(cs)) - return (0); -#else - printk(KERN_WARNING "Gazel: Card PCI requested and NO_PCI_BIOS, unable to config\n"); - return (0); -#endif /* CONFIG_PCI */ - } - - if (reserve_regions(card, cs)) { - return (0); - } - if (reset_gazel(cs)) { - printk(KERN_WARNING "Gazel: wrong IRQ\n"); - release_io_gazel(cs); - return (0); - } - cs->readisac = &ReadISAC; - cs->writeisac = &WriteISAC; - cs->readisacfifo = &ReadISACfifo; - cs->writeisacfifo = &WriteISACfifo; - cs->BC_Read_Reg = &ReadHSCX; - cs->BC_Write_Reg = &WriteHSCX; - cs->BC_Send_Data = &hscx_fill_fifo; - cs->cardmsg = &Gazel_card_msg; - - switch (cs->subtyp) { - case R647: - case R685: - cs->irq_func = &gazel_interrupt; - ISACVersion(cs, "Gazel:"); - if (HscxVersion(cs, "Gazel:")) { - printk(KERN_WARNING - "Gazel: wrong HSCX versions check IO address\n"); - release_io_gazel(cs); - return (0); - } - break; - case R742: - case R753: - cs->irq_func = &gazel_interrupt_ipac; - val = ReadISAC(cs, IPAC_ID - 0x80); - printk(KERN_INFO "Gazel: IPAC version %x\n", val); - break; - } - - return (1); -} diff --git a/drivers/isdn/hisax/hfc4s8s_l1.c b/drivers/isdn/hisax/hfc4s8s_l1.c deleted file mode 100644 index e9bb8fb67ad0..000000000000 --- a/drivers/isdn/hisax/hfc4s8s_l1.c +++ /dev/null @@ -1,1584 +0,0 @@ -/*************************************************************************/ -/* $Id: hfc4s8s_l1.c,v 1.10 2005/02/09 16:31:09 martinb1 Exp $ */ -/* HFC-4S/8S low layer interface for Cologne Chip HFC-4S/8S isdn chips */ -/* The low layer (L1) is implemented as a loadable module for usage with */ -/* the HiSax isdn driver for passive cards. */ -/* */ -/* Author: Werner Cornelius */ -/* (C) 2003 Cornelius Consult (werner@cornelius-consult.de) */ -/* */ -/* Driver maintained by Cologne Chip */ -/* - Martin Bachem, support@colognechip.com */ -/* */ -/* This driver only works with chip revisions >= 1, older revision 0 */ -/* engineering samples (only first manufacturer sample cards) will not */ -/* work and are rejected by the driver. */ -/* */ -/* This file distributed under the GNU GPL. */ -/* */ -/* See Version History at the end of this file */ -/* */ -/*************************************************************************/ - -#include <linux/module.h> -#include <linux/init.h> -#include <linux/pci.h> -#include <linux/interrupt.h> -#include <linux/delay.h> -#include <linux/slab.h> -#include <linux/timer.h> -#include <linux/skbuff.h> -#include <linux/wait.h> -#include <asm/io.h> -#include "hisax_if.h" -#include "hfc4s8s_l1.h" - -static const char hfc4s8s_rev[] = "Revision: 1.10"; - -/***************************************************************/ -/* adjustable transparent mode fifo threshold */ -/* The value defines the used fifo threshold with the equation */ -/* */ -/* notify number of bytes = 2 * 2 ^ TRANS_FIFO_THRES */ -/* */ -/* The default value is 5 which results in a buffer size of 64 */ -/* and an interrupt rate of 8ms. */ -/* The maximum value is 7 due to fifo size restrictions. */ -/* Values below 3-4 are not recommended due to high interrupt */ -/* load of the processor. For non critical applications the */ -/* value should be raised to 7 to reduce any interrupt overhead*/ -/***************************************************************/ -#define TRANS_FIFO_THRES 5 - -/*************/ -/* constants */ -/*************/ -#define CLOCKMODE_0 0 /* ext. 24.576 MhZ clk freq, int. single clock mode */ -#define CLOCKMODE_1 1 /* ext. 49.576 MhZ clk freq, int. single clock mode */ -#define CHIP_ID_SHIFT 4 -#define HFC_MAX_ST 8 -#define MAX_D_FRAME_SIZE 270 -#define MAX_B_FRAME_SIZE 1536 -#define TRANS_TIMER_MODE (TRANS_FIFO_THRES & 0xf) -#define TRANS_FIFO_BYTES (2 << TRANS_FIFO_THRES) -#define MAX_F_CNT 0x0f - -#define CLKDEL_NT 0x6c -#define CLKDEL_TE 0xf -#define CTRL0_NT 4 -#define CTRL0_TE 0 - -#define L1_TIMER_T4 2 /* minimum in jiffies */ -#define L1_TIMER_T3 (7 * HZ) /* activation timeout */ -#define L1_TIMER_T1 ((120 * HZ) / 1000) /* NT mode deactivation timeout */ - - -/******************/ -/* types and vars */ -/******************/ -static int card_cnt; - -/* private driver_data */ -typedef struct { - int chip_id; - int clock_mode; - int max_st_ports; - char *device_name; -} hfc4s8s_param; - -static const struct pci_device_id hfc4s8s_ids[] = { - {.vendor = PCI_VENDOR_ID_CCD, - .device = PCI_DEVICE_ID_4S, - .subvendor = 0x1397, - .subdevice = 0x08b4, - .driver_data = - (unsigned long) &((hfc4s8s_param) {CHIP_ID_4S, CLOCKMODE_0, 4, - "HFC-4S Evaluation Board"}), - }, - {.vendor = PCI_VENDOR_ID_CCD, - .device = PCI_DEVICE_ID_8S, - .subvendor = 0x1397, - .subdevice = 0x16b8, - .driver_data = - (unsigned long) &((hfc4s8s_param) {CHIP_ID_8S, CLOCKMODE_0, 8, - "HFC-8S Evaluation Board"}), - }, - {.vendor = PCI_VENDOR_ID_CCD, - .device = PCI_DEVICE_ID_4S, - .subvendor = 0x1397, - .subdevice = 0xb520, - .driver_data = - (unsigned long) &((hfc4s8s_param) {CHIP_ID_4S, CLOCKMODE_1, 4, - "IOB4ST"}), - }, - {.vendor = PCI_VENDOR_ID_CCD, - .device = PCI_DEVICE_ID_8S, - .subvendor = 0x1397, - .subdevice = 0xb522, - .driver_data = - (unsigned long) &((hfc4s8s_param) {CHIP_ID_8S, CLOCKMODE_1, 8, - "IOB8ST"}), - }, - {} -}; - -MODULE_DEVICE_TABLE(pci, hfc4s8s_ids); - -MODULE_AUTHOR("Werner Cornelius, werner@cornelius-consult.de"); -MODULE_DESCRIPTION("ISDN layer 1 for Cologne Chip HFC-4S/8S chips"); -MODULE_LICENSE("GPL"); - -/***********/ -/* layer 1 */ -/***********/ -struct hfc4s8s_btype { - spinlock_t lock; - struct hisax_b_if b_if; - struct hfc4s8s_l1 *l1p; - struct sk_buff_head tx_queue; - struct sk_buff *tx_skb; - struct sk_buff *rx_skb; - __u8 *rx_ptr; - int tx_cnt; - int bchan; - int mode; -}; - -struct _hfc4s8s_hw; - -struct hfc4s8s_l1 { - spinlock_t lock; - struct _hfc4s8s_hw *hw; /* pointer to hardware area */ - int l1_state; /* actual l1 state */ - struct timer_list l1_timer; /* layer 1 timer structure */ - int nt_mode; /* set to nt mode */ - int st_num; /* own index */ - int enabled; /* interface is enabled */ - struct sk_buff_head d_tx_queue; /* send queue */ - int tx_cnt; /* bytes to send */ - struct hisax_d_if d_if; /* D-channel interface */ - struct hfc4s8s_btype b_ch[2]; /* B-channel data */ - struct hisax_b_if *b_table[2]; -}; - -/**********************/ -/* hardware structure */ -/**********************/ -typedef struct _hfc4s8s_hw { - spinlock_t lock; - - int cardnum; - int ifnum; - int iobase; - int nt_mode; - u_char *membase; - u_char *hw_membase; - void *pdev; - int max_fifo; - hfc4s8s_param driver_data; - int irq; - int fifo_sched_cnt; - struct work_struct tqueue; - struct hfc4s8s_l1 l1[HFC_MAX_ST]; - char card_name[60]; - struct { - u_char r_irq_ctrl; - u_char r_ctrl0; - volatile u_char r_irq_statech; /* active isdn l1 status */ - u_char r_irqmsk_statchg; /* enabled isdn status ints */ - u_char r_irq_fifo_blx[8]; /* fifo status registers */ - u_char fifo_rx_trans_enables[8]; /* mask for enabled transparent rx fifos */ - u_char fifo_slow_timer_service[8]; /* mask for fifos needing slower timer service */ - volatile u_char r_irq_oview; /* contents of overview register */ - volatile u_char timer_irq; - int timer_usg_cnt; /* number of channels using timer */ - } mr; -} hfc4s8s_hw; - - - -/* inline functions io mapped */ -static inline void -SetRegAddr(hfc4s8s_hw *a, u_char b) -{ - outb(b, (a->iobase) + 4); -} - -static inline u_char -GetRegAddr(hfc4s8s_hw *a) -{ - return (inb((volatile u_int) (a->iobase + 4))); -} - - -static inline void -Write_hfc8(hfc4s8s_hw *a, u_char b, u_char c) -{ - SetRegAddr(a, b); - outb(c, a->iobase); -} - -static inline void -fWrite_hfc8(hfc4s8s_hw *a, u_char c) -{ - outb(c, a->iobase); -} - -static inline void -fWrite_hfc32(hfc4s8s_hw *a, u_long c) -{ - outl(c, a->iobase); -} - -static inline u_char -Read_hfc8(hfc4s8s_hw *a, u_char b) -{ - SetRegAddr(a, b); - return (inb((volatile u_int) a->iobase)); -} - -static inline u_char -fRead_hfc8(hfc4s8s_hw *a) -{ - return (inb((volatile u_int) a->iobase)); -} - - -static inline u_short -Read_hfc16(hfc4s8s_hw *a, u_char b) -{ - SetRegAddr(a, b); - return (inw((volatile u_int) a->iobase)); -} - -static inline u_long -fRead_hfc32(hfc4s8s_hw *a) -{ - return (inl((volatile u_int) a->iobase)); -} - -static inline void -wait_busy(hfc4s8s_hw *a) -{ - SetRegAddr(a, R_STATUS); - while (inb((volatile u_int) a->iobase) & M_BUSY); -} - -#define PCI_ENA_REGIO 0x01 - -/******************************************************/ -/* function to read critical counter registers that */ -/* may be updated by the chip during read */ -/******************************************************/ -static u_char -Read_hfc8_stable(hfc4s8s_hw *hw, int reg) -{ - u_char ref8; - u_char in8; - ref8 = Read_hfc8(hw, reg); - while (((in8 = Read_hfc8(hw, reg)) != ref8)) { - ref8 = in8; - } - return in8; -} - -static int -Read_hfc16_stable(hfc4s8s_hw *hw, int reg) -{ - int ref16; - int in16; - - ref16 = Read_hfc16(hw, reg); - while (((in16 = Read_hfc16(hw, reg)) != ref16)) { - ref16 = in16; - } - return in16; -} - -/*****************************/ -/* D-channel call from HiSax */ -/*****************************/ -static void -dch_l2l1(struct hisax_d_if *iface, int pr, void *arg) -{ - struct hfc4s8s_l1 *l1 = iface->ifc.priv; - struct sk_buff *skb = (struct sk_buff *) arg; - u_long flags; - - switch (pr) { - - case (PH_DATA | REQUEST): - if (!l1->enabled) { - dev_kfree_skb(skb); - break; - } - spin_lock_irqsave(&l1->lock, flags); - skb_queue_tail(&l1->d_tx_queue, skb); - if ((skb_queue_len(&l1->d_tx_queue) == 1) && - (l1->tx_cnt <= 0)) { - l1->hw->mr.r_irq_fifo_blx[l1->st_num] |= - 0x10; - spin_unlock_irqrestore(&l1->lock, flags); - schedule_work(&l1->hw->tqueue); - } else - spin_unlock_irqrestore(&l1->lock, flags); - break; - - case (PH_ACTIVATE | REQUEST): - if (!l1->enabled) - break; - if (!l1->nt_mode) { - if (l1->l1_state < 6) { - spin_lock_irqsave(&l1->lock, - flags); - - Write_hfc8(l1->hw, R_ST_SEL, - l1->st_num); - Write_hfc8(l1->hw, A_ST_WR_STA, - 0x60); - mod_timer(&l1->l1_timer, - jiffies + L1_TIMER_T3); - spin_unlock_irqrestore(&l1->lock, - flags); - } else if (l1->l1_state == 7) - l1->d_if.ifc.l1l2(&l1->d_if.ifc, - PH_ACTIVATE | - INDICATION, - NULL); - } else { - if (l1->l1_state != 3) { - spin_lock_irqsave(&l1->lock, - flags); - Write_hfc8(l1->hw, R_ST_SEL, - l1->st_num); - Write_hfc8(l1->hw, A_ST_WR_STA, - 0x60); - spin_unlock_irqrestore(&l1->lock, - flags); - } else if (l1->l1_state == 3) - l1->d_if.ifc.l1l2(&l1->d_if.ifc, - PH_ACTIVATE | - INDICATION, - NULL); - } - break; - - default: - printk(KERN_INFO - "HFC-4S/8S: Unknown D-chan cmd 0x%x received, ignored\n", - pr); - break; - } - if (!l1->enabled) - l1->d_if.ifc.l1l2(&l1->d_if.ifc, - PH_DEACTIVATE | INDICATION, NULL); -} /* dch_l2l1 */ - -/*****************************/ -/* B-channel call from HiSax */ -/*****************************/ -static void -bch_l2l1(struct hisax_if *ifc, int pr, void *arg) -{ - struct hfc4s8s_btype *bch = ifc->priv; - struct hfc4s8s_l1 *l1 = bch->l1p; - struct sk_buff *skb = (struct sk_buff *) arg; - long mode = (long) arg; - u_long flags; - - switch (pr) { - - case (PH_DATA | REQUEST): - if (!l1->enabled || (bch->mode == L1_MODE_NULL)) { - dev_kfree_skb(skb); - break; - } - spin_lock_irqsave(&l1->lock, flags); - skb_queue_tail(&bch->tx_queue, skb); - if (!bch->tx_skb && (bch->tx_cnt <= 0)) { - l1->hw->mr.r_irq_fifo_blx[l1->st_num] |= - ((bch->bchan == 1) ? 1 : 4); - spin_unlock_irqrestore(&l1->lock, flags); - schedule_work(&l1->hw->tqueue); - } else - spin_unlock_irqrestore(&l1->lock, flags); - break; - - case (PH_ACTIVATE | REQUEST): - case (PH_DEACTIVATE | REQUEST): - if (!l1->enabled) - break; - if (pr == (PH_DEACTIVATE | REQUEST)) - mode = L1_MODE_NULL; - - switch (mode) { - case L1_MODE_HDLC: - spin_lock_irqsave(&l1->lock, - flags); - l1->hw->mr.timer_usg_cnt++; - l1->hw->mr. - fifo_slow_timer_service[l1-> - st_num] - |= - ((bch->bchan == - 1) ? 0x2 : 0x8); - Write_hfc8(l1->hw, R_FIFO, - (l1->st_num * 8 + - ((bch->bchan == - 1) ? 0 : 2))); - wait_busy(l1->hw); - Write_hfc8(l1->hw, A_CON_HDLC, 0xc); /* HDLC mode, flag fill, connect ST */ - Write_hfc8(l1->hw, A_SUBCH_CFG, 0); /* 8 bits */ - Write_hfc8(l1->hw, A_IRQ_MSK, 1); /* enable TX interrupts for hdlc */ - Write_hfc8(l1->hw, A_INC_RES_FIFO, 2); /* reset fifo */ - wait_busy(l1->hw); - - Write_hfc8(l1->hw, R_FIFO, - (l1->st_num * 8 + - ((bch->bchan == - 1) ? 1 : 3))); - wait_busy(l1->hw); - Write_hfc8(l1->hw, A_CON_HDLC, 0xc); /* HDLC mode, flag fill, connect ST */ - Write_hfc8(l1->hw, A_SUBCH_CFG, 0); /* 8 bits */ - Write_hfc8(l1->hw, A_IRQ_MSK, 1); /* enable RX interrupts for hdlc */ - Write_hfc8(l1->hw, A_INC_RES_FIFO, 2); /* reset fifo */ - - Write_hfc8(l1->hw, R_ST_SEL, - l1->st_num); - l1->hw->mr.r_ctrl0 |= - (bch->bchan & 3); - Write_hfc8(l1->hw, A_ST_CTRL0, - l1->hw->mr.r_ctrl0); - bch->mode = L1_MODE_HDLC; - spin_unlock_irqrestore(&l1->lock, - flags); - - bch->b_if.ifc.l1l2(&bch->b_if.ifc, - PH_ACTIVATE | - INDICATION, - NULL); - break; - - case L1_MODE_TRANS: - spin_lock_irqsave(&l1->lock, - flags); - l1->hw->mr. - fifo_rx_trans_enables[l1-> - st_num] - |= - ((bch->bchan == - 1) ? 0x2 : 0x8); - l1->hw->mr.timer_usg_cnt++; - Write_hfc8(l1->hw, R_FIFO, - (l1->st_num * 8 + - ((bch->bchan == - 1) ? 0 : 2))); - wait_busy(l1->hw); - Write_hfc8(l1->hw, A_CON_HDLC, 0xf); /* Transparent mode, 1 fill, connect ST */ - Write_hfc8(l1->hw, A_SUBCH_CFG, 0); /* 8 bits */ - Write_hfc8(l1->hw, A_IRQ_MSK, 0); /* disable TX interrupts */ - Write_hfc8(l1->hw, A_INC_RES_FIFO, 2); /* reset fifo */ - wait_busy(l1->hw); - - Write_hfc8(l1->hw, R_FIFO, - (l1->st_num * 8 + - ((bch->bchan == - 1) ? 1 : 3))); - wait_busy(l1->hw); - Write_hfc8(l1->hw, A_CON_HDLC, 0xf); /* Transparent mode, 1 fill, connect ST */ - Write_hfc8(l1->hw, A_SUBCH_CFG, 0); /* 8 bits */ - Write_hfc8(l1->hw, A_IRQ_MSK, 0); /* disable RX interrupts */ - Write_hfc8(l1->hw, A_INC_RES_FIFO, 2); /* reset fifo */ - - Write_hfc8(l1->hw, R_ST_SEL, - l1->st_num); - l1->hw->mr.r_ctrl0 |= - (bch->bchan & 3); - Write_hfc8(l1->hw, A_ST_CTRL0, - l1->hw->mr.r_ctrl0); - bch->mode = L1_MODE_TRANS; - spin_unlock_irqrestore(&l1->lock, - flags); - - bch->b_if.ifc.l1l2(&bch->b_if.ifc, - PH_ACTIVATE | - INDICATION, - NULL); - break; - - default: - if (bch->mode == L1_MODE_NULL) - break; - spin_lock_irqsave(&l1->lock, - flags); - l1->hw->mr. - fifo_slow_timer_service[l1-> - st_num] - &= - ~((bch->bchan == - 1) ? 0x3 : 0xc); - l1->hw->mr. - fifo_rx_trans_enables[l1-> - st_num] - &= - ~((bch->bchan == - 1) ? 0x3 : 0xc); - l1->hw->mr.timer_usg_cnt--; - Write_hfc8(l1->hw, R_FIFO, - (l1->st_num * 8 + - ((bch->bchan == - 1) ? 0 : 2))); - wait_busy(l1->hw); - Write_hfc8(l1->hw, A_IRQ_MSK, 0); /* disable TX interrupts */ - wait_busy(l1->hw); - Write_hfc8(l1->hw, R_FIFO, - (l1->st_num * 8 + - ((bch->bchan == - 1) ? 1 : 3))); - wait_busy(l1->hw); - Write_hfc8(l1->hw, A_IRQ_MSK, 0); /* disable RX interrupts */ - Write_hfc8(l1->hw, R_ST_SEL, - l1->st_num); - l1->hw->mr.r_ctrl0 &= - ~(bch->bchan & 3); - Write_hfc8(l1->hw, A_ST_CTRL0, - l1->hw->mr.r_ctrl0); - spin_unlock_irqrestore(&l1->lock, - flags); - - bch->mode = L1_MODE_NULL; - bch->b_if.ifc.l1l2(&bch->b_if.ifc, - PH_DEACTIVATE | - INDICATION, - NULL); - if (bch->tx_skb) { - dev_kfree_skb(bch->tx_skb); - bch->tx_skb = NULL; - } - if (bch->rx_skb) { - dev_kfree_skb(bch->rx_skb); - bch->rx_skb = NULL; - } - skb_queue_purge(&bch->tx_queue); - bch->tx_cnt = 0; - bch->rx_ptr = NULL; - break; - } - - /* timer is only used when at least one b channel */ - /* is set up to transparent mode */ - if (l1->hw->mr.timer_usg_cnt) { - Write_hfc8(l1->hw, R_IRQMSK_MISC, - M_TI_IRQMSK); - } else { - Write_hfc8(l1->hw, R_IRQMSK_MISC, 0); - } - - break; - - default: - printk(KERN_INFO - "HFC-4S/8S: Unknown B-chan cmd 0x%x received, ignored\n", - pr); - break; - } - if (!l1->enabled) - bch->b_if.ifc.l1l2(&bch->b_if.ifc, - PH_DEACTIVATE | INDICATION, NULL); -} /* bch_l2l1 */ - -/**************************/ -/* layer 1 timer function */ -/**************************/ -static void -hfc_l1_timer(struct timer_list *t) -{ - struct hfc4s8s_l1 *l1 = from_timer(l1, t, l1_timer); - u_long flags; - - if (!l1->enabled) - return; - - spin_lock_irqsave(&l1->lock, flags); - if (l1->nt_mode) { - l1->l1_state = 1; - Write_hfc8(l1->hw, R_ST_SEL, l1->st_num); - Write_hfc8(l1->hw, A_ST_WR_STA, 0x11); - spin_unlock_irqrestore(&l1->lock, flags); - l1->d_if.ifc.l1l2(&l1->d_if.ifc, - PH_DEACTIVATE | INDICATION, NULL); - spin_lock_irqsave(&l1->lock, flags); - l1->l1_state = 1; - Write_hfc8(l1->hw, A_ST_WR_STA, 0x1); - spin_unlock_irqrestore(&l1->lock, flags); - } else { - /* activation timed out */ - Write_hfc8(l1->hw, R_ST_SEL, l1->st_num); - Write_hfc8(l1->hw, A_ST_WR_STA, 0x13); - spin_unlock_irqrestore(&l1->lock, flags); - l1->d_if.ifc.l1l2(&l1->d_if.ifc, - PH_DEACTIVATE | INDICATION, NULL); - spin_lock_irqsave(&l1->lock, flags); - Write_hfc8(l1->hw, R_ST_SEL, l1->st_num); - Write_hfc8(l1->hw, A_ST_WR_STA, 0x3); - spin_unlock_irqrestore(&l1->lock, flags); - } -} /* hfc_l1_timer */ - -/****************************************/ -/* a complete D-frame has been received */ -/****************************************/ -static void -rx_d_frame(struct hfc4s8s_l1 *l1p, int ech) -{ - int z1, z2; - u_char f1, f2, df; - struct sk_buff *skb; - u_char *cp; - - - if (!l1p->enabled) - return; - do { - /* E/D RX fifo */ - Write_hfc8(l1p->hw, R_FIFO, - (l1p->st_num * 8 + ((ech) ? 7 : 5))); - wait_busy(l1p->hw); - - f1 = Read_hfc8_stable(l1p->hw, A_F1); - f2 = Read_hfc8(l1p->hw, A_F2); - - if (f1 < f2) - df = MAX_F_CNT + 1 + f1 - f2; - else - df = f1 - f2; - - if (!df) - return; /* no complete frame in fifo */ - - z1 = Read_hfc16_stable(l1p->hw, A_Z1); - z2 = Read_hfc16(l1p->hw, A_Z2); - - z1 = z1 - z2 + 1; - if (z1 < 0) - z1 += 384; - - if (!(skb = dev_alloc_skb(MAX_D_FRAME_SIZE))) { - printk(KERN_INFO - "HFC-4S/8S: Could not allocate D/E " - "channel receive buffer"); - Write_hfc8(l1p->hw, A_INC_RES_FIFO, 2); - wait_busy(l1p->hw); - return; - } - - if (((z1 < 4) || (z1 > MAX_D_FRAME_SIZE))) { - if (skb) - dev_kfree_skb(skb); - /* remove errornous D frame */ - if (df == 1) { - /* reset fifo */ - Write_hfc8(l1p->hw, A_INC_RES_FIFO, 2); - wait_busy(l1p->hw); - return; - } else { - /* read errornous D frame */ - SetRegAddr(l1p->hw, A_FIFO_DATA0); - - while (z1 >= 4) { - fRead_hfc32(l1p->hw); - z1 -= 4; - } - - while (z1--) - fRead_hfc8(l1p->hw); - - Write_hfc8(l1p->hw, A_INC_RES_FIFO, 1); - wait_busy(l1p->hw); - return; - } - } - - cp = skb->data; - - SetRegAddr(l1p->hw, A_FIFO_DATA0); - - while (z1 >= 4) { - *((unsigned long *) cp) = fRead_hfc32(l1p->hw); - cp += 4; - z1 -= 4; - } - - while (z1--) - *cp++ = fRead_hfc8(l1p->hw); - - Write_hfc8(l1p->hw, A_INC_RES_FIFO, 1); /* increment f counter */ - wait_busy(l1p->hw); - - if (*(--cp)) { - dev_kfree_skb(skb); - } else { - skb->len = (cp - skb->data) - 2; - if (ech) - l1p->d_if.ifc.l1l2(&l1p->d_if.ifc, - PH_DATA_E | INDICATION, - skb); - else - l1p->d_if.ifc.l1l2(&l1p->d_if.ifc, - PH_DATA | INDICATION, - skb); - } - } while (1); -} /* rx_d_frame */ - -/*************************************************************/ -/* a B-frame has been received (perhaps not fully completed) */ -/*************************************************************/ -static void -rx_b_frame(struct hfc4s8s_btype *bch) -{ - int z1, z2, hdlc_complete; - u_char f1, f2; - struct hfc4s8s_l1 *l1 = bch->l1p; - struct sk_buff *skb; - - if (!l1->enabled || (bch->mode == L1_MODE_NULL)) - return; - - do { - /* RX Fifo */ - Write_hfc8(l1->hw, R_FIFO, - (l1->st_num * 8 + ((bch->bchan == 1) ? 1 : 3))); - wait_busy(l1->hw); - - if (bch->mode == L1_MODE_HDLC) { - f1 = Read_hfc8_stable(l1->hw, A_F1); - f2 = Read_hfc8(l1->hw, A_F2); - hdlc_complete = ((f1 ^ f2) & MAX_F_CNT); - } else - hdlc_complete = 0; - z1 = Read_hfc16_stable(l1->hw, A_Z1); - z2 = Read_hfc16(l1->hw, A_Z2); - z1 = (z1 - z2); - if (hdlc_complete) - z1++; - if (z1 < 0) - z1 += 384; - - if (!z1) - break; - - if (!(skb = bch->rx_skb)) { - if (! - (skb = - dev_alloc_skb((bch->mode == - L1_MODE_TRANS) ? z1 - : (MAX_B_FRAME_SIZE + 3)))) { - printk(KERN_ERR - "HFC-4S/8S: Could not allocate B " - "channel receive buffer"); - return; - } - bch->rx_ptr = skb->data; - bch->rx_skb = skb; - } - - skb->len = (bch->rx_ptr - skb->data) + z1; - - /* HDLC length check */ - if ((bch->mode == L1_MODE_HDLC) && - ((hdlc_complete && (skb->len < 4)) || - (skb->len > (MAX_B_FRAME_SIZE + 3)))) { - - skb->len = 0; - bch->rx_ptr = skb->data; - Write_hfc8(l1->hw, A_INC_RES_FIFO, 2); /* reset fifo */ - wait_busy(l1->hw); - return; - } - SetRegAddr(l1->hw, A_FIFO_DATA0); - - while (z1 >= 4) { - *((unsigned long *) bch->rx_ptr) = - fRead_hfc32(l1->hw); - bch->rx_ptr += 4; - z1 -= 4; - } - - while (z1--) - *(bch->rx_ptr++) = fRead_hfc8(l1->hw); - - if (hdlc_complete) { - /* increment f counter */ - Write_hfc8(l1->hw, A_INC_RES_FIFO, 1); - wait_busy(l1->hw); - - /* hdlc crc check */ - bch->rx_ptr--; - if (*bch->rx_ptr) { - skb->len = 0; - bch->rx_ptr = skb->data; - continue; - } - skb->len -= 3; - } - if (hdlc_complete || (bch->mode == L1_MODE_TRANS)) { - bch->rx_skb = NULL; - bch->rx_ptr = NULL; - bch->b_if.ifc.l1l2(&bch->b_if.ifc, - PH_DATA | INDICATION, skb); - } - - } while (1); -} /* rx_b_frame */ - -/********************************************/ -/* a D-frame has been/should be transmitted */ -/********************************************/ -static void -tx_d_frame(struct hfc4s8s_l1 *l1p) -{ - struct sk_buff *skb; - u_char f1, f2; - u_char *cp; - long cnt; - - if (l1p->l1_state != 7) - return; - - /* TX fifo */ - Write_hfc8(l1p->hw, R_FIFO, (l1p->st_num * 8 + 4)); - wait_busy(l1p->hw); - - f1 = Read_hfc8(l1p->hw, A_F1); - f2 = Read_hfc8_stable(l1p->hw, A_F2); - - if ((f1 ^ f2) & MAX_F_CNT) - return; /* fifo is still filled */ - - if (l1p->tx_cnt > 0) { - cnt = l1p->tx_cnt; - l1p->tx_cnt = 0; - l1p->d_if.ifc.l1l2(&l1p->d_if.ifc, PH_DATA | CONFIRM, - (void *) cnt); - } - - if ((skb = skb_dequeue(&l1p->d_tx_queue))) { - cp = skb->data; - cnt = skb->len; - SetRegAddr(l1p->hw, A_FIFO_DATA0); - - while (cnt >= 4) { - SetRegAddr(l1p->hw, A_FIFO_DATA0); - fWrite_hfc32(l1p->hw, *(unsigned long *) cp); - cp += 4; - cnt -= 4; - } - - while (cnt--) - fWrite_hfc8(l1p->hw, *cp++); - - l1p->tx_cnt = skb->truesize; - Write_hfc8(l1p->hw, A_INC_RES_FIFO, 1); /* increment f counter */ - wait_busy(l1p->hw); - - dev_kfree_skb(skb); - } -} /* tx_d_frame */ - -/******************************************************/ -/* a B-frame may be transmitted (or is not completed) */ -/******************************************************/ -static void -tx_b_frame(struct hfc4s8s_btype *bch) -{ - struct sk_buff *skb; - struct hfc4s8s_l1 *l1 = bch->l1p; - u_char *cp; - int cnt, max, hdlc_num; - long ack_len = 0; - - if (!l1->enabled || (bch->mode == L1_MODE_NULL)) - return; - - /* TX fifo */ - Write_hfc8(l1->hw, R_FIFO, - (l1->st_num * 8 + ((bch->bchan == 1) ? 0 : 2))); - wait_busy(l1->hw); - do { - - if (bch->mode == L1_MODE_HDLC) { - hdlc_num = Read_hfc8(l1->hw, A_F1) & MAX_F_CNT; - hdlc_num -= - (Read_hfc8_stable(l1->hw, A_F2) & MAX_F_CNT); - if (hdlc_num < 0) - hdlc_num += 16; - if (hdlc_num >= 15) - break; /* fifo still filled up with hdlc frames */ - } else - hdlc_num = 0; - - if (!(skb = bch->tx_skb)) { - if (!(skb = skb_dequeue(&bch->tx_queue))) { - l1->hw->mr.fifo_slow_timer_service[l1-> - st_num] - &= ~((bch->bchan == 1) ? 1 : 4); - break; /* list empty */ - } - bch->tx_skb = skb; - bch->tx_cnt = 0; - } - - if (!hdlc_num) - l1->hw->mr.fifo_slow_timer_service[l1->st_num] |= - ((bch->bchan == 1) ? 1 : 4); - else - l1->hw->mr.fifo_slow_timer_service[l1->st_num] &= - ~((bch->bchan == 1) ? 1 : 4); - - max = Read_hfc16_stable(l1->hw, A_Z2); - max -= Read_hfc16(l1->hw, A_Z1); - if (max <= 0) - max += 384; - max--; - - if (max < 16) - break; /* don't write to small amounts of bytes */ - - cnt = skb->len - bch->tx_cnt; - if (cnt > max) - cnt = max; - cp = skb->data + bch->tx_cnt; - bch->tx_cnt += cnt; - - SetRegAddr(l1->hw, A_FIFO_DATA0); - while (cnt >= 4) { - fWrite_hfc32(l1->hw, *(unsigned long *) cp); - cp += 4; - cnt -= 4; - } - - while (cnt--) - fWrite_hfc8(l1->hw, *cp++); - - if (bch->tx_cnt >= skb->len) { - if (bch->mode == L1_MODE_HDLC) { - /* increment f counter */ - Write_hfc8(l1->hw, A_INC_RES_FIFO, 1); - } - ack_len += skb->truesize; - bch->tx_skb = NULL; - bch->tx_cnt = 0; - dev_kfree_skb(skb); - } else - /* Re-Select */ - Write_hfc8(l1->hw, R_FIFO, - (l1->st_num * 8 + - ((bch->bchan == 1) ? 0 : 2))); - wait_busy(l1->hw); - } while (1); - - if (ack_len) - bch->b_if.ifc.l1l2((struct hisax_if *) &bch->b_if, - PH_DATA | CONFIRM, (void *) ack_len); -} /* tx_b_frame */ - -/*************************************/ -/* bottom half handler for interrupt */ -/*************************************/ -static void -hfc4s8s_bh(struct work_struct *work) -{ - hfc4s8s_hw *hw = container_of(work, hfc4s8s_hw, tqueue); - u_char b; - struct hfc4s8s_l1 *l1p; - volatile u_char *fifo_stat; - int idx; - - /* handle layer 1 state changes */ - b = 1; - l1p = hw->l1; - while (b) { - if ((b & hw->mr.r_irq_statech)) { - /* reset l1 event */ - hw->mr.r_irq_statech &= ~b; - if (l1p->enabled) { - if (l1p->nt_mode) { - u_char oldstate = l1p->l1_state; - - Write_hfc8(l1p->hw, R_ST_SEL, - l1p->st_num); - l1p->l1_state = - Read_hfc8(l1p->hw, - A_ST_RD_STA) & 0xf; - - if ((oldstate == 3) - && (l1p->l1_state != 3)) - l1p->d_if.ifc.l1l2(&l1p-> - d_if. - ifc, - PH_DEACTIVATE - | - INDICATION, - NULL); - - if (l1p->l1_state != 2) { - del_timer(&l1p->l1_timer); - if (l1p->l1_state == 3) { - l1p->d_if.ifc. - l1l2(&l1p-> - d_if.ifc, - PH_ACTIVATE - | - INDICATION, - NULL); - } - } else { - /* allow transition */ - Write_hfc8(hw, A_ST_WR_STA, - M_SET_G2_G3); - mod_timer(&l1p->l1_timer, - jiffies + - L1_TIMER_T1); - } - printk(KERN_INFO - "HFC-4S/8S: NT ch %d l1 state %d -> %d\n", - l1p->st_num, oldstate, - l1p->l1_state); - } else { - u_char oldstate = l1p->l1_state; - - Write_hfc8(l1p->hw, R_ST_SEL, - l1p->st_num); - l1p->l1_state = - Read_hfc8(l1p->hw, - A_ST_RD_STA) & 0xf; - - if (((l1p->l1_state == 3) && - ((oldstate == 7) || - (oldstate == 8))) || - ((timer_pending - (&l1p->l1_timer)) - && (l1p->l1_state == 8))) { - mod_timer(&l1p->l1_timer, - L1_TIMER_T4 + - jiffies); - } else { - if (l1p->l1_state == 7) { - del_timer(&l1p-> - l1_timer); - l1p->d_if.ifc. - l1l2(&l1p-> - d_if.ifc, - PH_ACTIVATE - | - INDICATION, - NULL); - tx_d_frame(l1p); - } - if (l1p->l1_state == 3) { - if (oldstate != 3) - l1p->d_if. - ifc. - l1l2 - (&l1p-> - d_if. - ifc, - PH_DEACTIVATE - | - INDICATION, - NULL); - } - } - printk(KERN_INFO - "HFC-4S/8S: TE %d ch %d l1 state %d -> %d\n", - l1p->hw->cardnum, - l1p->st_num, oldstate, - l1p->l1_state); - } - } - } - b <<= 1; - l1p++; - } - - /* now handle the fifos */ - idx = 0; - fifo_stat = hw->mr.r_irq_fifo_blx; - l1p = hw->l1; - while (idx < hw->driver_data.max_st_ports) { - - if (hw->mr.timer_irq) { - *fifo_stat |= hw->mr.fifo_rx_trans_enables[idx]; - if (hw->fifo_sched_cnt <= 0) { - *fifo_stat |= - hw->mr.fifo_slow_timer_service[l1p-> - st_num]; - } - } - /* ignore fifo 6 (TX E fifo) */ - *fifo_stat &= 0xff - 0x40; - - while (*fifo_stat) { - - if (!l1p->nt_mode) { - /* RX Fifo has data to read */ - if ((*fifo_stat & 0x20)) { - *fifo_stat &= ~0x20; - rx_d_frame(l1p, 0); - } - /* E Fifo has data to read */ - if ((*fifo_stat & 0x80)) { - *fifo_stat &= ~0x80; - rx_d_frame(l1p, 1); - } - /* TX Fifo completed send */ - if ((*fifo_stat & 0x10)) { - *fifo_stat &= ~0x10; - tx_d_frame(l1p); - } - } - /* B1 RX Fifo has data to read */ - if ((*fifo_stat & 0x2)) { - *fifo_stat &= ~0x2; - rx_b_frame(l1p->b_ch); - } - /* B1 TX Fifo has send completed */ - if ((*fifo_stat & 0x1)) { - *fifo_stat &= ~0x1; - tx_b_frame(l1p->b_ch); - } - /* B2 RX Fifo has data to read */ - if ((*fifo_stat & 0x8)) { - *fifo_stat &= ~0x8; - rx_b_frame(l1p->b_ch + 1); - } - /* B2 TX Fifo has send completed */ - if ((*fifo_stat & 0x4)) { - *fifo_stat &= ~0x4; - tx_b_frame(l1p->b_ch + 1); - } - } - fifo_stat++; - l1p++; - idx++; - } - - if (hw->fifo_sched_cnt <= 0) - hw->fifo_sched_cnt += (1 << (7 - TRANS_TIMER_MODE)); - hw->mr.timer_irq = 0; /* clear requested timer irq */ -} /* hfc4s8s_bh */ - -/*********************/ -/* interrupt handler */ -/*********************/ -static irqreturn_t -hfc4s8s_interrupt(int intno, void *dev_id) -{ - hfc4s8s_hw *hw = dev_id; - u_char b, ovr; - volatile u_char *ovp; - int idx; - u_char old_ioreg; - - if (!hw || !(hw->mr.r_irq_ctrl & M_GLOB_IRQ_EN)) - return IRQ_NONE; - - /* read current selected regsister */ - old_ioreg = GetRegAddr(hw); - - /* Layer 1 State change */ - hw->mr.r_irq_statech |= - (Read_hfc8(hw, R_SCI) & hw->mr.r_irqmsk_statchg); - if (! - (b = (Read_hfc8(hw, R_STATUS) & (M_MISC_IRQSTA | M_FR_IRQSTA))) - && !hw->mr.r_irq_statech) { - SetRegAddr(hw, old_ioreg); - return IRQ_NONE; - } - - /* timer event */ - if (Read_hfc8(hw, R_IRQ_MISC) & M_TI_IRQ) { - hw->mr.timer_irq = 1; - hw->fifo_sched_cnt--; - } - - /* FIFO event */ - if ((ovr = Read_hfc8(hw, R_IRQ_OVIEW))) { - hw->mr.r_irq_oview |= ovr; - idx = R_IRQ_FIFO_BL0; - ovp = hw->mr.r_irq_fifo_blx; - while (ovr) { - if ((ovr & 1)) { - *ovp |= Read_hfc8(hw, idx); - } - ovp++; - idx++; - ovr >>= 1; - } - } - - /* queue the request to allow other cards to interrupt */ - schedule_work(&hw->tqueue); - - SetRegAddr(hw, old_ioreg); - return IRQ_HANDLED; -} /* hfc4s8s_interrupt */ - -/***********************************************************************/ -/* reset the complete chip, don't release the chips irq but disable it */ -/***********************************************************************/ -static void -chipreset(hfc4s8s_hw *hw) -{ - u_long flags; - - spin_lock_irqsave(&hw->lock, flags); - Write_hfc8(hw, R_CTRL, 0); /* use internal RAM */ - Write_hfc8(hw, R_RAM_MISC, 0); /* 32k*8 RAM */ - Write_hfc8(hw, R_FIFO_MD, 0); /* fifo mode 386 byte/fifo simple mode */ - Write_hfc8(hw, R_CIRM, M_SRES); /* reset chip */ - hw->mr.r_irq_ctrl = 0; /* interrupt is inactive */ - spin_unlock_irqrestore(&hw->lock, flags); - - udelay(3); - Write_hfc8(hw, R_CIRM, 0); /* disable reset */ - wait_busy(hw); - - Write_hfc8(hw, R_PCM_MD0, M_PCM_MD); /* master mode */ - Write_hfc8(hw, R_RAM_MISC, M_FZ_MD); /* transmit fifo option */ - if (hw->driver_data.clock_mode == 1) - Write_hfc8(hw, R_BRG_PCM_CFG, M_PCM_CLK); /* PCM clk / 2 */ - Write_hfc8(hw, R_TI_WD, TRANS_TIMER_MODE); /* timer interval */ - - memset(&hw->mr, 0, sizeof(hw->mr)); -} /* chipreset */ - -/********************************************/ -/* disable/enable hardware in nt or te mode */ -/********************************************/ -static void -hfc_hardware_enable(hfc4s8s_hw *hw, int enable, int nt_mode) -{ - u_long flags; - char if_name[40]; - int i; - - if (enable) { - /* save system vars */ - hw->nt_mode = nt_mode; - - /* enable fifo and state irqs, but not global irq enable */ - hw->mr.r_irq_ctrl = M_FIFO_IRQ; - Write_hfc8(hw, R_IRQ_CTRL, hw->mr.r_irq_ctrl); - hw->mr.r_irqmsk_statchg = 0; - Write_hfc8(hw, R_SCI_MSK, hw->mr.r_irqmsk_statchg); - Write_hfc8(hw, R_PWM_MD, 0x80); - Write_hfc8(hw, R_PWM1, 26); - if (!nt_mode) - Write_hfc8(hw, R_ST_SYNC, M_AUTO_SYNC); - - /* enable the line interfaces and fifos */ - for (i = 0; i < hw->driver_data.max_st_ports; i++) { - hw->mr.r_irqmsk_statchg |= (1 << i); - Write_hfc8(hw, R_SCI_MSK, hw->mr.r_irqmsk_statchg); - Write_hfc8(hw, R_ST_SEL, i); - Write_hfc8(hw, A_ST_CLK_DLY, - ((nt_mode) ? CLKDEL_NT : CLKDEL_TE)); - hw->mr.r_ctrl0 = ((nt_mode) ? CTRL0_NT : CTRL0_TE); - Write_hfc8(hw, A_ST_CTRL0, hw->mr.r_ctrl0); - Write_hfc8(hw, A_ST_CTRL2, 3); - Write_hfc8(hw, A_ST_WR_STA, 0); /* enable state machine */ - - hw->l1[i].enabled = 1; - hw->l1[i].nt_mode = nt_mode; - - if (!nt_mode) { - /* setup E-fifo */ - Write_hfc8(hw, R_FIFO, i * 8 + 7); /* E fifo */ - wait_busy(hw); - Write_hfc8(hw, A_CON_HDLC, 0x11); /* HDLC mode, 1 fill, connect ST */ - Write_hfc8(hw, A_SUBCH_CFG, 2); /* only 2 bits */ - Write_hfc8(hw, A_IRQ_MSK, 1); /* enable interrupt */ - Write_hfc8(hw, A_INC_RES_FIFO, 2); /* reset fifo */ - wait_busy(hw); - - /* setup D RX-fifo */ - Write_hfc8(hw, R_FIFO, i * 8 + 5); /* RX fifo */ - wait_busy(hw); - Write_hfc8(hw, A_CON_HDLC, 0x11); /* HDLC mode, 1 fill, connect ST */ - Write_hfc8(hw, A_SUBCH_CFG, 2); /* only 2 bits */ - Write_hfc8(hw, A_IRQ_MSK, 1); /* enable interrupt */ - Write_hfc8(hw, A_INC_RES_FIFO, 2); /* reset fifo */ - wait_busy(hw); - - /* setup D TX-fifo */ - Write_hfc8(hw, R_FIFO, i * 8 + 4); /* TX fifo */ - wait_busy(hw); - Write_hfc8(hw, A_CON_HDLC, 0x11); /* HDLC mode, 1 fill, connect ST */ - Write_hfc8(hw, A_SUBCH_CFG, 2); /* only 2 bits */ - Write_hfc8(hw, A_IRQ_MSK, 1); /* enable interrupt */ - Write_hfc8(hw, A_INC_RES_FIFO, 2); /* reset fifo */ - wait_busy(hw); - } - - sprintf(if_name, "hfc4s8s_%d%d_", hw->cardnum, i); - - if (hisax_register - (&hw->l1[i].d_if, hw->l1[i].b_table, if_name, - ((nt_mode) ? 3 : 2))) { - - hw->l1[i].enabled = 0; - hw->mr.r_irqmsk_statchg &= ~(1 << i); - Write_hfc8(hw, R_SCI_MSK, - hw->mr.r_irqmsk_statchg); - printk(KERN_INFO - "HFC-4S/8S: Unable to register S/T device %s, break\n", - if_name); - break; - } - } - spin_lock_irqsave(&hw->lock, flags); - hw->mr.r_irq_ctrl |= M_GLOB_IRQ_EN; - Write_hfc8(hw, R_IRQ_CTRL, hw->mr.r_irq_ctrl); - spin_unlock_irqrestore(&hw->lock, flags); - } else { - /* disable hardware */ - spin_lock_irqsave(&hw->lock, flags); - hw->mr.r_irq_ctrl &= ~M_GLOB_IRQ_EN; - Write_hfc8(hw, R_IRQ_CTRL, hw->mr.r_irq_ctrl); - spin_unlock_irqrestore(&hw->lock, flags); - - for (i = hw->driver_data.max_st_ports - 1; i >= 0; i--) { - hw->l1[i].enabled = 0; - hisax_unregister(&hw->l1[i].d_if); - del_timer(&hw->l1[i].l1_timer); - skb_queue_purge(&hw->l1[i].d_tx_queue); - skb_queue_purge(&hw->l1[i].b_ch[0].tx_queue); - skb_queue_purge(&hw->l1[i].b_ch[1].tx_queue); - } - chipreset(hw); - } -} /* hfc_hardware_enable */ - -/******************************************/ -/* disable memory mapped ports / io ports */ -/******************************************/ -static void -release_pci_ports(hfc4s8s_hw *hw) -{ - pci_write_config_word(hw->pdev, PCI_COMMAND, 0); - if (hw->iobase) - release_region(hw->iobase, 8); -} - -/*****************************************/ -/* enable memory mapped ports / io ports */ -/*****************************************/ -static void -enable_pci_ports(hfc4s8s_hw *hw) -{ - pci_write_config_word(hw->pdev, PCI_COMMAND, PCI_ENA_REGIO); -} - -/*************************************/ -/* initialise the HFC-4s/8s hardware */ -/* return 0 on success. */ -/*************************************/ -static int -setup_instance(hfc4s8s_hw *hw) -{ - int err = -EIO; - int i; - - for (i = 0; i < HFC_MAX_ST; i++) { - struct hfc4s8s_l1 *l1p; - - l1p = hw->l1 + i; - spin_lock_init(&l1p->lock); - l1p->hw = hw; - timer_setup(&l1p->l1_timer, hfc_l1_timer, 0); - l1p->st_num = i; - skb_queue_head_init(&l1p->d_tx_queue); - l1p->d_if.ifc.priv = hw->l1 + i; - l1p->d_if.ifc.l2l1 = (void *) dch_l2l1; - - spin_lock_init(&l1p->b_ch[0].lock); - l1p->b_ch[0].b_if.ifc.l2l1 = (void *) bch_l2l1; - l1p->b_ch[0].b_if.ifc.priv = (void *) &l1p->b_ch[0]; - l1p->b_ch[0].l1p = hw->l1 + i; - l1p->b_ch[0].bchan = 1; - l1p->b_table[0] = &l1p->b_ch[0].b_if; - skb_queue_head_init(&l1p->b_ch[0].tx_queue); - - spin_lock_init(&l1p->b_ch[1].lock); - l1p->b_ch[1].b_if.ifc.l2l1 = (void *) bch_l2l1; - l1p->b_ch[1].b_if.ifc.priv = (void *) &l1p->b_ch[1]; - l1p->b_ch[1].l1p = hw->l1 + i; - l1p->b_ch[1].bchan = 2; - l1p->b_table[1] = &l1p->b_ch[1].b_if; - skb_queue_head_init(&l1p->b_ch[1].tx_queue); - } - - enable_pci_ports(hw); - chipreset(hw); - - i = Read_hfc8(hw, R_CHIP_ID) >> CHIP_ID_SHIFT; - if (i != hw->driver_data.chip_id) { - printk(KERN_INFO - "HFC-4S/8S: invalid chip id 0x%x instead of 0x%x, card ignored\n", - i, hw->driver_data.chip_id); - goto out; - } - - i = Read_hfc8(hw, R_CHIP_RV) & 0xf; - if (!i) { - printk(KERN_INFO - "HFC-4S/8S: chip revision 0 not supported, card ignored\n"); - goto out; - } - - INIT_WORK(&hw->tqueue, hfc4s8s_bh); - - if (request_irq - (hw->irq, hfc4s8s_interrupt, IRQF_SHARED, hw->card_name, hw)) { - printk(KERN_INFO - "HFC-4S/8S: unable to alloc irq %d, card ignored\n", - hw->irq); - goto out; - } - printk(KERN_INFO - "HFC-4S/8S: found PCI card at iobase 0x%x, irq %d\n", - hw->iobase, hw->irq); - - hfc_hardware_enable(hw, 1, 0); - - return (0); - -out: - hw->irq = 0; - release_pci_ports(hw); - kfree(hw); - return (err); -} - -/*****************************************/ -/* PCI hotplug interface: probe new card */ -/*****************************************/ -static int -hfc4s8s_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - int err = -ENOMEM; - hfc4s8s_param *driver_data = (hfc4s8s_param *) ent->driver_data; - hfc4s8s_hw *hw; - - if (!(hw = kzalloc(sizeof(hfc4s8s_hw), GFP_ATOMIC))) { - printk(KERN_ERR "No kmem for HFC-4S/8S card\n"); - return (err); - } - - hw->pdev = pdev; - err = pci_enable_device(pdev); - - if (err) - goto out; - - hw->cardnum = card_cnt; - sprintf(hw->card_name, "hfc4s8s_%d", hw->cardnum); - printk(KERN_INFO "HFC-4S/8S: found adapter %s (%s) at %s\n", - driver_data->device_name, hw->card_name, pci_name(pdev)); - - spin_lock_init(&hw->lock); - - hw->driver_data = *driver_data; - hw->irq = pdev->irq; - hw->iobase = pci_resource_start(pdev, 0); - - if (!request_region(hw->iobase, 8, hw->card_name)) { - printk(KERN_INFO - "HFC-4S/8S: failed to request address space at 0x%04x\n", - hw->iobase); - err = -EBUSY; - goto out; - } - - pci_set_drvdata(pdev, hw); - err = setup_instance(hw); - if (!err) - card_cnt++; - return (err); - -out: - kfree(hw); - return (err); -} - -/**************************************/ -/* PCI hotplug interface: remove card */ -/**************************************/ -static void -hfc4s8s_remove(struct pci_dev *pdev) -{ - hfc4s8s_hw *hw = pci_get_drvdata(pdev); - - printk(KERN_INFO "HFC-4S/8S: removing card %d\n", hw->cardnum); - hfc_hardware_enable(hw, 0, 0); - - if (hw->irq) - free_irq(hw->irq, hw); - hw->irq = 0; - release_pci_ports(hw); - - card_cnt--; - pci_disable_device(pdev); - kfree(hw); - return; -} - -static struct pci_driver hfc4s8s_driver = { - .name = "hfc4s8s_l1", - .probe = hfc4s8s_probe, - .remove = hfc4s8s_remove, - .id_table = hfc4s8s_ids, -}; - -/**********************/ -/* driver Module init */ -/**********************/ -static int __init -hfc4s8s_module_init(void) -{ - int err; - - printk(KERN_INFO - "HFC-4S/8S: Layer 1 driver module for HFC-4S/8S isdn chips, %s\n", - hfc4s8s_rev); - printk(KERN_INFO - "HFC-4S/8S: (C) 2003 Cornelius Consult, www.cornelius-consult.de\n"); - - card_cnt = 0; - - err = pci_register_driver(&hfc4s8s_driver); - if (err < 0) { - goto out; - } - printk(KERN_INFO "HFC-4S/8S: found %d cards\n", card_cnt); - - return 0; -out: - return (err); -} /* hfc4s8s_init_hw */ - -/*************************************/ -/* driver module exit : */ -/* release the HFC-4s/8s hardware */ -/*************************************/ -static void __exit -hfc4s8s_module_exit(void) -{ - pci_unregister_driver(&hfc4s8s_driver); - printk(KERN_INFO "HFC-4S/8S: module removed\n"); -} /* hfc4s8s_release_hw */ - -module_init(hfc4s8s_module_init); -module_exit(hfc4s8s_module_exit); diff --git a/drivers/isdn/hisax/hfc4s8s_l1.h b/drivers/isdn/hisax/hfc4s8s_l1.h deleted file mode 100644 index 4665b9d5df16..000000000000 --- a/drivers/isdn/hisax/hfc4s8s_l1.h +++ /dev/null @@ -1,89 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/***************************************************************/ -/* $Id: hfc4s8s_l1.h,v 1.1 2005/02/02 17:28:55 martinb1 Exp $ */ -/* */ -/* This file is a minimal required extraction of hfc48scu.h */ -/* (Genero 3.2, HFC XML 1.7a for HFC-E1, HFC-4S and HFC-8S) */ -/* */ -/* To get this complete register description contact */ -/* Cologne Chip AG : */ -/* Internet: http://www.colognechip.com/ */ -/* E-Mail: info@colognechip.com */ -/***************************************************************/ - -#ifndef _HFC4S8S_L1_H_ -#define _HFC4S8S_L1_H_ - - -/* - * include Genero generated HFC-4S/8S header file hfc48scu.h - * for complete register description. This will define _HFC48SCU_H_ - * to prevent redefinitions - */ - -// #include "hfc48scu.h" - -#ifndef _HFC48SCU_H_ -#define _HFC48SCU_H_ - -#ifndef PCI_VENDOR_ID_CCD -#define PCI_VENDOR_ID_CCD 0x1397 -#endif - -#define CHIP_ID_4S 0x0C -#define CHIP_ID_8S 0x08 -#define PCI_DEVICE_ID_4S 0x08B4 -#define PCI_DEVICE_ID_8S 0x16B8 - -#define R_IRQ_MISC 0x11 -#define M_TI_IRQ 0x02 -#define A_ST_RD_STA 0x30 -#define A_ST_WR_STA 0x30 -#define M_SET_G2_G3 0x80 -#define A_ST_CTRL0 0x31 -#define A_ST_CTRL2 0x33 -#define A_ST_CLK_DLY 0x37 -#define A_Z1 0x04 -#define A_Z2 0x06 -#define R_CIRM 0x00 -#define M_SRES 0x08 -#define R_CTRL 0x01 -#define R_BRG_PCM_CFG 0x02 -#define M_PCM_CLK 0x20 -#define R_RAM_MISC 0x0C -#define M_FZ_MD 0x80 -#define R_FIFO_MD 0x0D -#define A_INC_RES_FIFO 0x0E -#define R_FIFO 0x0F -#define A_F1 0x0C -#define A_F2 0x0D -#define R_IRQ_OVIEW 0x10 -#define R_CHIP_ID 0x16 -#define R_STATUS 0x1C -#define M_BUSY 0x01 -#define M_MISC_IRQSTA 0x40 -#define M_FR_IRQSTA 0x80 -#define R_CHIP_RV 0x1F -#define R_IRQ_CTRL 0x13 -#define M_FIFO_IRQ 0x01 -#define M_GLOB_IRQ_EN 0x08 -#define R_PCM_MD0 0x14 -#define M_PCM_MD 0x01 -#define A_FIFO_DATA0 0x80 -#define R_TI_WD 0x1A -#define R_PWM1 0x39 -#define R_PWM_MD 0x46 -#define R_IRQ_FIFO_BL0 0xC8 -#define A_CON_HDLC 0xFA -#define A_SUBCH_CFG 0xFB -#define A_IRQ_MSK 0xFF -#define R_SCI_MSK 0x12 -#define R_ST_SEL 0x16 -#define R_ST_SYNC 0x17 -#define M_AUTO_SYNC 0x08 -#define R_SCI 0x12 -#define R_IRQMSK_MISC 0x11 -#define M_TI_IRQMSK 0x02 - -#endif /* _HFC4S8S_L1_H_ */ -#endif /* _HFC48SCU_H_ */ diff --git a/drivers/isdn/hisax/hfc_2bds0.c b/drivers/isdn/hisax/hfc_2bds0.c deleted file mode 100644 index 3715fa0343db..000000000000 --- a/drivers/isdn/hisax/hfc_2bds0.c +++ /dev/null @@ -1,1078 +0,0 @@ -/* $Id: hfc_2bds0.c,v 1.18.2.6 2004/02/11 13:21:33 keil Exp $ - * - * specific routines for CCD's HFC 2BDS0 - * - * Author Karsten Keil - * Copyright by Karsten Keil <keil@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/init.h> -#include <linux/sched.h> -#include <linux/slab.h> -#include "hisax.h" -#include "hfc_2bds0.h" -#include "isdnl1.h" -#include <linux/interrupt.h> -/* - #define KDEBUG_DEF - #include "kdebug.h" -*/ - -#define byteout(addr, val) outb(val, addr) -#define bytein(addr) inb(addr) - -static void -dummyf(struct IsdnCardState *cs, u_char *data, int size) -{ - printk(KERN_WARNING "HiSax: hfcd dummy fifo called\n"); -} - -static inline u_char -ReadReg(struct IsdnCardState *cs, int data, u_char reg) -{ - register u_char ret; - - if (data) { - if (cs->hw.hfcD.cip != reg) { - cs->hw.hfcD.cip = reg; - byteout(cs->hw.hfcD.addr | 1, reg); - } - ret = bytein(cs->hw.hfcD.addr); -#ifdef HFC_REG_DEBUG - if (cs->debug & L1_DEB_HSCX_FIFO && (data != 2)) - debugl1(cs, "t3c RD %02x %02x", reg, ret); -#endif - } else - ret = bytein(cs->hw.hfcD.addr | 1); - return (ret); -} - -static inline void -WriteReg(struct IsdnCardState *cs, int data, u_char reg, u_char value) -{ - if (cs->hw.hfcD.cip != reg) { - cs->hw.hfcD.cip = reg; - byteout(cs->hw.hfcD.addr | 1, reg); - } - if (data) - byteout(cs->hw.hfcD.addr, value); -#ifdef HFC_REG_DEBUG - if (cs->debug & L1_DEB_HSCX_FIFO && (data != HFCD_DATA_NODEB)) - debugl1(cs, "t3c W%c %02x %02x", data ? 'D' : 'C', reg, value); -#endif -} - -/* Interface functions */ - -static u_char -readreghfcd(struct IsdnCardState *cs, u_char offset) -{ - return (ReadReg(cs, HFCD_DATA, offset)); -} - -static void -writereghfcd(struct IsdnCardState *cs, u_char offset, u_char value) -{ - WriteReg(cs, HFCD_DATA, offset, value); -} - -static inline int -WaitForBusy(struct IsdnCardState *cs) -{ - int to = 130; - - while (!(ReadReg(cs, HFCD_DATA, HFCD_STAT) & HFCD_BUSY) && to) { - udelay(1); - to--; - } - if (!to) - printk(KERN_WARNING "HiSax: WaitForBusy timeout\n"); - return (to); -} - -static inline int -WaitNoBusy(struct IsdnCardState *cs) -{ - int to = 130; - - while ((ReadReg(cs, HFCD_STATUS, HFCD_STATUS) & HFCD_BUSY) && to) { - udelay(1); - to--; - } - if (!to) - printk(KERN_WARNING "HiSax: WaitNoBusy timeout\n"); - return (to); -} - -static int -SelFiFo(struct IsdnCardState *cs, u_char FiFo) -{ - u_char cip; - - if (cs->hw.hfcD.fifo == FiFo) - return (1); - switch (FiFo) { - case 0: cip = HFCB_FIFO | HFCB_Z1 | HFCB_SEND | HFCB_B1; - break; - case 1: cip = HFCB_FIFO | HFCB_Z1 | HFCB_REC | HFCB_B1; - break; - case 2: cip = HFCB_FIFO | HFCB_Z1 | HFCB_SEND | HFCB_B2; - break; - case 3: cip = HFCB_FIFO | HFCB_Z1 | HFCB_REC | HFCB_B2; - break; - case 4: cip = HFCD_FIFO | HFCD_Z1 | HFCD_SEND; - break; - case 5: cip = HFCD_FIFO | HFCD_Z1 | HFCD_REC; - break; - default: - debugl1(cs, "SelFiFo Error"); - return (0); - } - cs->hw.hfcD.fifo = FiFo; - WaitNoBusy(cs); - cs->BC_Write_Reg(cs, HFCD_DATA, cip, 0); - WaitForBusy(cs); - return (2); -} - -static int -GetFreeFifoBytes_B(struct BCState *bcs) -{ - int s; - - if (bcs->hw.hfc.f1 == bcs->hw.hfc.f2) - return (bcs->cs->hw.hfcD.bfifosize); - s = bcs->hw.hfc.send[bcs->hw.hfc.f1] - bcs->hw.hfc.send[bcs->hw.hfc.f2]; - if (s <= 0) - s += bcs->cs->hw.hfcD.bfifosize; - s = bcs->cs->hw.hfcD.bfifosize - s; - return (s); -} - -static int -GetFreeFifoBytes_D(struct IsdnCardState *cs) -{ - int s; - - if (cs->hw.hfcD.f1 == cs->hw.hfcD.f2) - return (cs->hw.hfcD.dfifosize); - s = cs->hw.hfcD.send[cs->hw.hfcD.f1] - cs->hw.hfcD.send[cs->hw.hfcD.f2]; - if (s <= 0) - s += cs->hw.hfcD.dfifosize; - s = cs->hw.hfcD.dfifosize - s; - return (s); -} - -static int -ReadZReg(struct IsdnCardState *cs, u_char reg) -{ - int val; - - WaitNoBusy(cs); - val = 256 * ReadReg(cs, HFCD_DATA, reg | HFCB_Z_HIGH); - WaitNoBusy(cs); - val += ReadReg(cs, HFCD_DATA, reg | HFCB_Z_LOW); - return (val); -} - -static struct sk_buff -*hfc_empty_fifo(struct BCState *bcs, int count) -{ - u_char *ptr; - struct sk_buff *skb; - struct IsdnCardState *cs = bcs->cs; - int idx; - int chksum; - u_char stat, cip; - - if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) - debugl1(cs, "hfc_empty_fifo"); - idx = 0; - if (count > HSCX_BUFMAX + 3) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "hfc_empty_fifo: incoming packet too large"); - cip = HFCB_FIFO | HFCB_FIFO_OUT | HFCB_REC | HFCB_CHANNEL(bcs->channel); - while (idx++ < count) { - WaitNoBusy(cs); - ReadReg(cs, HFCD_DATA_NODEB, cip); - } - skb = NULL; - } else if (count < 4) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "hfc_empty_fifo: incoming packet too small"); - cip = HFCB_FIFO | HFCB_FIFO_OUT | HFCB_REC | HFCB_CHANNEL(bcs->channel); -#ifdef ERROR_STATISTIC - bcs->err_inv++; -#endif - while ((idx++ < count) && WaitNoBusy(cs)) - ReadReg(cs, HFCD_DATA_NODEB, cip); - skb = NULL; - } else if (!(skb = dev_alloc_skb(count - 3))) - printk(KERN_WARNING "HFC: receive out of memory\n"); - else { - ptr = skb_put(skb, count - 3); - idx = 0; - cip = HFCB_FIFO | HFCB_FIFO_OUT | HFCB_REC | HFCB_CHANNEL(bcs->channel); - while (idx < (count - 3)) { - if (!WaitNoBusy(cs)) - break; - *ptr = ReadReg(cs, HFCD_DATA_NODEB, cip); - ptr++; - idx++; - } - if (idx != count - 3) { - debugl1(cs, "RFIFO BUSY error"); - printk(KERN_WARNING "HFC FIFO channel %d BUSY Error\n", bcs->channel); - dev_kfree_skb_irq(skb); - skb = NULL; - } else { - WaitNoBusy(cs); - chksum = (ReadReg(cs, HFCD_DATA, cip) << 8); - WaitNoBusy(cs); - chksum += ReadReg(cs, HFCD_DATA, cip); - WaitNoBusy(cs); - stat = ReadReg(cs, HFCD_DATA, cip); - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "hfc_empty_fifo %d chksum %x stat %x", - bcs->channel, chksum, stat); - if (stat) { - debugl1(cs, "FIFO CRC error"); - dev_kfree_skb_irq(skb); - skb = NULL; -#ifdef ERROR_STATISTIC - bcs->err_crc++; -#endif - } - } - } - WaitForBusy(cs); - WaitNoBusy(cs); - stat = ReadReg(cs, HFCD_DATA, HFCB_FIFO | HFCB_F2_INC | - HFCB_REC | HFCB_CHANNEL(bcs->channel)); - WaitForBusy(cs); - return (skb); -} - -static void -hfc_fill_fifo(struct BCState *bcs) -{ - struct IsdnCardState *cs = bcs->cs; - int idx, fcnt; - int count; - u_char cip; - - if (!bcs->tx_skb) - return; - if (bcs->tx_skb->len <= 0) - return; - SelFiFo(cs, HFCB_SEND | HFCB_CHANNEL(bcs->channel)); - cip = HFCB_FIFO | HFCB_F1 | HFCB_SEND | HFCB_CHANNEL(bcs->channel); - WaitNoBusy(cs); - bcs->hw.hfc.f1 = ReadReg(cs, HFCD_DATA, cip); - WaitNoBusy(cs); - cip = HFCB_FIFO | HFCB_F2 | HFCB_SEND | HFCB_CHANNEL(bcs->channel); - WaitNoBusy(cs); - bcs->hw.hfc.f2 = ReadReg(cs, HFCD_DATA, cip); - bcs->hw.hfc.send[bcs->hw.hfc.f1] = ReadZReg(cs, HFCB_FIFO | HFCB_Z1 | HFCB_SEND | HFCB_CHANNEL(bcs->channel)); - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "hfc_fill_fifo %d f1(%d) f2(%d) z1(%x)", - bcs->channel, bcs->hw.hfc.f1, bcs->hw.hfc.f2, - bcs->hw.hfc.send[bcs->hw.hfc.f1]); - fcnt = bcs->hw.hfc.f1 - bcs->hw.hfc.f2; - if (fcnt < 0) - fcnt += 32; - if (fcnt > 30) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "hfc_fill_fifo more as 30 frames"); - return; - } - count = GetFreeFifoBytes_B(bcs); - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "hfc_fill_fifo %d count(%u/%d),%lx", - bcs->channel, bcs->tx_skb->len, - count, current->state); - if (count < bcs->tx_skb->len) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "hfc_fill_fifo no fifo mem"); - return; - } - cip = HFCB_FIFO | HFCB_FIFO_IN | HFCB_SEND | HFCB_CHANNEL(bcs->channel); - idx = 0; - WaitForBusy(cs); - WaitNoBusy(cs); - WriteReg(cs, HFCD_DATA_NODEB, cip, bcs->tx_skb->data[idx++]); - while (idx < bcs->tx_skb->len) { - if (!WaitNoBusy(cs)) - break; - WriteReg(cs, HFCD_DATA_NODEB, cip, bcs->tx_skb->data[idx]); - idx++; - } - if (idx != bcs->tx_skb->len) { - debugl1(cs, "FIFO Send BUSY error"); - printk(KERN_WARNING "HFC S FIFO channel %d BUSY Error\n", bcs->channel); - } else { - bcs->tx_cnt -= bcs->tx_skb->len; - if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) && - (PACKET_NOACK != bcs->tx_skb->pkt_type)) { - u_long flags; - spin_lock_irqsave(&bcs->aclock, flags); - bcs->ackcnt += bcs->tx_skb->len; - spin_unlock_irqrestore(&bcs->aclock, flags); - schedule_event(bcs, B_ACKPENDING); - } - dev_kfree_skb_any(bcs->tx_skb); - bcs->tx_skb = NULL; - } - WaitForBusy(cs); - WaitNoBusy(cs); - ReadReg(cs, HFCD_DATA, HFCB_FIFO | HFCB_F1_INC | HFCB_SEND | HFCB_CHANNEL(bcs->channel)); - WaitForBusy(cs); - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - return; -} - -static void -hfc_send_data(struct BCState *bcs) -{ - struct IsdnCardState *cs = bcs->cs; - - if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - hfc_fill_fifo(bcs); - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - } else - debugl1(cs, "send_data %d blocked", bcs->channel); -} - -static void -main_rec_2bds0(struct BCState *bcs) -{ - struct IsdnCardState *cs = bcs->cs; - int z1, z2, rcnt; - u_char f1, f2, cip; - int receive, count = 5; - struct sk_buff *skb; - -Begin: - count--; - if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - debugl1(cs, "rec_data %d blocked", bcs->channel); - return; - } - SelFiFo(cs, HFCB_REC | HFCB_CHANNEL(bcs->channel)); - cip = HFCB_FIFO | HFCB_F1 | HFCB_REC | HFCB_CHANNEL(bcs->channel); - WaitNoBusy(cs); - f1 = ReadReg(cs, HFCD_DATA, cip); - cip = HFCB_FIFO | HFCB_F2 | HFCB_REC | HFCB_CHANNEL(bcs->channel); - WaitNoBusy(cs); - f2 = ReadReg(cs, HFCD_DATA, cip); - if (f1 != f2) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "hfc rec %d f1(%d) f2(%d)", - bcs->channel, f1, f2); - z1 = ReadZReg(cs, HFCB_FIFO | HFCB_Z1 | HFCB_REC | HFCB_CHANNEL(bcs->channel)); - z2 = ReadZReg(cs, HFCB_FIFO | HFCB_Z2 | HFCB_REC | HFCB_CHANNEL(bcs->channel)); - rcnt = z1 - z2; - if (rcnt < 0) - rcnt += cs->hw.hfcD.bfifosize; - rcnt++; - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "hfc rec %d z1(%x) z2(%x) cnt(%d)", - bcs->channel, z1, z2, rcnt); - if ((skb = hfc_empty_fifo(bcs, rcnt))) { - skb_queue_tail(&bcs->rqueue, skb); - schedule_event(bcs, B_RCVBUFREADY); - } - rcnt = f1 - f2; - if (rcnt < 0) - rcnt += 32; - if (rcnt > 1) - receive = 1; - else - receive = 0; - } else - receive = 0; - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - if (count && receive) - goto Begin; - return; -} - -static void -mode_2bs0(struct BCState *bcs, int mode, int bc) -{ - struct IsdnCardState *cs = bcs->cs; - - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "HFCD bchannel mode %d bchan %d/%d", - mode, bc, bcs->channel); - bcs->mode = mode; - bcs->channel = bc; - switch (mode) { - case (L1_MODE_NULL): - if (bc) { - cs->hw.hfcD.conn |= 0x18; - cs->hw.hfcD.sctrl &= ~SCTRL_B2_ENA; - } else { - cs->hw.hfcD.conn |= 0x3; - cs->hw.hfcD.sctrl &= ~SCTRL_B1_ENA; - } - break; - case (L1_MODE_TRANS): - if (bc) { - cs->hw.hfcD.ctmt |= 2; - cs->hw.hfcD.conn &= ~0x18; - cs->hw.hfcD.sctrl |= SCTRL_B2_ENA; - } else { - cs->hw.hfcD.ctmt |= 1; - cs->hw.hfcD.conn &= ~0x3; - cs->hw.hfcD.sctrl |= SCTRL_B1_ENA; - } - break; - case (L1_MODE_HDLC): - if (bc) { - cs->hw.hfcD.ctmt &= ~2; - cs->hw.hfcD.conn &= ~0x18; - cs->hw.hfcD.sctrl |= SCTRL_B2_ENA; - } else { - cs->hw.hfcD.ctmt &= ~1; - cs->hw.hfcD.conn &= ~0x3; - cs->hw.hfcD.sctrl |= SCTRL_B1_ENA; - } - break; - } - WriteReg(cs, HFCD_DATA, HFCD_SCTRL, cs->hw.hfcD.sctrl); - WriteReg(cs, HFCD_DATA, HFCD_CTMT, cs->hw.hfcD.ctmt); - WriteReg(cs, HFCD_DATA, HFCD_CONN, cs->hw.hfcD.conn); -} - -static void -hfc_l2l1(struct PStack *st, int pr, void *arg) -{ - struct BCState *bcs = st->l1.bcs; - struct sk_buff *skb = arg; - u_long flags; - - switch (pr) { - case (PH_DATA | REQUEST): - spin_lock_irqsave(&bcs->cs->lock, flags); - if (bcs->tx_skb) { - skb_queue_tail(&bcs->squeue, skb); - } else { - bcs->tx_skb = skb; -// test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); - bcs->cs->BC_Send_Data(bcs); - } - spin_unlock_irqrestore(&bcs->cs->lock, flags); - break; - case (PH_PULL | INDICATION): - spin_lock_irqsave(&bcs->cs->lock, flags); - if (bcs->tx_skb) { - printk(KERN_WARNING "hfc_l2l1: this shouldn't happen\n"); - } else { -// test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); - bcs->tx_skb = skb; - bcs->cs->BC_Send_Data(bcs); - } - spin_unlock_irqrestore(&bcs->cs->lock, flags); - break; - case (PH_PULL | REQUEST): - if (!bcs->tx_skb) { - test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); - } else - test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - break; - case (PH_ACTIVATE | REQUEST): - spin_lock_irqsave(&bcs->cs->lock, flags); - test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag); - mode_2bs0(bcs, st->l1.mode, st->l1.bc); - spin_unlock_irqrestore(&bcs->cs->lock, flags); - l1_msg_b(st, pr, arg); - break; - case (PH_DEACTIVATE | REQUEST): - l1_msg_b(st, pr, arg); - break; - case (PH_DEACTIVATE | CONFIRM): - spin_lock_irqsave(&bcs->cs->lock, flags); - test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag); - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - mode_2bs0(bcs, 0, st->l1.bc); - spin_unlock_irqrestore(&bcs->cs->lock, flags); - st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL); - break; - } -} - -static void -close_2bs0(struct BCState *bcs) -{ - mode_2bs0(bcs, 0, bcs->channel); - if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) { - skb_queue_purge(&bcs->rqueue); - skb_queue_purge(&bcs->squeue); - if (bcs->tx_skb) { - dev_kfree_skb_any(bcs->tx_skb); - bcs->tx_skb = NULL; - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - } - } -} - -static int -open_hfcstate(struct IsdnCardState *cs, struct BCState *bcs) -{ - if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { - skb_queue_head_init(&bcs->rqueue); - skb_queue_head_init(&bcs->squeue); - } - bcs->tx_skb = NULL; - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - bcs->event = 0; - bcs->tx_cnt = 0; - return (0); -} - -static int -setstack_2b(struct PStack *st, struct BCState *bcs) -{ - bcs->channel = st->l1.bc; - if (open_hfcstate(st->l1.hardware, bcs)) - return (-1); - st->l1.bcs = bcs; - st->l2.l2l1 = hfc_l2l1; - setstack_manager(st); - bcs->st = st; - setstack_l1_B(st); - return (0); -} - -static void -hfcd_bh(struct work_struct *work) -{ - struct IsdnCardState *cs = - container_of(work, struct IsdnCardState, tqueue); - - if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) { - switch (cs->dc.hfcd.ph_state) { - case (0): - l1_msg(cs, HW_RESET | INDICATION, NULL); - break; - case (3): - l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL); - break; - case (8): - l1_msg(cs, HW_RSYNC | INDICATION, NULL); - break; - case (6): - l1_msg(cs, HW_INFO2 | INDICATION, NULL); - break; - case (7): - l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL); - break; - default: - break; - } - } - if (test_and_clear_bit(D_RCVBUFREADY, &cs->event)) - DChannel_proc_rcv(cs); - if (test_and_clear_bit(D_XMTBUFREADY, &cs->event)) - DChannel_proc_xmt(cs); -} - -static -int receive_dmsg(struct IsdnCardState *cs) -{ - struct sk_buff *skb; - int idx; - int rcnt, z1, z2; - u_char stat, cip, f1, f2; - int chksum; - int count = 5; - u_char *ptr; - - if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - debugl1(cs, "rec_dmsg blocked"); - return (1); - } - SelFiFo(cs, 4 | HFCD_REC); - cip = HFCD_FIFO | HFCD_F1 | HFCD_REC; - WaitNoBusy(cs); - f1 = cs->readisac(cs, cip) & 0xf; - cip = HFCD_FIFO | HFCD_F2 | HFCD_REC; - WaitNoBusy(cs); - f2 = cs->readisac(cs, cip) & 0xf; - while ((f1 != f2) && count--) { - z1 = ReadZReg(cs, HFCD_FIFO | HFCD_Z1 | HFCD_REC); - z2 = ReadZReg(cs, HFCD_FIFO | HFCD_Z2 | HFCD_REC); - rcnt = z1 - z2; - if (rcnt < 0) - rcnt += cs->hw.hfcD.dfifosize; - rcnt++; - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "hfcd recd f1(%d) f2(%d) z1(%x) z2(%x) cnt(%d)", - f1, f2, z1, z2, rcnt); - idx = 0; - cip = HFCD_FIFO | HFCD_FIFO_OUT | HFCD_REC; - if (rcnt > MAX_DFRAME_LEN + 3) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "empty_fifo d: incoming packet too large"); - while (idx < rcnt) { - if (!(WaitNoBusy(cs))) - break; - ReadReg(cs, HFCD_DATA_NODEB, cip); - idx++; - } - } else if (rcnt < 4) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "empty_fifo d: incoming packet too small"); - while ((idx++ < rcnt) && WaitNoBusy(cs)) - ReadReg(cs, HFCD_DATA_NODEB, cip); - } else if ((skb = dev_alloc_skb(rcnt - 3))) { - ptr = skb_put(skb, rcnt - 3); - while (idx < (rcnt - 3)) { - if (!(WaitNoBusy(cs))) - break; - *ptr = ReadReg(cs, HFCD_DATA_NODEB, cip); - idx++; - ptr++; - } - if (idx != (rcnt - 3)) { - debugl1(cs, "RFIFO D BUSY error"); - printk(KERN_WARNING "HFC DFIFO channel BUSY Error\n"); - dev_kfree_skb_irq(skb); - skb = NULL; -#ifdef ERROR_STATISTIC - cs->err_rx++; -#endif - } else { - WaitNoBusy(cs); - chksum = (ReadReg(cs, HFCD_DATA, cip) << 8); - WaitNoBusy(cs); - chksum += ReadReg(cs, HFCD_DATA, cip); - WaitNoBusy(cs); - stat = ReadReg(cs, HFCD_DATA, cip); - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "empty_dfifo chksum %x stat %x", - chksum, stat); - if (stat) { - debugl1(cs, "FIFO CRC error"); - dev_kfree_skb_irq(skb); - skb = NULL; -#ifdef ERROR_STATISTIC - cs->err_crc++; -#endif - } else { - skb_queue_tail(&cs->rq, skb); - schedule_event(cs, D_RCVBUFREADY); - } - } - } else - printk(KERN_WARNING "HFC: D receive out of memory\n"); - WaitForBusy(cs); - cip = HFCD_FIFO | HFCD_F2_INC | HFCD_REC; - WaitNoBusy(cs); - stat = ReadReg(cs, HFCD_DATA, cip); - WaitForBusy(cs); - cip = HFCD_FIFO | HFCD_F2 | HFCD_REC; - WaitNoBusy(cs); - f2 = cs->readisac(cs, cip) & 0xf; - } - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - return (1); -} - -static void -hfc_fill_dfifo(struct IsdnCardState *cs) -{ - int idx, fcnt; - int count; - u_char cip; - - if (!cs->tx_skb) - return; - if (cs->tx_skb->len <= 0) - return; - - SelFiFo(cs, 4 | HFCD_SEND); - cip = HFCD_FIFO | HFCD_F1 | HFCD_SEND; - WaitNoBusy(cs); - cs->hw.hfcD.f1 = ReadReg(cs, HFCD_DATA, cip) & 0xf; - WaitNoBusy(cs); - cip = HFCD_FIFO | HFCD_F2 | HFCD_SEND; - cs->hw.hfcD.f2 = ReadReg(cs, HFCD_DATA, cip) & 0xf; - cs->hw.hfcD.send[cs->hw.hfcD.f1] = ReadZReg(cs, HFCD_FIFO | HFCD_Z1 | HFCD_SEND); - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "hfc_fill_Dfifo f1(%d) f2(%d) z1(%x)", - cs->hw.hfcD.f1, cs->hw.hfcD.f2, - cs->hw.hfcD.send[cs->hw.hfcD.f1]); - fcnt = cs->hw.hfcD.f1 - cs->hw.hfcD.f2; - if (fcnt < 0) - fcnt += 16; - if (fcnt > 14) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "hfc_fill_Dfifo more as 14 frames"); - return; - } - count = GetFreeFifoBytes_D(cs); - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "hfc_fill_Dfifo count(%u/%d)", - cs->tx_skb->len, count); - if (count < cs->tx_skb->len) { - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "hfc_fill_Dfifo no fifo mem"); - return; - } - cip = HFCD_FIFO | HFCD_FIFO_IN | HFCD_SEND; - idx = 0; - WaitForBusy(cs); - WaitNoBusy(cs); - WriteReg(cs, HFCD_DATA_NODEB, cip, cs->tx_skb->data[idx++]); - while (idx < cs->tx_skb->len) { - if (!(WaitNoBusy(cs))) - break; - WriteReg(cs, HFCD_DATA_NODEB, cip, cs->tx_skb->data[idx]); - idx++; - } - if (idx != cs->tx_skb->len) { - debugl1(cs, "DFIFO Send BUSY error"); - printk(KERN_WARNING "HFC S DFIFO channel BUSY Error\n"); - } - WaitForBusy(cs); - WaitNoBusy(cs); - ReadReg(cs, HFCD_DATA, HFCD_FIFO | HFCD_F1_INC | HFCD_SEND); - dev_kfree_skb_any(cs->tx_skb); - cs->tx_skb = NULL; - WaitForBusy(cs); - return; -} - -static -struct BCState *Sel_BCS(struct IsdnCardState *cs, int channel) -{ - if (cs->bcs[0].mode && (cs->bcs[0].channel == channel)) - return (&cs->bcs[0]); - else if (cs->bcs[1].mode && (cs->bcs[1].channel == channel)) - return (&cs->bcs[1]); - else - return (NULL); -} - -void -hfc2bds0_interrupt(struct IsdnCardState *cs, u_char val) -{ - u_char exval; - struct BCState *bcs; - int count = 15; - - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "HFCD irq %x %s", val, - test_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags) ? - "locked" : "unlocked"); - val &= cs->hw.hfcD.int_m1; - if (val & 0x40) { /* TE state machine irq */ - exval = cs->readisac(cs, HFCD_STATES) & 0xf; - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "ph_state chg %d->%d", cs->dc.hfcd.ph_state, - exval); - cs->dc.hfcd.ph_state = exval; - schedule_event(cs, D_L1STATECHANGE); - val &= ~0x40; - } - while (val) { - if (test_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - cs->hw.hfcD.int_s1 |= val; - return; - } - if (cs->hw.hfcD.int_s1 & 0x18) { - exval = val; - val = cs->hw.hfcD.int_s1; - cs->hw.hfcD.int_s1 = exval; - } - if (val & 0x08) { - if (!(bcs = Sel_BCS(cs, 0))) { - if (cs->debug) - debugl1(cs, "hfcd spurious 0x08 IRQ"); - } else - main_rec_2bds0(bcs); - } - if (val & 0x10) { - if (!(bcs = Sel_BCS(cs, 1))) { - if (cs->debug) - debugl1(cs, "hfcd spurious 0x10 IRQ"); - } else - main_rec_2bds0(bcs); - } - if (val & 0x01) { - if (!(bcs = Sel_BCS(cs, 0))) { - if (cs->debug) - debugl1(cs, "hfcd spurious 0x01 IRQ"); - } else { - if (bcs->tx_skb) { - if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - hfc_fill_fifo(bcs); - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - } else - debugl1(cs, "fill_data %d blocked", bcs->channel); - } else { - if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) { - if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - hfc_fill_fifo(bcs); - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - } else - debugl1(cs, "fill_data %d blocked", bcs->channel); - } else { - schedule_event(bcs, B_XMTBUFREADY); - } - } - } - } - if (val & 0x02) { - if (!(bcs = Sel_BCS(cs, 1))) { - if (cs->debug) - debugl1(cs, "hfcd spurious 0x02 IRQ"); - } else { - if (bcs->tx_skb) { - if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - hfc_fill_fifo(bcs); - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - } else - debugl1(cs, "fill_data %d blocked", bcs->channel); - } else { - if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) { - if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - hfc_fill_fifo(bcs); - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - } else - debugl1(cs, "fill_data %d blocked", bcs->channel); - } else { - schedule_event(bcs, B_XMTBUFREADY); - } - } - } - } - if (val & 0x20) { /* receive dframe */ - receive_dmsg(cs); - } - if (val & 0x04) { /* dframe transmitted */ - if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) - del_timer(&cs->dbusytimer); - if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags)) - schedule_event(cs, D_CLEARBUSY); - if (cs->tx_skb) { - if (cs->tx_skb->len) { - if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - hfc_fill_dfifo(cs); - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - } else { - debugl1(cs, "hfc_fill_dfifo irq blocked"); - } - goto afterXPR; - } else { - dev_kfree_skb_irq(cs->tx_skb); - cs->tx_cnt = 0; - cs->tx_skb = NULL; - } - } - if ((cs->tx_skb = skb_dequeue(&cs->sq))) { - cs->tx_cnt = 0; - if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - hfc_fill_dfifo(cs); - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - } else { - debugl1(cs, "hfc_fill_dfifo irq blocked"); - } - } else - schedule_event(cs, D_XMTBUFREADY); - } - afterXPR: - if (cs->hw.hfcD.int_s1 && count--) { - val = cs->hw.hfcD.int_s1; - cs->hw.hfcD.int_s1 = 0; - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "HFCD irq %x loop %d", val, 15-count); - } else - val = 0; - } -} - -static void -HFCD_l1hw(struct PStack *st, int pr, void *arg) -{ - struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware; - struct sk_buff *skb = arg; - u_long flags; - - switch (pr) { - case (PH_DATA | REQUEST): - if (cs->debug & DEB_DLOG_HEX) - LogFrame(cs, skb->data, skb->len); - if (cs->debug & DEB_DLOG_VERBOSE) - dlogframe(cs, skb, 0); - spin_lock_irqsave(&cs->lock, flags); - if (cs->tx_skb) { - skb_queue_tail(&cs->sq, skb); -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - Logl2Frame(cs, skb, "PH_DATA Queued", 0); -#endif - } else { - cs->tx_skb = skb; - cs->tx_cnt = 0; -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - Logl2Frame(cs, skb, "PH_DATA", 0); -#endif - if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - hfc_fill_dfifo(cs); - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - } else - debugl1(cs, "hfc_fill_dfifo blocked"); - - } - spin_unlock_irqrestore(&cs->lock, flags); - break; - case (PH_PULL | INDICATION): - spin_lock_irqsave(&cs->lock, flags); - if (cs->tx_skb) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, " l2l1 tx_skb exist this shouldn't happen"); - skb_queue_tail(&cs->sq, skb); - spin_unlock_irqrestore(&cs->lock, flags); - break; - } - if (cs->debug & DEB_DLOG_HEX) - LogFrame(cs, skb->data, skb->len); - if (cs->debug & DEB_DLOG_VERBOSE) - dlogframe(cs, skb, 0); - cs->tx_skb = skb; - cs->tx_cnt = 0; -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - Logl2Frame(cs, skb, "PH_DATA_PULLED", 0); -#endif - if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - hfc_fill_dfifo(cs); - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - } else - debugl1(cs, "hfc_fill_dfifo blocked"); - spin_unlock_irqrestore(&cs->lock, flags); - break; - case (PH_PULL | REQUEST): -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - debugl1(cs, "-> PH_REQUEST_PULL"); -#endif - if (!cs->tx_skb) { - test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); - } else - test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - break; - case (HW_RESET | REQUEST): - spin_lock_irqsave(&cs->lock, flags); - cs->writeisac(cs, HFCD_STATES, HFCD_LOAD_STATE | 3); /* HFC ST 3 */ - udelay(6); - cs->writeisac(cs, HFCD_STATES, 3); /* HFC ST 2 */ - cs->hw.hfcD.mst_m |= HFCD_MASTER; - cs->writeisac(cs, HFCD_MST_MODE, cs->hw.hfcD.mst_m); - cs->writeisac(cs, HFCD_STATES, HFCD_ACTIVATE | HFCD_DO_ACTION); - spin_unlock_irqrestore(&cs->lock, flags); - l1_msg(cs, HW_POWERUP | CONFIRM, NULL); - break; - case (HW_ENABLE | REQUEST): - spin_lock_irqsave(&cs->lock, flags); - cs->writeisac(cs, HFCD_STATES, HFCD_ACTIVATE | HFCD_DO_ACTION); - spin_unlock_irqrestore(&cs->lock, flags); - break; - case (HW_DEACTIVATE | REQUEST): - spin_lock_irqsave(&cs->lock, flags); - cs->hw.hfcD.mst_m &= ~HFCD_MASTER; - cs->writeisac(cs, HFCD_MST_MODE, cs->hw.hfcD.mst_m); - spin_unlock_irqrestore(&cs->lock, flags); - break; - case (HW_INFO3 | REQUEST): - spin_lock_irqsave(&cs->lock, flags); - cs->hw.hfcD.mst_m |= HFCD_MASTER; - cs->writeisac(cs, HFCD_MST_MODE, cs->hw.hfcD.mst_m); - spin_unlock_irqrestore(&cs->lock, flags); - break; - default: - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "hfcd_l1hw unknown pr %4x", pr); - break; - } -} - -static void -setstack_hfcd(struct PStack *st, struct IsdnCardState *cs) -{ - st->l1.l1hw = HFCD_l1hw; -} - -static void -hfc_dbusy_timer(struct timer_list *t) -{ -} - -static unsigned int -*init_send_hfcd(int cnt) -{ - int i; - unsigned *send; - - if (!(send = kmalloc_array(cnt, sizeof(unsigned int), GFP_ATOMIC))) { - printk(KERN_WARNING - "HiSax: No memory for hfcd.send\n"); - return (NULL); - } - for (i = 0; i < cnt; i++) - send[i] = 0x1fff; - return (send); -} - -void -init2bds0(struct IsdnCardState *cs) -{ - cs->setstack_d = setstack_hfcd; - if (!cs->hw.hfcD.send) - cs->hw.hfcD.send = init_send_hfcd(16); - if (!cs->bcs[0].hw.hfc.send) - cs->bcs[0].hw.hfc.send = init_send_hfcd(32); - if (!cs->bcs[1].hw.hfc.send) - cs->bcs[1].hw.hfc.send = init_send_hfcd(32); - cs->BC_Send_Data = &hfc_send_data; - cs->bcs[0].BC_SetStack = setstack_2b; - cs->bcs[1].BC_SetStack = setstack_2b; - cs->bcs[0].BC_Close = close_2bs0; - cs->bcs[1].BC_Close = close_2bs0; - mode_2bs0(cs->bcs, 0, 0); - mode_2bs0(cs->bcs + 1, 0, 1); -} - -void -release2bds0(struct IsdnCardState *cs) -{ - kfree(cs->bcs[0].hw.hfc.send); - cs->bcs[0].hw.hfc.send = NULL; - kfree(cs->bcs[1].hw.hfc.send); - cs->bcs[1].hw.hfc.send = NULL; - kfree(cs->hw.hfcD.send); - cs->hw.hfcD.send = NULL; -} - -void -set_cs_func(struct IsdnCardState *cs) -{ - cs->readisac = &readreghfcd; - cs->writeisac = &writereghfcd; - cs->readisacfifo = &dummyf; - cs->writeisacfifo = &dummyf; - cs->BC_Read_Reg = &ReadReg; - cs->BC_Write_Reg = &WriteReg; - timer_setup(&cs->dbusytimer, hfc_dbusy_timer, 0); - INIT_WORK(&cs->tqueue, hfcd_bh); -} diff --git a/drivers/isdn/hisax/hfc_2bds0.h b/drivers/isdn/hisax/hfc_2bds0.h deleted file mode 100644 index 8c7582a3c51e..000000000000 --- a/drivers/isdn/hisax/hfc_2bds0.h +++ /dev/null @@ -1,128 +0,0 @@ -/* $Id: hfc_2bds0.h,v 1.6.2.2 2004/01/12 22:52:26 keil Exp $ - * - * specific defines for CCD's HFC 2BDS0 - * - * Author Karsten Keil - * Copyright by Karsten Keil <keil@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#define HFCD_CIRM 0x18 -#define HFCD_CTMT 0x19 -#define HFCD_INT_M1 0x1A -#define HFCD_INT_M2 0x1B -#define HFCD_INT_S1 0x1E -#define HFCD_STAT 0x1C -#define HFCD_STAT_DISB 0x1D -#define HFCD_STATES 0x30 -#define HFCD_SCTRL 0x31 -#define HFCD_TEST 0x32 -#define HFCD_SQ 0x34 -#define HFCD_CLKDEL 0x37 -#define HFCD_MST_MODE 0x2E -#define HFCD_CONN 0x2F - -#define HFCD_FIFO 0x80 -#define HFCD_Z1 0x10 -#define HFCD_Z2 0x18 -#define HFCD_Z_LOW 0x00 -#define HFCD_Z_HIGH 0x04 -#define HFCD_F1_INC 0x12 -#define HFCD_FIFO_IN 0x16 -#define HFCD_F1 0x1a -#define HFCD_F2 0x1e -#define HFCD_F2_INC 0x22 -#define HFCD_FIFO_OUT 0x26 -#define HFCD_REC 0x01 -#define HFCD_SEND 0x00 - -#define HFCB_FIFO 0x80 -#define HFCB_Z1 0x00 -#define HFCB_Z2 0x08 -#define HFCB_Z_LOW 0x00 -#define HFCB_Z_HIGH 0x04 -#define HFCB_F1_INC 0x28 -#define HFCB_FIFO_IN 0x2c -#define HFCB_F1 0x30 -#define HFCB_F2 0x34 -#define HFCB_F2_INC 0x38 -#define HFCB_FIFO_OUT 0x3c -#define HFCB_REC 0x01 -#define HFCB_SEND 0x00 -#define HFCB_B1 0x00 -#define HFCB_B2 0x02 -#define HFCB_CHANNEL(ch) (ch ? HFCB_B2 : HFCB_B1) - -#define HFCD_STATUS 0 -#define HFCD_DATA 1 -#define HFCD_DATA_NODEB 2 - -/* Status (READ) */ -#define HFCD_BUSY 0x01 -#define HFCD_BUSY_NBUSY 0x04 -#define HFCD_TIMER_ELAP 0x10 -#define HFCD_STATINT 0x20 -#define HFCD_FRAMEINT 0x40 -#define HFCD_ANYINT 0x80 - -/* CTMT (Write) */ -#define HFCD_CLTIMER 0x80 -#define HFCD_TIM25 0x00 -#define HFCD_TIM50 0x08 -#define HFCD_TIM400 0x10 -#define HFCD_TIM800 0x18 -#define HFCD_AUTO_TIMER 0x20 -#define HFCD_TRANSB2 0x02 -#define HFCD_TRANSB1 0x01 - -/* CIRM (Write) */ -#define HFCD_RESET 0x08 -#define HFCD_MEM8K 0x10 -#define HFCD_INTA 0x01 -#define HFCD_INTB 0x02 -#define HFCD_INTC 0x03 -#define HFCD_INTD 0x04 -#define HFCD_INTE 0x05 -#define HFCD_INTF 0x06 - -/* INT_M1;INT_S1 */ -#define HFCD_INTS_B1TRANS 0x01 -#define HFCD_INTS_B2TRANS 0x02 -#define HFCD_INTS_DTRANS 0x04 -#define HFCD_INTS_B1REC 0x08 -#define HFCD_INTS_B2REC 0x10 -#define HFCD_INTS_DREC 0x20 -#define HFCD_INTS_L1STATE 0x40 -#define HFCD_INTS_TIMER 0x80 - -/* INT_M2 */ -#define HFCD_IRQ_ENABLE 0x08 - -/* STATES */ -#define HFCD_LOAD_STATE 0x10 -#define HFCD_ACTIVATE 0x20 -#define HFCD_DO_ACTION 0x40 - -/* HFCD_MST_MODE */ -#define HFCD_MASTER 0x01 - -/* HFCD_SCTRL */ -#define SCTRL_B1_ENA 0x01 -#define SCTRL_B2_ENA 0x02 -#define SCTRL_LOW_PRIO 0x08 -#define SCTRL_SQ_ENA 0x10 -#define SCTRL_TEST 0x20 -#define SCTRL_NONE_CAP 0x40 -#define SCTRL_PWR_DOWN 0x80 - -/* HFCD_TEST */ -#define HFCD_AUTO_AWAKE 0x01 - -extern void main_irq_2bds0(struct BCState *bcs); -extern void init2bds0(struct IsdnCardState *cs); -extern void release2bds0(struct IsdnCardState *cs); -extern void hfc2bds0_interrupt(struct IsdnCardState *cs, u_char val); -extern void set_cs_func(struct IsdnCardState *cs); diff --git a/drivers/isdn/hisax/hfc_2bs0.c b/drivers/isdn/hisax/hfc_2bs0.c deleted file mode 100644 index 34d59992839a..000000000000 --- a/drivers/isdn/hisax/hfc_2bs0.c +++ /dev/null @@ -1,591 +0,0 @@ -/* $Id: hfc_2bs0.c,v 1.20.2.6 2004/02/11 13:21:33 keil Exp $ - * - * specific routines for CCD's HFC 2BS0 - * - * Author Karsten Keil - * Copyright by Karsten Keil <keil@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/init.h> -#include "hisax.h" -#include "hfc_2bs0.h" -#include "isac.h" -#include "isdnl1.h" -#include <linux/interrupt.h> -#include <linux/slab.h> - -static inline int -WaitForBusy(struct IsdnCardState *cs) -{ - int to = 130; - u_char val; - - while (!(cs->BC_Read_Reg(cs, HFC_STATUS, 0) & HFC_BUSY) && to) { - val = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2 | - (cs->hw.hfc.cip & 3)); - udelay(1); - to--; - } - if (!to) { - printk(KERN_WARNING "HiSax: %s timeout\n", __func__); - return (0); - } else - return (to); -} - -static inline int -WaitNoBusy(struct IsdnCardState *cs) -{ - int to = 125; - - while ((cs->BC_Read_Reg(cs, HFC_STATUS, 0) & HFC_BUSY) && to) { - udelay(1); - to--; - } - if (!to) { - printk(KERN_WARNING "HiSax: waitforBusy timeout\n"); - return (0); - } else - return (to); -} - -static int -GetFreeFifoBytes(struct BCState *bcs) -{ - int s; - - if (bcs->hw.hfc.f1 == bcs->hw.hfc.f2) - return (bcs->cs->hw.hfc.fifosize); - s = bcs->hw.hfc.send[bcs->hw.hfc.f1] - bcs->hw.hfc.send[bcs->hw.hfc.f2]; - if (s <= 0) - s += bcs->cs->hw.hfc.fifosize; - s = bcs->cs->hw.hfc.fifosize - s; - return (s); -} - -static int -ReadZReg(struct BCState *bcs, u_char reg) -{ - int val; - - WaitNoBusy(bcs->cs); - val = 256 * bcs->cs->BC_Read_Reg(bcs->cs, HFC_DATA, reg | HFC_CIP | HFC_Z_HIGH); - WaitNoBusy(bcs->cs); - val += bcs->cs->BC_Read_Reg(bcs->cs, HFC_DATA, reg | HFC_CIP | HFC_Z_LOW); - return (val); -} - -static void -hfc_clear_fifo(struct BCState *bcs) -{ - struct IsdnCardState *cs = bcs->cs; - int idx, cnt; - int rcnt, z1, z2; - u_char cip, f1, f2; - - if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) - debugl1(cs, "hfc_clear_fifo"); - cip = HFC_CIP | HFC_F1 | HFC_REC | HFC_CHANNEL(bcs->channel); - if ((cip & 0xc3) != (cs->hw.hfc.cip & 0xc3)) { - cs->BC_Write_Reg(cs, HFC_STATUS, cip, cip); - WaitForBusy(cs); - } - WaitNoBusy(cs); - f1 = cs->BC_Read_Reg(cs, HFC_DATA, cip); - cip = HFC_CIP | HFC_F2 | HFC_REC | HFC_CHANNEL(bcs->channel); - WaitNoBusy(cs); - f2 = cs->BC_Read_Reg(cs, HFC_DATA, cip); - z1 = ReadZReg(bcs, HFC_Z1 | HFC_REC | HFC_CHANNEL(bcs->channel)); - z2 = ReadZReg(bcs, HFC_Z2 | HFC_REC | HFC_CHANNEL(bcs->channel)); - cnt = 32; - while (((f1 != f2) || (z1 != z2)) && cnt--) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "hfc clear %d f1(%d) f2(%d)", - bcs->channel, f1, f2); - rcnt = z1 - z2; - if (rcnt < 0) - rcnt += cs->hw.hfc.fifosize; - if (rcnt) - rcnt++; - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "hfc clear %d z1(%x) z2(%x) cnt(%d)", - bcs->channel, z1, z2, rcnt); - cip = HFC_CIP | HFC_FIFO_OUT | HFC_REC | HFC_CHANNEL(bcs->channel); - idx = 0; - while ((idx < rcnt) && WaitNoBusy(cs)) { - cs->BC_Read_Reg(cs, HFC_DATA_NODEB, cip); - idx++; - } - if (f1 != f2) { - WaitNoBusy(cs); - cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC | - HFC_CHANNEL(bcs->channel)); - WaitForBusy(cs); - } - cip = HFC_CIP | HFC_F1 | HFC_REC | HFC_CHANNEL(bcs->channel); - WaitNoBusy(cs); - f1 = cs->BC_Read_Reg(cs, HFC_DATA, cip); - cip = HFC_CIP | HFC_F2 | HFC_REC | HFC_CHANNEL(bcs->channel); - WaitNoBusy(cs); - f2 = cs->BC_Read_Reg(cs, HFC_DATA, cip); - z1 = ReadZReg(bcs, HFC_Z1 | HFC_REC | HFC_CHANNEL(bcs->channel)); - z2 = ReadZReg(bcs, HFC_Z2 | HFC_REC | HFC_CHANNEL(bcs->channel)); - } - return; -} - - -static struct sk_buff -* -hfc_empty_fifo(struct BCState *bcs, int count) -{ - u_char *ptr; - struct sk_buff *skb; - struct IsdnCardState *cs = bcs->cs; - int idx; - int chksum; - u_char stat, cip; - - if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) - debugl1(cs, "hfc_empty_fifo"); - idx = 0; - if (count > HSCX_BUFMAX + 3) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "hfc_empty_fifo: incoming packet too large"); - cip = HFC_CIP | HFC_FIFO_OUT | HFC_REC | HFC_CHANNEL(bcs->channel); - while ((idx++ < count) && WaitNoBusy(cs)) - cs->BC_Read_Reg(cs, HFC_DATA_NODEB, cip); - WaitNoBusy(cs); - stat = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC | - HFC_CHANNEL(bcs->channel)); - WaitForBusy(cs); - return (NULL); - } - if ((count < 4) && (bcs->mode != L1_MODE_TRANS)) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "hfc_empty_fifo: incoming packet too small"); - cip = HFC_CIP | HFC_FIFO_OUT | HFC_REC | HFC_CHANNEL(bcs->channel); - while ((idx++ < count) && WaitNoBusy(cs)) - cs->BC_Read_Reg(cs, HFC_DATA_NODEB, cip); - WaitNoBusy(cs); - stat = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC | - HFC_CHANNEL(bcs->channel)); - WaitForBusy(cs); -#ifdef ERROR_STATISTIC - bcs->err_inv++; -#endif - return (NULL); - } - if (bcs->mode == L1_MODE_TRANS) - count -= 1; - else - count -= 3; - if (!(skb = dev_alloc_skb(count))) - printk(KERN_WARNING "HFC: receive out of memory\n"); - else { - ptr = skb_put(skb, count); - idx = 0; - cip = HFC_CIP | HFC_FIFO_OUT | HFC_REC | HFC_CHANNEL(bcs->channel); - while ((idx < count) && WaitNoBusy(cs)) { - *ptr++ = cs->BC_Read_Reg(cs, HFC_DATA_NODEB, cip); - idx++; - } - if (idx != count) { - debugl1(cs, "RFIFO BUSY error"); - printk(KERN_WARNING "HFC FIFO channel %d BUSY Error\n", bcs->channel); - dev_kfree_skb_any(skb); - if (bcs->mode != L1_MODE_TRANS) { - WaitNoBusy(cs); - stat = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC | - HFC_CHANNEL(bcs->channel)); - WaitForBusy(cs); - } - return (NULL); - } - if (bcs->mode != L1_MODE_TRANS) { - WaitNoBusy(cs); - chksum = (cs->BC_Read_Reg(cs, HFC_DATA, cip) << 8); - WaitNoBusy(cs); - chksum += cs->BC_Read_Reg(cs, HFC_DATA, cip); - WaitNoBusy(cs); - stat = cs->BC_Read_Reg(cs, HFC_DATA, cip); - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "hfc_empty_fifo %d chksum %x stat %x", - bcs->channel, chksum, stat); - if (stat) { - debugl1(cs, "FIFO CRC error"); - dev_kfree_skb_any(skb); - skb = NULL; -#ifdef ERROR_STATISTIC - bcs->err_crc++; -#endif - } - WaitNoBusy(cs); - stat = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC | - HFC_CHANNEL(bcs->channel)); - WaitForBusy(cs); - } - } - return (skb); -} - -static void -hfc_fill_fifo(struct BCState *bcs) -{ - struct IsdnCardState *cs = bcs->cs; - int idx, fcnt; - int count; - int z1, z2; - u_char cip; - - if (!bcs->tx_skb) - return; - if (bcs->tx_skb->len <= 0) - return; - - cip = HFC_CIP | HFC_F1 | HFC_SEND | HFC_CHANNEL(bcs->channel); - if ((cip & 0xc3) != (cs->hw.hfc.cip & 0xc3)) { - cs->BC_Write_Reg(cs, HFC_STATUS, cip, cip); - WaitForBusy(cs); - } - WaitNoBusy(cs); - if (bcs->mode != L1_MODE_TRANS) { - bcs->hw.hfc.f1 = cs->BC_Read_Reg(cs, HFC_DATA, cip); - cip = HFC_CIP | HFC_F2 | HFC_SEND | HFC_CHANNEL(bcs->channel); - WaitNoBusy(cs); - bcs->hw.hfc.f2 = cs->BC_Read_Reg(cs, HFC_DATA, cip); - bcs->hw.hfc.send[bcs->hw.hfc.f1] = ReadZReg(bcs, HFC_Z1 | HFC_SEND | HFC_CHANNEL(bcs->channel)); - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "hfc_fill_fifo %d f1(%d) f2(%d) z1(%x)", - bcs->channel, bcs->hw.hfc.f1, bcs->hw.hfc.f2, - bcs->hw.hfc.send[bcs->hw.hfc.f1]); - fcnt = bcs->hw.hfc.f1 - bcs->hw.hfc.f2; - if (fcnt < 0) - fcnt += 32; - if (fcnt > 30) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "hfc_fill_fifo more as 30 frames"); - return; - } - count = GetFreeFifoBytes(bcs); - } - else { - WaitForBusy(cs); - z1 = ReadZReg(bcs, HFC_Z1 | HFC_REC | HFC_CHANNEL(bcs->channel)); - z2 = ReadZReg(bcs, HFC_Z2 | HFC_REC | HFC_CHANNEL(bcs->channel)); - count = z1 - z2; - if (count < 0) - count += cs->hw.hfc.fifosize; - } /* L1_MODE_TRANS */ - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "hfc_fill_fifo %d count(%u/%d)", - bcs->channel, bcs->tx_skb->len, - count); - if (count < bcs->tx_skb->len) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "hfc_fill_fifo no fifo mem"); - return; - } - cip = HFC_CIP | HFC_FIFO_IN | HFC_SEND | HFC_CHANNEL(bcs->channel); - idx = 0; - while ((idx < bcs->tx_skb->len) && WaitNoBusy(cs)) - cs->BC_Write_Reg(cs, HFC_DATA_NODEB, cip, bcs->tx_skb->data[idx++]); - if (idx != bcs->tx_skb->len) { - debugl1(cs, "FIFO Send BUSY error"); - printk(KERN_WARNING "HFC S FIFO channel %d BUSY Error\n", bcs->channel); - } else { - count = bcs->tx_skb->len; - bcs->tx_cnt -= count; - if (PACKET_NOACK == bcs->tx_skb->pkt_type) - count = -1; - dev_kfree_skb_any(bcs->tx_skb); - bcs->tx_skb = NULL; - if (bcs->mode != L1_MODE_TRANS) { - WaitForBusy(cs); - WaitNoBusy(cs); - cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F1_INC | HFC_SEND | HFC_CHANNEL(bcs->channel)); - } - if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) && - (count >= 0)) { - u_long flags; - spin_lock_irqsave(&bcs->aclock, flags); - bcs->ackcnt += count; - spin_unlock_irqrestore(&bcs->aclock, flags); - schedule_event(bcs, B_ACKPENDING); - } - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - } - return; -} - -void -main_irq_hfc(struct BCState *bcs) -{ - struct IsdnCardState *cs = bcs->cs; - int z1, z2, rcnt; - u_char f1, f2, cip; - int receive, transmit, count = 5; - struct sk_buff *skb; - -Begin: - count--; - cip = HFC_CIP | HFC_F1 | HFC_REC | HFC_CHANNEL(bcs->channel); - if ((cip & 0xc3) != (cs->hw.hfc.cip & 0xc3)) { - cs->BC_Write_Reg(cs, HFC_STATUS, cip, cip); - WaitForBusy(cs); - } - WaitNoBusy(cs); - receive = 0; - if (bcs->mode == L1_MODE_HDLC) { - f1 = cs->BC_Read_Reg(cs, HFC_DATA, cip); - cip = HFC_CIP | HFC_F2 | HFC_REC | HFC_CHANNEL(bcs->channel); - WaitNoBusy(cs); - f2 = cs->BC_Read_Reg(cs, HFC_DATA, cip); - if (f1 != f2) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "hfc rec %d f1(%d) f2(%d)", - bcs->channel, f1, f2); - receive = 1; - } - } - if (receive || (bcs->mode == L1_MODE_TRANS)) { - WaitForBusy(cs); - z1 = ReadZReg(bcs, HFC_Z1 | HFC_REC | HFC_CHANNEL(bcs->channel)); - z2 = ReadZReg(bcs, HFC_Z2 | HFC_REC | HFC_CHANNEL(bcs->channel)); - rcnt = z1 - z2; - if (rcnt < 0) - rcnt += cs->hw.hfc.fifosize; - if ((bcs->mode == L1_MODE_HDLC) || (rcnt)) { - rcnt++; - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "hfc rec %d z1(%x) z2(%x) cnt(%d)", - bcs->channel, z1, z2, rcnt); - /* sti(); */ - if ((skb = hfc_empty_fifo(bcs, rcnt))) { - skb_queue_tail(&bcs->rqueue, skb); - schedule_event(bcs, B_RCVBUFREADY); - } - } - receive = 1; - } - if (bcs->tx_skb) { - transmit = 1; - test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); - hfc_fill_fifo(bcs); - if (test_bit(BC_FLG_BUSY, &bcs->Flag)) - transmit = 0; - } else { - if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) { - transmit = 1; - test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); - hfc_fill_fifo(bcs); - if (test_bit(BC_FLG_BUSY, &bcs->Flag)) - transmit = 0; - } else { - transmit = 0; - schedule_event(bcs, B_XMTBUFREADY); - } - } - if ((receive || transmit) && count) - goto Begin; - return; -} - -static void -mode_hfc(struct BCState *bcs, int mode, int bc) -{ - struct IsdnCardState *cs = bcs->cs; - - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "HFC 2BS0 mode %d bchan %d/%d", - mode, bc, bcs->channel); - bcs->mode = mode; - bcs->channel = bc; - - switch (mode) { - case (L1_MODE_NULL): - if (bc) { - cs->hw.hfc.ctmt &= ~1; - cs->hw.hfc.isac_spcr &= ~0x03; - } - else { - cs->hw.hfc.ctmt &= ~2; - cs->hw.hfc.isac_spcr &= ~0x0c; - } - break; - case (L1_MODE_TRANS): - cs->hw.hfc.ctmt &= ~(1 << bc); /* set HDLC mode */ - cs->BC_Write_Reg(cs, HFC_STATUS, cs->hw.hfc.ctmt, cs->hw.hfc.ctmt); - hfc_clear_fifo(bcs); /* complete fifo clear */ - if (bc) { - cs->hw.hfc.ctmt |= 1; - cs->hw.hfc.isac_spcr &= ~0x03; - cs->hw.hfc.isac_spcr |= 0x02; - } else { - cs->hw.hfc.ctmt |= 2; - cs->hw.hfc.isac_spcr &= ~0x0c; - cs->hw.hfc.isac_spcr |= 0x08; - } - break; - case (L1_MODE_HDLC): - if (bc) { - cs->hw.hfc.ctmt &= ~1; - cs->hw.hfc.isac_spcr &= ~0x03; - cs->hw.hfc.isac_spcr |= 0x02; - } else { - cs->hw.hfc.ctmt &= ~2; - cs->hw.hfc.isac_spcr &= ~0x0c; - cs->hw.hfc.isac_spcr |= 0x08; - } - break; - } - cs->BC_Write_Reg(cs, HFC_STATUS, cs->hw.hfc.ctmt, cs->hw.hfc.ctmt); - cs->writeisac(cs, ISAC_SPCR, cs->hw.hfc.isac_spcr); - if (mode == L1_MODE_HDLC) - hfc_clear_fifo(bcs); -} - -static void -hfc_l2l1(struct PStack *st, int pr, void *arg) -{ - struct BCState *bcs = st->l1.bcs; - struct sk_buff *skb = arg; - u_long flags; - - switch (pr) { - case (PH_DATA | REQUEST): - spin_lock_irqsave(&bcs->cs->lock, flags); - if (bcs->tx_skb) { - skb_queue_tail(&bcs->squeue, skb); - } else { - bcs->tx_skb = skb; - test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); - bcs->cs->BC_Send_Data(bcs); - } - spin_unlock_irqrestore(&bcs->cs->lock, flags); - break; - case (PH_PULL | INDICATION): - spin_lock_irqsave(&bcs->cs->lock, flags); - if (bcs->tx_skb) { - printk(KERN_WARNING "hfc_l2l1: this shouldn't happen\n"); - } else { - test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); - bcs->tx_skb = skb; - bcs->cs->BC_Send_Data(bcs); - } - spin_unlock_irqrestore(&bcs->cs->lock, flags); - break; - case (PH_PULL | REQUEST): - if (!bcs->tx_skb) { - test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); - } else - test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - break; - case (PH_ACTIVATE | REQUEST): - spin_lock_irqsave(&bcs->cs->lock, flags); - test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag); - mode_hfc(bcs, st->l1.mode, st->l1.bc); - spin_unlock_irqrestore(&bcs->cs->lock, flags); - l1_msg_b(st, pr, arg); - break; - case (PH_DEACTIVATE | REQUEST): - l1_msg_b(st, pr, arg); - break; - case (PH_DEACTIVATE | CONFIRM): - spin_lock_irqsave(&bcs->cs->lock, flags); - test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag); - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - mode_hfc(bcs, 0, st->l1.bc); - spin_unlock_irqrestore(&bcs->cs->lock, flags); - st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL); - break; - } -} - - -static void -close_hfcstate(struct BCState *bcs) -{ - mode_hfc(bcs, 0, bcs->channel); - if (test_bit(BC_FLG_INIT, &bcs->Flag)) { - skb_queue_purge(&bcs->rqueue); - skb_queue_purge(&bcs->squeue); - if (bcs->tx_skb) { - dev_kfree_skb_any(bcs->tx_skb); - bcs->tx_skb = NULL; - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - } - } - test_and_clear_bit(BC_FLG_INIT, &bcs->Flag); -} - -static int -open_hfcstate(struct IsdnCardState *cs, struct BCState *bcs) -{ - if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { - skb_queue_head_init(&bcs->rqueue); - skb_queue_head_init(&bcs->squeue); - } - bcs->tx_skb = NULL; - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - bcs->event = 0; - bcs->tx_cnt = 0; - return (0); -} - -static int -setstack_hfc(struct PStack *st, struct BCState *bcs) -{ - bcs->channel = st->l1.bc; - if (open_hfcstate(st->l1.hardware, bcs)) - return (-1); - st->l1.bcs = bcs; - st->l2.l2l1 = hfc_l2l1; - setstack_manager(st); - bcs->st = st; - setstack_l1_B(st); - return (0); -} - -static void -init_send(struct BCState *bcs) -{ - int i; - - bcs->hw.hfc.send = kmalloc_array(32, sizeof(unsigned int), GFP_ATOMIC); - if (!bcs->hw.hfc.send) { - printk(KERN_WARNING - "HiSax: No memory for hfc.send\n"); - return; - } - for (i = 0; i < 32; i++) - bcs->hw.hfc.send[i] = 0x1fff; -} - -void -inithfc(struct IsdnCardState *cs) -{ - init_send(&cs->bcs[0]); - init_send(&cs->bcs[1]); - cs->BC_Send_Data = &hfc_fill_fifo; - cs->bcs[0].BC_SetStack = setstack_hfc; - cs->bcs[1].BC_SetStack = setstack_hfc; - cs->bcs[0].BC_Close = close_hfcstate; - cs->bcs[1].BC_Close = close_hfcstate; - mode_hfc(cs->bcs, 0, 0); - mode_hfc(cs->bcs + 1, 0, 0); -} - -void -releasehfc(struct IsdnCardState *cs) -{ - kfree(cs->bcs[0].hw.hfc.send); - cs->bcs[0].hw.hfc.send = NULL; - kfree(cs->bcs[1].hw.hfc.send); - cs->bcs[1].hw.hfc.send = NULL; -} diff --git a/drivers/isdn/hisax/hfc_2bs0.h b/drivers/isdn/hisax/hfc_2bs0.h deleted file mode 100644 index 1510096363dc..000000000000 --- a/drivers/isdn/hisax/hfc_2bs0.h +++ /dev/null @@ -1,60 +0,0 @@ -/* $Id: hfc_2bs0.h,v 1.5.2.2 2004/01/12 22:52:26 keil Exp $ - * - * specific defines for CCD's HFC 2BS0 - * - * Author Karsten Keil - * Copyright by Karsten Keil <keil@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#define HFC_CTMT 0xe0 -#define HFC_CIRM 0xc0 -#define HFC_CIP 0x80 -#define HFC_Z1 0x00 -#define HFC_Z2 0x08 -#define HFC_Z_LOW 0x00 -#define HFC_Z_HIGH 0x04 -#define HFC_F1_INC 0x28 -#define HFC_FIFO_IN 0x2c -#define HFC_F1 0x30 -#define HFC_F2 0x34 -#define HFC_F2_INC 0x38 -#define HFC_FIFO_OUT 0x3c -#define HFC_B1 0x00 -#define HFC_B2 0x02 -#define HFC_REC 0x01 -#define HFC_SEND 0x00 -#define HFC_CHANNEL(ch) (ch ? HFC_B2 : HFC_B1) - -#define HFC_STATUS 0 -#define HFC_DATA 1 -#define HFC_DATA_NODEB 2 - -/* Status (READ) */ -#define HFC_BUSY 0x01 -#define HFC_TIMINT 0x02 -#define HFC_EXTINT 0x04 - -/* CTMT (Write) */ -#define HFC_CLTIMER 0x10 -#define HFC_TIM50MS 0x08 -#define HFC_TIMIRQE 0x04 -#define HFC_TRANSB2 0x02 -#define HFC_TRANSB1 0x01 - -/* CIRM (Write) */ -#define HFC_RESET 0x08 -#define HFC_MEM8K 0x10 -#define HFC_INTA 0x01 -#define HFC_INTB 0x02 -#define HFC_INTC 0x03 -#define HFC_INTD 0x04 -#define HFC_INTE 0x05 -#define HFC_INTF 0x06 - -extern void main_irq_hfc(struct BCState *bcs); -extern void inithfc(struct IsdnCardState *cs); -extern void releasehfc(struct IsdnCardState *cs); diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c deleted file mode 100644 index 71a8312592d6..000000000000 --- a/drivers/isdn/hisax/hfc_pci.c +++ /dev/null @@ -1,1755 +0,0 @@ -/* $Id: hfc_pci.c,v 1.48.2.4 2004/02/11 13:21:33 keil Exp $ - * - * low level driver for CCD's hfc-pci based cards - * - * Author Werner Cornelius - * based on existing driver for CCD hfc ISA cards - * Copyright by Werner Cornelius <werner@isdn4linux.de> - * by Karsten Keil <keil@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * For changes and modifications please read - * Documentation/isdn/HiSax.cert - * - */ - -#include <linux/init.h> -#include "hisax.h" -#include "hfc_pci.h" -#include "isdnl1.h" -#include <linux/pci.h> -#include <linux/sched.h> -#include <linux/interrupt.h> - -static const char *hfcpci_revision = "$Revision: 1.48.2.4 $"; - -/* table entry in the PCI devices list */ -typedef struct { - int vendor_id; - int device_id; - char *vendor_name; - char *card_name; -} PCI_ENTRY; - -#define NT_T1_COUNT 20 /* number of 3.125ms interrupts for G2 timeout */ -#define CLKDEL_TE 0x0e /* CLKDEL in TE mode */ -#define CLKDEL_NT 0x6c /* CLKDEL in NT mode */ - -static const PCI_ENTRY id_list[] = -{ - {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_2BD0, "CCD/Billion/Asuscom", "2BD0"}, - {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B000, "Billion", "B000"}, - {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B006, "Billion", "B006"}, - {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B007, "Billion", "B007"}, - {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B008, "Billion", "B008"}, - {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B009, "Billion", "B009"}, - {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00A, "Billion", "B00A"}, - {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00B, "Billion", "B00B"}, - {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00C, "Billion", "B00C"}, - {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B100, "Seyeon", "B100"}, - {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B700, "Primux II S0", "B700"}, - {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B701, "Primux II S0 NT", "B701"}, - {PCI_VENDOR_ID_ABOCOM, PCI_DEVICE_ID_ABOCOM_2BD1, "Abocom/Magitek", "2BD1"}, - {PCI_VENDOR_ID_ASUSTEK, PCI_DEVICE_ID_ASUSTEK_0675, "Asuscom/Askey", "675"}, - {PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_T_CONCEPT, "German telekom", "T-Concept"}, - {PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_A1T, "German telekom", "A1T"}, - {PCI_VENDOR_ID_ANIGMA, PCI_DEVICE_ID_ANIGMA_MC145575, "Motorola MC145575", "MC145575"}, - {PCI_VENDOR_ID_ZOLTRIX, PCI_DEVICE_ID_ZOLTRIX_2BD0, "Zoltrix", "2BD0"}, - {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_E, "Digi International", "Digi DataFire Micro V IOM2 (Europe)"}, - {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_E, "Digi International", "Digi DataFire Micro V (Europe)"}, - {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_A, "Digi International", "Digi DataFire Micro V IOM2 (North America)"}, - {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_A, "Digi International", "Digi DataFire Micro V (North America)"}, - {PCI_VENDOR_ID_SITECOM, PCI_DEVICE_ID_SITECOM_DC105V2, "Sitecom Europe", "DC-105 ISDN PCI"}, - {0, 0, NULL, NULL}, -}; - - -/******************************************/ -/* free hardware resources used by driver */ -/******************************************/ -static void -release_io_hfcpci(struct IsdnCardState *cs) -{ - printk(KERN_INFO "HiSax: release hfcpci at %p\n", - cs->hw.hfcpci.pci_io); - cs->hw.hfcpci.int_m2 = 0; /* interrupt output off ! */ - Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2); - Write_hfc(cs, HFCPCI_CIRM, HFCPCI_RESET); /* Reset On */ - mdelay(10); - Write_hfc(cs, HFCPCI_CIRM, 0); /* Reset Off */ - mdelay(10); - Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2); - pci_write_config_word(cs->hw.hfcpci.dev, PCI_COMMAND, 0); /* disable memory mapped ports + busmaster */ - del_timer(&cs->hw.hfcpci.timer); - pci_free_consistent(cs->hw.hfcpci.dev, 0x8000, - cs->hw.hfcpci.fifos, cs->hw.hfcpci.dma); - cs->hw.hfcpci.fifos = NULL; - iounmap(cs->hw.hfcpci.pci_io); -} - -/********************************************************************************/ -/* function called to reset the HFC PCI chip. A complete software reset of chip */ -/* and fifos is done. */ -/********************************************************************************/ -static void -reset_hfcpci(struct IsdnCardState *cs) -{ - pci_write_config_word(cs->hw.hfcpci.dev, PCI_COMMAND, PCI_ENA_MEMIO); /* enable memory mapped ports, disable busmaster */ - cs->hw.hfcpci.int_m2 = 0; /* interrupt output off ! */ - Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2); - - printk(KERN_INFO "HFC_PCI: resetting card\n"); - pci_write_config_word(cs->hw.hfcpci.dev, PCI_COMMAND, PCI_ENA_MEMIO + PCI_ENA_MASTER); /* enable memory ports + busmaster */ - Write_hfc(cs, HFCPCI_CIRM, HFCPCI_RESET); /* Reset On */ - mdelay(10); - Write_hfc(cs, HFCPCI_CIRM, 0); /* Reset Off */ - mdelay(10); - if (Read_hfc(cs, HFCPCI_STATUS) & 2) - printk(KERN_WARNING "HFC-PCI init bit busy\n"); - - cs->hw.hfcpci.fifo_en = 0x30; /* only D fifos enabled */ - Write_hfc(cs, HFCPCI_FIFO_EN, cs->hw.hfcpci.fifo_en); - - cs->hw.hfcpci.trm = 0 + HFCPCI_BTRANS_THRESMASK; /* no echo connect , threshold */ - Write_hfc(cs, HFCPCI_TRM, cs->hw.hfcpci.trm); - - Write_hfc(cs, HFCPCI_CLKDEL, CLKDEL_TE); /* ST-Bit delay for TE-Mode */ - cs->hw.hfcpci.sctrl_e = HFCPCI_AUTO_AWAKE; - Write_hfc(cs, HFCPCI_SCTRL_E, cs->hw.hfcpci.sctrl_e); /* S/T Auto awake */ - cs->hw.hfcpci.bswapped = 0; /* no exchange */ - cs->hw.hfcpci.nt_mode = 0; /* we are in TE mode */ - cs->hw.hfcpci.ctmt = HFCPCI_TIM3_125 | HFCPCI_AUTO_TIMER; - Write_hfc(cs, HFCPCI_CTMT, cs->hw.hfcpci.ctmt); - - cs->hw.hfcpci.int_m1 = HFCPCI_INTS_DTRANS | HFCPCI_INTS_DREC | - HFCPCI_INTS_L1STATE | HFCPCI_INTS_TIMER; - Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1); - - /* Clear already pending ints */ - Read_hfc(cs, HFCPCI_INT_S1); - - Write_hfc(cs, HFCPCI_STATES, HFCPCI_LOAD_STATE | 2); /* HFC ST 2 */ - udelay(10); - Write_hfc(cs, HFCPCI_STATES, 2); /* HFC ST 2 */ - cs->hw.hfcpci.mst_m = HFCPCI_MASTER; /* HFC Master Mode */ - - Write_hfc(cs, HFCPCI_MST_MODE, cs->hw.hfcpci.mst_m); - cs->hw.hfcpci.sctrl = 0x40; /* set tx_lo mode, error in datasheet ! */ - Write_hfc(cs, HFCPCI_SCTRL, cs->hw.hfcpci.sctrl); - cs->hw.hfcpci.sctrl_r = 0; - Write_hfc(cs, HFCPCI_SCTRL_R, cs->hw.hfcpci.sctrl_r); - - /* Init GCI/IOM2 in master mode */ - /* Slots 0 and 1 are set for B-chan 1 and 2 */ - /* D- and monitor/CI channel are not enabled */ - /* STIO1 is used as output for data, B1+B2 from ST->IOM+HFC */ - /* STIO2 is used as data input, B1+B2 from IOM->ST */ - /* ST B-channel send disabled -> continuous 1s */ - /* The IOM slots are always enabled */ - cs->hw.hfcpci.conn = 0x36; /* set data flow directions */ - Write_hfc(cs, HFCPCI_CONNECT, cs->hw.hfcpci.conn); - Write_hfc(cs, HFCPCI_B1_SSL, 0x80); /* B1-Slot 0 STIO1 out enabled */ - Write_hfc(cs, HFCPCI_B2_SSL, 0x81); /* B2-Slot 1 STIO1 out enabled */ - Write_hfc(cs, HFCPCI_B1_RSL, 0x80); /* B1-Slot 0 STIO2 in enabled */ - Write_hfc(cs, HFCPCI_B2_RSL, 0x81); /* B2-Slot 1 STIO2 in enabled */ - - /* Finally enable IRQ output */ - cs->hw.hfcpci.int_m2 = HFCPCI_IRQ_ENABLE; - Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2); - Read_hfc(cs, HFCPCI_INT_S1); -} - -/***************************************************/ -/* Timer function called when kernel timer expires */ -/***************************************************/ -static void -hfcpci_Timer(struct timer_list *t) -{ - struct IsdnCardState *cs = from_timer(cs, t, hw.hfcpci.timer); - cs->hw.hfcpci.timer.expires = jiffies + 75; - /* WD RESET */ -/* WriteReg(cs, HFCD_DATA, HFCD_CTMT, cs->hw.hfcpci.ctmt | 0x80); - add_timer(&cs->hw.hfcpci.timer); -*/ -} - - -/*********************************/ -/* schedule a new D-channel task */ -/*********************************/ -static void -sched_event_D_pci(struct IsdnCardState *cs, int event) -{ - test_and_set_bit(event, &cs->event); - schedule_work(&cs->tqueue); -} - -/*********************************/ -/* schedule a new b_channel task */ -/*********************************/ -static void -hfcpci_sched_event(struct BCState *bcs, int event) -{ - test_and_set_bit(event, &bcs->event); - schedule_work(&bcs->tqueue); -} - -/************************************************/ -/* select a b-channel entry matching and active */ -/************************************************/ -static -struct BCState * -Sel_BCS(struct IsdnCardState *cs, int channel) -{ - if (cs->bcs[0].mode && (cs->bcs[0].channel == channel)) - return (&cs->bcs[0]); - else if (cs->bcs[1].mode && (cs->bcs[1].channel == channel)) - return (&cs->bcs[1]); - else - return (NULL); -} - -/***************************************/ -/* clear the desired B-channel rx fifo */ -/***************************************/ -static void hfcpci_clear_fifo_rx(struct IsdnCardState *cs, int fifo) -{ u_char fifo_state; - bzfifo_type *bzr; - - if (fifo) { - bzr = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxbz_b2; - fifo_state = cs->hw.hfcpci.fifo_en & HFCPCI_FIFOEN_B2RX; - } else { - bzr = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxbz_b1; - fifo_state = cs->hw.hfcpci.fifo_en & HFCPCI_FIFOEN_B1RX; - } - if (fifo_state) - cs->hw.hfcpci.fifo_en ^= fifo_state; - Write_hfc(cs, HFCPCI_FIFO_EN, cs->hw.hfcpci.fifo_en); - cs->hw.hfcpci.last_bfifo_cnt[fifo] = 0; - bzr->za[MAX_B_FRAMES].z1 = B_FIFO_SIZE + B_SUB_VAL - 1; - bzr->za[MAX_B_FRAMES].z2 = bzr->za[MAX_B_FRAMES].z1; - bzr->f1 = MAX_B_FRAMES; - bzr->f2 = bzr->f1; /* init F pointers to remain constant */ - if (fifo_state) - cs->hw.hfcpci.fifo_en |= fifo_state; - Write_hfc(cs, HFCPCI_FIFO_EN, cs->hw.hfcpci.fifo_en); -} - -/***************************************/ -/* clear the desired B-channel tx fifo */ -/***************************************/ -static void hfcpci_clear_fifo_tx(struct IsdnCardState *cs, int fifo) -{ u_char fifo_state; - bzfifo_type *bzt; - - if (fifo) { - bzt = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.txbz_b2; - fifo_state = cs->hw.hfcpci.fifo_en & HFCPCI_FIFOEN_B2TX; - } else { - bzt = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.txbz_b1; - fifo_state = cs->hw.hfcpci.fifo_en & HFCPCI_FIFOEN_B1TX; - } - if (fifo_state) - cs->hw.hfcpci.fifo_en ^= fifo_state; - Write_hfc(cs, HFCPCI_FIFO_EN, cs->hw.hfcpci.fifo_en); - bzt->za[MAX_B_FRAMES].z1 = B_FIFO_SIZE + B_SUB_VAL - 1; - bzt->za[MAX_B_FRAMES].z2 = bzt->za[MAX_B_FRAMES].z1; - bzt->f1 = MAX_B_FRAMES; - bzt->f2 = bzt->f1; /* init F pointers to remain constant */ - if (fifo_state) - cs->hw.hfcpci.fifo_en |= fifo_state; - Write_hfc(cs, HFCPCI_FIFO_EN, cs->hw.hfcpci.fifo_en); -} - -/*********************************************/ -/* read a complete B-frame out of the buffer */ -/*********************************************/ -static struct sk_buff -* -hfcpci_empty_fifo(struct BCState *bcs, bzfifo_type *bz, u_char *bdata, int count) -{ - u_char *ptr, *ptr1, new_f2; - struct sk_buff *skb; - struct IsdnCardState *cs = bcs->cs; - int maxlen, new_z2; - z_type *zp; - - if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) - debugl1(cs, "hfcpci_empty_fifo"); - zp = &bz->za[bz->f2]; /* point to Z-Regs */ - new_z2 = zp->z2 + count; /* new position in fifo */ - if (new_z2 >= (B_FIFO_SIZE + B_SUB_VAL)) - new_z2 -= B_FIFO_SIZE; /* buffer wrap */ - new_f2 = (bz->f2 + 1) & MAX_B_FRAMES; - if ((count > HSCX_BUFMAX + 3) || (count < 4) || - (*(bdata + (zp->z1 - B_SUB_VAL)))) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "hfcpci_empty_fifo: incoming packet invalid length %d or crc", count); -#ifdef ERROR_STATISTIC - bcs->err_inv++; -#endif - bz->za[new_f2].z2 = new_z2; - bz->f2 = new_f2; /* next buffer */ - skb = NULL; - } else if (!(skb = dev_alloc_skb(count - 3))) - printk(KERN_WARNING "HFCPCI: receive out of memory\n"); - else { - count -= 3; - ptr = skb_put(skb, count); - - if (zp->z2 + count <= B_FIFO_SIZE + B_SUB_VAL) - maxlen = count; /* complete transfer */ - else - maxlen = B_FIFO_SIZE + B_SUB_VAL - zp->z2; /* maximum */ - - ptr1 = bdata + (zp->z2 - B_SUB_VAL); /* start of data */ - memcpy(ptr, ptr1, maxlen); /* copy data */ - count -= maxlen; - - if (count) { /* rest remaining */ - ptr += maxlen; - ptr1 = bdata; /* start of buffer */ - memcpy(ptr, ptr1, count); /* rest */ - } - bz->za[new_f2].z2 = new_z2; - bz->f2 = new_f2; /* next buffer */ - - } - return (skb); -} - -/*******************************/ -/* D-channel receive procedure */ -/*******************************/ -static -int -receive_dmsg(struct IsdnCardState *cs) -{ - struct sk_buff *skb; - int maxlen; - int rcnt, total; - int count = 5; - u_char *ptr, *ptr1; - dfifo_type *df; - z_type *zp; - - df = &((fifo_area *) (cs->hw.hfcpci.fifos))->d_chan.d_rx; - if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - debugl1(cs, "rec_dmsg blocked"); - return (1); - } - while (((df->f1 & D_FREG_MASK) != (df->f2 & D_FREG_MASK)) && count--) { - zp = &df->za[df->f2 & D_FREG_MASK]; - rcnt = zp->z1 - zp->z2; - if (rcnt < 0) - rcnt += D_FIFO_SIZE; - rcnt++; - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "hfcpci recd f1(%d) f2(%d) z1(%x) z2(%x) cnt(%d)", - df->f1, df->f2, zp->z1, zp->z2, rcnt); - - if ((rcnt > MAX_DFRAME_LEN + 3) || (rcnt < 4) || - (df->data[zp->z1])) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "empty_fifo hfcpci packet inv. len %d or crc %d", rcnt, df->data[zp->z1]); -#ifdef ERROR_STATISTIC - cs->err_rx++; -#endif - df->f2 = ((df->f2 + 1) & MAX_D_FRAMES) | (MAX_D_FRAMES + 1); /* next buffer */ - df->za[df->f2 & D_FREG_MASK].z2 = (zp->z2 + rcnt) & (D_FIFO_SIZE - 1); - } else if ((skb = dev_alloc_skb(rcnt - 3))) { - total = rcnt; - rcnt -= 3; - ptr = skb_put(skb, rcnt); - - if (zp->z2 + rcnt <= D_FIFO_SIZE) - maxlen = rcnt; /* complete transfer */ - else - maxlen = D_FIFO_SIZE - zp->z2; /* maximum */ - - ptr1 = df->data + zp->z2; /* start of data */ - memcpy(ptr, ptr1, maxlen); /* copy data */ - rcnt -= maxlen; - - if (rcnt) { /* rest remaining */ - ptr += maxlen; - ptr1 = df->data; /* start of buffer */ - memcpy(ptr, ptr1, rcnt); /* rest */ - } - df->f2 = ((df->f2 + 1) & MAX_D_FRAMES) | (MAX_D_FRAMES + 1); /* next buffer */ - df->za[df->f2 & D_FREG_MASK].z2 = (zp->z2 + total) & (D_FIFO_SIZE - 1); - - skb_queue_tail(&cs->rq, skb); - sched_event_D_pci(cs, D_RCVBUFREADY); - } else - printk(KERN_WARNING "HFC-PCI: D receive out of memory\n"); - } - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - return (1); -} - -/*******************************************************************************/ -/* check for transparent receive data and read max one threshold size if avail */ -/*******************************************************************************/ -static int -hfcpci_empty_fifo_trans(struct BCState *bcs, bzfifo_type *bz, u_char *bdata) -{ - unsigned short *z1r, *z2r; - int new_z2, fcnt, maxlen; - struct sk_buff *skb; - u_char *ptr, *ptr1; - - z1r = &bz->za[MAX_B_FRAMES].z1; /* pointer to z reg */ - z2r = z1r + 1; - - if (!(fcnt = *z1r - *z2r)) - return (0); /* no data avail */ - - if (fcnt <= 0) - fcnt += B_FIFO_SIZE; /* bytes actually buffered */ - if (fcnt > HFCPCI_BTRANS_THRESHOLD) - fcnt = HFCPCI_BTRANS_THRESHOLD; /* limit size */ - - new_z2 = *z2r + fcnt; /* new position in fifo */ - if (new_z2 >= (B_FIFO_SIZE + B_SUB_VAL)) - new_z2 -= B_FIFO_SIZE; /* buffer wrap */ - - if (!(skb = dev_alloc_skb(fcnt))) - printk(KERN_WARNING "HFCPCI: receive out of memory\n"); - else { - ptr = skb_put(skb, fcnt); - if (*z2r + fcnt <= B_FIFO_SIZE + B_SUB_VAL) - maxlen = fcnt; /* complete transfer */ - else - maxlen = B_FIFO_SIZE + B_SUB_VAL - *z2r; /* maximum */ - - ptr1 = bdata + (*z2r - B_SUB_VAL); /* start of data */ - memcpy(ptr, ptr1, maxlen); /* copy data */ - fcnt -= maxlen; - - if (fcnt) { /* rest remaining */ - ptr += maxlen; - ptr1 = bdata; /* start of buffer */ - memcpy(ptr, ptr1, fcnt); /* rest */ - } - skb_queue_tail(&bcs->rqueue, skb); - hfcpci_sched_event(bcs, B_RCVBUFREADY); - } - - *z2r = new_z2; /* new position */ - return (1); -} /* hfcpci_empty_fifo_trans */ - -/**********************************/ -/* B-channel main receive routine */ -/**********************************/ -static void -main_rec_hfcpci(struct BCState *bcs) -{ - struct IsdnCardState *cs = bcs->cs; - int rcnt, real_fifo; - int receive, count = 5; - struct sk_buff *skb; - bzfifo_type *bz; - u_char *bdata; - z_type *zp; - - - if ((bcs->channel) && (!cs->hw.hfcpci.bswapped)) { - bz = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxbz_b2; - bdata = ((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxdat_b2; - real_fifo = 1; - } else { - bz = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxbz_b1; - bdata = ((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxdat_b1; - real_fifo = 0; - } -Begin: - count--; - if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - debugl1(cs, "rec_data %d blocked", bcs->channel); - return; - } - if (bz->f1 != bz->f2) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "hfcpci rec %d f1(%d) f2(%d)", - bcs->channel, bz->f1, bz->f2); - zp = &bz->za[bz->f2]; - - rcnt = zp->z1 - zp->z2; - if (rcnt < 0) - rcnt += B_FIFO_SIZE; - rcnt++; - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "hfcpci rec %d z1(%x) z2(%x) cnt(%d)", - bcs->channel, zp->z1, zp->z2, rcnt); - if ((skb = hfcpci_empty_fifo(bcs, bz, bdata, rcnt))) { - skb_queue_tail(&bcs->rqueue, skb); - hfcpci_sched_event(bcs, B_RCVBUFREADY); - } - rcnt = bz->f1 - bz->f2; - if (rcnt < 0) - rcnt += MAX_B_FRAMES + 1; - if (cs->hw.hfcpci.last_bfifo_cnt[real_fifo] > rcnt + 1) { - rcnt = 0; - hfcpci_clear_fifo_rx(cs, real_fifo); - } - cs->hw.hfcpci.last_bfifo_cnt[real_fifo] = rcnt; - if (rcnt > 1) - receive = 1; - else - receive = 0; - } else if (bcs->mode == L1_MODE_TRANS) - receive = hfcpci_empty_fifo_trans(bcs, bz, bdata); - else - receive = 0; - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - if (count && receive) - goto Begin; -} - -/**************************/ -/* D-channel send routine */ -/**************************/ -static void -hfcpci_fill_dfifo(struct IsdnCardState *cs) -{ - int fcnt; - int count, new_z1, maxlen; - dfifo_type *df; - u_char *src, *dst, new_f1; - - if (!cs->tx_skb) - return; - if (cs->tx_skb->len <= 0) - return; - - df = &((fifo_area *) (cs->hw.hfcpci.fifos))->d_chan.d_tx; - - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "hfcpci_fill_Dfifo f1(%d) f2(%d) z1(f1)(%x)", - df->f1, df->f2, - df->za[df->f1 & D_FREG_MASK].z1); - fcnt = df->f1 - df->f2; /* frame count actually buffered */ - if (fcnt < 0) - fcnt += (MAX_D_FRAMES + 1); /* if wrap around */ - if (fcnt > (MAX_D_FRAMES - 1)) { - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "hfcpci_fill_Dfifo more as 14 frames"); -#ifdef ERROR_STATISTIC - cs->err_tx++; -#endif - return; - } - /* now determine free bytes in FIFO buffer */ - count = df->za[df->f2 & D_FREG_MASK].z2 - df->za[df->f1 & D_FREG_MASK].z1 - 1; - if (count <= 0) - count += D_FIFO_SIZE; /* count now contains available bytes */ - - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "hfcpci_fill_Dfifo count(%u/%d)", - cs->tx_skb->len, count); - if (count < cs->tx_skb->len) { - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "hfcpci_fill_Dfifo no fifo mem"); - return; - } - count = cs->tx_skb->len; /* get frame len */ - new_z1 = (df->za[df->f1 & D_FREG_MASK].z1 + count) & (D_FIFO_SIZE - 1); - new_f1 = ((df->f1 + 1) & D_FREG_MASK) | (D_FREG_MASK + 1); - src = cs->tx_skb->data; /* source pointer */ - dst = df->data + df->za[df->f1 & D_FREG_MASK].z1; - maxlen = D_FIFO_SIZE - df->za[df->f1 & D_FREG_MASK].z1; /* end fifo */ - if (maxlen > count) - maxlen = count; /* limit size */ - memcpy(dst, src, maxlen); /* first copy */ - - count -= maxlen; /* remaining bytes */ - if (count) { - dst = df->data; /* start of buffer */ - src += maxlen; /* new position */ - memcpy(dst, src, count); - } - df->za[new_f1 & D_FREG_MASK].z1 = new_z1; /* for next buffer */ - df->za[df->f1 & D_FREG_MASK].z1 = new_z1; /* new pos actual buffer */ - df->f1 = new_f1; /* next frame */ - - dev_kfree_skb_any(cs->tx_skb); - cs->tx_skb = NULL; -} - -/**************************/ -/* B-channel send routine */ -/**************************/ -static void -hfcpci_fill_fifo(struct BCState *bcs) -{ - struct IsdnCardState *cs = bcs->cs; - int maxlen, fcnt; - int count, new_z1; - bzfifo_type *bz; - u_char *bdata; - u_char new_f1, *src, *dst; - unsigned short *z1t, *z2t; - - if (!bcs->tx_skb) - return; - if (bcs->tx_skb->len <= 0) - return; - - if ((bcs->channel) && (!cs->hw.hfcpci.bswapped)) { - bz = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.txbz_b2; - bdata = ((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.txdat_b2; - } else { - bz = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.txbz_b1; - bdata = ((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.txdat_b1; - } - - if (bcs->mode == L1_MODE_TRANS) { - z1t = &bz->za[MAX_B_FRAMES].z1; - z2t = z1t + 1; - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "hfcpci_fill_fifo_trans %d z1(%x) z2(%x)", - bcs->channel, *z1t, *z2t); - fcnt = *z2t - *z1t; - if (fcnt <= 0) - fcnt += B_FIFO_SIZE; /* fcnt contains available bytes in fifo */ - fcnt = B_FIFO_SIZE - fcnt; /* remaining bytes to send */ - - while ((fcnt < 2 * HFCPCI_BTRANS_THRESHOLD) && (bcs->tx_skb)) { - if (bcs->tx_skb->len < B_FIFO_SIZE - fcnt) { - /* data is suitable for fifo */ - count = bcs->tx_skb->len; - - new_z1 = *z1t + count; /* new buffer Position */ - if (new_z1 >= (B_FIFO_SIZE + B_SUB_VAL)) - new_z1 -= B_FIFO_SIZE; /* buffer wrap */ - src = bcs->tx_skb->data; /* source pointer */ - dst = bdata + (*z1t - B_SUB_VAL); - maxlen = (B_FIFO_SIZE + B_SUB_VAL) - *z1t; /* end of fifo */ - if (maxlen > count) - maxlen = count; /* limit size */ - memcpy(dst, src, maxlen); /* first copy */ - - count -= maxlen; /* remaining bytes */ - if (count) { - dst = bdata; /* start of buffer */ - src += maxlen; /* new position */ - memcpy(dst, src, count); - } - bcs->tx_cnt -= bcs->tx_skb->len; - fcnt += bcs->tx_skb->len; - *z1t = new_z1; /* now send data */ - } else if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "hfcpci_fill_fifo_trans %d frame length %d discarded", - bcs->channel, bcs->tx_skb->len); - - if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) && - (PACKET_NOACK != bcs->tx_skb->pkt_type)) { - u_long flags; - spin_lock_irqsave(&bcs->aclock, flags); - bcs->ackcnt += bcs->tx_skb->len; - spin_unlock_irqrestore(&bcs->aclock, flags); - schedule_event(bcs, B_ACKPENDING); - } - - dev_consume_skb_any(bcs->tx_skb); - bcs->tx_skb = skb_dequeue(&bcs->squeue); /* fetch next data */ - } - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - return; - } - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "hfcpci_fill_fifo_hdlc %d f1(%d) f2(%d) z1(f1)(%x)", - bcs->channel, bz->f1, bz->f2, - bz->za[bz->f1].z1); - - fcnt = bz->f1 - bz->f2; /* frame count actually buffered */ - if (fcnt < 0) - fcnt += (MAX_B_FRAMES + 1); /* if wrap around */ - if (fcnt > (MAX_B_FRAMES - 1)) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "hfcpci_fill_Bfifo more as 14 frames"); - return; - } - /* now determine free bytes in FIFO buffer */ - count = bz->za[bz->f2].z2 - bz->za[bz->f1].z1 - 1; - if (count <= 0) - count += B_FIFO_SIZE; /* count now contains available bytes */ - - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "hfcpci_fill_fifo %d count(%u/%d),%lx", - bcs->channel, bcs->tx_skb->len, - count, current->state); - - if (count < bcs->tx_skb->len) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "hfcpci_fill_fifo no fifo mem"); - return; - } - count = bcs->tx_skb->len; /* get frame len */ - new_z1 = bz->za[bz->f1].z1 + count; /* new buffer Position */ - if (new_z1 >= (B_FIFO_SIZE + B_SUB_VAL)) - new_z1 -= B_FIFO_SIZE; /* buffer wrap */ - - new_f1 = ((bz->f1 + 1) & MAX_B_FRAMES); - src = bcs->tx_skb->data; /* source pointer */ - dst = bdata + (bz->za[bz->f1].z1 - B_SUB_VAL); - maxlen = (B_FIFO_SIZE + B_SUB_VAL) - bz->za[bz->f1].z1; /* end fifo */ - if (maxlen > count) - maxlen = count; /* limit size */ - memcpy(dst, src, maxlen); /* first copy */ - - count -= maxlen; /* remaining bytes */ - if (count) { - dst = bdata; /* start of buffer */ - src += maxlen; /* new position */ - memcpy(dst, src, count); - } - bcs->tx_cnt -= bcs->tx_skb->len; - if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) && - (PACKET_NOACK != bcs->tx_skb->pkt_type)) { - u_long flags; - spin_lock_irqsave(&bcs->aclock, flags); - bcs->ackcnt += bcs->tx_skb->len; - spin_unlock_irqrestore(&bcs->aclock, flags); - schedule_event(bcs, B_ACKPENDING); - } - - bz->za[new_f1].z1 = new_z1; /* for next buffer */ - bz->f1 = new_f1; /* next frame */ - - dev_kfree_skb_any(bcs->tx_skb); - bcs->tx_skb = NULL; - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); -} - -/**********************************************/ -/* D-channel l1 state call for leased NT-mode */ -/**********************************************/ -static void -dch_nt_l2l1(struct PStack *st, int pr, void *arg) -{ - struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware; - - switch (pr) { - case (PH_DATA | REQUEST): - case (PH_PULL | REQUEST): - case (PH_PULL | INDICATION): - st->l1.l1hw(st, pr, arg); - break; - case (PH_ACTIVATE | REQUEST): - st->l1.l1l2(st, PH_ACTIVATE | CONFIRM, NULL); - break; - case (PH_TESTLOOP | REQUEST): - if (1 & (long) arg) - debugl1(cs, "PH_TEST_LOOP B1"); - if (2 & (long) arg) - debugl1(cs, "PH_TEST_LOOP B2"); - if (!(3 & (long) arg)) - debugl1(cs, "PH_TEST_LOOP DISABLED"); - st->l1.l1hw(st, HW_TESTLOOP | REQUEST, arg); - break; - default: - if (cs->debug) - debugl1(cs, "dch_nt_l2l1 msg %04X unhandled", pr); - break; - } -} - - - -/***********************/ -/* set/reset echo mode */ -/***********************/ -static int -hfcpci_auxcmd(struct IsdnCardState *cs, isdn_ctrl *ic) -{ - u_long flags; - int i = *(unsigned int *) ic->parm.num; - - if ((ic->arg == 98) && - (!(cs->hw.hfcpci.int_m1 & (HFCPCI_INTS_B2TRANS + HFCPCI_INTS_B2REC + HFCPCI_INTS_B1TRANS + HFCPCI_INTS_B1REC)))) { - spin_lock_irqsave(&cs->lock, flags); - Write_hfc(cs, HFCPCI_CLKDEL, CLKDEL_NT); /* ST-Bit delay for NT-Mode */ - Write_hfc(cs, HFCPCI_STATES, HFCPCI_LOAD_STATE | 0); /* HFC ST G0 */ - udelay(10); - cs->hw.hfcpci.sctrl |= SCTRL_MODE_NT; - Write_hfc(cs, HFCPCI_SCTRL, cs->hw.hfcpci.sctrl); /* set NT-mode */ - udelay(10); - Write_hfc(cs, HFCPCI_STATES, HFCPCI_LOAD_STATE | 1); /* HFC ST G1 */ - udelay(10); - Write_hfc(cs, HFCPCI_STATES, 1 | HFCPCI_ACTIVATE | HFCPCI_DO_ACTION); - cs->dc.hfcpci.ph_state = 1; - cs->hw.hfcpci.nt_mode = 1; - cs->hw.hfcpci.nt_timer = 0; - cs->stlist->l2.l2l1 = dch_nt_l2l1; - spin_unlock_irqrestore(&cs->lock, flags); - debugl1(cs, "NT mode activated"); - return (0); - } - if ((cs->chanlimit > 1) || (cs->hw.hfcpci.bswapped) || - (cs->hw.hfcpci.nt_mode) || (ic->arg != 12)) - return (-EINVAL); - - spin_lock_irqsave(&cs->lock, flags); - if (i) { - cs->logecho = 1; - cs->hw.hfcpci.trm |= 0x20; /* enable echo chan */ - cs->hw.hfcpci.int_m1 |= HFCPCI_INTS_B2REC; - cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B2RX; - } else { - cs->logecho = 0; - cs->hw.hfcpci.trm &= ~0x20; /* disable echo chan */ - cs->hw.hfcpci.int_m1 &= ~HFCPCI_INTS_B2REC; - cs->hw.hfcpci.fifo_en &= ~HFCPCI_FIFOEN_B2RX; - } - cs->hw.hfcpci.sctrl_r &= ~SCTRL_B2_ENA; - cs->hw.hfcpci.sctrl &= ~SCTRL_B2_ENA; - cs->hw.hfcpci.conn |= 0x10; /* B2-IOM -> B2-ST */ - cs->hw.hfcpci.ctmt &= ~2; - Write_hfc(cs, HFCPCI_CTMT, cs->hw.hfcpci.ctmt); - Write_hfc(cs, HFCPCI_SCTRL_R, cs->hw.hfcpci.sctrl_r); - Write_hfc(cs, HFCPCI_SCTRL, cs->hw.hfcpci.sctrl); - Write_hfc(cs, HFCPCI_CONNECT, cs->hw.hfcpci.conn); - Write_hfc(cs, HFCPCI_TRM, cs->hw.hfcpci.trm); - Write_hfc(cs, HFCPCI_FIFO_EN, cs->hw.hfcpci.fifo_en); - Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); -} /* hfcpci_auxcmd */ - -/*****************************/ -/* E-channel receive routine */ -/*****************************/ -static void -receive_emsg(struct IsdnCardState *cs) -{ - int rcnt; - int receive, count = 5; - bzfifo_type *bz; - u_char *bdata; - z_type *zp; - u_char *ptr, *ptr1, new_f2; - int total, maxlen, new_z2; - u_char e_buffer[256]; - - bz = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxbz_b2; - bdata = ((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxdat_b2; -Begin: - count--; - if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - debugl1(cs, "echo_rec_data blocked"); - return; - } - if (bz->f1 != bz->f2) { - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "hfcpci e_rec f1(%d) f2(%d)", - bz->f1, bz->f2); - zp = &bz->za[bz->f2]; - - rcnt = zp->z1 - zp->z2; - if (rcnt < 0) - rcnt += B_FIFO_SIZE; - rcnt++; - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "hfcpci e_rec z1(%x) z2(%x) cnt(%d)", - zp->z1, zp->z2, rcnt); - new_z2 = zp->z2 + rcnt; /* new position in fifo */ - if (new_z2 >= (B_FIFO_SIZE + B_SUB_VAL)) - new_z2 -= B_FIFO_SIZE; /* buffer wrap */ - new_f2 = (bz->f2 + 1) & MAX_B_FRAMES; - if ((rcnt > 256 + 3) || (count < 4) || - (*(bdata + (zp->z1 - B_SUB_VAL)))) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "hfcpci_empty_echan: incoming packet invalid length %d or crc", rcnt); - bz->za[new_f2].z2 = new_z2; - bz->f2 = new_f2; /* next buffer */ - } else { - total = rcnt; - rcnt -= 3; - ptr = e_buffer; - - if (zp->z2 <= B_FIFO_SIZE + B_SUB_VAL) - maxlen = rcnt; /* complete transfer */ - else - maxlen = B_FIFO_SIZE + B_SUB_VAL - zp->z2; /* maximum */ - - ptr1 = bdata + (zp->z2 - B_SUB_VAL); /* start of data */ - memcpy(ptr, ptr1, maxlen); /* copy data */ - rcnt -= maxlen; - - if (rcnt) { /* rest remaining */ - ptr += maxlen; - ptr1 = bdata; /* start of buffer */ - memcpy(ptr, ptr1, rcnt); /* rest */ - } - bz->za[new_f2].z2 = new_z2; - bz->f2 = new_f2; /* next buffer */ - if (cs->debug & DEB_DLOG_HEX) { - ptr = cs->dlog; - if ((total - 3) < MAX_DLOG_SPACE / 3 - 10) { - *ptr++ = 'E'; - *ptr++ = 'C'; - *ptr++ = 'H'; - *ptr++ = 'O'; - *ptr++ = ':'; - ptr += QuickHex(ptr, e_buffer, total - 3); - ptr--; - *ptr++ = '\n'; - *ptr = 0; - HiSax_putstatus(cs, NULL, cs->dlog); - } else - HiSax_putstatus(cs, "LogEcho: ", "warning Frame too big (%d)", total - 3); - } - } - - rcnt = bz->f1 - bz->f2; - if (rcnt < 0) - rcnt += MAX_B_FRAMES + 1; - if (rcnt > 1) - receive = 1; - else - receive = 0; - } else - receive = 0; - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - if (count && receive) - goto Begin; -} /* receive_emsg */ - -/*********************/ -/* Interrupt handler */ -/*********************/ -static irqreturn_t -hfcpci_interrupt(int intno, void *dev_id) -{ - u_long flags; - struct IsdnCardState *cs = dev_id; - u_char exval; - struct BCState *bcs; - int count = 15; - u_char val, stat; - - if (!(cs->hw.hfcpci.int_m2 & 0x08)) { - debugl1(cs, "HFC-PCI: int_m2 %x not initialised", cs->hw.hfcpci.int_m2); - return IRQ_NONE; /* not initialised */ - } - spin_lock_irqsave(&cs->lock, flags); - if (HFCPCI_ANYINT & (stat = Read_hfc(cs, HFCPCI_STATUS))) { - val = Read_hfc(cs, HFCPCI_INT_S1); - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "HFC-PCI: stat(%02x) s1(%02x)", stat, val); - } else { - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_NONE; - } - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "HFC-PCI irq %x %s", val, - test_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags) ? - "locked" : "unlocked"); - val &= cs->hw.hfcpci.int_m1; - if (val & 0x40) { /* state machine irq */ - exval = Read_hfc(cs, HFCPCI_STATES) & 0xf; - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "ph_state chg %d->%d", cs->dc.hfcpci.ph_state, - exval); - cs->dc.hfcpci.ph_state = exval; - sched_event_D_pci(cs, D_L1STATECHANGE); - val &= ~0x40; - } - if (val & 0x80) { /* timer irq */ - if (cs->hw.hfcpci.nt_mode) { - if ((--cs->hw.hfcpci.nt_timer) < 0) - sched_event_D_pci(cs, D_L1STATECHANGE); - } - val &= ~0x80; - Write_hfc(cs, HFCPCI_CTMT, cs->hw.hfcpci.ctmt | HFCPCI_CLTIMER); - } - while (val) { - if (test_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - cs->hw.hfcpci.int_s1 |= val; - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; - } - if (cs->hw.hfcpci.int_s1 & 0x18) { - exval = val; - val = cs->hw.hfcpci.int_s1; - cs->hw.hfcpci.int_s1 = exval; - } - if (val & 0x08) { - if (!(bcs = Sel_BCS(cs, cs->hw.hfcpci.bswapped ? 1 : 0))) { - if (cs->debug) - debugl1(cs, "hfcpci spurious 0x08 IRQ"); - } else - main_rec_hfcpci(bcs); - } - if (val & 0x10) { - if (cs->logecho) - receive_emsg(cs); - else if (!(bcs = Sel_BCS(cs, 1))) { - if (cs->debug) - debugl1(cs, "hfcpci spurious 0x10 IRQ"); - } else - main_rec_hfcpci(bcs); - } - if (val & 0x01) { - if (!(bcs = Sel_BCS(cs, cs->hw.hfcpci.bswapped ? 1 : 0))) { - if (cs->debug) - debugl1(cs, "hfcpci spurious 0x01 IRQ"); - } else { - if (bcs->tx_skb) { - if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - hfcpci_fill_fifo(bcs); - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - } else - debugl1(cs, "fill_data %d blocked", bcs->channel); - } else { - if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) { - if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - hfcpci_fill_fifo(bcs); - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - } else - debugl1(cs, "fill_data %d blocked", bcs->channel); - } else { - hfcpci_sched_event(bcs, B_XMTBUFREADY); - } - } - } - } - if (val & 0x02) { - if (!(bcs = Sel_BCS(cs, 1))) { - if (cs->debug) - debugl1(cs, "hfcpci spurious 0x02 IRQ"); - } else { - if (bcs->tx_skb) { - if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - hfcpci_fill_fifo(bcs); - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - } else - debugl1(cs, "fill_data %d blocked", bcs->channel); - } else { - if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) { - if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - hfcpci_fill_fifo(bcs); - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - } else - debugl1(cs, "fill_data %d blocked", bcs->channel); - } else { - hfcpci_sched_event(bcs, B_XMTBUFREADY); - } - } - } - } - if (val & 0x20) { /* receive dframe */ - receive_dmsg(cs); - } - if (val & 0x04) { /* dframe transmitted */ - if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) - del_timer(&cs->dbusytimer); - if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags)) - sched_event_D_pci(cs, D_CLEARBUSY); - if (cs->tx_skb) { - if (cs->tx_skb->len) { - if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - hfcpci_fill_dfifo(cs); - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - } else { - debugl1(cs, "hfcpci_fill_dfifo irq blocked"); - } - goto afterXPR; - } else { - dev_kfree_skb_irq(cs->tx_skb); - cs->tx_cnt = 0; - cs->tx_skb = NULL; - } - } - if ((cs->tx_skb = skb_dequeue(&cs->sq))) { - cs->tx_cnt = 0; - if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - hfcpci_fill_dfifo(cs); - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - } else { - debugl1(cs, "hfcpci_fill_dfifo irq blocked"); - } - } else - sched_event_D_pci(cs, D_XMTBUFREADY); - } - afterXPR: - if (cs->hw.hfcpci.int_s1 && count--) { - val = cs->hw.hfcpci.int_s1; - cs->hw.hfcpci.int_s1 = 0; - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "HFC-PCI irq %x loop %d", val, 15 - count); - } else - val = 0; - } - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -/********************************************************************/ -/* timer callback for D-chan busy resolution. Currently no function */ -/********************************************************************/ -static void -hfcpci_dbusy_timer(struct timer_list *t) -{ -} - -/*************************************/ -/* Layer 1 D-channel hardware access */ -/*************************************/ -static void -HFCPCI_l1hw(struct PStack *st, int pr, void *arg) -{ - u_long flags; - struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware; - struct sk_buff *skb = arg; - - switch (pr) { - case (PH_DATA | REQUEST): - if (cs->debug & DEB_DLOG_HEX) - LogFrame(cs, skb->data, skb->len); - if (cs->debug & DEB_DLOG_VERBOSE) - dlogframe(cs, skb, 0); - spin_lock_irqsave(&cs->lock, flags); - if (cs->tx_skb) { - skb_queue_tail(&cs->sq, skb); -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - Logl2Frame(cs, skb, "PH_DATA Queued", 0); -#endif - } else { - cs->tx_skb = skb; - cs->tx_cnt = 0; -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - Logl2Frame(cs, skb, "PH_DATA", 0); -#endif - if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - hfcpci_fill_dfifo(cs); - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - } else - debugl1(cs, "hfcpci_fill_dfifo blocked"); - - } - spin_unlock_irqrestore(&cs->lock, flags); - break; - case (PH_PULL | INDICATION): - spin_lock_irqsave(&cs->lock, flags); - if (cs->tx_skb) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, " l2l1 tx_skb exist this shouldn't happen"); - skb_queue_tail(&cs->sq, skb); - spin_unlock_irqrestore(&cs->lock, flags); - break; - } - if (cs->debug & DEB_DLOG_HEX) - LogFrame(cs, skb->data, skb->len); - if (cs->debug & DEB_DLOG_VERBOSE) - dlogframe(cs, skb, 0); - cs->tx_skb = skb; - cs->tx_cnt = 0; -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - Logl2Frame(cs, skb, "PH_DATA_PULLED", 0); -#endif - if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - hfcpci_fill_dfifo(cs); - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - } else - debugl1(cs, "hfcpci_fill_dfifo blocked"); - spin_unlock_irqrestore(&cs->lock, flags); - break; - case (PH_PULL | REQUEST): -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - debugl1(cs, "-> PH_REQUEST_PULL"); -#endif - spin_lock_irqsave(&cs->lock, flags); - if (!cs->tx_skb) { - test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); - } else - test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - spin_unlock_irqrestore(&cs->lock, flags); - break; - case (HW_RESET | REQUEST): - spin_lock_irqsave(&cs->lock, flags); - Write_hfc(cs, HFCPCI_STATES, HFCPCI_LOAD_STATE | 3); /* HFC ST 3 */ - udelay(6); - Write_hfc(cs, HFCPCI_STATES, 3); /* HFC ST 2 */ - cs->hw.hfcpci.mst_m |= HFCPCI_MASTER; - Write_hfc(cs, HFCPCI_MST_MODE, cs->hw.hfcpci.mst_m); - Write_hfc(cs, HFCPCI_STATES, HFCPCI_ACTIVATE | HFCPCI_DO_ACTION); - spin_unlock_irqrestore(&cs->lock, flags); - l1_msg(cs, HW_POWERUP | CONFIRM, NULL); - break; - case (HW_ENABLE | REQUEST): - spin_lock_irqsave(&cs->lock, flags); - Write_hfc(cs, HFCPCI_STATES, HFCPCI_DO_ACTION); - spin_unlock_irqrestore(&cs->lock, flags); - break; - case (HW_DEACTIVATE | REQUEST): - spin_lock_irqsave(&cs->lock, flags); - cs->hw.hfcpci.mst_m &= ~HFCPCI_MASTER; - Write_hfc(cs, HFCPCI_MST_MODE, cs->hw.hfcpci.mst_m); - spin_unlock_irqrestore(&cs->lock, flags); - break; - case (HW_INFO3 | REQUEST): - spin_lock_irqsave(&cs->lock, flags); - cs->hw.hfcpci.mst_m |= HFCPCI_MASTER; - Write_hfc(cs, HFCPCI_MST_MODE, cs->hw.hfcpci.mst_m); - spin_unlock_irqrestore(&cs->lock, flags); - break; - case (HW_TESTLOOP | REQUEST): - spin_lock_irqsave(&cs->lock, flags); - switch ((long) arg) { - case (1): - Write_hfc(cs, HFCPCI_B1_SSL, 0x80); /* tx slot */ - Write_hfc(cs, HFCPCI_B1_RSL, 0x80); /* rx slot */ - cs->hw.hfcpci.conn = (cs->hw.hfcpci.conn & ~7) | 1; - Write_hfc(cs, HFCPCI_CONNECT, cs->hw.hfcpci.conn); - break; - - case (2): - Write_hfc(cs, HFCPCI_B2_SSL, 0x81); /* tx slot */ - Write_hfc(cs, HFCPCI_B2_RSL, 0x81); /* rx slot */ - cs->hw.hfcpci.conn = (cs->hw.hfcpci.conn & ~0x38) | 0x08; - Write_hfc(cs, HFCPCI_CONNECT, cs->hw.hfcpci.conn); - break; - - default: - spin_unlock_irqrestore(&cs->lock, flags); - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "hfcpci_l1hw loop invalid %4lx", (long) arg); - return; - } - cs->hw.hfcpci.trm |= 0x80; /* enable IOM-loop */ - Write_hfc(cs, HFCPCI_TRM, cs->hw.hfcpci.trm); - spin_unlock_irqrestore(&cs->lock, flags); - break; - default: - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "hfcpci_l1hw unknown pr %4x", pr); - break; - } -} - -/***********************************************/ -/* called during init setting l1 stack pointer */ -/***********************************************/ -static void -setstack_hfcpci(struct PStack *st, struct IsdnCardState *cs) -{ - st->l1.l1hw = HFCPCI_l1hw; -} - -/**************************************/ -/* send B-channel data if not blocked */ -/**************************************/ -static void -hfcpci_send_data(struct BCState *bcs) -{ - struct IsdnCardState *cs = bcs->cs; - - if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - hfcpci_fill_fifo(bcs); - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - } else - debugl1(cs, "send_data %d blocked", bcs->channel); -} - -/***************************************************************/ -/* activate/deactivate hardware for selected channels and mode */ -/***************************************************************/ -static void -mode_hfcpci(struct BCState *bcs, int mode, int bc) -{ - struct IsdnCardState *cs = bcs->cs; - int fifo2; - - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "HFCPCI bchannel mode %d bchan %d/%d", - mode, bc, bcs->channel); - bcs->mode = mode; - bcs->channel = bc; - fifo2 = bc; - if (cs->chanlimit > 1) { - cs->hw.hfcpci.bswapped = 0; /* B1 and B2 normal mode */ - cs->hw.hfcpci.sctrl_e &= ~0x80; - } else { - if (bc) { - if (mode != L1_MODE_NULL) { - cs->hw.hfcpci.bswapped = 1; /* B1 and B2 exchanged */ - cs->hw.hfcpci.sctrl_e |= 0x80; - } else { - cs->hw.hfcpci.bswapped = 0; /* B1 and B2 normal mode */ - cs->hw.hfcpci.sctrl_e &= ~0x80; - } - fifo2 = 0; - } else { - cs->hw.hfcpci.bswapped = 0; /* B1 and B2 normal mode */ - cs->hw.hfcpci.sctrl_e &= ~0x80; - } - } - switch (mode) { - case (L1_MODE_NULL): - if (bc) { - cs->hw.hfcpci.sctrl &= ~SCTRL_B2_ENA; - cs->hw.hfcpci.sctrl_r &= ~SCTRL_B2_ENA; - } else { - cs->hw.hfcpci.sctrl &= ~SCTRL_B1_ENA; - cs->hw.hfcpci.sctrl_r &= ~SCTRL_B1_ENA; - } - if (fifo2) { - cs->hw.hfcpci.fifo_en &= ~HFCPCI_FIFOEN_B2; - cs->hw.hfcpci.int_m1 &= ~(HFCPCI_INTS_B2TRANS + HFCPCI_INTS_B2REC); - } else { - cs->hw.hfcpci.fifo_en &= ~HFCPCI_FIFOEN_B1; - cs->hw.hfcpci.int_m1 &= ~(HFCPCI_INTS_B1TRANS + HFCPCI_INTS_B1REC); - } - break; - case (L1_MODE_TRANS): - hfcpci_clear_fifo_rx(cs, fifo2); - hfcpci_clear_fifo_tx(cs, fifo2); - if (bc) { - cs->hw.hfcpci.sctrl |= SCTRL_B2_ENA; - cs->hw.hfcpci.sctrl_r |= SCTRL_B2_ENA; - } else { - cs->hw.hfcpci.sctrl |= SCTRL_B1_ENA; - cs->hw.hfcpci.sctrl_r |= SCTRL_B1_ENA; - } - if (fifo2) { - cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B2; - cs->hw.hfcpci.int_m1 |= (HFCPCI_INTS_B2TRANS + HFCPCI_INTS_B2REC); - cs->hw.hfcpci.ctmt |= 2; - cs->hw.hfcpci.conn &= ~0x18; - } else { - cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B1; - cs->hw.hfcpci.int_m1 |= (HFCPCI_INTS_B1TRANS + HFCPCI_INTS_B1REC); - cs->hw.hfcpci.ctmt |= 1; - cs->hw.hfcpci.conn &= ~0x03; - } - break; - case (L1_MODE_HDLC): - hfcpci_clear_fifo_rx(cs, fifo2); - hfcpci_clear_fifo_tx(cs, fifo2); - if (bc) { - cs->hw.hfcpci.sctrl |= SCTRL_B2_ENA; - cs->hw.hfcpci.sctrl_r |= SCTRL_B2_ENA; - } else { - cs->hw.hfcpci.sctrl |= SCTRL_B1_ENA; - cs->hw.hfcpci.sctrl_r |= SCTRL_B1_ENA; - } - if (fifo2) { - cs->hw.hfcpci.last_bfifo_cnt[1] = 0; - cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B2; - cs->hw.hfcpci.int_m1 |= (HFCPCI_INTS_B2TRANS + HFCPCI_INTS_B2REC); - cs->hw.hfcpci.ctmt &= ~2; - cs->hw.hfcpci.conn &= ~0x18; - } else { - cs->hw.hfcpci.last_bfifo_cnt[0] = 0; - cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B1; - cs->hw.hfcpci.int_m1 |= (HFCPCI_INTS_B1TRANS + HFCPCI_INTS_B1REC); - cs->hw.hfcpci.ctmt &= ~1; - cs->hw.hfcpci.conn &= ~0x03; - } - break; - case (L1_MODE_EXTRN): - if (bc) { - cs->hw.hfcpci.conn |= 0x10; - cs->hw.hfcpci.sctrl |= SCTRL_B2_ENA; - cs->hw.hfcpci.sctrl_r |= SCTRL_B2_ENA; - cs->hw.hfcpci.fifo_en &= ~HFCPCI_FIFOEN_B2; - cs->hw.hfcpci.int_m1 &= ~(HFCPCI_INTS_B2TRANS + HFCPCI_INTS_B2REC); - } else { - cs->hw.hfcpci.conn |= 0x02; - cs->hw.hfcpci.sctrl |= SCTRL_B1_ENA; - cs->hw.hfcpci.sctrl_r |= SCTRL_B1_ENA; - cs->hw.hfcpci.fifo_en &= ~HFCPCI_FIFOEN_B1; - cs->hw.hfcpci.int_m1 &= ~(HFCPCI_INTS_B1TRANS + HFCPCI_INTS_B1REC); - } - break; - } - Write_hfc(cs, HFCPCI_SCTRL_E, cs->hw.hfcpci.sctrl_e); - Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1); - Write_hfc(cs, HFCPCI_FIFO_EN, cs->hw.hfcpci.fifo_en); - Write_hfc(cs, HFCPCI_SCTRL, cs->hw.hfcpci.sctrl); - Write_hfc(cs, HFCPCI_SCTRL_R, cs->hw.hfcpci.sctrl_r); - Write_hfc(cs, HFCPCI_CTMT, cs->hw.hfcpci.ctmt); - Write_hfc(cs, HFCPCI_CONNECT, cs->hw.hfcpci.conn); -} - -/******************************/ -/* Layer2 -> Layer 1 Transfer */ -/******************************/ -static void -hfcpci_l2l1(struct PStack *st, int pr, void *arg) -{ - struct BCState *bcs = st->l1.bcs; - u_long flags; - struct sk_buff *skb = arg; - - switch (pr) { - case (PH_DATA | REQUEST): - spin_lock_irqsave(&bcs->cs->lock, flags); - if (bcs->tx_skb) { - skb_queue_tail(&bcs->squeue, skb); - } else { - bcs->tx_skb = skb; -// test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); - bcs->cs->BC_Send_Data(bcs); - } - spin_unlock_irqrestore(&bcs->cs->lock, flags); - break; - case (PH_PULL | INDICATION): - spin_lock_irqsave(&bcs->cs->lock, flags); - if (bcs->tx_skb) { - spin_unlock_irqrestore(&bcs->cs->lock, flags); - printk(KERN_WARNING "hfc_l2l1: this shouldn't happen\n"); - break; - } -// test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); - bcs->tx_skb = skb; - bcs->cs->BC_Send_Data(bcs); - spin_unlock_irqrestore(&bcs->cs->lock, flags); - break; - case (PH_PULL | REQUEST): - if (!bcs->tx_skb) { - test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); - } else - test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - break; - case (PH_ACTIVATE | REQUEST): - spin_lock_irqsave(&bcs->cs->lock, flags); - test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag); - mode_hfcpci(bcs, st->l1.mode, st->l1.bc); - spin_unlock_irqrestore(&bcs->cs->lock, flags); - l1_msg_b(st, pr, arg); - break; - case (PH_DEACTIVATE | REQUEST): - l1_msg_b(st, pr, arg); - break; - case (PH_DEACTIVATE | CONFIRM): - spin_lock_irqsave(&bcs->cs->lock, flags); - test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag); - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - mode_hfcpci(bcs, 0, st->l1.bc); - spin_unlock_irqrestore(&bcs->cs->lock, flags); - st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL); - break; - } -} - -/******************************************/ -/* deactivate B-channel access and queues */ -/******************************************/ -static void -close_hfcpci(struct BCState *bcs) -{ - mode_hfcpci(bcs, 0, bcs->channel); - if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) { - skb_queue_purge(&bcs->rqueue); - skb_queue_purge(&bcs->squeue); - if (bcs->tx_skb) { - dev_kfree_skb_any(bcs->tx_skb); - bcs->tx_skb = NULL; - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - } - } -} - -/*************************************/ -/* init B-channel queues and control */ -/*************************************/ -static int -open_hfcpcistate(struct IsdnCardState *cs, struct BCState *bcs) -{ - if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { - skb_queue_head_init(&bcs->rqueue); - skb_queue_head_init(&bcs->squeue); - } - bcs->tx_skb = NULL; - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - bcs->event = 0; - bcs->tx_cnt = 0; - return (0); -} - -/*********************************/ -/* inits the stack for B-channel */ -/*********************************/ -static int -setstack_2b(struct PStack *st, struct BCState *bcs) -{ - bcs->channel = st->l1.bc; - if (open_hfcpcistate(st->l1.hardware, bcs)) - return (-1); - st->l1.bcs = bcs; - st->l2.l2l1 = hfcpci_l2l1; - setstack_manager(st); - bcs->st = st; - setstack_l1_B(st); - return (0); -} - -/***************************/ -/* handle L1 state changes */ -/***************************/ -static void -hfcpci_bh(struct work_struct *work) -{ - struct IsdnCardState *cs = - container_of(work, struct IsdnCardState, tqueue); - u_long flags; -// struct PStack *stptr; - - if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) { - if (!cs->hw.hfcpci.nt_mode) - switch (cs->dc.hfcpci.ph_state) { - case (0): - l1_msg(cs, HW_RESET | INDICATION, NULL); - break; - case (3): - l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL); - break; - case (8): - l1_msg(cs, HW_RSYNC | INDICATION, NULL); - break; - case (6): - l1_msg(cs, HW_INFO2 | INDICATION, NULL); - break; - case (7): - l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL); - break; - default: - break; - } else { - spin_lock_irqsave(&cs->lock, flags); - switch (cs->dc.hfcpci.ph_state) { - case (2): - if (cs->hw.hfcpci.nt_timer < 0) { - cs->hw.hfcpci.nt_timer = 0; - cs->hw.hfcpci.int_m1 &= ~HFCPCI_INTS_TIMER; - Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1); - /* Clear already pending ints */ - Read_hfc(cs, HFCPCI_INT_S1); - Write_hfc(cs, HFCPCI_STATES, 4 | HFCPCI_LOAD_STATE); - udelay(10); - Write_hfc(cs, HFCPCI_STATES, 4); - cs->dc.hfcpci.ph_state = 4; - } else { - cs->hw.hfcpci.int_m1 |= HFCPCI_INTS_TIMER; - Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1); - cs->hw.hfcpci.ctmt &= ~HFCPCI_AUTO_TIMER; - cs->hw.hfcpci.ctmt |= HFCPCI_TIM3_125; - Write_hfc(cs, HFCPCI_CTMT, cs->hw.hfcpci.ctmt | HFCPCI_CLTIMER); - Write_hfc(cs, HFCPCI_CTMT, cs->hw.hfcpci.ctmt | HFCPCI_CLTIMER); - cs->hw.hfcpci.nt_timer = NT_T1_COUNT; - Write_hfc(cs, HFCPCI_STATES, 2 | HFCPCI_NT_G2_G3); /* allow G2 -> G3 transition */ - } - break; - case (1): - case (3): - case (4): - cs->hw.hfcpci.nt_timer = 0; - cs->hw.hfcpci.int_m1 &= ~HFCPCI_INTS_TIMER; - Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1); - break; - default: - break; - } - spin_unlock_irqrestore(&cs->lock, flags); - } - } - if (test_and_clear_bit(D_RCVBUFREADY, &cs->event)) - DChannel_proc_rcv(cs); - if (test_and_clear_bit(D_XMTBUFREADY, &cs->event)) - DChannel_proc_xmt(cs); -} - - -/********************************/ -/* called for card init message */ -/********************************/ -static void -inithfcpci(struct IsdnCardState *cs) -{ - cs->bcs[0].BC_SetStack = setstack_2b; - cs->bcs[1].BC_SetStack = setstack_2b; - cs->bcs[0].BC_Close = close_hfcpci; - cs->bcs[1].BC_Close = close_hfcpci; - timer_setup(&cs->dbusytimer, hfcpci_dbusy_timer, 0); - mode_hfcpci(cs->bcs, 0, 0); - mode_hfcpci(cs->bcs + 1, 0, 1); -} - - - -/*******************************************/ -/* handle card messages from control layer */ -/*******************************************/ -static int -hfcpci_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - u_long flags; - - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "HFCPCI: card_msg %x", mt); - switch (mt) { - case CARD_RESET: - spin_lock_irqsave(&cs->lock, flags); - reset_hfcpci(cs); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_RELEASE: - release_io_hfcpci(cs); - return (0); - case CARD_INIT: - spin_lock_irqsave(&cs->lock, flags); - inithfcpci(cs); - reset_hfcpci(cs); - spin_unlock_irqrestore(&cs->lock, flags); - msleep(80); /* Timeout 80ms */ - /* now switch timer interrupt off */ - spin_lock_irqsave(&cs->lock, flags); - cs->hw.hfcpci.int_m1 &= ~HFCPCI_INTS_TIMER; - Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1); - /* reinit mode reg */ - Write_hfc(cs, HFCPCI_MST_MODE, cs->hw.hfcpci.mst_m); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_TEST: - return (0); - } - return (0); -} - - -/* this variable is used as card index when more than one cards are present */ -static struct pci_dev *dev_hfcpci = NULL; - -int -setup_hfcpci(struct IsdnCard *card) -{ - u_long flags; - struct IsdnCardState *cs = card->cs; - char tmp[64]; - int i; - struct pci_dev *tmp_hfcpci = NULL; - - strcpy(tmp, hfcpci_revision); - printk(KERN_INFO "HiSax: HFC-PCI driver Rev. %s\n", HiSax_getrev(tmp)); - - cs->hw.hfcpci.int_s1 = 0; - cs->dc.hfcpci.ph_state = 0; - cs->hw.hfcpci.fifo = 255; - if (cs->typ != ISDN_CTYPE_HFC_PCI) - return (0); - - i = 0; - while (id_list[i].vendor_id) { - tmp_hfcpci = hisax_find_pci_device(id_list[i].vendor_id, - id_list[i].device_id, - dev_hfcpci); - i++; - if (tmp_hfcpci) { - dma_addr_t dma_mask = DMA_BIT_MASK(32) & ~0x7fffUL; - if (pci_enable_device(tmp_hfcpci)) - continue; - if (pci_set_dma_mask(tmp_hfcpci, dma_mask)) { - printk(KERN_WARNING - "HiSax hfc_pci: No suitable DMA available.\n"); - continue; - } - if (pci_set_consistent_dma_mask(tmp_hfcpci, dma_mask)) { - printk(KERN_WARNING - "HiSax hfc_pci: No suitable consistent DMA available.\n"); - continue; - } - pci_set_master(tmp_hfcpci); - if ((card->para[0]) && (card->para[0] != (tmp_hfcpci->resource[0].start & PCI_BASE_ADDRESS_IO_MASK))) - continue; - else - break; - } - } - - if (!tmp_hfcpci) { - printk(KERN_WARNING "HFC-PCI: No PCI card found\n"); - return (0); - } - - i--; - dev_hfcpci = tmp_hfcpci; /* old device */ - cs->hw.hfcpci.dev = dev_hfcpci; - cs->irq = dev_hfcpci->irq; - if (!cs->irq) { - printk(KERN_WARNING "HFC-PCI: No IRQ for PCI card found\n"); - return (0); - } - cs->hw.hfcpci.pci_io = ioremap(dev_hfcpci->resource[1].start, 256); - printk(KERN_INFO "HiSax: HFC-PCI card manufacturer: %s card name: %s\n", id_list[i].vendor_name, id_list[i].card_name); - - if (!cs->hw.hfcpci.pci_io) { - printk(KERN_WARNING "HFC-PCI: No IO-Mem for PCI card found\n"); - return (0); - } - - /* Allocate memory for FIFOS */ - cs->hw.hfcpci.fifos = pci_alloc_consistent(cs->hw.hfcpci.dev, - 0x8000, &cs->hw.hfcpci.dma); - if (!cs->hw.hfcpci.fifos) { - printk(KERN_WARNING "HFC-PCI: Error allocating FIFO memory!\n"); - return 0; - } - if (cs->hw.hfcpci.dma & 0x7fff) { - printk(KERN_WARNING - "HFC-PCI: Error DMA memory not on 32K boundary (%lx)\n", - (u_long)cs->hw.hfcpci.dma); - pci_free_consistent(cs->hw.hfcpci.dev, 0x8000, - cs->hw.hfcpci.fifos, cs->hw.hfcpci.dma); - return 0; - } - pci_write_config_dword(cs->hw.hfcpci.dev, 0x80, (u32)cs->hw.hfcpci.dma); - printk(KERN_INFO - "HFC-PCI: defined at mem %p fifo %p(%lx) IRQ %d HZ %d\n", - cs->hw.hfcpci.pci_io, - cs->hw.hfcpci.fifos, - (u_long)cs->hw.hfcpci.dma, - cs->irq, HZ); - - spin_lock_irqsave(&cs->lock, flags); - - pci_write_config_word(cs->hw.hfcpci.dev, PCI_COMMAND, PCI_ENA_MEMIO); /* enable memory mapped ports, disable busmaster */ - cs->hw.hfcpci.int_m2 = 0; /* disable alle interrupts */ - cs->hw.hfcpci.int_m1 = 0; - Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1); - Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2); - /* At this point the needed PCI config is done */ - /* fifos are still not enabled */ - - INIT_WORK(&cs->tqueue, hfcpci_bh); - cs->setstack_d = setstack_hfcpci; - cs->BC_Send_Data = &hfcpci_send_data; - cs->readisac = NULL; - cs->writeisac = NULL; - cs->readisacfifo = NULL; - cs->writeisacfifo = NULL; - cs->BC_Read_Reg = NULL; - cs->BC_Write_Reg = NULL; - cs->irq_func = &hfcpci_interrupt; - cs->irq_flags |= IRQF_SHARED; - timer_setup(&cs->hw.hfcpci.timer, hfcpci_Timer, 0); - cs->cardmsg = &hfcpci_card_msg; - cs->auxcmd = &hfcpci_auxcmd; - - spin_unlock_irqrestore(&cs->lock, flags); - - return (1); -} diff --git a/drivers/isdn/hisax/hfc_pci.h b/drivers/isdn/hisax/hfc_pci.h deleted file mode 100644 index 4c3b3ba35726..000000000000 --- a/drivers/isdn/hisax/hfc_pci.h +++ /dev/null @@ -1,235 +0,0 @@ -/* $Id: hfc_pci.h,v 1.10.2.2 2004/01/12 22:52:26 keil Exp $ - * - * specific defines for CCD's HFC 2BDS0 PCI chips - * - * Author Werner Cornelius - * Copyright by Werner Cornelius <werner@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -/*********************************************/ -/* thresholds for transparent B-channel mode */ -/* change mask and threshold simultaneously */ -/*********************************************/ -#define HFCPCI_BTRANS_THRESHOLD 128 -#define HFCPCI_BTRANS_THRESMASK 0x00 - - - -/* defines for PCI config */ - -#define PCI_ENA_MEMIO 0x02 -#define PCI_ENA_MASTER 0x04 - - -/* GCI/IOM bus monitor registers */ - -#define HCFPCI_C_I 0x08 -#define HFCPCI_TRxR 0x0C -#define HFCPCI_MON1_D 0x28 -#define HFCPCI_MON2_D 0x2C - - -/* GCI/IOM bus timeslot registers */ - -#define HFCPCI_B1_SSL 0x80 -#define HFCPCI_B2_SSL 0x84 -#define HFCPCI_AUX1_SSL 0x88 -#define HFCPCI_AUX2_SSL 0x8C -#define HFCPCI_B1_RSL 0x90 -#define HFCPCI_B2_RSL 0x94 -#define HFCPCI_AUX1_RSL 0x98 -#define HFCPCI_AUX2_RSL 0x9C - -/* GCI/IOM bus data registers */ - -#define HFCPCI_B1_D 0xA0 -#define HFCPCI_B2_D 0xA4 -#define HFCPCI_AUX1_D 0xA8 -#define HFCPCI_AUX2_D 0xAC - -/* GCI/IOM bus configuration registers */ - -#define HFCPCI_MST_EMOD 0xB4 -#define HFCPCI_MST_MODE 0xB8 -#define HFCPCI_CONNECT 0xBC - - -/* Interrupt and status registers */ - -#define HFCPCI_FIFO_EN 0x44 -#define HFCPCI_TRM 0x48 -#define HFCPCI_B_MODE 0x4C -#define HFCPCI_CHIP_ID 0x58 -#define HFCPCI_CIRM 0x60 -#define HFCPCI_CTMT 0x64 -#define HFCPCI_INT_M1 0x68 -#define HFCPCI_INT_M2 0x6C -#define HFCPCI_INT_S1 0x78 -#define HFCPCI_INT_S2 0x7C -#define HFCPCI_STATUS 0x70 - -/* S/T section registers */ - -#define HFCPCI_STATES 0xC0 -#define HFCPCI_SCTRL 0xC4 -#define HFCPCI_SCTRL_E 0xC8 -#define HFCPCI_SCTRL_R 0xCC -#define HFCPCI_SQ 0xD0 -#define HFCPCI_CLKDEL 0xDC -#define HFCPCI_B1_REC 0xF0 -#define HFCPCI_B1_SEND 0xF0 -#define HFCPCI_B2_REC 0xF4 -#define HFCPCI_B2_SEND 0xF4 -#define HFCPCI_D_REC 0xF8 -#define HFCPCI_D_SEND 0xF8 -#define HFCPCI_E_REC 0xFC - - -/* bits in status register (READ) */ -#define HFCPCI_PCI_PROC 0x02 -#define HFCPCI_NBUSY 0x04 -#define HFCPCI_TIMER_ELAP 0x10 -#define HFCPCI_STATINT 0x20 -#define HFCPCI_FRAMEINT 0x40 -#define HFCPCI_ANYINT 0x80 - -/* bits in CTMT (Write) */ -#define HFCPCI_CLTIMER 0x80 -#define HFCPCI_TIM3_125 0x04 -#define HFCPCI_TIM25 0x10 -#define HFCPCI_TIM50 0x14 -#define HFCPCI_TIM400 0x18 -#define HFCPCI_TIM800 0x1C -#define HFCPCI_AUTO_TIMER 0x20 -#define HFCPCI_TRANSB2 0x02 -#define HFCPCI_TRANSB1 0x01 - -/* bits in CIRM (Write) */ -#define HFCPCI_AUX_MSK 0x07 -#define HFCPCI_RESET 0x08 -#define HFCPCI_B1_REV 0x40 -#define HFCPCI_B2_REV 0x80 - -/* bits in INT_M1 and INT_S1 */ -#define HFCPCI_INTS_B1TRANS 0x01 -#define HFCPCI_INTS_B2TRANS 0x02 -#define HFCPCI_INTS_DTRANS 0x04 -#define HFCPCI_INTS_B1REC 0x08 -#define HFCPCI_INTS_B2REC 0x10 -#define HFCPCI_INTS_DREC 0x20 -#define HFCPCI_INTS_L1STATE 0x40 -#define HFCPCI_INTS_TIMER 0x80 - -/* bits in INT_M2 */ -#define HFCPCI_PROC_TRANS 0x01 -#define HFCPCI_GCI_I_CHG 0x02 -#define HFCPCI_GCI_MON_REC 0x04 -#define HFCPCI_IRQ_ENABLE 0x08 -#define HFCPCI_PMESEL 0x80 - -/* bits in STATES */ -#define HFCPCI_STATE_MSK 0x0F -#define HFCPCI_LOAD_STATE 0x10 -#define HFCPCI_ACTIVATE 0x20 -#define HFCPCI_DO_ACTION 0x40 -#define HFCPCI_NT_G2_G3 0x80 - -/* bits in HFCD_MST_MODE */ -#define HFCPCI_MASTER 0x01 -#define HFCPCI_SLAVE 0x00 -/* remaining bits are for codecs control */ - -/* bits in HFCD_SCTRL */ -#define SCTRL_B1_ENA 0x01 -#define SCTRL_B2_ENA 0x02 -#define SCTRL_MODE_TE 0x00 -#define SCTRL_MODE_NT 0x04 -#define SCTRL_LOW_PRIO 0x08 -#define SCTRL_SQ_ENA 0x10 -#define SCTRL_TEST 0x20 -#define SCTRL_NONE_CAP 0x40 -#define SCTRL_PWR_DOWN 0x80 - -/* bits in SCTRL_E */ -#define HFCPCI_AUTO_AWAKE 0x01 -#define HFCPCI_DBIT_1 0x04 -#define HFCPCI_IGNORE_COL 0x08 -#define HFCPCI_CHG_B1_B2 0x80 - -/****************************/ -/* bits in FIFO_EN register */ -/****************************/ -#define HFCPCI_FIFOEN_B1 0x03 -#define HFCPCI_FIFOEN_B2 0x0C -#define HFCPCI_FIFOEN_DTX 0x10 -#define HFCPCI_FIFOEN_B1TX 0x01 -#define HFCPCI_FIFOEN_B1RX 0x02 -#define HFCPCI_FIFOEN_B2TX 0x04 -#define HFCPCI_FIFOEN_B2RX 0x08 - - -/***********************************/ -/* definitions of fifo memory area */ -/***********************************/ -#define MAX_D_FRAMES 15 -#define MAX_B_FRAMES 31 -#define B_SUB_VAL 0x200 -#define B_FIFO_SIZE (0x2000 - B_SUB_VAL) -#define D_FIFO_SIZE 512 -#define D_FREG_MASK 0xF - -typedef struct { - unsigned short z1; /* Z1 pointer 16 Bit */ - unsigned short z2; /* Z2 pointer 16 Bit */ -} z_type; - -typedef struct { - u_char data[D_FIFO_SIZE]; /* FIFO data space */ - u_char fill1[0x20A0 - D_FIFO_SIZE]; /* reserved, do not use */ - u_char f1, f2; /* f pointers */ - u_char fill2[0x20C0 - 0x20A2]; /* reserved, do not use */ - z_type za[MAX_D_FRAMES + 1]; /* mask index with D_FREG_MASK for access */ - u_char fill3[0x4000 - 0x2100]; /* align 16K */ -} dfifo_type; - -typedef struct { - z_type za[MAX_B_FRAMES + 1]; /* only range 0x0..0x1F allowed */ - u_char f1, f2; /* f pointers */ - u_char fill[0x2100 - 0x2082]; /* alignment */ -} bzfifo_type; - - -typedef union { - struct { - dfifo_type d_tx; /* D-send channel */ - dfifo_type d_rx; /* D-receive channel */ - } d_chan; - struct { - u_char fill1[0x200]; - u_char txdat_b1[B_FIFO_SIZE]; - bzfifo_type txbz_b1; - - bzfifo_type txbz_b2; - u_char txdat_b2[B_FIFO_SIZE]; - - u_char fill2[D_FIFO_SIZE]; - - u_char rxdat_b1[B_FIFO_SIZE]; - bzfifo_type rxbz_b1; - - bzfifo_type rxbz_b2; - u_char rxdat_b2[B_FIFO_SIZE]; - } b_chans; - u_char fill[32768]; -} fifo_area; - - -#define Write_hfc(a, b, c) (writeb(c, (a->hw.hfcpci.pci_io) + b)) -#define Read_hfc(a, b) (readb((a->hw.hfcpci.pci_io) + b)) - -extern void main_irq_hcpci(struct BCState *bcs); -extern void releasehfcpci(struct IsdnCardState *cs); diff --git a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c deleted file mode 100644 index 12af628d9b2c..000000000000 --- a/drivers/isdn/hisax/hfc_sx.c +++ /dev/null @@ -1,1517 +0,0 @@ -/* $Id: hfc_sx.c,v 1.12.2.5 2004/02/11 13:21:33 keil Exp $ - * - * level driver for Cologne Chip Designs hfc-s+/sp based cards - * - * Author Werner Cornelius - * based on existing driver for CCD HFC PCI cards - * Copyright by Werner Cornelius <werner@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/init.h> -#include "hisax.h" -#include "hfc_sx.h" -#include "isdnl1.h" -#include <linux/interrupt.h> -#include <linux/isapnp.h> -#include <linux/slab.h> - -static const char *hfcsx_revision = "$Revision: 1.12.2.5 $"; - -/***************************************/ -/* IRQ-table for CCDs demo board */ -/* IRQs 6,5,10,11,12,15 are supported */ -/***************************************/ - -/* Teles 16.3c Vendor Id TAG2620, Version 1.0, Vendor version 2.1 - * - * Thanks to Uwe Wisniewski - * - * ISA-SLOT Signal PIN - * B25 IRQ3 92 IRQ_G - * B23 IRQ5 94 IRQ_A - * B4 IRQ2/9 95 IRQ_B - * D3 IRQ10 96 IRQ_C - * D4 IRQ11 97 IRQ_D - * D5 IRQ12 98 IRQ_E - * D6 IRQ15 99 IRQ_F - */ - -#undef CCD_DEMO_BOARD -#ifdef CCD_DEMO_BOARD -static u_char ccd_sp_irqtab[16] = { - 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 3, 4, 5, 0, 0, 6 -}; -#else /* Teles 16.3c */ -static u_char ccd_sp_irqtab[16] = { - 0, 0, 0, 7, 0, 1, 0, 0, 0, 2, 3, 4, 5, 0, 0, 6 -}; -#endif -#define NT_T1_COUNT 20 /* number of 3.125ms interrupts for G2 timeout */ - -#define byteout(addr, val) outb(val, addr) -#define bytein(addr) inb(addr) - -/******************************/ -/* In/Out access to registers */ -/******************************/ -static inline void -Write_hfc(struct IsdnCardState *cs, u_char regnum, u_char val) -{ - byteout(cs->hw.hfcsx.base + 1, regnum); - byteout(cs->hw.hfcsx.base, val); -} - -static inline u_char -Read_hfc(struct IsdnCardState *cs, u_char regnum) -{ - u_char ret; - - byteout(cs->hw.hfcsx.base + 1, regnum); - ret = bytein(cs->hw.hfcsx.base); - return (ret); -} - - -/**************************************************/ -/* select a fifo and remember which one for reuse */ -/**************************************************/ -static void -fifo_select(struct IsdnCardState *cs, u_char fifo) -{ - if (fifo == cs->hw.hfcsx.last_fifo) - return; /* still valid */ - - byteout(cs->hw.hfcsx.base + 1, HFCSX_FIF_SEL); - byteout(cs->hw.hfcsx.base, fifo); - while (bytein(cs->hw.hfcsx.base + 1) & 1); /* wait for busy */ - udelay(4); - byteout(cs->hw.hfcsx.base, fifo); - while (bytein(cs->hw.hfcsx.base + 1) & 1); /* wait for busy */ -} - -/******************************************/ -/* reset the specified fifo to defaults. */ -/* If its a send fifo init needed markers */ -/******************************************/ -static void -reset_fifo(struct IsdnCardState *cs, u_char fifo) -{ - fifo_select(cs, fifo); /* first select the fifo */ - byteout(cs->hw.hfcsx.base + 1, HFCSX_CIRM); - byteout(cs->hw.hfcsx.base, cs->hw.hfcsx.cirm | 0x80); /* reset cmd */ - udelay(1); - while (bytein(cs->hw.hfcsx.base + 1) & 1); /* wait for busy */ -} - - -/*************************************************************/ -/* write_fifo writes the skb contents to the desired fifo */ -/* if no space is available or an error occurs 0 is returned */ -/* the skb is not released in any way. */ -/*************************************************************/ -static int -write_fifo(struct IsdnCardState *cs, struct sk_buff *skb, u_char fifo, int trans_max) -{ - unsigned short *msp; - int fifo_size, count, z1, z2; - u_char f_msk, f1, f2, *src; - - if (skb->len <= 0) return (0); - if (fifo & 1) return (0); /* no write fifo */ - - fifo_select(cs, fifo); - if (fifo & 4) { - fifo_size = D_FIFO_SIZE; /* D-channel */ - f_msk = MAX_D_FRAMES; - if (trans_max) return (0); /* only HDLC */ - } - else { - fifo_size = cs->hw.hfcsx.b_fifo_size; /* B-channel */ - f_msk = MAX_B_FRAMES; - } - - z1 = Read_hfc(cs, HFCSX_FIF_Z1H); - z1 = ((z1 << 8) | Read_hfc(cs, HFCSX_FIF_Z1L)); - - /* Check for transparent mode */ - if (trans_max) { - z2 = Read_hfc(cs, HFCSX_FIF_Z2H); - z2 = ((z2 << 8) | Read_hfc(cs, HFCSX_FIF_Z2L)); - count = z2 - z1; - if (count <= 0) - count += fifo_size; /* free bytes */ - if (count < skb->len + 1) return (0); /* no room */ - count = fifo_size - count; /* bytes still not send */ - if (count > 2 * trans_max) return (0); /* delay to long */ - count = skb->len; - src = skb->data; - while (count--) - Write_hfc(cs, HFCSX_FIF_DWR, *src++); - return (1); /* success */ - } - - msp = ((struct hfcsx_extra *)(cs->hw.hfcsx.extra))->marker; - msp += (((fifo >> 1) & 3) * (MAX_B_FRAMES + 1)); - f1 = Read_hfc(cs, HFCSX_FIF_F1) & f_msk; - f2 = Read_hfc(cs, HFCSX_FIF_F2) & f_msk; - - count = f1 - f2; /* frame count actually buffered */ - if (count < 0) - count += (f_msk + 1); /* if wrap around */ - if (count > f_msk - 1) { - if (cs->debug & L1_DEB_ISAC_FIFO) - debugl1(cs, "hfcsx_write_fifo %d more as %d frames", fifo, f_msk - 1); - return (0); - } - - *(msp + f1) = z1; /* remember marker */ - - if (cs->debug & L1_DEB_ISAC_FIFO) - debugl1(cs, "hfcsx_write_fifo %d f1(%x) f2(%x) z1(f1)(%x)", - fifo, f1, f2, z1); - /* now determine free bytes in FIFO buffer */ - count = *(msp + f2) - z1; - if (count <= 0) - count += fifo_size; /* count now contains available bytes */ - - if (cs->debug & L1_DEB_ISAC_FIFO) - debugl1(cs, "hfcsx_write_fifo %d count(%u/%d)", - fifo, skb->len, count); - if (count < skb->len) { - if (cs->debug & L1_DEB_ISAC_FIFO) - debugl1(cs, "hfcsx_write_fifo %d no fifo mem", fifo); - return (0); - } - - count = skb->len; /* get frame len */ - src = skb->data; /* source pointer */ - while (count--) - Write_hfc(cs, HFCSX_FIF_DWR, *src++); - - Read_hfc(cs, HFCSX_FIF_INCF1); /* increment F1 */ - udelay(1); - while (bytein(cs->hw.hfcsx.base + 1) & 1); /* wait for busy */ - return (1); -} - -/***************************************************************/ -/* read_fifo reads data to an skb from the desired fifo */ -/* if no data is available or an error occurs NULL is returned */ -/* the skb is not released in any way. */ -/***************************************************************/ -static struct sk_buff * -read_fifo(struct IsdnCardState *cs, u_char fifo, int trans_max) -{ int fifo_size, count, z1, z2; - u_char f_msk, f1, f2, *dst; - struct sk_buff *skb; - - if (!(fifo & 1)) return (NULL); /* no read fifo */ - fifo_select(cs, fifo); - if (fifo & 4) { - fifo_size = D_FIFO_SIZE; /* D-channel */ - f_msk = MAX_D_FRAMES; - if (trans_max) return (NULL); /* only hdlc */ - } - else { - fifo_size = cs->hw.hfcsx.b_fifo_size; /* B-channel */ - f_msk = MAX_B_FRAMES; - } - - /* transparent mode */ - if (trans_max) { - z1 = Read_hfc(cs, HFCSX_FIF_Z1H); - z1 = ((z1 << 8) | Read_hfc(cs, HFCSX_FIF_Z1L)); - z2 = Read_hfc(cs, HFCSX_FIF_Z2H); - z2 = ((z2 << 8) | Read_hfc(cs, HFCSX_FIF_Z2L)); - /* now determine bytes in actual FIFO buffer */ - count = z1 - z2; - if (count <= 0) - count += fifo_size; /* count now contains buffered bytes */ - count++; - if (count > trans_max) - count = trans_max; /* limit length */ - skb = dev_alloc_skb(count); - if (skb) { - dst = skb_put(skb, count); - while (count--) - *dst++ = Read_hfc(cs, HFCSX_FIF_DRD); - return skb; - } else - return NULL; /* no memory */ - } - - do { - f1 = Read_hfc(cs, HFCSX_FIF_F1) & f_msk; - f2 = Read_hfc(cs, HFCSX_FIF_F2) & f_msk; - - if (f1 == f2) return (NULL); /* no frame available */ - - z1 = Read_hfc(cs, HFCSX_FIF_Z1H); - z1 = ((z1 << 8) | Read_hfc(cs, HFCSX_FIF_Z1L)); - z2 = Read_hfc(cs, HFCSX_FIF_Z2H); - z2 = ((z2 << 8) | Read_hfc(cs, HFCSX_FIF_Z2L)); - - if (cs->debug & L1_DEB_ISAC_FIFO) - debugl1(cs, "hfcsx_read_fifo %d f1(%x) f2(%x) z1(f2)(%x) z2(f2)(%x)", - fifo, f1, f2, z1, z2); - /* now determine bytes in actual FIFO buffer */ - count = z1 - z2; - if (count <= 0) - count += fifo_size; /* count now contains buffered bytes */ - count++; - - if (cs->debug & L1_DEB_ISAC_FIFO) - debugl1(cs, "hfcsx_read_fifo %d count %u)", - fifo, count); - - if ((count > fifo_size) || (count < 4)) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "hfcsx_read_fifo %d packet inv. len %d ", fifo , count); - while (count) { - count--; /* empty fifo */ - Read_hfc(cs, HFCSX_FIF_DRD); - } - skb = NULL; - } else - if ((skb = dev_alloc_skb(count - 3))) { - count -= 3; - dst = skb_put(skb, count); - - while (count--) - *dst++ = Read_hfc(cs, HFCSX_FIF_DRD); - - Read_hfc(cs, HFCSX_FIF_DRD); /* CRC 1 */ - Read_hfc(cs, HFCSX_FIF_DRD); /* CRC 2 */ - if (Read_hfc(cs, HFCSX_FIF_DRD)) { - dev_kfree_skb_irq(skb); - if (cs->debug & L1_DEB_ISAC_FIFO) - debugl1(cs, "hfcsx_read_fifo %d crc error", fifo); - skb = NULL; - } - } else { - printk(KERN_WARNING "HFC-SX: receive out of memory\n"); - return (NULL); - } - - Read_hfc(cs, HFCSX_FIF_INCF2); /* increment F2 */ - udelay(1); - while (bytein(cs->hw.hfcsx.base + 1) & 1); /* wait for busy */ - udelay(1); - } while (!skb); /* retry in case of crc error */ - return (skb); -} - -/******************************************/ -/* free hardware resources used by driver */ -/******************************************/ -static void -release_io_hfcsx(struct IsdnCardState *cs) -{ - cs->hw.hfcsx.int_m2 = 0; /* interrupt output off ! */ - Write_hfc(cs, HFCSX_INT_M2, cs->hw.hfcsx.int_m2); - Write_hfc(cs, HFCSX_CIRM, HFCSX_RESET); /* Reset On */ - msleep(30); /* Timeout 30ms */ - Write_hfc(cs, HFCSX_CIRM, 0); /* Reset Off */ - del_timer(&cs->hw.hfcsx.timer); - release_region(cs->hw.hfcsx.base, 2); /* release IO-Block */ - kfree(cs->hw.hfcsx.extra); - cs->hw.hfcsx.extra = NULL; -} - -/**********************************************************/ -/* set_fifo_size determines the size of the RAM and FIFOs */ -/* returning 0 -> need to reset the chip again. */ -/**********************************************************/ -static int set_fifo_size(struct IsdnCardState *cs) -{ - - if (cs->hw.hfcsx.b_fifo_size) return (1); /* already determined */ - - if ((cs->hw.hfcsx.chip >> 4) == 9) { - cs->hw.hfcsx.b_fifo_size = B_FIFO_SIZE_32K; - return (1); - } - - cs->hw.hfcsx.b_fifo_size = B_FIFO_SIZE_8K; - cs->hw.hfcsx.cirm |= 0x10; /* only 8K of ram */ - return (0); - -} - -/********************************************************************************/ -/* function called to reset the HFC SX chip. A complete software reset of chip */ -/* and fifos is done. */ -/********************************************************************************/ -static void -reset_hfcsx(struct IsdnCardState *cs) -{ - cs->hw.hfcsx.int_m2 = 0; /* interrupt output off ! */ - Write_hfc(cs, HFCSX_INT_M2, cs->hw.hfcsx.int_m2); - - printk(KERN_INFO "HFC_SX: resetting card\n"); - while (1) { - Write_hfc(cs, HFCSX_CIRM, HFCSX_RESET | cs->hw.hfcsx.cirm); /* Reset */ - mdelay(30); - Write_hfc(cs, HFCSX_CIRM, cs->hw.hfcsx.cirm); /* Reset Off */ - mdelay(20); - if (Read_hfc(cs, HFCSX_STATUS) & 2) - printk(KERN_WARNING "HFC-SX init bit busy\n"); - cs->hw.hfcsx.last_fifo = 0xff; /* invalidate */ - if (!set_fifo_size(cs)) continue; - break; - } - - cs->hw.hfcsx.trm = 0 + HFCSX_BTRANS_THRESMASK; /* no echo connect , threshold */ - Write_hfc(cs, HFCSX_TRM, cs->hw.hfcsx.trm); - - Write_hfc(cs, HFCSX_CLKDEL, 0x0e); /* ST-Bit delay for TE-Mode */ - cs->hw.hfcsx.sctrl_e = HFCSX_AUTO_AWAKE; - Write_hfc(cs, HFCSX_SCTRL_E, cs->hw.hfcsx.sctrl_e); /* S/T Auto awake */ - cs->hw.hfcsx.bswapped = 0; /* no exchange */ - cs->hw.hfcsx.nt_mode = 0; /* we are in TE mode */ - cs->hw.hfcsx.ctmt = HFCSX_TIM3_125 | HFCSX_AUTO_TIMER; - Write_hfc(cs, HFCSX_CTMT, cs->hw.hfcsx.ctmt); - - cs->hw.hfcsx.int_m1 = HFCSX_INTS_DTRANS | HFCSX_INTS_DREC | - HFCSX_INTS_L1STATE | HFCSX_INTS_TIMER; - Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1); - - /* Clear already pending ints */ - Read_hfc(cs, HFCSX_INT_S1); - - Write_hfc(cs, HFCSX_STATES, HFCSX_LOAD_STATE | 2); /* HFC ST 2 */ - udelay(10); - Write_hfc(cs, HFCSX_STATES, 2); /* HFC ST 2 */ - cs->hw.hfcsx.mst_m = HFCSX_MASTER; /* HFC Master Mode */ - - Write_hfc(cs, HFCSX_MST_MODE, cs->hw.hfcsx.mst_m); - cs->hw.hfcsx.sctrl = 0x40; /* set tx_lo mode, error in datasheet ! */ - Write_hfc(cs, HFCSX_SCTRL, cs->hw.hfcsx.sctrl); - cs->hw.hfcsx.sctrl_r = 0; - Write_hfc(cs, HFCSX_SCTRL_R, cs->hw.hfcsx.sctrl_r); - - /* Init GCI/IOM2 in master mode */ - /* Slots 0 and 1 are set for B-chan 1 and 2 */ - /* D- and monitor/CI channel are not enabled */ - /* STIO1 is used as output for data, B1+B2 from ST->IOM+HFC */ - /* STIO2 is used as data input, B1+B2 from IOM->ST */ - /* ST B-channel send disabled -> continuous 1s */ - /* The IOM slots are always enabled */ - cs->hw.hfcsx.conn = 0x36; /* set data flow directions */ - Write_hfc(cs, HFCSX_CONNECT, cs->hw.hfcsx.conn); - Write_hfc(cs, HFCSX_B1_SSL, 0x80); /* B1-Slot 0 STIO1 out enabled */ - Write_hfc(cs, HFCSX_B2_SSL, 0x81); /* B2-Slot 1 STIO1 out enabled */ - Write_hfc(cs, HFCSX_B1_RSL, 0x80); /* B1-Slot 0 STIO2 in enabled */ - Write_hfc(cs, HFCSX_B2_RSL, 0x81); /* B2-Slot 1 STIO2 in enabled */ - - /* Finally enable IRQ output */ - cs->hw.hfcsx.int_m2 = HFCSX_IRQ_ENABLE; - Write_hfc(cs, HFCSX_INT_M2, cs->hw.hfcsx.int_m2); - Read_hfc(cs, HFCSX_INT_S2); -} - -/***************************************************/ -/* Timer function called when kernel timer expires */ -/***************************************************/ -static void -hfcsx_Timer(struct timer_list *t) -{ - struct IsdnCardState *cs = from_timer(cs, t, hw.hfcsx.timer); - cs->hw.hfcsx.timer.expires = jiffies + 75; - /* WD RESET */ -/* WriteReg(cs, HFCD_DATA, HFCD_CTMT, cs->hw.hfcsx.ctmt | 0x80); - add_timer(&cs->hw.hfcsx.timer); -*/ -} - -/************************************************/ -/* select a b-channel entry matching and active */ -/************************************************/ -static -struct BCState * -Sel_BCS(struct IsdnCardState *cs, int channel) -{ - if (cs->bcs[0].mode && (cs->bcs[0].channel == channel)) - return (&cs->bcs[0]); - else if (cs->bcs[1].mode && (cs->bcs[1].channel == channel)) - return (&cs->bcs[1]); - else - return (NULL); -} - -/*******************************/ -/* D-channel receive procedure */ -/*******************************/ -static -int -receive_dmsg(struct IsdnCardState *cs) -{ - struct sk_buff *skb; - int count = 5; - - if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - debugl1(cs, "rec_dmsg blocked"); - return (1); - } - - do { - skb = read_fifo(cs, HFCSX_SEL_D_RX, 0); - if (skb) { - skb_queue_tail(&cs->rq, skb); - schedule_event(cs, D_RCVBUFREADY); - } - } while (--count && skb); - - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - return (1); -} - -/**********************************/ -/* B-channel main receive routine */ -/**********************************/ -static void -main_rec_hfcsx(struct BCState *bcs) -{ - struct IsdnCardState *cs = bcs->cs; - int count = 5; - struct sk_buff *skb; - -Begin: - count--; - if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - debugl1(cs, "rec_data %d blocked", bcs->channel); - return; - } - skb = read_fifo(cs, ((bcs->channel) && (!cs->hw.hfcsx.bswapped)) ? - HFCSX_SEL_B2_RX : HFCSX_SEL_B1_RX, - (bcs->mode == L1_MODE_TRANS) ? - HFCSX_BTRANS_THRESHOLD : 0); - - if (skb) { - skb_queue_tail(&bcs->rqueue, skb); - schedule_event(bcs, B_RCVBUFREADY); - } - - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - if (count && skb) - goto Begin; - return; -} - -/**************************/ -/* D-channel send routine */ -/**************************/ -static void -hfcsx_fill_dfifo(struct IsdnCardState *cs) -{ - if (!cs->tx_skb) - return; - if (cs->tx_skb->len <= 0) - return; - - if (write_fifo(cs, cs->tx_skb, HFCSX_SEL_D_TX, 0)) { - dev_kfree_skb_any(cs->tx_skb); - cs->tx_skb = NULL; - } - return; -} - -/**************************/ -/* B-channel send routine */ -/**************************/ -static void -hfcsx_fill_fifo(struct BCState *bcs) -{ - struct IsdnCardState *cs = bcs->cs; - - if (!bcs->tx_skb) - return; - if (bcs->tx_skb->len <= 0) - return; - - if (write_fifo(cs, bcs->tx_skb, - ((bcs->channel) && (!cs->hw.hfcsx.bswapped)) ? - HFCSX_SEL_B2_TX : HFCSX_SEL_B1_TX, - (bcs->mode == L1_MODE_TRANS) ? - HFCSX_BTRANS_THRESHOLD : 0)) { - - bcs->tx_cnt -= bcs->tx_skb->len; - if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) && - (PACKET_NOACK != bcs->tx_skb->pkt_type)) { - u_long flags; - spin_lock_irqsave(&bcs->aclock, flags); - bcs->ackcnt += bcs->tx_skb->len; - spin_unlock_irqrestore(&bcs->aclock, flags); - schedule_event(bcs, B_ACKPENDING); - } - dev_kfree_skb_any(bcs->tx_skb); - bcs->tx_skb = NULL; - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - } -} - -/**********************************************/ -/* D-channel l1 state call for leased NT-mode */ -/**********************************************/ -static void -dch_nt_l2l1(struct PStack *st, int pr, void *arg) -{ - struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware; - - switch (pr) { - case (PH_DATA | REQUEST): - case (PH_PULL | REQUEST): - case (PH_PULL | INDICATION): - st->l1.l1hw(st, pr, arg); - break; - case (PH_ACTIVATE | REQUEST): - st->l1.l1l2(st, PH_ACTIVATE | CONFIRM, NULL); - break; - case (PH_TESTLOOP | REQUEST): - if (1 & (long) arg) - debugl1(cs, "PH_TEST_LOOP B1"); - if (2 & (long) arg) - debugl1(cs, "PH_TEST_LOOP B2"); - if (!(3 & (long) arg)) - debugl1(cs, "PH_TEST_LOOP DISABLED"); - st->l1.l1hw(st, HW_TESTLOOP | REQUEST, arg); - break; - default: - if (cs->debug) - debugl1(cs, "dch_nt_l2l1 msg %04X unhandled", pr); - break; - } -} - - - -/***********************/ -/* set/reset echo mode */ -/***********************/ -static int -hfcsx_auxcmd(struct IsdnCardState *cs, isdn_ctrl *ic) -{ - unsigned long flags; - int i = *(unsigned int *) ic->parm.num; - - if ((ic->arg == 98) && - (!(cs->hw.hfcsx.int_m1 & (HFCSX_INTS_B2TRANS + HFCSX_INTS_B2REC + HFCSX_INTS_B1TRANS + HFCSX_INTS_B1REC)))) { - spin_lock_irqsave(&cs->lock, flags); - Write_hfc(cs, HFCSX_STATES, HFCSX_LOAD_STATE | 0); /* HFC ST G0 */ - udelay(10); - cs->hw.hfcsx.sctrl |= SCTRL_MODE_NT; - Write_hfc(cs, HFCSX_SCTRL, cs->hw.hfcsx.sctrl); /* set NT-mode */ - udelay(10); - Write_hfc(cs, HFCSX_STATES, HFCSX_LOAD_STATE | 1); /* HFC ST G1 */ - udelay(10); - Write_hfc(cs, HFCSX_STATES, 1 | HFCSX_ACTIVATE | HFCSX_DO_ACTION); - cs->dc.hfcsx.ph_state = 1; - cs->hw.hfcsx.nt_mode = 1; - cs->hw.hfcsx.nt_timer = 0; - spin_unlock_irqrestore(&cs->lock, flags); - cs->stlist->l2.l2l1 = dch_nt_l2l1; - debugl1(cs, "NT mode activated"); - return (0); - } - if ((cs->chanlimit > 1) || (cs->hw.hfcsx.bswapped) || - (cs->hw.hfcsx.nt_mode) || (ic->arg != 12)) - return (-EINVAL); - - if (i) { - cs->logecho = 1; - cs->hw.hfcsx.trm |= 0x20; /* enable echo chan */ - cs->hw.hfcsx.int_m1 |= HFCSX_INTS_B2REC; - /* reset Channel !!!!! */ - } else { - cs->logecho = 0; - cs->hw.hfcsx.trm &= ~0x20; /* disable echo chan */ - cs->hw.hfcsx.int_m1 &= ~HFCSX_INTS_B2REC; - } - cs->hw.hfcsx.sctrl_r &= ~SCTRL_B2_ENA; - cs->hw.hfcsx.sctrl &= ~SCTRL_B2_ENA; - cs->hw.hfcsx.conn |= 0x10; /* B2-IOM -> B2-ST */ - cs->hw.hfcsx.ctmt &= ~2; - spin_lock_irqsave(&cs->lock, flags); - Write_hfc(cs, HFCSX_CTMT, cs->hw.hfcsx.ctmt); - Write_hfc(cs, HFCSX_SCTRL_R, cs->hw.hfcsx.sctrl_r); - Write_hfc(cs, HFCSX_SCTRL, cs->hw.hfcsx.sctrl); - Write_hfc(cs, HFCSX_CONNECT, cs->hw.hfcsx.conn); - Write_hfc(cs, HFCSX_TRM, cs->hw.hfcsx.trm); - Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); -} /* hfcsx_auxcmd */ - -/*****************************/ -/* E-channel receive routine */ -/*****************************/ -static void -receive_emsg(struct IsdnCardState *cs) -{ - int count = 5; - u_char *ptr; - struct sk_buff *skb; - - if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - debugl1(cs, "echo_rec_data blocked"); - return; - } - do { - skb = read_fifo(cs, HFCSX_SEL_B2_RX, 0); - if (skb) { - if (cs->debug & DEB_DLOG_HEX) { - ptr = cs->dlog; - if ((skb->len) < MAX_DLOG_SPACE / 3 - 10) { - *ptr++ = 'E'; - *ptr++ = 'C'; - *ptr++ = 'H'; - *ptr++ = 'O'; - *ptr++ = ':'; - ptr += QuickHex(ptr, skb->data, skb->len); - ptr--; - *ptr++ = '\n'; - *ptr = 0; - HiSax_putstatus(cs, NULL, cs->dlog); - } else - HiSax_putstatus(cs, "LogEcho: ", "warning Frame too big (%d)", skb->len); - } - dev_kfree_skb_any(skb); - } - } while (--count && skb); - - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - return; -} /* receive_emsg */ - - -/*********************/ -/* Interrupt handler */ -/*********************/ -static irqreturn_t -hfcsx_interrupt(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - u_char exval; - struct BCState *bcs; - int count = 15; - u_long flags; - u_char val, stat; - - if (!(cs->hw.hfcsx.int_m2 & 0x08)) - return IRQ_NONE; /* not initialised */ - - spin_lock_irqsave(&cs->lock, flags); - if (HFCSX_ANYINT & (stat = Read_hfc(cs, HFCSX_STATUS))) { - val = Read_hfc(cs, HFCSX_INT_S1); - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "HFC-SX: stat(%02x) s1(%02x)", stat, val); - } else { - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_NONE; - } - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "HFC-SX irq %x %s", val, - test_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags) ? - "locked" : "unlocked"); - val &= cs->hw.hfcsx.int_m1; - if (val & 0x40) { /* state machine irq */ - exval = Read_hfc(cs, HFCSX_STATES) & 0xf; - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "ph_state chg %d->%d", cs->dc.hfcsx.ph_state, - exval); - cs->dc.hfcsx.ph_state = exval; - schedule_event(cs, D_L1STATECHANGE); - val &= ~0x40; - } - if (val & 0x80) { /* timer irq */ - if (cs->hw.hfcsx.nt_mode) { - if ((--cs->hw.hfcsx.nt_timer) < 0) - schedule_event(cs, D_L1STATECHANGE); - } - val &= ~0x80; - Write_hfc(cs, HFCSX_CTMT, cs->hw.hfcsx.ctmt | HFCSX_CLTIMER); - } - while (val) { - if (test_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - cs->hw.hfcsx.int_s1 |= val; - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; - } - if (cs->hw.hfcsx.int_s1 & 0x18) { - exval = val; - val = cs->hw.hfcsx.int_s1; - cs->hw.hfcsx.int_s1 = exval; - } - if (val & 0x08) { - if (!(bcs = Sel_BCS(cs, cs->hw.hfcsx.bswapped ? 1 : 0))) { - if (cs->debug) - debugl1(cs, "hfcsx spurious 0x08 IRQ"); - } else - main_rec_hfcsx(bcs); - } - if (val & 0x10) { - if (cs->logecho) - receive_emsg(cs); - else if (!(bcs = Sel_BCS(cs, 1))) { - if (cs->debug) - debugl1(cs, "hfcsx spurious 0x10 IRQ"); - } else - main_rec_hfcsx(bcs); - } - if (val & 0x01) { - if (!(bcs = Sel_BCS(cs, cs->hw.hfcsx.bswapped ? 1 : 0))) { - if (cs->debug) - debugl1(cs, "hfcsx spurious 0x01 IRQ"); - } else { - if (bcs->tx_skb) { - if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - hfcsx_fill_fifo(bcs); - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - } else - debugl1(cs, "fill_data %d blocked", bcs->channel); - } else { - if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) { - if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - hfcsx_fill_fifo(bcs); - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - } else - debugl1(cs, "fill_data %d blocked", bcs->channel); - } else { - schedule_event(bcs, B_XMTBUFREADY); - } - } - } - } - if (val & 0x02) { - if (!(bcs = Sel_BCS(cs, 1))) { - if (cs->debug) - debugl1(cs, "hfcsx spurious 0x02 IRQ"); - } else { - if (bcs->tx_skb) { - if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - hfcsx_fill_fifo(bcs); - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - } else - debugl1(cs, "fill_data %d blocked", bcs->channel); - } else { - if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) { - if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - hfcsx_fill_fifo(bcs); - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - } else - debugl1(cs, "fill_data %d blocked", bcs->channel); - } else { - schedule_event(bcs, B_XMTBUFREADY); - } - } - } - } - if (val & 0x20) { /* receive dframe */ - receive_dmsg(cs); - } - if (val & 0x04) { /* dframe transmitted */ - if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) - del_timer(&cs->dbusytimer); - if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags)) - schedule_event(cs, D_CLEARBUSY); - if (cs->tx_skb) { - if (cs->tx_skb->len) { - if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - hfcsx_fill_dfifo(cs); - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - } else { - debugl1(cs, "hfcsx_fill_dfifo irq blocked"); - } - goto afterXPR; - } else { - dev_kfree_skb_irq(cs->tx_skb); - cs->tx_cnt = 0; - cs->tx_skb = NULL; - } - } - if ((cs->tx_skb = skb_dequeue(&cs->sq))) { - cs->tx_cnt = 0; - if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - hfcsx_fill_dfifo(cs); - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - } else { - debugl1(cs, "hfcsx_fill_dfifo irq blocked"); - } - } else - schedule_event(cs, D_XMTBUFREADY); - } - afterXPR: - if (cs->hw.hfcsx.int_s1 && count--) { - val = cs->hw.hfcsx.int_s1; - cs->hw.hfcsx.int_s1 = 0; - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "HFC-SX irq %x loop %d", val, 15 - count); - } else - val = 0; - } - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -/********************************************************************/ -/* timer callback for D-chan busy resolution. Currently no function */ -/********************************************************************/ -static void -hfcsx_dbusy_timer(struct timer_list *t) -{ -} - -/*************************************/ -/* Layer 1 D-channel hardware access */ -/*************************************/ -static void -HFCSX_l1hw(struct PStack *st, int pr, void *arg) -{ - struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware; - struct sk_buff *skb = arg; - u_long flags; - - switch (pr) { - case (PH_DATA | REQUEST): - if (cs->debug & DEB_DLOG_HEX) - LogFrame(cs, skb->data, skb->len); - if (cs->debug & DEB_DLOG_VERBOSE) - dlogframe(cs, skb, 0); - spin_lock_irqsave(&cs->lock, flags); - if (cs->tx_skb) { - skb_queue_tail(&cs->sq, skb); -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - Logl2Frame(cs, skb, "PH_DATA Queued", 0); -#endif - } else { - cs->tx_skb = skb; - cs->tx_cnt = 0; -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - Logl2Frame(cs, skb, "PH_DATA", 0); -#endif - if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - hfcsx_fill_dfifo(cs); - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - } else - debugl1(cs, "hfcsx_fill_dfifo blocked"); - - } - spin_unlock_irqrestore(&cs->lock, flags); - break; - case (PH_PULL | INDICATION): - spin_lock_irqsave(&cs->lock, flags); - if (cs->tx_skb) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, " l2l1 tx_skb exist this shouldn't happen"); - skb_queue_tail(&cs->sq, skb); - spin_unlock_irqrestore(&cs->lock, flags); - break; - } - if (cs->debug & DEB_DLOG_HEX) - LogFrame(cs, skb->data, skb->len); - if (cs->debug & DEB_DLOG_VERBOSE) - dlogframe(cs, skb, 0); - cs->tx_skb = skb; - cs->tx_cnt = 0; -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - Logl2Frame(cs, skb, "PH_DATA_PULLED", 0); -#endif - if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - hfcsx_fill_dfifo(cs); - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - } else - debugl1(cs, "hfcsx_fill_dfifo blocked"); - spin_unlock_irqrestore(&cs->lock, flags); - break; - case (PH_PULL | REQUEST): -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - debugl1(cs, "-> PH_REQUEST_PULL"); -#endif - if (!cs->tx_skb) { - test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); - } else - test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - break; - case (HW_RESET | REQUEST): - spin_lock_irqsave(&cs->lock, flags); - Write_hfc(cs, HFCSX_STATES, HFCSX_LOAD_STATE | 3); /* HFC ST 3 */ - udelay(6); - Write_hfc(cs, HFCSX_STATES, 3); /* HFC ST 2 */ - cs->hw.hfcsx.mst_m |= HFCSX_MASTER; - Write_hfc(cs, HFCSX_MST_MODE, cs->hw.hfcsx.mst_m); - Write_hfc(cs, HFCSX_STATES, HFCSX_ACTIVATE | HFCSX_DO_ACTION); - spin_unlock_irqrestore(&cs->lock, flags); - l1_msg(cs, HW_POWERUP | CONFIRM, NULL); - break; - case (HW_ENABLE | REQUEST): - spin_lock_irqsave(&cs->lock, flags); - Write_hfc(cs, HFCSX_STATES, HFCSX_ACTIVATE | HFCSX_DO_ACTION); - spin_unlock_irqrestore(&cs->lock, flags); - break; - case (HW_DEACTIVATE | REQUEST): - spin_lock_irqsave(&cs->lock, flags); - cs->hw.hfcsx.mst_m &= ~HFCSX_MASTER; - Write_hfc(cs, HFCSX_MST_MODE, cs->hw.hfcsx.mst_m); - spin_unlock_irqrestore(&cs->lock, flags); - break; - case (HW_INFO3 | REQUEST): - spin_lock_irqsave(&cs->lock, flags); - cs->hw.hfcsx.mst_m |= HFCSX_MASTER; - Write_hfc(cs, HFCSX_MST_MODE, cs->hw.hfcsx.mst_m); - spin_unlock_irqrestore(&cs->lock, flags); - break; - case (HW_TESTLOOP | REQUEST): - spin_lock_irqsave(&cs->lock, flags); - switch ((long) arg) { - case (1): - Write_hfc(cs, HFCSX_B1_SSL, 0x80); /* tx slot */ - Write_hfc(cs, HFCSX_B1_RSL, 0x80); /* rx slot */ - cs->hw.hfcsx.conn = (cs->hw.hfcsx.conn & ~7) | 1; - Write_hfc(cs, HFCSX_CONNECT, cs->hw.hfcsx.conn); - break; - case (2): - Write_hfc(cs, HFCSX_B2_SSL, 0x81); /* tx slot */ - Write_hfc(cs, HFCSX_B2_RSL, 0x81); /* rx slot */ - cs->hw.hfcsx.conn = (cs->hw.hfcsx.conn & ~0x38) | 0x08; - Write_hfc(cs, HFCSX_CONNECT, cs->hw.hfcsx.conn); - break; - default: - spin_unlock_irqrestore(&cs->lock, flags); - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "hfcsx_l1hw loop invalid %4lx", (unsigned long)arg); - return; - } - cs->hw.hfcsx.trm |= 0x80; /* enable IOM-loop */ - Write_hfc(cs, HFCSX_TRM, cs->hw.hfcsx.trm); - spin_unlock_irqrestore(&cs->lock, flags); - break; - default: - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "hfcsx_l1hw unknown pr %4x", pr); - break; - } -} - -/***********************************************/ -/* called during init setting l1 stack pointer */ -/***********************************************/ -static void -setstack_hfcsx(struct PStack *st, struct IsdnCardState *cs) -{ - st->l1.l1hw = HFCSX_l1hw; -} - -/**************************************/ -/* send B-channel data if not blocked */ -/**************************************/ -static void -hfcsx_send_data(struct BCState *bcs) -{ - struct IsdnCardState *cs = bcs->cs; - - if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - hfcsx_fill_fifo(bcs); - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - } else - debugl1(cs, "send_data %d blocked", bcs->channel); -} - -/***************************************************************/ -/* activate/deactivate hardware for selected channels and mode */ -/***************************************************************/ -static void -mode_hfcsx(struct BCState *bcs, int mode, int bc) -{ - struct IsdnCardState *cs = bcs->cs; - int fifo2; - - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "HFCSX bchannel mode %d bchan %d/%d", - mode, bc, bcs->channel); - bcs->mode = mode; - bcs->channel = bc; - fifo2 = bc; - if (cs->chanlimit > 1) { - cs->hw.hfcsx.bswapped = 0; /* B1 and B2 normal mode */ - cs->hw.hfcsx.sctrl_e &= ~0x80; - } else { - if (bc) { - if (mode != L1_MODE_NULL) { - cs->hw.hfcsx.bswapped = 1; /* B1 and B2 exchanged */ - cs->hw.hfcsx.sctrl_e |= 0x80; - } else { - cs->hw.hfcsx.bswapped = 0; /* B1 and B2 normal mode */ - cs->hw.hfcsx.sctrl_e &= ~0x80; - } - fifo2 = 0; - } else { - cs->hw.hfcsx.bswapped = 0; /* B1 and B2 normal mode */ - cs->hw.hfcsx.sctrl_e &= ~0x80; - } - } - switch (mode) { - case (L1_MODE_NULL): - if (bc) { - cs->hw.hfcsx.sctrl &= ~SCTRL_B2_ENA; - cs->hw.hfcsx.sctrl_r &= ~SCTRL_B2_ENA; - } else { - cs->hw.hfcsx.sctrl &= ~SCTRL_B1_ENA; - cs->hw.hfcsx.sctrl_r &= ~SCTRL_B1_ENA; - } - if (fifo2) { - cs->hw.hfcsx.int_m1 &= ~(HFCSX_INTS_B2TRANS + HFCSX_INTS_B2REC); - } else { - cs->hw.hfcsx.int_m1 &= ~(HFCSX_INTS_B1TRANS + HFCSX_INTS_B1REC); - } - break; - case (L1_MODE_TRANS): - if (bc) { - cs->hw.hfcsx.sctrl |= SCTRL_B2_ENA; - cs->hw.hfcsx.sctrl_r |= SCTRL_B2_ENA; - } else { - cs->hw.hfcsx.sctrl |= SCTRL_B1_ENA; - cs->hw.hfcsx.sctrl_r |= SCTRL_B1_ENA; - } - if (fifo2) { - cs->hw.hfcsx.int_m1 |= (HFCSX_INTS_B2TRANS + HFCSX_INTS_B2REC); - cs->hw.hfcsx.ctmt |= 2; - cs->hw.hfcsx.conn &= ~0x18; - } else { - cs->hw.hfcsx.int_m1 |= (HFCSX_INTS_B1TRANS + HFCSX_INTS_B1REC); - cs->hw.hfcsx.ctmt |= 1; - cs->hw.hfcsx.conn &= ~0x03; - } - break; - case (L1_MODE_HDLC): - if (bc) { - cs->hw.hfcsx.sctrl |= SCTRL_B2_ENA; - cs->hw.hfcsx.sctrl_r |= SCTRL_B2_ENA; - } else { - cs->hw.hfcsx.sctrl |= SCTRL_B1_ENA; - cs->hw.hfcsx.sctrl_r |= SCTRL_B1_ENA; - } - if (fifo2) { - cs->hw.hfcsx.int_m1 |= (HFCSX_INTS_B2TRANS + HFCSX_INTS_B2REC); - cs->hw.hfcsx.ctmt &= ~2; - cs->hw.hfcsx.conn &= ~0x18; - } else { - cs->hw.hfcsx.int_m1 |= (HFCSX_INTS_B1TRANS + HFCSX_INTS_B1REC); - cs->hw.hfcsx.ctmt &= ~1; - cs->hw.hfcsx.conn &= ~0x03; - } - break; - case (L1_MODE_EXTRN): - if (bc) { - cs->hw.hfcsx.conn |= 0x10; - cs->hw.hfcsx.sctrl |= SCTRL_B2_ENA; - cs->hw.hfcsx.sctrl_r |= SCTRL_B2_ENA; - cs->hw.hfcsx.int_m1 &= ~(HFCSX_INTS_B2TRANS + HFCSX_INTS_B2REC); - } else { - cs->hw.hfcsx.conn |= 0x02; - cs->hw.hfcsx.sctrl |= SCTRL_B1_ENA; - cs->hw.hfcsx.sctrl_r |= SCTRL_B1_ENA; - cs->hw.hfcsx.int_m1 &= ~(HFCSX_INTS_B1TRANS + HFCSX_INTS_B1REC); - } - break; - } - Write_hfc(cs, HFCSX_SCTRL_E, cs->hw.hfcsx.sctrl_e); - Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1); - Write_hfc(cs, HFCSX_SCTRL, cs->hw.hfcsx.sctrl); - Write_hfc(cs, HFCSX_SCTRL_R, cs->hw.hfcsx.sctrl_r); - Write_hfc(cs, HFCSX_CTMT, cs->hw.hfcsx.ctmt); - Write_hfc(cs, HFCSX_CONNECT, cs->hw.hfcsx.conn); - if (mode != L1_MODE_EXTRN) { - reset_fifo(cs, fifo2 ? HFCSX_SEL_B2_RX : HFCSX_SEL_B1_RX); - reset_fifo(cs, fifo2 ? HFCSX_SEL_B2_TX : HFCSX_SEL_B1_TX); - } -} - -/******************************/ -/* Layer2 -> Layer 1 Transfer */ -/******************************/ -static void -hfcsx_l2l1(struct PStack *st, int pr, void *arg) -{ - struct BCState *bcs = st->l1.bcs; - struct sk_buff *skb = arg; - u_long flags; - - switch (pr) { - case (PH_DATA | REQUEST): - spin_lock_irqsave(&bcs->cs->lock, flags); - if (bcs->tx_skb) { - skb_queue_tail(&bcs->squeue, skb); - } else { - bcs->tx_skb = skb; -// test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); - bcs->cs->BC_Send_Data(bcs); - } - spin_unlock_irqrestore(&bcs->cs->lock, flags); - break; - case (PH_PULL | INDICATION): - spin_lock_irqsave(&bcs->cs->lock, flags); - if (bcs->tx_skb) { - printk(KERN_WARNING "%s: this shouldn't happen\n", - __func__); - } else { -// test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); - bcs->tx_skb = skb; - bcs->cs->BC_Send_Data(bcs); - } - spin_unlock_irqrestore(&bcs->cs->lock, flags); - break; - case (PH_PULL | REQUEST): - if (!bcs->tx_skb) { - test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); - } else - test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - break; - case (PH_ACTIVATE | REQUEST): - spin_lock_irqsave(&bcs->cs->lock, flags); - test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag); - mode_hfcsx(bcs, st->l1.mode, st->l1.bc); - spin_unlock_irqrestore(&bcs->cs->lock, flags); - l1_msg_b(st, pr, arg); - break; - case (PH_DEACTIVATE | REQUEST): - l1_msg_b(st, pr, arg); - break; - case (PH_DEACTIVATE | CONFIRM): - spin_lock_irqsave(&bcs->cs->lock, flags); - test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag); - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - mode_hfcsx(bcs, 0, st->l1.bc); - spin_unlock_irqrestore(&bcs->cs->lock, flags); - st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL); - break; - } -} - -/******************************************/ -/* deactivate B-channel access and queues */ -/******************************************/ -static void -close_hfcsx(struct BCState *bcs) -{ - mode_hfcsx(bcs, 0, bcs->channel); - if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) { - skb_queue_purge(&bcs->rqueue); - skb_queue_purge(&bcs->squeue); - if (bcs->tx_skb) { - dev_kfree_skb_any(bcs->tx_skb); - bcs->tx_skb = NULL; - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - } - } -} - -/*************************************/ -/* init B-channel queues and control */ -/*************************************/ -static int -open_hfcsxstate(struct IsdnCardState *cs, struct BCState *bcs) -{ - if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { - skb_queue_head_init(&bcs->rqueue); - skb_queue_head_init(&bcs->squeue); - } - bcs->tx_skb = NULL; - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - bcs->event = 0; - bcs->tx_cnt = 0; - return (0); -} - -/*********************************/ -/* inits the stack for B-channel */ -/*********************************/ -static int -setstack_2b(struct PStack *st, struct BCState *bcs) -{ - bcs->channel = st->l1.bc; - if (open_hfcsxstate(st->l1.hardware, bcs)) - return (-1); - st->l1.bcs = bcs; - st->l2.l2l1 = hfcsx_l2l1; - setstack_manager(st); - bcs->st = st; - setstack_l1_B(st); - return (0); -} - -/***************************/ -/* handle L1 state changes */ -/***************************/ -static void -hfcsx_bh(struct work_struct *work) -{ - struct IsdnCardState *cs = - container_of(work, struct IsdnCardState, tqueue); - u_long flags; - - if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) { - if (!cs->hw.hfcsx.nt_mode) - switch (cs->dc.hfcsx.ph_state) { - case (0): - l1_msg(cs, HW_RESET | INDICATION, NULL); - break; - case (3): - l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL); - break; - case (8): - l1_msg(cs, HW_RSYNC | INDICATION, NULL); - break; - case (6): - l1_msg(cs, HW_INFO2 | INDICATION, NULL); - break; - case (7): - l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL); - break; - default: - break; - } else { - switch (cs->dc.hfcsx.ph_state) { - case (2): - spin_lock_irqsave(&cs->lock, flags); - if (cs->hw.hfcsx.nt_timer < 0) { - cs->hw.hfcsx.nt_timer = 0; - cs->hw.hfcsx.int_m1 &= ~HFCSX_INTS_TIMER; - Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1); - /* Clear already pending ints */ - Read_hfc(cs, HFCSX_INT_S1); - - Write_hfc(cs, HFCSX_STATES, 4 | HFCSX_LOAD_STATE); - udelay(10); - Write_hfc(cs, HFCSX_STATES, 4); - cs->dc.hfcsx.ph_state = 4; - } else { - cs->hw.hfcsx.int_m1 |= HFCSX_INTS_TIMER; - Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1); - cs->hw.hfcsx.ctmt &= ~HFCSX_AUTO_TIMER; - cs->hw.hfcsx.ctmt |= HFCSX_TIM3_125; - Write_hfc(cs, HFCSX_CTMT, cs->hw.hfcsx.ctmt | HFCSX_CLTIMER); - Write_hfc(cs, HFCSX_CTMT, cs->hw.hfcsx.ctmt | HFCSX_CLTIMER); - cs->hw.hfcsx.nt_timer = NT_T1_COUNT; - Write_hfc(cs, HFCSX_STATES, 2 | HFCSX_NT_G2_G3); /* allow G2 -> G3 transition */ - } - spin_unlock_irqrestore(&cs->lock, flags); - break; - case (1): - case (3): - case (4): - spin_lock_irqsave(&cs->lock, flags); - cs->hw.hfcsx.nt_timer = 0; - cs->hw.hfcsx.int_m1 &= ~HFCSX_INTS_TIMER; - Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1); - spin_unlock_irqrestore(&cs->lock, flags); - break; - default: - break; - } - } - } - if (test_and_clear_bit(D_RCVBUFREADY, &cs->event)) - DChannel_proc_rcv(cs); - if (test_and_clear_bit(D_XMTBUFREADY, &cs->event)) - DChannel_proc_xmt(cs); -} - - -/********************************/ -/* called for card init message */ -/********************************/ -static void inithfcsx(struct IsdnCardState *cs) -{ - cs->setstack_d = setstack_hfcsx; - cs->BC_Send_Data = &hfcsx_send_data; - cs->bcs[0].BC_SetStack = setstack_2b; - cs->bcs[1].BC_SetStack = setstack_2b; - cs->bcs[0].BC_Close = close_hfcsx; - cs->bcs[1].BC_Close = close_hfcsx; - mode_hfcsx(cs->bcs, 0, 0); - mode_hfcsx(cs->bcs + 1, 0, 1); -} - - - -/*******************************************/ -/* handle card messages from control layer */ -/*******************************************/ -static int -hfcsx_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - u_long flags; - - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "HFCSX: card_msg %x", mt); - switch (mt) { - case CARD_RESET: - spin_lock_irqsave(&cs->lock, flags); - reset_hfcsx(cs); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_RELEASE: - release_io_hfcsx(cs); - return (0); - case CARD_INIT: - spin_lock_irqsave(&cs->lock, flags); - inithfcsx(cs); - spin_unlock_irqrestore(&cs->lock, flags); - msleep(80); /* Timeout 80ms */ - /* now switch timer interrupt off */ - spin_lock_irqsave(&cs->lock, flags); - cs->hw.hfcsx.int_m1 &= ~HFCSX_INTS_TIMER; - Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1); - /* reinit mode reg */ - Write_hfc(cs, HFCSX_MST_MODE, cs->hw.hfcsx.mst_m); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_TEST: - return (0); - } - return (0); -} - -#ifdef __ISAPNP__ -static struct isapnp_device_id hfc_ids[] = { - { ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x2620), - ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x2620), - (unsigned long) "Teles 16.3c2" }, - { 0, } -}; - -static struct isapnp_device_id *ipid = &hfc_ids[0]; -static struct pnp_card *pnp_c = NULL; -#endif - -int setup_hfcsx(struct IsdnCard *card) -{ - struct IsdnCardState *cs = card->cs; - char tmp[64]; - - strcpy(tmp, hfcsx_revision); - printk(KERN_INFO "HiSax: HFC-SX driver Rev. %s\n", HiSax_getrev(tmp)); -#ifdef __ISAPNP__ - if (!card->para[1] && isapnp_present()) { - struct pnp_dev *pnp_d; - while (ipid->card_vendor) { - if ((pnp_c = pnp_find_card(ipid->card_vendor, - ipid->card_device, pnp_c))) { - pnp_d = NULL; - if ((pnp_d = pnp_find_dev(pnp_c, - ipid->vendor, ipid->function, pnp_d))) { - int err; - - printk(KERN_INFO "HiSax: %s detected\n", - (char *)ipid->driver_data); - pnp_disable_dev(pnp_d); - err = pnp_activate_dev(pnp_d); - if (err < 0) { - printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n", - __func__, err); - return (0); - } - card->para[1] = pnp_port_start(pnp_d, 0); - card->para[0] = pnp_irq(pnp_d, 0); - if (card->para[0] == -1 || !card->para[1]) { - printk(KERN_ERR "HFC PnP:some resources are missing %ld/%lx\n", - card->para[0], card->para[1]); - pnp_disable_dev(pnp_d); - return (0); - } - break; - } else { - printk(KERN_ERR "HFC PnP: PnP error card found, no device\n"); - } - } - ipid++; - pnp_c = NULL; - } - if (!ipid->card_vendor) { - printk(KERN_INFO "HFC PnP: no ISAPnP card found\n"); - return (0); - } - } -#endif - cs->hw.hfcsx.base = card->para[1] & 0xfffe; - cs->irq = card->para[0]; - cs->hw.hfcsx.int_s1 = 0; - cs->dc.hfcsx.ph_state = 0; - cs->hw.hfcsx.fifo = 255; - if ((cs->typ == ISDN_CTYPE_HFC_SX) || - (cs->typ == ISDN_CTYPE_HFC_SP_PCMCIA)) { - if ((!cs->hw.hfcsx.base) || !request_region(cs->hw.hfcsx.base, 2, "HFCSX isdn")) { - printk(KERN_WARNING - "HiSax: HFC-SX io-base %#lx already in use\n", - cs->hw.hfcsx.base); - return (0); - } - byteout(cs->hw.hfcsx.base, cs->hw.hfcsx.base & 0xFF); - byteout(cs->hw.hfcsx.base + 1, - ((cs->hw.hfcsx.base >> 8) & 3) | 0x54); - udelay(10); - cs->hw.hfcsx.chip = Read_hfc(cs, HFCSX_CHIP_ID); - switch (cs->hw.hfcsx.chip >> 4) { - case 1: - tmp[0] = '+'; - break; - case 9: - tmp[0] = 'P'; - break; - default: - printk(KERN_WARNING - "HFC-SX: invalid chip id 0x%x\n", - cs->hw.hfcsx.chip >> 4); - release_region(cs->hw.hfcsx.base, 2); - return (0); - } - if (!ccd_sp_irqtab[cs->irq & 0xF]) { - printk(KERN_WARNING - "HFC_SX: invalid irq %d specified\n", cs->irq & 0xF); - release_region(cs->hw.hfcsx.base, 2); - return (0); - } - if (!(cs->hw.hfcsx.extra = - kmalloc(sizeof(struct hfcsx_extra), GFP_ATOMIC))) { - release_region(cs->hw.hfcsx.base, 2); - printk(KERN_WARNING "HFC-SX: unable to allocate memory\n"); - return (0); - } - printk(KERN_INFO "HFC-S%c chip detected at base 0x%x IRQ %d HZ %d\n", - tmp[0], (u_int) cs->hw.hfcsx.base, cs->irq, HZ); - cs->hw.hfcsx.int_m2 = 0; /* disable alle interrupts */ - cs->hw.hfcsx.int_m1 = 0; - Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1); - Write_hfc(cs, HFCSX_INT_M2, cs->hw.hfcsx.int_m2); - } else - return (0); /* no valid card type */ - - timer_setup(&cs->dbusytimer, hfcsx_dbusy_timer, 0); - INIT_WORK(&cs->tqueue, hfcsx_bh); - cs->readisac = NULL; - cs->writeisac = NULL; - cs->readisacfifo = NULL; - cs->writeisacfifo = NULL; - cs->BC_Read_Reg = NULL; - cs->BC_Write_Reg = NULL; - cs->irq_func = &hfcsx_interrupt; - - cs->hw.hfcsx.b_fifo_size = 0; /* fifo size still unknown */ - cs->hw.hfcsx.cirm = ccd_sp_irqtab[cs->irq & 0xF]; /* RAM not evaluated */ - timer_setup(&cs->hw.hfcsx.timer, hfcsx_Timer, 0); - - reset_hfcsx(cs); - cs->cardmsg = &hfcsx_card_msg; - cs->auxcmd = &hfcsx_auxcmd; - return (1); -} diff --git a/drivers/isdn/hisax/hfc_sx.h b/drivers/isdn/hisax/hfc_sx.h deleted file mode 100644 index eee85dbb0883..000000000000 --- a/drivers/isdn/hisax/hfc_sx.h +++ /dev/null @@ -1,196 +0,0 @@ -/* $Id: hfc_sx.h,v 1.2.6.1 2001/09/23 22:24:48 kai Exp $ - * - * specific defines for CCD's HFC 2BDS0 S+,SP chips - * - * Author Werner Cornelius - * based on existing driver for CCD HFC PCI cards - * Copyright by Werner Cornelius <werner@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -/*********************************************/ -/* thresholds for transparent B-channel mode */ -/* change mask and threshold simultaneously */ -/*********************************************/ -#define HFCSX_BTRANS_THRESHOLD 128 -#define HFCSX_BTRANS_THRESMASK 0x00 - -/* GCI/IOM bus monitor registers */ - -#define HFCSX_C_I 0x02 -#define HFCSX_TRxR 0x03 -#define HFCSX_MON1_D 0x0A -#define HFCSX_MON2_D 0x0B - - -/* GCI/IOM bus timeslot registers */ - -#define HFCSX_B1_SSL 0x20 -#define HFCSX_B2_SSL 0x21 -#define HFCSX_AUX1_SSL 0x22 -#define HFCSX_AUX2_SSL 0x23 -#define HFCSX_B1_RSL 0x24 -#define HFCSX_B2_RSL 0x25 -#define HFCSX_AUX1_RSL 0x26 -#define HFCSX_AUX2_RSL 0x27 - -/* GCI/IOM bus data registers */ - -#define HFCSX_B1_D 0x28 -#define HFCSX_B2_D 0x29 -#define HFCSX_AUX1_D 0x2A -#define HFCSX_AUX2_D 0x2B - -/* GCI/IOM bus configuration registers */ - -#define HFCSX_MST_EMOD 0x2D -#define HFCSX_MST_MODE 0x2E -#define HFCSX_CONNECT 0x2F - - -/* Interrupt and status registers */ - -#define HFCSX_TRM 0x12 -#define HFCSX_B_MODE 0x13 -#define HFCSX_CHIP_ID 0x16 -#define HFCSX_CIRM 0x18 -#define HFCSX_CTMT 0x19 -#define HFCSX_INT_M1 0x1A -#define HFCSX_INT_M2 0x1B -#define HFCSX_INT_S1 0x1E -#define HFCSX_INT_S2 0x1F -#define HFCSX_STATUS 0x1C - -/* S/T section registers */ - -#define HFCSX_STATES 0x30 -#define HFCSX_SCTRL 0x31 -#define HFCSX_SCTRL_E 0x32 -#define HFCSX_SCTRL_R 0x33 -#define HFCSX_SQ 0x34 -#define HFCSX_CLKDEL 0x37 -#define HFCSX_B1_REC 0x3C -#define HFCSX_B1_SEND 0x3C -#define HFCSX_B2_REC 0x3D -#define HFCSX_B2_SEND 0x3D -#define HFCSX_D_REC 0x3E -#define HFCSX_D_SEND 0x3E -#define HFCSX_E_REC 0x3F - -/****************/ -/* FIFO section */ -/****************/ -#define HFCSX_FIF_SEL 0x10 -#define HFCSX_FIF_Z1L 0x80 -#define HFCSX_FIF_Z1H 0x84 -#define HFCSX_FIF_Z2L 0x88 -#define HFCSX_FIF_Z2H 0x8C -#define HFCSX_FIF_INCF1 0xA8 -#define HFCSX_FIF_DWR 0xAC -#define HFCSX_FIF_F1 0xB0 -#define HFCSX_FIF_F2 0xB4 -#define HFCSX_FIF_INCF2 0xB8 -#define HFCSX_FIF_DRD 0xBC - -/* bits in status register (READ) */ -#define HFCSX_SX_PROC 0x02 -#define HFCSX_NBUSY 0x04 -#define HFCSX_TIMER_ELAP 0x10 -#define HFCSX_STATINT 0x20 -#define HFCSX_FRAMEINT 0x40 -#define HFCSX_ANYINT 0x80 - -/* bits in CTMT (Write) */ -#define HFCSX_CLTIMER 0x80 -#define HFCSX_TIM3_125 0x04 -#define HFCSX_TIM25 0x10 -#define HFCSX_TIM50 0x14 -#define HFCSX_TIM400 0x18 -#define HFCSX_TIM800 0x1C -#define HFCSX_AUTO_TIMER 0x20 -#define HFCSX_TRANSB2 0x02 -#define HFCSX_TRANSB1 0x01 - -/* bits in CIRM (Write) */ -#define HFCSX_IRQ_SELMSK 0x07 -#define HFCSX_IRQ_SELDIS 0x00 -#define HFCSX_RESET 0x08 -#define HFCSX_FIFO_RESET 0x80 - - -/* bits in INT_M1 and INT_S1 */ -#define HFCSX_INTS_B1TRANS 0x01 -#define HFCSX_INTS_B2TRANS 0x02 -#define HFCSX_INTS_DTRANS 0x04 -#define HFCSX_INTS_B1REC 0x08 -#define HFCSX_INTS_B2REC 0x10 -#define HFCSX_INTS_DREC 0x20 -#define HFCSX_INTS_L1STATE 0x40 -#define HFCSX_INTS_TIMER 0x80 - -/* bits in INT_M2 */ -#define HFCSX_PROC_TRANS 0x01 -#define HFCSX_GCI_I_CHG 0x02 -#define HFCSX_GCI_MON_REC 0x04 -#define HFCSX_IRQ_ENABLE 0x08 - -/* bits in STATES */ -#define HFCSX_STATE_MSK 0x0F -#define HFCSX_LOAD_STATE 0x10 -#define HFCSX_ACTIVATE 0x20 -#define HFCSX_DO_ACTION 0x40 -#define HFCSX_NT_G2_G3 0x80 - -/* bits in HFCD_MST_MODE */ -#define HFCSX_MASTER 0x01 -#define HFCSX_SLAVE 0x00 -/* remaining bits are for codecs control */ - -/* bits in HFCD_SCTRL */ -#define SCTRL_B1_ENA 0x01 -#define SCTRL_B2_ENA 0x02 -#define SCTRL_MODE_TE 0x00 -#define SCTRL_MODE_NT 0x04 -#define SCTRL_LOW_PRIO 0x08 -#define SCTRL_SQ_ENA 0x10 -#define SCTRL_TEST 0x20 -#define SCTRL_NONE_CAP 0x40 -#define SCTRL_PWR_DOWN 0x80 - -/* bits in SCTRL_E */ -#define HFCSX_AUTO_AWAKE 0x01 -#define HFCSX_DBIT_1 0x04 -#define HFCSX_IGNORE_COL 0x08 -#define HFCSX_CHG_B1_B2 0x80 - -/**********************************/ -/* definitions for FIFO selection */ -/**********************************/ -#define HFCSX_SEL_D_RX 5 -#define HFCSX_SEL_D_TX 4 -#define HFCSX_SEL_B1_RX 1 -#define HFCSX_SEL_B1_TX 0 -#define HFCSX_SEL_B2_RX 3 -#define HFCSX_SEL_B2_TX 2 - -#define MAX_D_FRAMES 15 -#define MAX_B_FRAMES 31 -#define B_SUB_VAL_32K 0x0200 -#define B_FIFO_SIZE_32K (0x2000 - B_SUB_VAL_32K) -#define B_SUB_VAL_8K 0x1A00 -#define B_FIFO_SIZE_8K (0x2000 - B_SUB_VAL_8K) -#define D_FIFO_SIZE 512 -#define D_FREG_MASK 0xF - -/************************************************************/ -/* structure holding additional dynamic data -> send marker */ -/************************************************************/ -struct hfcsx_extra { - unsigned short marker[2 * (MAX_B_FRAMES + 1) + (MAX_D_FRAMES + 1)]; -}; - -extern void main_irq_hfcsx(struct BCState *bcs); -extern void releasehfcsx(struct IsdnCardState *cs); diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c deleted file mode 100644 index 1d4cd01d4685..000000000000 --- a/drivers/isdn/hisax/hfc_usb.c +++ /dev/null @@ -1,1608 +0,0 @@ -/* - * hfc_usb.c - * - * $Id: hfc_usb.c,v 2.3.2.24 2007/10/14 08:40:29 mbachem Exp $ - * - * modular HiSax ISDN driver for Colognechip HFC-S USB chip - * - * Authors : Peter Sprenger (sprenger@moving-bytes.de) - * Martin Bachem (m.bachem@gmx.de, info@colognechip.com) - * - * based on the first hfc_usb driver of - * Werner Cornelius (werner@isdn-development.de) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * See Version Histroy at the bottom of this file - * - */ - -#include <linux/types.h> -#include <linux/stddef.h> -#include <linux/timer.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/kernel_stat.h> -#include <linux/usb.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/moduleparam.h> -#include <linux/slab.h> -#include "hisax.h" -#include "hisax_if.h" -#include "hfc_usb.h" - -static const char *hfcusb_revision = - "$Revision: 2.3.2.24 $ $Date: 2007/10/14 08:40:29 $ "; - -/* Hisax debug support - * debug flags defined in hfc_usb.h as HFCUSB_DBG_[*] - */ -#define __debug_variable hfc_debug -#include "hisax_debug.h" -static u_int debug; -module_param(debug, uint, 0); -static int hfc_debug; - - -/* private vendor specific data */ -typedef struct { - __u8 led_scheme; // led display scheme - signed short led_bits[8]; // array of 8 possible LED bitmask settings - char *vend_name; // device name -} hfcsusb_vdata; - -/* VID/PID device list */ -static const struct usb_device_id hfcusb_idtab[] = { - { - USB_DEVICE(0x0959, 0x2bd0), - .driver_info = (unsigned long) &((hfcsusb_vdata) - {LED_OFF, {4, 0, 2, 1}, - "ISDN USB TA (Cologne Chip HFC-S USB based)"}), - }, - { - USB_DEVICE(0x0675, 0x1688), - .driver_info = (unsigned long) &((hfcsusb_vdata) - {LED_SCHEME1, {1, 2, 0, 0}, - "DrayTek miniVigor 128 USB ISDN TA"}), - }, - { - USB_DEVICE(0x07b0, 0x0007), - .driver_info = (unsigned long) &((hfcsusb_vdata) - {LED_SCHEME1, {0x80, -64, -32, -16}, - "Billion tiny USB ISDN TA 128"}), - }, - { - USB_DEVICE(0x0742, 0x2008), - .driver_info = (unsigned long) &((hfcsusb_vdata) - {LED_SCHEME1, {4, 0, 2, 1}, - "Stollmann USB TA"}), - }, - { - USB_DEVICE(0x0742, 0x2009), - .driver_info = (unsigned long) &((hfcsusb_vdata) - {LED_SCHEME1, {4, 0, 2, 1}, - "Aceex USB ISDN TA"}), - }, - { - USB_DEVICE(0x0742, 0x200A), - .driver_info = (unsigned long) &((hfcsusb_vdata) - {LED_SCHEME1, {4, 0, 2, 1}, - "OEM USB ISDN TA"}), - }, - { - USB_DEVICE(0x08e3, 0x0301), - .driver_info = (unsigned long) &((hfcsusb_vdata) - {LED_SCHEME1, {2, 0, 1, 4}, - "Olitec USB RNIS"}), - }, - { - USB_DEVICE(0x07fa, 0x0846), - .driver_info = (unsigned long) &((hfcsusb_vdata) - {LED_SCHEME1, {0x80, -64, -32, -16}, - "Bewan Modem RNIS USB"}), - }, - { - USB_DEVICE(0x07fa, 0x0847), - .driver_info = (unsigned long) &((hfcsusb_vdata) - {LED_SCHEME1, {0x80, -64, -32, -16}, - "Djinn Numeris USB"}), - }, - { - USB_DEVICE(0x07b0, 0x0006), - .driver_info = (unsigned long) &((hfcsusb_vdata) - {LED_SCHEME1, {0x80, -64, -32, -16}, - "Twister ISDN TA"}), - }, - { - USB_DEVICE(0x071d, 0x1005), - .driver_info = (unsigned long) &((hfcsusb_vdata) - {LED_SCHEME1, {0x02, 0, 0x01, 0x04}, - "Eicon DIVA USB 4.0"}), - }, - { } -}; - -/* structure defining input+output fifos (interrupt/bulk mode) */ -struct usb_fifo; /* forward definition */ -typedef struct iso_urb_struct { - struct urb *purb; - __u8 buffer[ISO_BUFFER_SIZE]; /* buffer incoming/outgoing data */ - struct usb_fifo *owner_fifo; /* pointer to owner fifo */ -} iso_urb_struct; - -struct hfcusb_data; /* forward definition */ - -typedef struct usb_fifo { - int fifonum; /* fifo index attached to this structure */ - int active; /* fifo is currently active */ - struct hfcusb_data *hfc; /* pointer to main structure */ - int pipe; /* address of endpoint */ - __u8 usb_packet_maxlen; /* maximum length for usb transfer */ - unsigned int max_size; /* maximum size of receive/send packet */ - __u8 intervall; /* interrupt interval */ - struct sk_buff *skbuff; /* actual used buffer */ - struct urb *urb; /* transfer structure for usb routines */ - __u8 buffer[128]; /* buffer incoming/outgoing data */ - int bit_line; /* how much bits are in the fifo? */ - - volatile __u8 usb_transfer_mode; /* switched between ISO and INT */ - iso_urb_struct iso[2]; /* need two urbs to have one always for pending */ - struct hisax_if *hif; /* hisax interface */ - int delete_flg; /* only delete skbuff once */ - int last_urblen; /* remember length of last packet */ -} usb_fifo; - -/* structure holding all data for one device */ -typedef struct hfcusb_data { - /* HiSax Interface for loadable Layer1 drivers */ - struct hisax_d_if d_if; /* see hisax_if.h */ - struct hisax_b_if b_if[2]; /* see hisax_if.h */ - int protocol; - - struct usb_device *dev; /* our device */ - int if_used; /* used interface number */ - int alt_used; /* used alternate config */ - int ctrl_paksize; /* control pipe packet size */ - int ctrl_in_pipe, /* handles for control pipe */ - ctrl_out_pipe; - int cfg_used; /* configuration index used */ - int vend_idx; /* vendor found */ - int b_mode[2]; /* B-channel mode */ - int l1_activated; /* layer 1 activated */ - int disc_flag; /* TRUE if device was disonnected to avoid some USB actions */ - int packet_size, iso_packet_size; - - /* control pipe background handling */ - ctrl_buft ctrl_buff[HFC_CTRL_BUFSIZE]; /* buffer holding queued data */ - volatile int ctrl_in_idx, ctrl_out_idx, ctrl_cnt; /* input/output pointer + count */ - struct urb *ctrl_urb; /* transfer structure for control channel */ - - struct usb_ctrlrequest ctrl_write; /* buffer for control write request */ - struct usb_ctrlrequest ctrl_read; /* same for read request */ - - __u8 old_led_state, led_state; - - volatile __u8 threshold_mask; /* threshold actually reported */ - volatile __u8 bch_enables; /* or mask for sctrl_r and sctrl register values */ - - usb_fifo fifos[HFCUSB_NUM_FIFOS]; /* structure holding all fifo data */ - - volatile __u8 l1_state; /* actual l1 state */ - struct timer_list t3_timer; /* timer 3 for activation/deactivation */ - struct timer_list t4_timer; /* timer 4 for activation/deactivation */ -} hfcusb_data; - - -static void collect_rx_frame(usb_fifo *fifo, __u8 *data, int len, - int finish); - -static inline const char * -symbolic(struct hfcusb_symbolic_list list[], const int num) -{ - int i; - for (i = 0; list[i].name != NULL; i++) - if (list[i].num == num) - return (list[i].name); - return "<unknown ERROR>"; -} - -static void -ctrl_start_transfer(hfcusb_data *hfc) -{ - if (hfc->ctrl_cnt) { - hfc->ctrl_urb->pipe = hfc->ctrl_out_pipe; - hfc->ctrl_urb->setup_packet = (u_char *)&hfc->ctrl_write; - hfc->ctrl_urb->transfer_buffer = NULL; - hfc->ctrl_urb->transfer_buffer_length = 0; - hfc->ctrl_write.wIndex = - cpu_to_le16(hfc->ctrl_buff[hfc->ctrl_out_idx].hfc_reg); - hfc->ctrl_write.wValue = - cpu_to_le16(hfc->ctrl_buff[hfc->ctrl_out_idx].reg_val); - - usb_submit_urb(hfc->ctrl_urb, GFP_ATOMIC); /* start transfer */ - } -} /* ctrl_start_transfer */ - -static int -queue_control_request(hfcusb_data *hfc, __u8 reg, __u8 val, int action) -{ - ctrl_buft *buf; - - if (hfc->ctrl_cnt >= HFC_CTRL_BUFSIZE) - return (1); /* no space left */ - buf = &hfc->ctrl_buff[hfc->ctrl_in_idx]; /* pointer to new index */ - buf->hfc_reg = reg; - buf->reg_val = val; - buf->action = action; - if (++hfc->ctrl_in_idx >= HFC_CTRL_BUFSIZE) - hfc->ctrl_in_idx = 0; /* pointer wrap */ - if (++hfc->ctrl_cnt == 1) - ctrl_start_transfer(hfc); - return (0); -} - -static void -ctrl_complete(struct urb *urb) -{ - hfcusb_data *hfc = (hfcusb_data *) urb->context; - - urb->dev = hfc->dev; - if (hfc->ctrl_cnt) { - hfc->ctrl_cnt--; /* decrement actual count */ - if (++hfc->ctrl_out_idx >= HFC_CTRL_BUFSIZE) - hfc->ctrl_out_idx = 0; /* pointer wrap */ - - ctrl_start_transfer(hfc); /* start next transfer */ - } -} - -/* write led data to auxport & invert if necessary */ -static void -write_led(hfcusb_data *hfc, __u8 led_state) -{ - if (led_state != hfc->old_led_state) { - hfc->old_led_state = led_state; - queue_control_request(hfc, HFCUSB_P_DATA, led_state, 1); - } -} - -static void -set_led_bit(hfcusb_data *hfc, signed short led_bits, int on) -{ - if (on) { - if (led_bits < 0) - hfc->led_state &= ~abs(led_bits); - else - hfc->led_state |= led_bits; - } else { - if (led_bits < 0) - hfc->led_state |= abs(led_bits); - else - hfc->led_state &= ~led_bits; - } -} - -/* handle LED requests */ -static void -handle_led(hfcusb_data *hfc, int event) -{ - hfcsusb_vdata *driver_info = - (hfcsusb_vdata *) hfcusb_idtab[hfc->vend_idx].driver_info; - - /* if no scheme -> no LED action */ - if (driver_info->led_scheme == LED_OFF) - return; - - switch (event) { - case LED_POWER_ON: - set_led_bit(hfc, driver_info->led_bits[0], 1); - set_led_bit(hfc, driver_info->led_bits[1], 0); - set_led_bit(hfc, driver_info->led_bits[2], 0); - set_led_bit(hfc, driver_info->led_bits[3], 0); - break; - case LED_POWER_OFF: - set_led_bit(hfc, driver_info->led_bits[0], 0); - set_led_bit(hfc, driver_info->led_bits[1], 0); - set_led_bit(hfc, driver_info->led_bits[2], 0); - set_led_bit(hfc, driver_info->led_bits[3], 0); - break; - case LED_S0_ON: - set_led_bit(hfc, driver_info->led_bits[1], 1); - break; - case LED_S0_OFF: - set_led_bit(hfc, driver_info->led_bits[1], 0); - break; - case LED_B1_ON: - set_led_bit(hfc, driver_info->led_bits[2], 1); - break; - case LED_B1_OFF: - set_led_bit(hfc, driver_info->led_bits[2], 0); - break; - case LED_B2_ON: - set_led_bit(hfc, driver_info->led_bits[3], 1); - break; - case LED_B2_OFF: - set_led_bit(hfc, driver_info->led_bits[3], 0); - break; - } - write_led(hfc, hfc->led_state); -} - -/* ISDN l1 timer T3 expires */ -static void -l1_timer_expire_t3(struct timer_list *t) -{ - hfcusb_data *hfc = from_timer(hfc, t, t3_timer); - hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION, - NULL); - - DBG(HFCUSB_DBG_STATES, - "HFC-S USB: PH_DEACTIVATE | INDICATION sent (T3 expire)"); - - hfc->l1_activated = 0; - handle_led(hfc, LED_S0_OFF); - /* deactivate : */ - queue_control_request(hfc, HFCUSB_STATES, 0x10, 1); - queue_control_request(hfc, HFCUSB_STATES, 3, 1); -} - -/* ISDN l1 timer T4 expires */ -static void -l1_timer_expire_t4(struct timer_list *t) -{ - hfcusb_data *hfc = from_timer(hfc, t, t4_timer); - hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION, - NULL); - - DBG(HFCUSB_DBG_STATES, - "HFC-S USB: PH_DEACTIVATE | INDICATION sent (T4 expire)"); - - hfc->l1_activated = 0; - handle_led(hfc, LED_S0_OFF); -} - -/* S0 state changed */ -static void -s0_state_handler(hfcusb_data *hfc, __u8 state) -{ - __u8 old_state; - - old_state = hfc->l1_state; - if (state == old_state || state < 1 || state > 8) - return; - - DBG(HFCUSB_DBG_STATES, "HFC-S USB: S0 statechange(%d -> %d)", - old_state, state); - - if (state < 4 || state == 7 || state == 8) { - if (timer_pending(&hfc->t3_timer)) - del_timer(&hfc->t3_timer); - DBG(HFCUSB_DBG_STATES, "HFC-S USB: T3 deactivated"); - } - if (state >= 7) { - if (timer_pending(&hfc->t4_timer)) - del_timer(&hfc->t4_timer); - DBG(HFCUSB_DBG_STATES, "HFC-S USB: T4 deactivated"); - } - - if (state == 7 && !hfc->l1_activated) { - hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, - PH_ACTIVATE | INDICATION, NULL); - DBG(HFCUSB_DBG_STATES, "HFC-S USB: PH_ACTIVATE | INDICATION sent"); - hfc->l1_activated = 1; - handle_led(hfc, LED_S0_ON); - } else if (state <= 3 /* && activated */) { - if (old_state == 7 || old_state == 8) { - DBG(HFCUSB_DBG_STATES, "HFC-S USB: T4 activated"); - if (!timer_pending(&hfc->t4_timer)) { - hfc->t4_timer.expires = - jiffies + (HFC_TIMER_T4 * HZ) / 1000; - add_timer(&hfc->t4_timer); - } - } else { - hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, - PH_DEACTIVATE | INDICATION, - NULL); - DBG(HFCUSB_DBG_STATES, - "HFC-S USB: PH_DEACTIVATE | INDICATION sent"); - hfc->l1_activated = 0; - handle_led(hfc, LED_S0_OFF); - } - } - hfc->l1_state = state; -} - -static void -fill_isoc_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe, - void *buf, int num_packets, int packet_size, int interval, - usb_complete_t complete, void *context) -{ - int k; - - usb_fill_int_urb(urb, dev, pipe, buf, packet_size * num_packets, - complete, context, interval); - - urb->number_of_packets = num_packets; - urb->transfer_flags = URB_ISO_ASAP; - urb->actual_length = 0; - for (k = 0; k < num_packets; k++) { - urb->iso_frame_desc[k].offset = packet_size * k; - urb->iso_frame_desc[k].length = packet_size; - urb->iso_frame_desc[k].actual_length = 0; - } -} - -/* allocs urbs and start isoc transfer with two pending urbs to avoid - * gaps in the transfer chain - */ -static int -start_isoc_chain(usb_fifo *fifo, int num_packets_per_urb, - usb_complete_t complete, int packet_size) -{ - int i, k, errcode; - - DBG(HFCUSB_DBG_INIT, "HFC-S USB: starting ISO-URBs for fifo:%d\n", - fifo->fifonum); - - /* allocate Memory for Iso out Urbs */ - for (i = 0; i < 2; i++) { - if (!(fifo->iso[i].purb)) { - fifo->iso[i].purb = - usb_alloc_urb(num_packets_per_urb, GFP_KERNEL); - if (!(fifo->iso[i].purb)) { - printk(KERN_INFO - "alloc urb for fifo %i failed!!!", - fifo->fifonum); - } - fifo->iso[i].owner_fifo = (struct usb_fifo *) fifo; - - /* Init the first iso */ - if (ISO_BUFFER_SIZE >= - (fifo->usb_packet_maxlen * - num_packets_per_urb)) { - fill_isoc_urb(fifo->iso[i].purb, - fifo->hfc->dev, fifo->pipe, - fifo->iso[i].buffer, - num_packets_per_urb, - fifo->usb_packet_maxlen, - fifo->intervall, complete, - &fifo->iso[i]); - memset(fifo->iso[i].buffer, 0, - sizeof(fifo->iso[i].buffer)); - /* defining packet delimeters in fifo->buffer */ - for (k = 0; k < num_packets_per_urb; k++) { - fifo->iso[i].purb-> - iso_frame_desc[k].offset = - k * packet_size; - fifo->iso[i].purb-> - iso_frame_desc[k].length = - packet_size; - } - } else { - printk(KERN_INFO - "HFC-S USB: ISO Buffer size to small!\n"); - } - } - fifo->bit_line = BITLINE_INF; - - errcode = usb_submit_urb(fifo->iso[i].purb, GFP_KERNEL); - fifo->active = (errcode >= 0) ? 1 : 0; - if (errcode < 0) - printk(KERN_INFO "HFC-S USB: usb_submit_urb URB nr:%d, error(%i): '%s'\n", - i, errcode, symbolic(urb_errlist, errcode)); - } - return (fifo->active); -} - -/* stops running iso chain and frees their pending urbs */ -static void -stop_isoc_chain(usb_fifo *fifo) -{ - int i; - - for (i = 0; i < 2; i++) { - if (fifo->iso[i].purb) { - DBG(HFCUSB_DBG_INIT, - "HFC-S USB: Stopping iso chain for fifo %i.%i", - fifo->fifonum, i); - usb_kill_urb(fifo->iso[i].purb); - usb_free_urb(fifo->iso[i].purb); - fifo->iso[i].purb = NULL; - } - } - - usb_kill_urb(fifo->urb); - usb_free_urb(fifo->urb); - fifo->urb = NULL; - fifo->active = 0; -} - -/* defines how much ISO packets are handled in one URB */ -static int iso_packets[8] = -{ ISOC_PACKETS_B, ISOC_PACKETS_B, ISOC_PACKETS_B, ISOC_PACKETS_B, - ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D -}; - -static void -tx_iso_complete(struct urb *urb) -{ - iso_urb_struct *context_iso_urb = (iso_urb_struct *) urb->context; - usb_fifo *fifo = context_iso_urb->owner_fifo; - hfcusb_data *hfc = fifo->hfc; - int k, tx_offset, num_isoc_packets, sink, len, current_len, - errcode; - int frame_complete, transp_mode, fifon, status; - __u8 threshbit; - - fifon = fifo->fifonum; - status = urb->status; - - tx_offset = 0; - - /* ISO transfer only partially completed, - look at individual frame status for details */ - if (status == -EXDEV) { - DBG(HFCUSB_DBG_VERBOSE_USB, "HFC-S USB: tx_iso_complete with -EXDEV" - ", urb->status %d, fifonum %d\n", - status, fifon); - - for (k = 0; k < iso_packets[fifon]; ++k) { - errcode = urb->iso_frame_desc[k].status; - if (errcode) - DBG(HFCUSB_DBG_VERBOSE_USB, "HFC-S USB: tx_iso_complete " - "packet %i, status: %i\n", - k, errcode); - } - - // clear status, so go on with ISO transfers - status = 0; - } - - if (fifo->active && !status) { - transp_mode = 0; - if (fifon < 4 && hfc->b_mode[fifon / 2] == L1_MODE_TRANS) - transp_mode = 1; - - /* is FifoFull-threshold set for our channel? */ - threshbit = (hfc->threshold_mask & (1 << fifon)); - num_isoc_packets = iso_packets[fifon]; - - /* predict dataflow to avoid fifo overflow */ - if (fifon >= HFCUSB_D_TX) { - sink = (threshbit) ? SINK_DMIN : SINK_DMAX; - } else { - sink = (threshbit) ? SINK_MIN : SINK_MAX; - } - fill_isoc_urb(urb, fifo->hfc->dev, fifo->pipe, - context_iso_urb->buffer, num_isoc_packets, - fifo->usb_packet_maxlen, fifo->intervall, - tx_iso_complete, urb->context); - memset(context_iso_urb->buffer, 0, - sizeof(context_iso_urb->buffer)); - frame_complete = 0; - - /* Generate next ISO Packets */ - for (k = 0; k < num_isoc_packets; ++k) { - if (fifo->skbuff) { - len = fifo->skbuff->len; - /* we lower data margin every msec */ - fifo->bit_line -= sink; - current_len = (0 - fifo->bit_line) / 8; - /* maximum 15 byte for every ISO packet makes our life easier */ - if (current_len > 14) - current_len = 14; - current_len = - (len <= - current_len) ? len : current_len; - /* how much bit do we put on the line? */ - fifo->bit_line += current_len * 8; - - context_iso_urb->buffer[tx_offset] = 0; - if (current_len == len) { - if (!transp_mode) { - /* here frame completion */ - context_iso_urb-> - buffer[tx_offset] = 1; - /* add 2 byte flags and 16bit CRC at end of ISDN frame */ - fifo->bit_line += 32; - } - frame_complete = 1; - } - - memcpy(context_iso_urb->buffer + - tx_offset + 1, fifo->skbuff->data, - current_len); - skb_pull(fifo->skbuff, current_len); - - /* define packet delimeters within the URB buffer */ - urb->iso_frame_desc[k].offset = tx_offset; - urb->iso_frame_desc[k].length = - current_len + 1; - - tx_offset += (current_len + 1); - } else { - urb->iso_frame_desc[k].offset = - tx_offset++; - - urb->iso_frame_desc[k].length = 1; - fifo->bit_line -= sink; /* we lower data margin every msec */ - - if (fifo->bit_line < BITLINE_INF) { - fifo->bit_line = BITLINE_INF; - } - } - - if (frame_complete) { - fifo->delete_flg = 1; - fifo->hif->l1l2(fifo->hif, - PH_DATA | CONFIRM, - (void *) (unsigned long) fifo->skbuff-> - truesize); - if (fifo->skbuff && fifo->delete_flg) { - dev_kfree_skb_any(fifo->skbuff); - fifo->skbuff = NULL; - fifo->delete_flg = 0; - } - frame_complete = 0; - } - } - errcode = usb_submit_urb(urb, GFP_ATOMIC); - if (errcode < 0) { - printk(KERN_INFO - "HFC-S USB: error submitting ISO URB: %d\n", - errcode); - } - } else { - if (status && !hfc->disc_flag) { - printk(KERN_INFO - "HFC-S USB: tx_iso_complete: error(%i): '%s', fifonum=%d\n", - status, symbolic(urb_errlist, status), fifon); - } - } -} - -static void -rx_iso_complete(struct urb *urb) -{ - iso_urb_struct *context_iso_urb = (iso_urb_struct *) urb->context; - usb_fifo *fifo = context_iso_urb->owner_fifo; - hfcusb_data *hfc = fifo->hfc; - int k, len, errcode, offset, num_isoc_packets, fifon, maxlen, - status; - unsigned int iso_status; - __u8 *buf; - static __u8 eof[8]; - - fifon = fifo->fifonum; - status = urb->status; - - if (urb->status == -EOVERFLOW) { - DBG(HFCUSB_DBG_VERBOSE_USB, - "HFC-USB: ignoring USB DATAOVERRUN fifo(%i)", fifon); - status = 0; - } - - /* ISO transfer only partially completed, - look at individual frame status for details */ - if (status == -EXDEV) { - DBG(HFCUSB_DBG_VERBOSE_USB, "HFC-S USB: rx_iso_complete with -EXDEV " - "urb->status %d, fifonum %d\n", - status, fifon); - status = 0; - } - - if (fifo->active && !status) { - num_isoc_packets = iso_packets[fifon]; - maxlen = fifo->usb_packet_maxlen; - for (k = 0; k < num_isoc_packets; ++k) { - len = urb->iso_frame_desc[k].actual_length; - offset = urb->iso_frame_desc[k].offset; - buf = context_iso_urb->buffer + offset; - iso_status = urb->iso_frame_desc[k].status; - - if (iso_status && !hfc->disc_flag) - DBG(HFCUSB_DBG_VERBOSE_USB, - "HFC-S USB: rx_iso_complete " - "ISO packet %i, status: %i\n", - k, iso_status); - - if (fifon == HFCUSB_D_RX) { - DBG(HFCUSB_DBG_VERBOSE_USB, - "HFC-S USB: ISO-D-RX lst_urblen:%2d " - "act_urblen:%2d max-urblen:%2d EOF:0x%0x", - fifo->last_urblen, len, maxlen, - eof[5]); - - DBG_PACKET(HFCUSB_DBG_VERBOSE_USB, buf, len); - } - - if (fifo->last_urblen != maxlen) { - /* the threshold mask is in the 2nd status byte */ - hfc->threshold_mask = buf[1]; - /* care for L1 state only for D-Channel - to avoid overlapped iso completions */ - if (fifon == HFCUSB_D_RX) { - /* the S0 state is in the upper half - of the 1st status byte */ - s0_state_handler(hfc, buf[0] >> 4); - } - eof[fifon] = buf[0] & 1; - if (len > 2) - collect_rx_frame(fifo, buf + 2, - len - 2, - (len < maxlen) ? - eof[fifon] : 0); - } else { - collect_rx_frame(fifo, buf, len, - (len < - maxlen) ? eof[fifon] : - 0); - } - fifo->last_urblen = len; - } - - fill_isoc_urb(urb, fifo->hfc->dev, fifo->pipe, - context_iso_urb->buffer, num_isoc_packets, - fifo->usb_packet_maxlen, fifo->intervall, - rx_iso_complete, urb->context); - errcode = usb_submit_urb(urb, GFP_ATOMIC); - if (errcode < 0) { - printk(KERN_ERR - "HFC-S USB: error submitting ISO URB: %d\n", - errcode); - } - } else { - if (status && !hfc->disc_flag) { - printk(KERN_ERR - "HFC-S USB: rx_iso_complete : " - "urb->status %d, fifonum %d\n", - status, fifon); - } - } -} - -/* collect rx data from INT- and ISO-URBs */ -static void -collect_rx_frame(usb_fifo *fifo, __u8 *data, int len, int finish) -{ - hfcusb_data *hfc = fifo->hfc; - int transp_mode, fifon; - - fifon = fifo->fifonum; - transp_mode = 0; - if (fifon < 4 && hfc->b_mode[fifon / 2] == L1_MODE_TRANS) - transp_mode = 1; - - if (!fifo->skbuff) { - fifo->skbuff = dev_alloc_skb(fifo->max_size + 3); - if (!fifo->skbuff) { - printk(KERN_ERR - "HFC-S USB: cannot allocate buffer for fifo(%d)\n", - fifon); - return; - } - } - if (len) { - if (fifo->skbuff->len + len < fifo->max_size) { - skb_put_data(fifo->skbuff, data, len); - } else { - DBG(HFCUSB_DBG_FIFO_ERR, - "HCF-USB: got frame exceeded fifo->max_size(%d) fifo(%d)", - fifo->max_size, fifon); - DBG_SKB(HFCUSB_DBG_VERBOSE_USB, fifo->skbuff); - skb_trim(fifo->skbuff, 0); - } - } - if (transp_mode && fifo->skbuff->len >= 128) { - fifo->hif->l1l2(fifo->hif, PH_DATA | INDICATION, - fifo->skbuff); - fifo->skbuff = NULL; - return; - } - /* we have a complete hdlc packet */ - if (finish) { - if (fifo->skbuff->len > 3 && - !fifo->skbuff->data[fifo->skbuff->len - 1]) { - - if (fifon == HFCUSB_D_RX) { - DBG(HFCUSB_DBG_DCHANNEL, - "HFC-S USB: D-RX len(%d)", fifo->skbuff->len); - DBG_SKB(HFCUSB_DBG_DCHANNEL, fifo->skbuff); - } - - /* remove CRC & status */ - skb_trim(fifo->skbuff, fifo->skbuff->len - 3); - if (fifon == HFCUSB_PCM_RX) { - fifo->hif->l1l2(fifo->hif, - PH_DATA_E | INDICATION, - fifo->skbuff); - } else - fifo->hif->l1l2(fifo->hif, - PH_DATA | INDICATION, - fifo->skbuff); - fifo->skbuff = NULL; /* buffer was freed from upper layer */ - } else { - DBG(HFCUSB_DBG_FIFO_ERR, - "HFC-S USB: ERROR frame len(%d) fifo(%d)", - fifo->skbuff->len, fifon); - DBG_SKB(HFCUSB_DBG_VERBOSE_USB, fifo->skbuff); - skb_trim(fifo->skbuff, 0); - } - } -} - -static void -rx_int_complete(struct urb *urb) -{ - int len; - int status; - __u8 *buf, maxlen, fifon; - usb_fifo *fifo = (usb_fifo *) urb->context; - hfcusb_data *hfc = fifo->hfc; - static __u8 eof[8]; - - urb->dev = hfc->dev; /* security init */ - - fifon = fifo->fifonum; - if ((!fifo->active) || (urb->status)) { - DBG(HFCUSB_DBG_INIT, "HFC-S USB: RX-Fifo %i is going down (%i)", - fifon, urb->status); - - fifo->urb->interval = 0; /* cancel automatic rescheduling */ - if (fifo->skbuff) { - dev_kfree_skb_any(fifo->skbuff); - fifo->skbuff = NULL; - } - return; - } - len = urb->actual_length; - buf = fifo->buffer; - maxlen = fifo->usb_packet_maxlen; - - if (fifon == HFCUSB_D_RX) { - DBG(HFCUSB_DBG_VERBOSE_USB, - "HFC-S USB: INT-D-RX lst_urblen:%2d " - "act_urblen:%2d max-urblen:%2d EOF:0x%0x", - fifo->last_urblen, len, maxlen, - eof[5]); - DBG_PACKET(HFCUSB_DBG_VERBOSE_USB, buf, len); - } - - if (fifo->last_urblen != fifo->usb_packet_maxlen) { - /* the threshold mask is in the 2nd status byte */ - hfc->threshold_mask = buf[1]; - /* the S0 state is in the upper half of the 1st status byte */ - s0_state_handler(hfc, buf[0] >> 4); - eof[fifon] = buf[0] & 1; - /* if we have more than the 2 status bytes -> collect data */ - if (len > 2) - collect_rx_frame(fifo, buf + 2, - urb->actual_length - 2, - (len < maxlen) ? eof[fifon] : 0); - } else { - collect_rx_frame(fifo, buf, urb->actual_length, - (len < maxlen) ? eof[fifon] : 0); - } - fifo->last_urblen = urb->actual_length; - status = usb_submit_urb(urb, GFP_ATOMIC); - if (status) { - printk(KERN_INFO - "HFC-S USB: %s error resubmitting URB fifo(%d)\n", - __func__, fifon); - } -} - -/* start initial INT-URB for certain fifo */ -static void -start_int_fifo(usb_fifo *fifo) -{ - int errcode; - - DBG(HFCUSB_DBG_INIT, "HFC-S USB: starting RX INT-URB for fifo:%d\n", - fifo->fifonum); - - if (!fifo->urb) { - fifo->urb = usb_alloc_urb(0, GFP_KERNEL); - if (!fifo->urb) - return; - } - usb_fill_int_urb(fifo->urb, fifo->hfc->dev, fifo->pipe, - fifo->buffer, fifo->usb_packet_maxlen, - rx_int_complete, fifo, fifo->intervall); - fifo->active = 1; /* must be marked active */ - errcode = usb_submit_urb(fifo->urb, GFP_KERNEL); - if (errcode) { - printk(KERN_ERR "HFC-S USB: submit URB error(%s): status:%i\n", - __func__, errcode); - fifo->active = 0; - fifo->skbuff = NULL; - } -} - -static void -setup_bchannel(hfcusb_data *hfc, int channel, int mode) -{ - __u8 val, idx_table[2] = { 0, 2 }; - - if (hfc->disc_flag) { - return; - } - DBG(HFCUSB_DBG_STATES, "HFC-S USB: setting channel %d to mode %d", - channel, mode); - hfc->b_mode[channel] = mode; - - /* setup CON_HDLC */ - val = 0; - if (mode != L1_MODE_NULL) - val = 8; /* enable fifo? */ - if (mode == L1_MODE_TRANS) - val |= 2; /* set transparent bit */ - - /* set FIFO to transmit register */ - queue_control_request(hfc, HFCUSB_FIFO, idx_table[channel], 1); - queue_control_request(hfc, HFCUSB_CON_HDLC, val, 1); - /* reset fifo */ - queue_control_request(hfc, HFCUSB_INC_RES_F, 2, 1); - /* set FIFO to receive register */ - queue_control_request(hfc, HFCUSB_FIFO, idx_table[channel] + 1, 1); - queue_control_request(hfc, HFCUSB_CON_HDLC, val, 1); - /* reset fifo */ - queue_control_request(hfc, HFCUSB_INC_RES_F, 2, 1); - - val = 0x40; - if (hfc->b_mode[0]) - val |= 1; - if (hfc->b_mode[1]) - val |= 2; - queue_control_request(hfc, HFCUSB_SCTRL, val, 1); - - val = 0; - if (hfc->b_mode[0]) - val |= 1; - if (hfc->b_mode[1]) - val |= 2; - queue_control_request(hfc, HFCUSB_SCTRL_R, val, 1); - - if (mode == L1_MODE_NULL) { - if (channel) - handle_led(hfc, LED_B2_OFF); - else - handle_led(hfc, LED_B1_OFF); - } else { - if (channel) - handle_led(hfc, LED_B2_ON); - else - handle_led(hfc, LED_B1_ON); - } -} - -static void -hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) -{ - usb_fifo *fifo = my_hisax_if->priv; - hfcusb_data *hfc = fifo->hfc; - - switch (pr) { - case PH_ACTIVATE | REQUEST: - if (fifo->fifonum == HFCUSB_D_TX) { - DBG(HFCUSB_DBG_STATES, - "HFC_USB: hfc_usb_d_l2l1 D-chan: PH_ACTIVATE | REQUEST"); - - if (hfc->l1_state != 3 - && hfc->l1_state != 7) { - hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, - PH_DEACTIVATE | - INDICATION, - NULL); - DBG(HFCUSB_DBG_STATES, - "HFC-S USB: PH_DEACTIVATE | INDICATION sent (not state 3 or 7)"); - } else { - if (hfc->l1_state == 7) { /* l1 already active */ - hfc->d_if.ifc.l1l2(&hfc-> - d_if. - ifc, - PH_ACTIVATE - | - INDICATION, - NULL); - DBG(HFCUSB_DBG_STATES, - "HFC-S USB: PH_ACTIVATE | INDICATION sent again ;)"); - } else { - /* force sending sending INFO1 */ - queue_control_request(hfc, - HFCUSB_STATES, - 0x14, - 1); - mdelay(1); - /* start l1 activation */ - queue_control_request(hfc, - HFCUSB_STATES, - 0x04, - 1); - if (!timer_pending - (&hfc->t3_timer)) { - hfc->t3_timer. - expires = - jiffies + - (HFC_TIMER_T3 * - HZ) / 1000; - add_timer(&hfc-> - t3_timer); - } - } - } - } else { - DBG(HFCUSB_DBG_STATES, - "HFC_USB: hfc_usb_d_l2l1 B-chan: PH_ACTIVATE | REQUEST"); - setup_bchannel(hfc, - (fifo->fifonum == - HFCUSB_B1_TX) ? 0 : 1, - (long) arg); - fifo->hif->l1l2(fifo->hif, - PH_ACTIVATE | INDICATION, - NULL); - } - break; - case PH_DEACTIVATE | REQUEST: - if (fifo->fifonum == HFCUSB_D_TX) { - DBG(HFCUSB_DBG_STATES, - "HFC_USB: hfc_usb_d_l2l1 D-chan: PH_DEACTIVATE | REQUEST"); - } else { - DBG(HFCUSB_DBG_STATES, - "HFC_USB: hfc_usb_d_l2l1 Bx-chan: PH_DEACTIVATE | REQUEST"); - setup_bchannel(hfc, - (fifo->fifonum == - HFCUSB_B1_TX) ? 0 : 1, - (int) L1_MODE_NULL); - fifo->hif->l1l2(fifo->hif, - PH_DEACTIVATE | INDICATION, - NULL); - } - break; - case PH_DATA | REQUEST: - if (fifo->skbuff && fifo->delete_flg) { - dev_kfree_skb_any(fifo->skbuff); - fifo->skbuff = NULL; - fifo->delete_flg = 0; - } - fifo->skbuff = arg; /* we have a new buffer */ - break; - default: - DBG(HFCUSB_DBG_STATES, - "HFC_USB: hfc_usb_d_l2l1: unknown state : %#x", pr); - break; - } -} - -/* initial init HFC-S USB chip registers, HiSax interface, USB URBs */ -static int -hfc_usb_init(hfcusb_data *hfc) -{ - usb_fifo *fifo; - int i; - u_char b; - struct hisax_b_if *p_b_if[2]; - - /* check the chip id */ - if (read_usb(hfc, HFCUSB_CHIP_ID, &b) != 1) { - printk(KERN_INFO "HFC-USB: cannot read chip id\n"); - return (1); - } - if (b != HFCUSB_CHIPID) { - printk(KERN_INFO "HFC-S USB: Invalid chip id 0x%02x\n", b); - return (1); - } - - /* first set the needed config, interface and alternate */ - usb_set_interface(hfc->dev, hfc->if_used, hfc->alt_used); - - /* do Chip reset */ - write_usb(hfc, HFCUSB_CIRM, 8); - /* aux = output, reset off */ - write_usb(hfc, HFCUSB_CIRM, 0x10); - - /* set USB_SIZE to match wMaxPacketSize for INT or BULK transfers */ - write_usb(hfc, HFCUSB_USB_SIZE, - (hfc->packet_size / 8) | ((hfc->packet_size / 8) << 4)); - - /* set USB_SIZE_I to match wMaxPacketSize for ISO transfers */ - write_usb(hfc, HFCUSB_USB_SIZE_I, hfc->iso_packet_size); - - /* enable PCM/GCI master mode */ - write_usb(hfc, HFCUSB_MST_MODE1, 0); /* set default values */ - write_usb(hfc, HFCUSB_MST_MODE0, 1); /* enable master mode */ - - /* init the fifos */ - write_usb(hfc, HFCUSB_F_THRES, - (HFCUSB_TX_THRESHOLD / - 8) | ((HFCUSB_RX_THRESHOLD / 8) << 4)); - - fifo = hfc->fifos; - for (i = 0; i < HFCUSB_NUM_FIFOS; i++) { - write_usb(hfc, HFCUSB_FIFO, i); /* select the desired fifo */ - fifo[i].skbuff = NULL; /* init buffer pointer */ - fifo[i].max_size = - (i <= HFCUSB_B2_RX) ? MAX_BCH_SIZE : MAX_DFRAME_LEN; - fifo[i].last_urblen = 0; - /* set 2 bit for D- & E-channel */ - write_usb(hfc, HFCUSB_HDLC_PAR, - ((i <= HFCUSB_B2_RX) ? 0 : 2)); - /* rx hdlc, enable IFF for D-channel */ - write_usb(hfc, HFCUSB_CON_HDLC, - ((i == HFCUSB_D_TX) ? 0x09 : 0x08)); - write_usb(hfc, HFCUSB_INC_RES_F, 2); /* reset the fifo */ - } - - write_usb(hfc, HFCUSB_CLKDEL, 0x0f); /* clock delay value */ - write_usb(hfc, HFCUSB_STATES, 3 | 0x10); /* set deactivated mode */ - write_usb(hfc, HFCUSB_STATES, 3); /* enable state machine */ - - write_usb(hfc, HFCUSB_SCTRL_R, 0); /* disable both B receivers */ - write_usb(hfc, HFCUSB_SCTRL, 0x40); /* disable B transmitters + capacitive mode */ - - /* set both B-channel to not connected */ - hfc->b_mode[0] = L1_MODE_NULL; - hfc->b_mode[1] = L1_MODE_NULL; - - hfc->l1_activated = 0; - hfc->disc_flag = 0; - hfc->led_state = 0; - hfc->old_led_state = 0; - - /* init the t3 timer */ - timer_setup(&hfc->t3_timer, l1_timer_expire_t3, 0); - - /* init the t4 timer */ - timer_setup(&hfc->t4_timer, l1_timer_expire_t4, 0); - - /* init the background machinery for control requests */ - hfc->ctrl_read.bRequestType = 0xc0; - hfc->ctrl_read.bRequest = 1; - hfc->ctrl_read.wLength = cpu_to_le16(1); - hfc->ctrl_write.bRequestType = 0x40; - hfc->ctrl_write.bRequest = 0; - hfc->ctrl_write.wLength = 0; - usb_fill_control_urb(hfc->ctrl_urb, - hfc->dev, - hfc->ctrl_out_pipe, - (u_char *)&hfc->ctrl_write, - NULL, 0, ctrl_complete, hfc); - /* Init All Fifos */ - for (i = 0; i < HFCUSB_NUM_FIFOS; i++) { - hfc->fifos[i].iso[0].purb = NULL; - hfc->fifos[i].iso[1].purb = NULL; - hfc->fifos[i].active = 0; - } - /* register Modul to upper Hisax Layers */ - hfc->d_if.owner = THIS_MODULE; - hfc->d_if.ifc.priv = &hfc->fifos[HFCUSB_D_TX]; - hfc->d_if.ifc.l2l1 = hfc_usb_l2l1; - for (i = 0; i < 2; i++) { - hfc->b_if[i].ifc.priv = &hfc->fifos[HFCUSB_B1_TX + i * 2]; - hfc->b_if[i].ifc.l2l1 = hfc_usb_l2l1; - p_b_if[i] = &hfc->b_if[i]; - } - /* default Prot: EURO ISDN, should be a module_param */ - hfc->protocol = 2; - i = hisax_register(&hfc->d_if, p_b_if, "hfc_usb", hfc->protocol); - if (i) { - printk(KERN_INFO "HFC-S USB: hisax_register -> %d\n", i); - return i; - } - -#ifdef CONFIG_HISAX_DEBUG - hfc_debug = debug; -#endif - - for (i = 0; i < 4; i++) - hfc->fifos[i].hif = &p_b_if[i / 2]->ifc; - for (i = 4; i < 8; i++) - hfc->fifos[i].hif = &hfc->d_if.ifc; - - /* 3 (+1) INT IN + 3 ISO OUT */ - if (hfc->cfg_used == CNF_3INT3ISO || hfc->cfg_used == CNF_4INT3ISO) { - start_int_fifo(hfc->fifos + HFCUSB_D_RX); - if (hfc->fifos[HFCUSB_PCM_RX].pipe) - start_int_fifo(hfc->fifos + HFCUSB_PCM_RX); - start_int_fifo(hfc->fifos + HFCUSB_B1_RX); - start_int_fifo(hfc->fifos + HFCUSB_B2_RX); - } - /* 3 (+1) ISO IN + 3 ISO OUT */ - if (hfc->cfg_used == CNF_3ISO3ISO || hfc->cfg_used == CNF_4ISO3ISO) { - start_isoc_chain(hfc->fifos + HFCUSB_D_RX, ISOC_PACKETS_D, - rx_iso_complete, 16); - if (hfc->fifos[HFCUSB_PCM_RX].pipe) - start_isoc_chain(hfc->fifos + HFCUSB_PCM_RX, - ISOC_PACKETS_D, rx_iso_complete, - 16); - start_isoc_chain(hfc->fifos + HFCUSB_B1_RX, ISOC_PACKETS_B, - rx_iso_complete, 16); - start_isoc_chain(hfc->fifos + HFCUSB_B2_RX, ISOC_PACKETS_B, - rx_iso_complete, 16); - } - - start_isoc_chain(hfc->fifos + HFCUSB_D_TX, ISOC_PACKETS_D, - tx_iso_complete, 1); - start_isoc_chain(hfc->fifos + HFCUSB_B1_TX, ISOC_PACKETS_B, - tx_iso_complete, 1); - start_isoc_chain(hfc->fifos + HFCUSB_B2_TX, ISOC_PACKETS_B, - tx_iso_complete, 1); - - handle_led(hfc, LED_POWER_ON); - - return (0); -} - -/* initial callback for each plugged USB device */ -static int -hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) -{ - struct usb_device *dev = interface_to_usbdev(intf); - hfcusb_data *context; - struct usb_host_interface *iface = intf->cur_altsetting; - struct usb_host_interface *iface_used = NULL; - struct usb_host_endpoint *ep; - int ifnum = iface->desc.bInterfaceNumber; - int i, idx, alt_idx, probe_alt_setting, vend_idx, cfg_used, *vcf, - attr, cfg_found, cidx, ep_addr; - int cmptbl[16], small_match, iso_packet_size, packet_size, - alt_used = 0; - hfcsusb_vdata *driver_info; - - vend_idx = 0xffff; - for (i = 0; hfcusb_idtab[i].idVendor; i++) { - if ((le16_to_cpu(dev->descriptor.idVendor) == hfcusb_idtab[i].idVendor) - && (le16_to_cpu(dev->descriptor.idProduct) == hfcusb_idtab[i].idProduct)) { - vend_idx = i; - continue; - } - } - - printk(KERN_INFO - "HFC-S USB: probing interface(%d) actalt(%d) minor(%d)\n", - ifnum, iface->desc.bAlternateSetting, intf->minor); - - if (vend_idx != 0xffff) { - /* if vendor and product ID is OK, start probing alternate settings */ - alt_idx = 0; - small_match = 0xffff; - - /* default settings */ - iso_packet_size = 16; - packet_size = 64; - - while (alt_idx < intf->num_altsetting) { - iface = intf->altsetting + alt_idx; - probe_alt_setting = iface->desc.bAlternateSetting; - cfg_used = 0; - - /* check for config EOL element */ - while (validconf[cfg_used][0]) { - cfg_found = 1; - vcf = validconf[cfg_used]; - /* first endpoint descriptor */ - ep = iface->endpoint; - - memcpy(cmptbl, vcf, 16 * sizeof(int)); - - /* check for all endpoints in this alternate setting */ - for (i = 0; i < iface->desc.bNumEndpoints; - i++) { - ep_addr = - ep->desc.bEndpointAddress; - /* get endpoint base */ - idx = ((ep_addr & 0x7f) - 1) * 2; - if (ep_addr & 0x80) - idx++; - attr = ep->desc.bmAttributes; - if (cmptbl[idx] == EP_NUL) { - cfg_found = 0; - } - if (attr == USB_ENDPOINT_XFER_INT - && cmptbl[idx] == EP_INT) - cmptbl[idx] = EP_NUL; - if (attr == USB_ENDPOINT_XFER_BULK - && cmptbl[idx] == EP_BLK) - cmptbl[idx] = EP_NUL; - if (attr == USB_ENDPOINT_XFER_ISOC - && cmptbl[idx] == EP_ISO) - cmptbl[idx] = EP_NUL; - - /* check if all INT endpoints match minimum interval */ - if ((attr == USB_ENDPOINT_XFER_INT) - && (ep->desc.bInterval < vcf[17])) { - cfg_found = 0; - } - ep++; - } - for (i = 0; i < 16; i++) { - /* all entries must be EP_NOP or EP_NUL for a valid config */ - if (cmptbl[i] != EP_NOP - && cmptbl[i] != EP_NUL) - cfg_found = 0; - } - if (cfg_found) { - if (cfg_used < small_match) { - small_match = cfg_used; - alt_used = - probe_alt_setting; - iface_used = iface; - } - } - cfg_used++; - } - alt_idx++; - } /* (alt_idx < intf->num_altsetting) */ - - /* found a valid USB Ta Endpint config */ - if (small_match != 0xffff) { - iface = iface_used; - if (!(context = kzalloc(sizeof(hfcusb_data), GFP_KERNEL))) - return (-ENOMEM); /* got no mem */ - - ep = iface->endpoint; - vcf = validconf[small_match]; - - for (i = 0; i < iface->desc.bNumEndpoints; i++) { - ep_addr = ep->desc.bEndpointAddress; - /* get endpoint base */ - idx = ((ep_addr & 0x7f) - 1) * 2; - if (ep_addr & 0x80) - idx++; - cidx = idx & 7; - attr = ep->desc.bmAttributes; - - /* init Endpoints */ - if (vcf[idx] != EP_NOP - && vcf[idx] != EP_NUL) { - switch (attr) { - case USB_ENDPOINT_XFER_INT: - context-> - fifos[cidx]. - pipe = - usb_rcvintpipe - (dev, - ep->desc. - bEndpointAddress); - context-> - fifos[cidx]. - usb_transfer_mode - = USB_INT; - packet_size = - le16_to_cpu(ep->desc.wMaxPacketSize); - break; - case USB_ENDPOINT_XFER_BULK: - if (ep_addr & 0x80) - context-> - fifos - [cidx]. - pipe = - usb_rcvbulkpipe - (dev, - ep-> - desc. - bEndpointAddress); - else - context-> - fifos - [cidx]. - pipe = - usb_sndbulkpipe - (dev, - ep-> - desc. - bEndpointAddress); - context-> - fifos[cidx]. - usb_transfer_mode - = USB_BULK; - packet_size = - le16_to_cpu(ep->desc.wMaxPacketSize); - break; - case USB_ENDPOINT_XFER_ISOC: - if (ep_addr & 0x80) - context-> - fifos - [cidx]. - pipe = - usb_rcvisocpipe - (dev, - ep-> - desc. - bEndpointAddress); - else - context-> - fifos - [cidx]. - pipe = - usb_sndisocpipe - (dev, - ep-> - desc. - bEndpointAddress); - context-> - fifos[cidx]. - usb_transfer_mode - = USB_ISOC; - iso_packet_size = - le16_to_cpu(ep->desc.wMaxPacketSize); - break; - default: - context-> - fifos[cidx]. - pipe = 0; - } /* switch attribute */ - - if (context->fifos[cidx].pipe) { - context->fifos[cidx]. - fifonum = cidx; - context->fifos[cidx].hfc = - context; - context->fifos[cidx].usb_packet_maxlen = - le16_to_cpu(ep->desc.wMaxPacketSize); - context->fifos[cidx]. - intervall = - ep->desc.bInterval; - context->fifos[cidx]. - skbuff = NULL; - } - } - ep++; - } - context->dev = dev; /* save device */ - context->if_used = ifnum; /* save used interface */ - context->alt_used = alt_used; /* and alternate config */ - context->ctrl_paksize = dev->descriptor.bMaxPacketSize0; /* control size */ - context->cfg_used = vcf[16]; /* store used config */ - context->vend_idx = vend_idx; /* store found vendor */ - context->packet_size = packet_size; - context->iso_packet_size = iso_packet_size; - - /* create the control pipes needed for register access */ - context->ctrl_in_pipe = - usb_rcvctrlpipe(context->dev, 0); - context->ctrl_out_pipe = - usb_sndctrlpipe(context->dev, 0); - - driver_info = (hfcsusb_vdata *) - hfcusb_idtab[vend_idx].driver_info; - - context->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL); - - if (!context->ctrl_urb) { - pr_warn("%s: No memory for control urb\n", - driver_info->vend_name); - kfree(context); - return -ENOMEM; - } - - pr_info("HFC-S USB: detected \"%s\"\n", - driver_info->vend_name); - - DBG(HFCUSB_DBG_INIT, - "HFC-S USB: Endpoint-Config: %s (if=%d alt=%d), E-Channel(%d)", - conf_str[small_match], context->if_used, - context->alt_used, - validconf[small_match][18]); - - /* init the chip and register the driver */ - if (hfc_usb_init(context)) { - usb_kill_urb(context->ctrl_urb); - usb_free_urb(context->ctrl_urb); - context->ctrl_urb = NULL; - kfree(context); - return (-EIO); - } - usb_set_intfdata(intf, context); - return (0); - } - } else { - printk(KERN_INFO - "HFC-S USB: no valid vendor found in USB descriptor\n"); - } - return (-EIO); -} - -/* callback for unplugged USB device */ -static void -hfc_usb_disconnect(struct usb_interface *intf) -{ - hfcusb_data *context = usb_get_intfdata(intf); - int i; - - handle_led(context, LED_POWER_OFF); - schedule_timeout(HZ / 100); - - printk(KERN_INFO "HFC-S USB: device disconnect\n"); - context->disc_flag = 1; - usb_set_intfdata(intf, NULL); - - if (timer_pending(&context->t3_timer)) - del_timer(&context->t3_timer); - if (timer_pending(&context->t4_timer)) - del_timer(&context->t4_timer); - - /* tell all fifos to terminate */ - for (i = 0; i < HFCUSB_NUM_FIFOS; i++) { - if (context->fifos[i].usb_transfer_mode == USB_ISOC) { - if (context->fifos[i].active > 0) { - stop_isoc_chain(&context->fifos[i]); - DBG(HFCUSB_DBG_INIT, - "HFC-S USB: %s stopping ISOC chain Fifo(%i)", - __func__, i); - } - } else { - if (context->fifos[i].active > 0) { - context->fifos[i].active = 0; - DBG(HFCUSB_DBG_INIT, - "HFC-S USB: %s unlinking URB for Fifo(%i)", - __func__, i); - } - usb_kill_urb(context->fifos[i].urb); - usb_free_urb(context->fifos[i].urb); - context->fifos[i].urb = NULL; - } - context->fifos[i].active = 0; - } - usb_kill_urb(context->ctrl_urb); - usb_free_urb(context->ctrl_urb); - context->ctrl_urb = NULL; - hisax_unregister(&context->d_if); - kfree(context); /* free our structure again */ -} - -static struct usb_driver hfc_drv = { - .name = "hfc_usb", - .id_table = hfcusb_idtab, - .probe = hfc_usb_probe, - .disconnect = hfc_usb_disconnect, - .disable_hub_initiated_lpm = 1, -}; - -static void __exit -hfc_usb_mod_exit(void) -{ - usb_deregister(&hfc_drv); /* release our driver */ - printk(KERN_INFO "HFC-S USB: module removed\n"); -} - -static int __init -hfc_usb_mod_init(void) -{ - char revstr[30], datestr[30], dummy[30]; -#ifndef CONFIG_HISAX_DEBUG - hfc_debug = debug; -#endif - sscanf(hfcusb_revision, - "%s %s $ %s %s %s $ ", dummy, revstr, - dummy, datestr, dummy); - printk(KERN_INFO - "HFC-S USB: driver module revision %s date %s loaded, (debug=%i)\n", - revstr, datestr, debug); - if (usb_register(&hfc_drv)) { - printk(KERN_INFO - "HFC-S USB: Unable to register HFC-S USB module at usb stack\n"); - return (-1); /* unable to register */ - } - return (0); -} - -module_init(hfc_usb_mod_init); -module_exit(hfc_usb_mod_exit); -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); -MODULE_DEVICE_TABLE(usb, hfcusb_idtab); diff --git a/drivers/isdn/hisax/hfc_usb.h b/drivers/isdn/hisax/hfc_usb.h deleted file mode 100644 index 9a212330e8a8..000000000000 --- a/drivers/isdn/hisax/hfc_usb.h +++ /dev/null @@ -1,208 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * hfc_usb.h - * - * $Id: hfc_usb.h,v 1.1.2.5 2007/08/20 14:36:03 mbachem Exp $ - */ - -#ifndef __HFC_USB_H__ -#define __HFC_USB_H__ - -#define DRIVER_AUTHOR "Peter Sprenger (sprenger@moving-byters.de)" -#define DRIVER_DESC "HFC-S USB based HiSAX ISDN driver" - - -#define HFC_CTRL_TIMEOUT 20 /* 5ms timeout writing/reading regs */ -#define HFC_TIMER_T3 8000 /* timeout for l1 activation timer */ -#define HFC_TIMER_T4 500 /* time for state change interval */ - -#define HFCUSB_L1_STATECHANGE 0 /* L1 state changed */ -#define HFCUSB_L1_DRX 1 /* D-frame received */ -#define HFCUSB_L1_ERX 2 /* E-frame received */ -#define HFCUSB_L1_DTX 4 /* D-frames completed */ - -#define MAX_BCH_SIZE 2048 /* allowed B-channel packet size */ - -#define HFCUSB_RX_THRESHOLD 64 /* threshold for fifo report bit rx */ -#define HFCUSB_TX_THRESHOLD 64 /* threshold for fifo report bit tx */ - -#define HFCUSB_CHIP_ID 0x16 /* Chip ID register index */ -#define HFCUSB_CIRM 0x00 /* cirm register index */ -#define HFCUSB_USB_SIZE 0x07 /* int length register */ -#define HFCUSB_USB_SIZE_I 0x06 /* iso length register */ -#define HFCUSB_F_CROSS 0x0b /* bit order register */ -#define HFCUSB_CLKDEL 0x37 /* bit delay register */ -#define HFCUSB_CON_HDLC 0xfa /* channel connect register */ -#define HFCUSB_HDLC_PAR 0xfb -#define HFCUSB_SCTRL 0x31 /* S-bus control register (tx) */ -#define HFCUSB_SCTRL_E 0x32 /* same for E and special funcs */ -#define HFCUSB_SCTRL_R 0x33 /* S-bus control register (rx) */ -#define HFCUSB_F_THRES 0x0c /* threshold register */ -#define HFCUSB_FIFO 0x0f /* fifo select register */ -#define HFCUSB_F_USAGE 0x1a /* fifo usage register */ -#define HFCUSB_MST_MODE0 0x14 -#define HFCUSB_MST_MODE1 0x15 -#define HFCUSB_P_DATA 0x1f -#define HFCUSB_INC_RES_F 0x0e -#define HFCUSB_STATES 0x30 - -#define HFCUSB_CHIPID 0x40 /* ID value of HFC-S USB */ - - -/* fifo registers */ -#define HFCUSB_NUM_FIFOS 8 /* maximum number of fifos */ -#define HFCUSB_B1_TX 0 /* index for B1 transmit bulk/int */ -#define HFCUSB_B1_RX 1 /* index for B1 receive bulk/int */ -#define HFCUSB_B2_TX 2 -#define HFCUSB_B2_RX 3 -#define HFCUSB_D_TX 4 -#define HFCUSB_D_RX 5 -#define HFCUSB_PCM_TX 6 -#define HFCUSB_PCM_RX 7 - -/* - * used to switch snd_transfer_mode for different TA modes e.g. the Billion USB TA just - * supports ISO out, while the Cologne Chip EVAL TA just supports BULK out - */ -#define USB_INT 0 -#define USB_BULK 1 -#define USB_ISOC 2 - -#define ISOC_PACKETS_D 8 -#define ISOC_PACKETS_B 8 -#define ISO_BUFFER_SIZE 128 - -/* Fifo flow Control for TX ISO */ -#define SINK_MAX 68 -#define SINK_MIN 48 -#define SINK_DMIN 12 -#define SINK_DMAX 18 -#define BITLINE_INF (-64 * 8) - -/* HFC-S USB register access by Control-URSs */ -#define write_usb(a, b, c) usb_control_msg((a)->dev, (a)->ctrl_out_pipe, 0, 0x40, (c), (b), NULL, 0, HFC_CTRL_TIMEOUT) -#define read_usb(a, b, c) usb_control_msg((a)->dev, (a)->ctrl_in_pipe, 1, 0xC0, 0, (b), (c), 1, HFC_CTRL_TIMEOUT) -#define HFC_CTRL_BUFSIZE 32 - -/* entry and size of output/input control buffer */ -typedef struct { - __u8 hfc_reg; /* register number */ - __u8 reg_val; /* value to be written (or read) */ - int action; /* data for action handler */ -} ctrl_buft; - -/* Debugging Flags */ -#define HFCUSB_DBG_INIT 0x0001 -#define HFCUSB_DBG_STATES 0x0002 -#define HFCUSB_DBG_DCHANNEL 0x0080 -#define HFCUSB_DBG_FIFO_ERR 0x4000 -#define HFCUSB_DBG_VERBOSE_USB 0x8000 - -/* - * URB error codes: - * Used to represent a list of values and their respective symbolic names - */ -struct hfcusb_symbolic_list { - const int num; - const char *name; -}; - -static struct hfcusb_symbolic_list urb_errlist[] = { - {-ENOMEM, "No memory for allocation of internal structures"}, - {-ENOSPC, "The host controller's bandwidth is already consumed"}, - {-ENOENT, "URB was canceled by unlink_urb"}, - {-EXDEV, "ISO transfer only partially completed"}, - {-EAGAIN, "Too match scheduled for the future"}, - {-ENXIO, "URB already queued"}, - {-EFBIG, "Too much ISO frames requested"}, - {-ENOSR, "Buffer error (overrun)"}, - {-EPIPE, "Specified endpoint is stalled (device not responding)"}, - {-EOVERFLOW, "Babble (bad cable?)"}, - {-EPROTO, "Bit-stuff error (bad cable?)"}, - {-EILSEQ, "CRC/Timeout"}, - {-ETIMEDOUT, "NAK (device does not respond)"}, - {-ESHUTDOWN, "Device unplugged"}, - {-1, NULL} -}; - - -/* - * device dependent information to support different - * ISDN Ta's using the HFC-S USB chip - */ - -/* USB descriptor need to contain one of the following EndPoint combination: */ -#define CNF_4INT3ISO 1 // 4 INT IN, 3 ISO OUT -#define CNF_3INT3ISO 2 // 3 INT IN, 3 ISO OUT -#define CNF_4ISO3ISO 3 // 4 ISO IN, 3 ISO OUT -#define CNF_3ISO3ISO 4 // 3 ISO IN, 3 ISO OUT - -#define EP_NUL 1 // Endpoint at this position not allowed -#define EP_NOP 2 // all type of endpoints allowed at this position -#define EP_ISO 3 // Isochron endpoint mandatory at this position -#define EP_BLK 4 // Bulk endpoint mandatory at this position -#define EP_INT 5 // Interrupt endpoint mandatory at this position - -/* - * List of all supported endpoint configuration sets, used to find the - * best matching endpoint configuration within a devices' USB descriptor. - * We need at least 3 RX endpoints, and 3 TX endpoints, either - * INT-in and ISO-out, or ISO-in and ISO-out) - * with 4 RX endpoints even E-Channel logging is possible - */ -static int validconf[][19] = { - // INT in, ISO out config - {EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NOP, EP_INT, - EP_ISO, EP_NUL, EP_ISO, EP_NUL, EP_ISO, EP_NUL, EP_NUL, EP_NUL, - CNF_4INT3ISO, 2, 1}, - {EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NUL, EP_NUL, - EP_ISO, EP_NUL, EP_ISO, EP_NUL, EP_ISO, EP_NUL, EP_NUL, EP_NUL, - CNF_3INT3ISO, 2, 0}, - // ISO in, ISO out config - {EP_NUL, EP_NUL, EP_NUL, EP_NUL, EP_NUL, EP_NUL, EP_NUL, EP_NUL, - EP_ISO, EP_ISO, EP_ISO, EP_ISO, EP_ISO, EP_ISO, EP_NOP, EP_ISO, - CNF_4ISO3ISO, 2, 1}, - {EP_NUL, EP_NUL, EP_NUL, EP_NUL, EP_NUL, EP_NUL, EP_NUL, EP_NUL, - EP_ISO, EP_ISO, EP_ISO, EP_ISO, EP_ISO, EP_ISO, EP_NUL, EP_NUL, - CNF_3ISO3ISO, 2, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} // EOL element -}; - -#ifdef CONFIG_HISAX_DEBUG -// string description of chosen config -static char *conf_str[] = { - "4 Interrupt IN + 3 Isochron OUT", - "3 Interrupt IN + 3 Isochron OUT", - "4 Isochron IN + 3 Isochron OUT", - "3 Isochron IN + 3 Isochron OUT" -}; -#endif - -typedef struct { - int vendor; // vendor id - int prod_id; // product id - char *vend_name; // vendor string - __u8 led_scheme; // led display scheme - signed short led_bits[8]; // array of 8 possible LED bitmask settings -} vendor_data; - -#define LED_OFF 0 // no LED support -#define LED_SCHEME1 1 // LED standard scheme -#define LED_SCHEME2 2 // not used yet... - -#define LED_POWER_ON 1 -#define LED_POWER_OFF 2 -#define LED_S0_ON 3 -#define LED_S0_OFF 4 -#define LED_B1_ON 5 -#define LED_B1_OFF 6 -#define LED_B1_DATA 7 -#define LED_B2_ON 8 -#define LED_B2_OFF 9 -#define LED_B2_DATA 10 - -#define LED_NORMAL 0 // LEDs are normal -#define LED_INVERTED 1 // LEDs are inverted - - -#endif // __HFC_USB_H__ diff --git a/drivers/isdn/hisax/hfcscard.c b/drivers/isdn/hisax/hfcscard.c deleted file mode 100644 index 91b5219499ca..000000000000 --- a/drivers/isdn/hisax/hfcscard.c +++ /dev/null @@ -1,261 +0,0 @@ -/* $Id: hfcscard.c,v 1.10.2.4 2004/01/14 16:04:48 keil Exp $ - * - * low level stuff for hfcs based cards (Teles3c, ACER P10) - * - * Author Karsten Keil - * Copyright by Karsten Keil <keil@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/init.h> -#include <linux/isapnp.h> -#include "hisax.h" -#include "hfc_2bds0.h" -#include "isdnl1.h" - -static const char *hfcs_revision = "$Revision: 1.10.2.4 $"; - -static irqreturn_t -hfcs_interrupt(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - u_char val, stat; - u_long flags; - - spin_lock_irqsave(&cs->lock, flags); - if ((HFCD_ANYINT | HFCD_BUSY_NBUSY) & - (stat = cs->BC_Read_Reg(cs, HFCD_DATA, HFCD_STAT))) { - val = cs->BC_Read_Reg(cs, HFCD_DATA, HFCD_INT_S1); - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "HFCS: stat(%02x) s1(%02x)", stat, val); - hfc2bds0_interrupt(cs, val); - } else { - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "HFCS: irq_no_irq stat(%02x)", stat); - } - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -static void -hfcs_Timer(struct timer_list *t) -{ - struct IsdnCardState *cs = from_timer(cs, t, hw.hfcD.timer); - cs->hw.hfcD.timer.expires = jiffies + 75; - /* WD RESET */ -/* WriteReg(cs, HFCD_DATA, HFCD_CTMT, cs->hw.hfcD.ctmt | 0x80); - add_timer(&cs->hw.hfcD.timer); -*/ -} - -static void -release_io_hfcs(struct IsdnCardState *cs) -{ - release2bds0(cs); - del_timer(&cs->hw.hfcD.timer); - if (cs->hw.hfcD.addr) - release_region(cs->hw.hfcD.addr, 2); -} - -static void -reset_hfcs(struct IsdnCardState *cs) -{ - printk(KERN_INFO "HFCS: resetting card\n"); - cs->hw.hfcD.cirm = HFCD_RESET; - if (cs->typ == ISDN_CTYPE_TELES3C) - cs->hw.hfcD.cirm |= HFCD_MEM8K; - cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_CIRM, cs->hw.hfcD.cirm); /* Reset On */ - mdelay(10); - cs->hw.hfcD.cirm = 0; - if (cs->typ == ISDN_CTYPE_TELES3C) - cs->hw.hfcD.cirm |= HFCD_MEM8K; - cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_CIRM, cs->hw.hfcD.cirm); /* Reset Off */ - mdelay(10); - if (cs->typ == ISDN_CTYPE_TELES3C) - cs->hw.hfcD.cirm |= HFCD_INTB; - else if (cs->typ == ISDN_CTYPE_ACERP10) - cs->hw.hfcD.cirm |= HFCD_INTA; - cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_CIRM, cs->hw.hfcD.cirm); - cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_CLKDEL, 0x0e); - cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_TEST, HFCD_AUTO_AWAKE); /* S/T Auto awake */ - cs->hw.hfcD.ctmt = HFCD_TIM25 | HFCD_AUTO_TIMER; - cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_CTMT, cs->hw.hfcD.ctmt); - cs->hw.hfcD.int_m2 = HFCD_IRQ_ENABLE; - cs->hw.hfcD.int_m1 = HFCD_INTS_B1TRANS | HFCD_INTS_B2TRANS | - HFCD_INTS_DTRANS | HFCD_INTS_B1REC | HFCD_INTS_B2REC | - HFCD_INTS_DREC | HFCD_INTS_L1STATE; - cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_INT_M1, cs->hw.hfcD.int_m1); - cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_INT_M2, cs->hw.hfcD.int_m2); - cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_STATES, HFCD_LOAD_STATE | 2); /* HFC ST 2 */ - udelay(10); - cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_STATES, 2); /* HFC ST 2 */ - cs->hw.hfcD.mst_m = HFCD_MASTER; - cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_MST_MODE, cs->hw.hfcD.mst_m); /* HFC Master */ - cs->hw.hfcD.sctrl = 0; - cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_SCTRL, cs->hw.hfcD.sctrl); -} - -static int -hfcs_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - u_long flags; - int delay; - - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "HFCS: card_msg %x", mt); - switch (mt) { - case CARD_RESET: - spin_lock_irqsave(&cs->lock, flags); - reset_hfcs(cs); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_RELEASE: - release_io_hfcs(cs); - return (0); - case CARD_INIT: - delay = (75 * HZ) / 100 + 1; - mod_timer(&cs->hw.hfcD.timer, jiffies + delay); - spin_lock_irqsave(&cs->lock, flags); - reset_hfcs(cs); - init2bds0(cs); - spin_unlock_irqrestore(&cs->lock, flags); - delay = (80 * HZ) / 1000 + 1; - msleep(80); - spin_lock_irqsave(&cs->lock, flags); - cs->hw.hfcD.ctmt |= HFCD_TIM800; - cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_CTMT, cs->hw.hfcD.ctmt); - cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_MST_MODE, cs->hw.hfcD.mst_m); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_TEST: - return (0); - } - return (0); -} - -#ifdef __ISAPNP__ -static struct isapnp_device_id hfc_ids[] = { - { ISAPNP_VENDOR('A', 'N', 'X'), ISAPNP_FUNCTION(0x1114), - ISAPNP_VENDOR('A', 'N', 'X'), ISAPNP_FUNCTION(0x1114), - (unsigned long) "Acer P10" }, - { ISAPNP_VENDOR('B', 'I', 'L'), ISAPNP_FUNCTION(0x0002), - ISAPNP_VENDOR('B', 'I', 'L'), ISAPNP_FUNCTION(0x0002), - (unsigned long) "Billion 2" }, - { ISAPNP_VENDOR('B', 'I', 'L'), ISAPNP_FUNCTION(0x0001), - ISAPNP_VENDOR('B', 'I', 'L'), ISAPNP_FUNCTION(0x0001), - (unsigned long) "Billion 1" }, - { ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x7410), - ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x7410), - (unsigned long) "IStar PnP" }, - { ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x2610), - ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x2610), - (unsigned long) "Teles 16.3c" }, - { ISAPNP_VENDOR('S', 'F', 'M'), ISAPNP_FUNCTION(0x0001), - ISAPNP_VENDOR('S', 'F', 'M'), ISAPNP_FUNCTION(0x0001), - (unsigned long) "Tornado Tipa C" }, - { ISAPNP_VENDOR('K', 'Y', 'E'), ISAPNP_FUNCTION(0x0001), - ISAPNP_VENDOR('K', 'Y', 'E'), ISAPNP_FUNCTION(0x0001), - (unsigned long) "Genius Speed Surfer" }, - { 0, } -}; - -static struct isapnp_device_id *ipid = &hfc_ids[0]; -static struct pnp_card *pnp_c = NULL; -#endif - -int setup_hfcs(struct IsdnCard *card) -{ - struct IsdnCardState *cs = card->cs; - char tmp[64]; - - strcpy(tmp, hfcs_revision); - printk(KERN_INFO "HiSax: HFC-S driver Rev. %s\n", HiSax_getrev(tmp)); - -#ifdef __ISAPNP__ - if (!card->para[1] && isapnp_present()) { - struct pnp_dev *pnp_d; - while (ipid->card_vendor) { - if ((pnp_c = pnp_find_card(ipid->card_vendor, - ipid->card_device, pnp_c))) { - pnp_d = NULL; - if ((pnp_d = pnp_find_dev(pnp_c, - ipid->vendor, ipid->function, pnp_d))) { - int err; - - printk(KERN_INFO "HiSax: %s detected\n", - (char *)ipid->driver_data); - pnp_disable_dev(pnp_d); - err = pnp_activate_dev(pnp_d); - if (err < 0) { - printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n", - __func__, err); - return (0); - } - card->para[1] = pnp_port_start(pnp_d, 0); - card->para[0] = pnp_irq(pnp_d, 0); - if (card->para[0] == -1 || !card->para[1]) { - printk(KERN_ERR "HFC PnP:some resources are missing %ld/%lx\n", - card->para[0], card->para[1]); - pnp_disable_dev(pnp_d); - return (0); - } - break; - } else { - printk(KERN_ERR "HFC PnP: PnP error card found, no device\n"); - } - } - ipid++; - pnp_c = NULL; - } - if (!ipid->card_vendor) { - printk(KERN_INFO "HFC PnP: no ISAPnP card found\n"); - return (0); - } - } -#endif - cs->hw.hfcD.addr = card->para[1] & 0xfffe; - cs->irq = card->para[0]; - cs->hw.hfcD.cip = 0; - cs->hw.hfcD.int_s1 = 0; - cs->hw.hfcD.send = NULL; - cs->bcs[0].hw.hfc.send = NULL; - cs->bcs[1].hw.hfc.send = NULL; - cs->hw.hfcD.dfifosize = 512; - cs->dc.hfcd.ph_state = 0; - cs->hw.hfcD.fifo = 255; - if (cs->typ == ISDN_CTYPE_TELES3C) { - cs->hw.hfcD.bfifosize = 1024 + 512; - } else if (cs->typ == ISDN_CTYPE_ACERP10) { - cs->hw.hfcD.bfifosize = 7 * 1024 + 512; - } else - return (0); - if (!request_region(cs->hw.hfcD.addr, 2, "HFCS isdn")) { - printk(KERN_WARNING - "HiSax: %s config port %x-%x already in use\n", - CardType[card->typ], - cs->hw.hfcD.addr, - cs->hw.hfcD.addr + 2); - return (0); - } - printk(KERN_INFO - "HFCS: defined at 0x%x IRQ %d HZ %d\n", - cs->hw.hfcD.addr, - cs->irq, HZ); - if (cs->typ == ISDN_CTYPE_TELES3C) { - /* Teles 16.3c IO ADR is 0x200 | YY0U (YY Bit 15/14 address) */ - outb(0x00, cs->hw.hfcD.addr); - outb(0x56, cs->hw.hfcD.addr | 1); - } else if (cs->typ == ISDN_CTYPE_ACERP10) { - /* Acer P10 IO ADR is 0x300 */ - outb(0x00, cs->hw.hfcD.addr); - outb(0x57, cs->hw.hfcD.addr | 1); - } - set_cs_func(cs); - timer_setup(&cs->hw.hfcD.timer, hfcs_Timer, 0); - cs->cardmsg = &hfcs_card_msg; - cs->irq_func = &hfcs_interrupt; - return (1); -} diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h deleted file mode 100644 index 40080e06421c..000000000000 --- a/drivers/isdn/hisax/hisax.h +++ /dev/null @@ -1,1352 +0,0 @@ -/* $Id: hisax.h,v 2.64.2.4 2004/02/11 13:21:33 keil Exp $ - * - * Basic declarations, defines and prototypes - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ -#include <linux/errno.h> -#include <linux/fs.h> -#include <linux/major.h> -#include <asm/io.h> -#include <linux/delay.h> -#include <linux/kernel.h> -#include <linux/signal.h> -#include <linux/slab.h> -#include <linux/mm.h> -#include <linux/mman.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/timer.h> -#include <linux/wait.h> -#include <linux/isdnif.h> -#include <linux/tty.h> -#include <linux/serial_reg.h> -#include <linux/netdevice.h> - -#define ERROR_STATISTIC - -#define REQUEST 0 -#define CONFIRM 1 -#define INDICATION 2 -#define RESPONSE 3 - -#define HW_ENABLE 0x0000 -#define HW_RESET 0x0004 -#define HW_POWERUP 0x0008 -#define HW_ACTIVATE 0x0010 -#define HW_DEACTIVATE 0x0018 - -#define HW_INFO1 0x0010 -#define HW_INFO2 0x0020 -#define HW_INFO3 0x0030 -#define HW_INFO4 0x0040 -#define HW_INFO4_P8 0x0040 -#define HW_INFO4_P10 0x0048 -#define HW_RSYNC 0x0060 -#define HW_TESTLOOP 0x0070 -#define CARD_RESET 0x00F0 -#define CARD_INIT 0x00F2 -#define CARD_RELEASE 0x00F3 -#define CARD_TEST 0x00F4 -#define CARD_AUX_IND 0x00F5 - -#define PH_ACTIVATE 0x0100 -#define PH_DEACTIVATE 0x0110 -#define PH_DATA 0x0120 -#define PH_PULL 0x0130 -#define PH_TESTLOOP 0x0140 -#define PH_PAUSE 0x0150 -#define MPH_ACTIVATE 0x0180 -#define MPH_DEACTIVATE 0x0190 -#define MPH_INFORMATION 0x01A0 - -#define DL_ESTABLISH 0x0200 -#define DL_RELEASE 0x0210 -#define DL_DATA 0x0220 -#define DL_FLUSH 0x0224 -#define DL_UNIT_DATA 0x0230 - -#define MDL_BC_RELEASE 0x0278 // Formula-n enter:now -#define MDL_BC_ASSIGN 0x027C // Formula-n enter:now -#define MDL_ASSIGN 0x0280 -#define MDL_REMOVE 0x0284 -#define MDL_ERROR 0x0288 -#define MDL_INFO_SETUP 0x02E0 -#define MDL_INFO_CONN 0x02E4 -#define MDL_INFO_REL 0x02E8 - -#define CC_SETUP 0x0300 -#define CC_RESUME 0x0304 -#define CC_MORE_INFO 0x0310 -#define CC_IGNORE 0x0320 -#define CC_REJECT 0x0324 -#define CC_SETUP_COMPL 0x0330 -#define CC_PROCEEDING 0x0340 -#define CC_ALERTING 0x0344 -#define CC_PROGRESS 0x0348 -#define CC_CONNECT 0x0350 -#define CC_CHARGE 0x0354 -#define CC_NOTIFY 0x0358 -#define CC_DISCONNECT 0x0360 -#define CC_RELEASE 0x0368 -#define CC_SUSPEND 0x0370 -#define CC_PROCEED_SEND 0x0374 -#define CC_REDIR 0x0378 -#define CC_T302 0x0382 -#define CC_T303 0x0383 -#define CC_T304 0x0384 -#define CC_T305 0x0385 -#define CC_T308_1 0x0388 -#define CC_T308_2 0x038A -#define CC_T309 0x0309 -#define CC_T310 0x0390 -#define CC_T313 0x0393 -#define CC_T318 0x0398 -#define CC_T319 0x0399 -#define CC_TSPID 0x03A0 -#define CC_NOSETUP_RSP 0x03E0 -#define CC_SETUP_ERR 0x03E1 -#define CC_SUSPEND_ERR 0x03E2 -#define CC_RESUME_ERR 0x03E3 -#define CC_CONNECT_ERR 0x03E4 -#define CC_RELEASE_ERR 0x03E5 -#define CC_RESTART 0x03F4 -#define CC_TDSS1_IO 0x13F4 /* DSS1 IO user timer */ -#define CC_TNI1_IO 0x13F5 /* NI1 IO user timer */ - -/* define maximum number of possible waiting incoming calls */ -#define MAX_WAITING_CALLS 2 - - -#ifdef __KERNEL__ - -extern const char *CardType[]; -extern int nrcards; - -extern const char *l1_revision; -extern const char *l2_revision; -extern const char *l3_revision; -extern const char *lli_revision; -extern const char *tei_revision; - -/* include l3dss1 & ni1 specific process structures, but no other defines */ -#ifdef CONFIG_HISAX_EURO -#define l3dss1_process -#include "l3dss1.h" -#undef l3dss1_process -#endif /* CONFIG_HISAX_EURO */ - -#ifdef CONFIG_HISAX_NI1 -#define l3ni1_process -#include "l3ni1.h" -#undef l3ni1_process -#endif /* CONFIG_HISAX_NI1 */ - -#define MAX_DFRAME_LEN 260 -#define MAX_DFRAME_LEN_L1 300 -#define HSCX_BUFMAX 4096 -#define MAX_DATA_SIZE (HSCX_BUFMAX - 4) -#define MAX_DATA_MEM (HSCX_BUFMAX + 64) -#define RAW_BUFMAX (((HSCX_BUFMAX * 6) / 5) + 5) -#define MAX_HEADER_LEN 4 -#define MAX_WINDOW 8 -#define MAX_MON_FRAME 32 -#define MAX_DLOG_SPACE 2048 -#define MAX_BLOG_SPACE 256 - -/* #define I4L_IRQ_FLAG SA_INTERRUPT */ -#define I4L_IRQ_FLAG 0 - -/* - * Statemachine - */ - -struct FsmInst; - -typedef void (*FSMFNPTR)(struct FsmInst *, int, void *); - -struct Fsm { - FSMFNPTR *jumpmatrix; - int state_count, event_count; - char **strEvent, **strState; -}; - -struct FsmInst { - struct Fsm *fsm; - int state; - int debug; - void *userdata; - int userint; - void (*printdebug) (struct FsmInst *, char *, ...); -}; - -struct FsmNode { - int state, event; - void (*routine) (struct FsmInst *, int, void *); -}; - -struct FsmTimer { - struct FsmInst *fi; - struct timer_list tl; - int event; - void *arg; -}; - -struct L3Timer { - struct l3_process *pc; - struct timer_list tl; - int event; -}; - -#define FLG_L1_ACTIVATING 1 -#define FLG_L1_ACTIVATED 2 -#define FLG_L1_DEACTTIMER 3 -#define FLG_L1_ACTTIMER 4 -#define FLG_L1_T3RUN 5 -#define FLG_L1_PULL_REQ 6 -#define FLG_L1_UINT 7 - -struct Layer1 { - void *hardware; - struct BCState *bcs; - struct PStack **stlistp; - unsigned long Flags; - struct FsmInst l1m; - struct FsmTimer timer; - void (*l1l2) (struct PStack *, int, void *); - void (*l1hw) (struct PStack *, int, void *); - void (*l1tei) (struct PStack *, int, void *); - int mode, bc; - int delay; -}; - -#define GROUP_TEI 127 -#define TEI_SAPI 63 -#define CTRL_SAPI 0 -#define PACKET_NOACK 7 - -/* Layer2 Flags */ - -#define FLG_LAPB 0 -#define FLG_LAPD 1 -#define FLG_ORIG 2 -#define FLG_MOD128 3 -#define FLG_PEND_REL 4 -#define FLG_L3_INIT 5 -#define FLG_T200_RUN 6 -#define FLG_ACK_PEND 7 -#define FLG_REJEXC 8 -#define FLG_OWN_BUSY 9 -#define FLG_PEER_BUSY 10 -#define FLG_DCHAN_BUSY 11 -#define FLG_L1_ACTIV 12 -#define FLG_ESTAB_PEND 13 -#define FLG_PTP 14 -#define FLG_FIXED_TEI 15 -#define FLG_L2BLOCK 16 - -struct Layer2 { - int tei; - int sap; - int maxlen; - u_long flag; - spinlock_t lock; - u_int vs, va, vr; - int rc; - unsigned int window; - unsigned int sow; - struct sk_buff *windowar[MAX_WINDOW]; - struct sk_buff_head i_queue; - struct sk_buff_head ui_queue; - void (*l2l1) (struct PStack *, int, void *); - void (*l2l3) (struct PStack *, int, void *); - void (*l2tei) (struct PStack *, int, void *); - struct FsmInst l2m; - struct FsmTimer t200, t203; - int T200, N200, T203; - int debug; - char debug_id[16]; -}; - -struct Layer3 { - void (*l3l4) (struct PStack *, int, void *); - void (*l3ml3) (struct PStack *, int, void *); - void (*l3l2) (struct PStack *, int, void *); - struct FsmInst l3m; - struct FsmTimer l3m_timer; - struct sk_buff_head squeue; - struct l3_process *proc; - struct l3_process *global; - int N303; - int debug; - char debug_id[8]; -}; - -struct LLInterface { - void (*l4l3) (struct PStack *, int, void *); - int (*l4l3_proto) (struct PStack *, isdn_ctrl *); - void *userdata; - u_long flag; -}; - -#define FLG_LLI_L1WAKEUP 1 -#define FLG_LLI_L2WAKEUP 2 - -struct Management { - int ri; - struct FsmInst tei_m; - struct FsmTimer t202; - int T202, N202, debug; - void (*layer) (struct PStack *, int, void *); -}; - -#define NO_CAUSE 254 - -struct Param { - u_char cause; - u_char loc; - u_char diag[6]; - int bchannel; - int chargeinfo; - int spv; /* SPV Flag */ - setup_parm setup; /* from isdnif.h numbers and Serviceindicator */ - u_char moderate; /* transfer mode and rate (bearer octet 4) */ -}; - - -struct PStack { - struct PStack *next; - struct Layer1 l1; - struct Layer2 l2; - struct Layer3 l3; - struct LLInterface lli; - struct Management ma; - int protocol; /* EDSS1, 1TR6 or NI1 */ - - /* protocol specific data fields */ - union - { u_char uuuu; /* only as dummy */ -#ifdef CONFIG_HISAX_EURO - dss1_stk_priv dss1; /* private dss1 data */ -#endif /* CONFIG_HISAX_EURO */ -#ifdef CONFIG_HISAX_NI1 - ni1_stk_priv ni1; /* private ni1 data */ -#endif /* CONFIG_HISAX_NI1 */ - } prot; -}; - -struct l3_process { - int callref; - int state; - struct L3Timer timer; - int N303; - int debug; - struct Param para; - struct Channel *chan; - struct PStack *st; - struct l3_process *next; - ulong redir_result; - - /* protocol specific data fields */ - union - { u_char uuuu; /* only when euro not defined, avoiding empty union */ -#ifdef CONFIG_HISAX_EURO - dss1_proc_priv dss1; /* private dss1 data */ -#endif /* CONFIG_HISAX_EURO */ -#ifdef CONFIG_HISAX_NI1 - ni1_proc_priv ni1; /* private ni1 data */ -#endif /* CONFIG_HISAX_NI1 */ - } prot; -}; - -struct hscx_hw { - int hscx; - int rcvidx; - int count; /* Current skb sent count */ - u_char *rcvbuf; /* B-Channel receive Buffer */ - u_char tsaxr0; - u_char tsaxr1; -}; - -struct w6692B_hw { - int bchan; - int rcvidx; - int count; /* Current skb sent count */ - u_char *rcvbuf; /* B-Channel receive Buffer */ -}; - -struct isar_reg { - unsigned long Flags; - volatile u_char bstat; - volatile u_char iis; - volatile u_char cmsb; - volatile u_char clsb; - volatile u_char par[8]; -}; - -struct isar_hw { - int dpath; - int rcvidx; - int txcnt; - int mml; - u_char state; - u_char cmd; - u_char mod; - u_char newcmd; - u_char newmod; - char try_mod; - struct timer_list ftimer; - u_char *rcvbuf; /* B-Channel receive Buffer */ - u_char conmsg[16]; - struct isar_reg *reg; -}; - -struct hdlc_stat_reg { -#ifdef __BIG_ENDIAN - u_char fill; - u_char mode; - u_char xml; - u_char cmd; -#else - u_char cmd; - u_char xml; - u_char mode; - u_char fill; -#endif -} __attribute__((packed)); - -struct hdlc_hw { - union { - u_int ctrl; - struct hdlc_stat_reg sr; - } ctrl; - u_int stat; - int rcvidx; - int count; /* Current skb sent count */ - u_char *rcvbuf; /* B-Channel receive Buffer */ -}; - -struct hfcB_hw { - unsigned int *send; - int f1; - int f2; -}; - -struct tiger_hw { - u_int *send; - u_int *s_irq; - u_int *s_end; - u_int *sendp; - u_int *rec; - int free; - u_char *rcvbuf; - u_char *sendbuf; - u_char *sp; - int sendcnt; - u_int s_tot; - u_int r_bitcnt; - u_int r_tot; - u_int r_err; - u_int r_fcs; - u_char r_state; - u_char r_one; - u_char r_val; - u_char s_state; -}; - -struct amd7930_hw { - u_char *tx_buff; - u_char *rv_buff; - int rv_buff_in; - int rv_buff_out; - struct sk_buff *rv_skb; - struct hdlc_state *hdlc_state; - struct work_struct tq_rcv; - struct work_struct tq_xmt; -}; - -#define BC_FLG_INIT 1 -#define BC_FLG_ACTIV 2 -#define BC_FLG_BUSY 3 -#define BC_FLG_NOFRAME 4 -#define BC_FLG_HALF 5 -#define BC_FLG_EMPTY 6 -#define BC_FLG_ORIG 7 -#define BC_FLG_DLEETX 8 -#define BC_FLG_LASTDLE 9 -#define BC_FLG_FIRST 10 -#define BC_FLG_LASTDATA 11 -#define BC_FLG_NMD_DATA 12 -#define BC_FLG_FTI_RUN 13 -#define BC_FLG_LL_OK 14 -#define BC_FLG_LL_CONN 15 -#define BC_FLG_FTI_FTS 16 -#define BC_FLG_FRH_WAIT 17 - -#define L1_MODE_NULL 0 -#define L1_MODE_TRANS 1 -#define L1_MODE_HDLC 2 -#define L1_MODE_EXTRN 3 -#define L1_MODE_HDLC_56K 4 -#define L1_MODE_MODEM 7 -#define L1_MODE_V32 8 -#define L1_MODE_FAX 9 - -struct BCState { - int channel; - int mode; - u_long Flag; - struct IsdnCardState *cs; - int tx_cnt; /* B-Channel transmit counter */ - struct sk_buff *tx_skb; /* B-Channel transmit Buffer */ - struct sk_buff_head rqueue; /* B-Channel receive Queue */ - struct sk_buff_head squeue; /* B-Channel send Queue */ - int ackcnt; - spinlock_t aclock; - struct PStack *st; - u_char *blog; - u_char *conmsg; - struct timer_list transbusy; - struct work_struct tqueue; - u_long event; - int (*BC_SetStack) (struct PStack *, struct BCState *); - void (*BC_Close) (struct BCState *); -#ifdef ERROR_STATISTIC - int err_crc; - int err_tx; - int err_rdo; - int err_inv; -#endif - union { - struct hscx_hw hscx; - struct hdlc_hw hdlc; - struct isar_hw isar; - struct hfcB_hw hfc; - struct tiger_hw tiger; - struct amd7930_hw amd7930; - struct w6692B_hw w6692; - struct hisax_b_if *b_if; - } hw; -}; - -struct Channel { - struct PStack *b_st, *d_st; - struct IsdnCardState *cs; - struct BCState *bcs; - int chan; - int incoming; - struct FsmInst fi; - struct FsmTimer drel_timer, dial_timer; - int debug; - int l2_protocol, l2_active_protocol; - int l3_protocol; - int data_open; - struct l3_process *proc; - setup_parm setup; /* from isdnif.h numbers and Serviceindicator */ - u_long Flags; /* for remembering action done in l4 */ - int leased; -}; - -struct elsa_hw { - struct pci_dev *dev; - unsigned long base; - unsigned int cfg; - unsigned int ctrl; - unsigned int ale; - unsigned int isac; - unsigned int itac; - unsigned int hscx; - unsigned int trig; - unsigned int timer; - unsigned int counter; - unsigned int status; - struct timer_list tl; - unsigned int MFlag; - struct BCState *bcs; - u_char *transbuf; - u_char *rcvbuf; - unsigned int transp; - unsigned int rcvp; - unsigned int transcnt; - unsigned int rcvcnt; - u_char IER; - u_char FCR; - u_char LCR; - u_char MCR; - u_char ctrl_reg; -}; - -struct teles3_hw { - unsigned int cfg_reg; - signed int isac; - signed int hscx[2]; - signed int isacfifo; - signed int hscxfifo[2]; -}; - -struct teles0_hw { - unsigned int cfg_reg; - void __iomem *membase; - unsigned long phymem; -}; - -struct avm_hw { - unsigned int cfg_reg; - unsigned int isac; - unsigned int hscx[2]; - unsigned int isacfifo; - unsigned int hscxfifo[2]; - unsigned int counter; - struct pci_dev *dev; -}; - -struct ix1_hw { - unsigned int cfg_reg; - unsigned int isac_ale; - unsigned int isac; - unsigned int hscx_ale; - unsigned int hscx; -}; - -struct diva_hw { - unsigned long cfg_reg; - unsigned long pci_cfg; - unsigned int ctrl; - unsigned long isac_adr; - unsigned int isac; - unsigned long hscx_adr; - unsigned int hscx; - unsigned int status; - struct timer_list tl; - u_char ctrl_reg; - struct pci_dev *dev; -}; - -struct asus_hw { - unsigned int cfg_reg; - unsigned int adr; - unsigned int isac; - unsigned int hscx; - unsigned int u7; - unsigned int pots; -}; - - -struct hfc_hw { - unsigned int addr; - unsigned int fifosize; - unsigned char cirm; - unsigned char ctmt; - unsigned char cip; - u_char isac_spcr; - struct timer_list timer; -}; - -struct sedl_hw { - unsigned int cfg_reg; - unsigned int adr; - unsigned int isac; - unsigned int hscx; - unsigned int reset_on; - unsigned int reset_off; - struct isar_reg isar; - unsigned int chip; - unsigned int bus; - struct pci_dev *dev; -}; - -struct spt_hw { - unsigned int cfg_reg; - unsigned int isac; - unsigned int hscx[2]; - unsigned char res_irq; -}; - -struct mic_hw { - unsigned int cfg_reg; - unsigned int adr; - unsigned int isac; - unsigned int hscx; -}; - -struct njet_hw { - unsigned long base; - unsigned int isac; - unsigned int auxa; - unsigned char auxd; - unsigned char dmactrl; - unsigned char ctrl_reg; - unsigned char irqmask0; - unsigned char irqstat0; - unsigned char last_is0; - struct pci_dev *dev; -}; - -struct hfcPCI_hw { - unsigned char cirm; - unsigned char ctmt; - unsigned char conn; - unsigned char mst_m; - unsigned char int_m1; - unsigned char int_m2; - unsigned char int_s1; - unsigned char sctrl; - unsigned char sctrl_r; - unsigned char sctrl_e; - unsigned char trm; - unsigned char stat; - unsigned char fifo; - unsigned char fifo_en; - unsigned char bswapped; - unsigned char nt_mode; - int nt_timer; - struct pci_dev *dev; - void __iomem *pci_io; /* start of PCI IO memory */ - dma_addr_t dma; /* dma handle for Fifos */ - void *fifos; /* FIFO memory */ - int last_bfifo_cnt[2]; /* marker saving last b-fifo frame count */ - struct timer_list timer; -}; - -struct hfcSX_hw { - unsigned long base; - unsigned char cirm; - unsigned char ctmt; - unsigned char conn; - unsigned char mst_m; - unsigned char int_m1; - unsigned char int_m2; - unsigned char int_s1; - unsigned char sctrl; - unsigned char sctrl_r; - unsigned char sctrl_e; - unsigned char trm; - unsigned char stat; - unsigned char fifo; - unsigned char bswapped; - unsigned char nt_mode; - unsigned char chip; - int b_fifo_size; - unsigned char last_fifo; - void *extra; - int nt_timer; - struct timer_list timer; -}; - -struct hfcD_hw { - unsigned int addr; - unsigned int bfifosize; - unsigned int dfifosize; - unsigned char cirm; - unsigned char ctmt; - unsigned char cip; - unsigned char conn; - unsigned char mst_m; - unsigned char int_m1; - unsigned char int_m2; - unsigned char int_s1; - unsigned char sctrl; - unsigned char stat; - unsigned char fifo; - unsigned char f1; - unsigned char f2; - unsigned int *send; - struct timer_list timer; -}; - -struct isurf_hw { - unsigned int reset; - unsigned long phymem; - void __iomem *isac; - void __iomem *isar; - struct isar_reg isar_r; -}; - -struct saphir_hw { - struct pci_dev *dev; - unsigned int cfg_reg; - unsigned int ale; - unsigned int isac; - unsigned int hscx; - struct timer_list timer; -}; - -struct bkm_hw { - struct pci_dev *dev; - unsigned long base; - /* A4T stuff */ - unsigned long isac_adr; - unsigned int isac_ale; - unsigned long jade_adr; - unsigned int jade_ale; - /* Scitel Quadro stuff */ - unsigned long plx_adr; - unsigned long data_adr; -}; - -struct gazel_hw { - struct pci_dev *dev; - unsigned int cfg_reg; - unsigned int pciaddr[2]; - signed int ipac; - signed int isac; - signed int hscx[2]; - signed int isacfifo; - signed int hscxfifo[2]; - unsigned char timeslot; - unsigned char iom2; -}; - -struct w6692_hw { - struct pci_dev *dev; - unsigned int iobase; - struct timer_list timer; -}; - -struct arcofi_msg { - struct arcofi_msg *next; - u_char receive; - u_char len; - u_char msg[10]; -}; - -struct isac_chip { - int ph_state; - u_char *mon_tx; - u_char *mon_rx; - int mon_txp; - int mon_txc; - int mon_rxp; - struct arcofi_msg *arcofi_list; - struct timer_list arcofitimer; - wait_queue_head_t arcofi_wait; - u_char arcofi_bc; - u_char arcofi_state; - u_char mocr; - u_char adf2; -}; - -struct hfcd_chip { - int ph_state; -}; - -struct hfcpci_chip { - int ph_state; -}; - -struct hfcsx_chip { - int ph_state; -}; - -struct w6692_chip { - int ph_state; -}; - -struct amd7930_chip { - u_char lmr1; - u_char ph_state; - u_char old_state; - u_char flg_t3; - unsigned int tx_xmtlen; - struct timer_list timer3; - void (*ph_command) (struct IsdnCardState *, u_char, char *); - void (*setIrqMask) (struct IsdnCardState *, u_char); -}; - -struct icc_chip { - int ph_state; - u_char *mon_tx; - u_char *mon_rx; - int mon_txp; - int mon_txc; - int mon_rxp; - struct arcofi_msg *arcofi_list; - struct timer_list arcofitimer; - wait_queue_head_t arcofi_wait; - u_char arcofi_bc; - u_char arcofi_state; - u_char mocr; - u_char adf2; -}; - -#define HW_IOM1 0 -#define HW_IPAC 1 -#define HW_ISAR 2 -#define HW_ARCOFI 3 -#define FLG_TWO_DCHAN 4 -#define FLG_L1_DBUSY 5 -#define FLG_DBUSY_TIMER 6 -#define FLG_LOCK_ATOMIC 7 -#define FLG_ARCOFI_TIMER 8 -#define FLG_ARCOFI_ERROR 9 -#define FLG_HW_L1_UINT 10 - -struct IsdnCardState { - spinlock_t lock; - u_char typ; - u_char subtyp; - int protocol; - u_int irq; - u_long irq_flags; - u_long HW_Flags; - int *busy_flag; - int chanlimit; /* limited number of B-chans to use */ - int logecho; /* log echo if supported by card */ - union { - struct elsa_hw elsa; - struct teles0_hw teles0; - struct teles3_hw teles3; - struct avm_hw avm; - struct ix1_hw ix1; - struct diva_hw diva; - struct asus_hw asus; - struct hfc_hw hfc; - struct sedl_hw sedl; - struct spt_hw spt; - struct mic_hw mic; - struct njet_hw njet; - struct hfcD_hw hfcD; - struct hfcPCI_hw hfcpci; - struct hfcSX_hw hfcsx; - struct ix1_hw niccy; - struct isurf_hw isurf; - struct saphir_hw saphir; - struct bkm_hw ax; - struct gazel_hw gazel; - struct w6692_hw w6692; - struct hisax_d_if *hisax_d_if; - } hw; - int myid; - isdn_if iif; - spinlock_t statlock; - u_char *status_buf; - u_char *status_read; - u_char *status_write; - u_char *status_end; - u_char (*readisac) (struct IsdnCardState *, u_char); - void (*writeisac) (struct IsdnCardState *, u_char, u_char); - void (*readisacfifo) (struct IsdnCardState *, u_char *, int); - void (*writeisacfifo) (struct IsdnCardState *, u_char *, int); - u_char (*BC_Read_Reg) (struct IsdnCardState *, int, u_char); - void (*BC_Write_Reg) (struct IsdnCardState *, int, u_char, u_char); - void (*BC_Send_Data) (struct BCState *); - int (*cardmsg) (struct IsdnCardState *, int, void *); - void (*setstack_d) (struct PStack *, struct IsdnCardState *); - void (*DC_Close) (struct IsdnCardState *); - irq_handler_t irq_func; - int (*auxcmd) (struct IsdnCardState *, isdn_ctrl *); - struct Channel channel[2 + MAX_WAITING_CALLS]; - struct BCState bcs[2 + MAX_WAITING_CALLS]; - struct PStack *stlist; - struct sk_buff_head rq, sq; /* D-channel queues */ - int cardnr; - char *dlog; - int debug; - union { - struct isac_chip isac; - struct hfcd_chip hfcd; - struct hfcpci_chip hfcpci; - struct hfcsx_chip hfcsx; - struct w6692_chip w6692; - struct amd7930_chip amd7930; - struct icc_chip icc; - } dc; - u_char *rcvbuf; - int rcvidx; - struct sk_buff *tx_skb; - int tx_cnt; - u_long event; - struct work_struct tqueue; - struct timer_list dbusytimer; - unsigned int irq_cnt; -#ifdef ERROR_STATISTIC - int err_crc; - int err_tx; - int err_rx; -#endif -}; - - -#define schedule_event(s, ev) do { test_and_set_bit(ev, &s->event); schedule_work(&s->tqueue); } while (0) - -#define MON0_RX 1 -#define MON1_RX 2 -#define MON0_TX 4 -#define MON1_TX 8 - - -#ifdef ISDN_CHIP_ISAC -#undef ISDN_CHIP_ISAC -#endif - -#ifdef CONFIG_HISAX_16_0 -#define CARD_TELES0 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_TELES0 0 -#endif - -#ifdef CONFIG_HISAX_16_3 -#define CARD_TELES3 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_TELES3 0 -#endif - -#ifdef CONFIG_HISAX_TELESPCI -#define CARD_TELESPCI 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_TELESPCI 0 -#endif - -#ifdef CONFIG_HISAX_AVM_A1 -#define CARD_AVM_A1 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_AVM_A1 0 -#endif - -#ifdef CONFIG_HISAX_AVM_A1_PCMCIA -#define CARD_AVM_A1_PCMCIA 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_AVM_A1_PCMCIA 0 -#endif - -#ifdef CONFIG_HISAX_FRITZPCI -#define CARD_FRITZPCI 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_FRITZPCI 0 -#endif - -#ifdef CONFIG_HISAX_ELSA -#define CARD_ELSA 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_ELSA 0 -#endif - -#ifdef CONFIG_HISAX_IX1MICROR2 -#define CARD_IX1MICROR2 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_IX1MICROR2 0 -#endif - -#ifdef CONFIG_HISAX_DIEHLDIVA -#define CARD_DIEHLDIVA 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_DIEHLDIVA 0 -#endif - -#ifdef CONFIG_HISAX_ASUSCOM -#define CARD_ASUSCOM 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_ASUSCOM 0 -#endif - -#ifdef CONFIG_HISAX_TELEINT -#define CARD_TELEINT 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_TELEINT 0 -#endif - -#ifdef CONFIG_HISAX_SEDLBAUER -#define CARD_SEDLBAUER 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_SEDLBAUER 0 -#endif - -#ifdef CONFIG_HISAX_SPORTSTER -#define CARD_SPORTSTER 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_SPORTSTER 0 -#endif - -#ifdef CONFIG_HISAX_MIC -#define CARD_MIC 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_MIC 0 -#endif - -#ifdef CONFIG_HISAX_NETJET -#define CARD_NETJET_S 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_NETJET_S 0 -#endif - -#ifdef CONFIG_HISAX_HFCS -#define CARD_HFCS 1 -#else -#define CARD_HFCS 0 -#endif - -#ifdef CONFIG_HISAX_HFC_PCI -#define CARD_HFC_PCI 1 -#else -#define CARD_HFC_PCI 0 -#endif - -#ifdef CONFIG_HISAX_HFC_SX -#define CARD_HFC_SX 1 -#else -#define CARD_HFC_SX 0 -#endif - -#ifdef CONFIG_HISAX_NICCY -#define CARD_NICCY 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_NICCY 0 -#endif - -#ifdef CONFIG_HISAX_ISURF -#define CARD_ISURF 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_ISURF 0 -#endif - -#ifdef CONFIG_HISAX_S0BOX -#define CARD_S0BOX 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_S0BOX 0 -#endif - -#ifdef CONFIG_HISAX_HSTSAPHIR -#define CARD_HSTSAPHIR 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_HSTSAPHIR 0 -#endif - -#ifdef CONFIG_HISAX_BKM_A4T -#define CARD_BKM_A4T 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_BKM_A4T 0 -#endif - -#ifdef CONFIG_HISAX_SCT_QUADRO -#define CARD_SCT_QUADRO 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_SCT_QUADRO 0 -#endif - -#ifdef CONFIG_HISAX_GAZEL -#define CARD_GAZEL 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_GAZEL 0 -#endif - -#ifdef CONFIG_HISAX_W6692 -#define CARD_W6692 1 -#ifndef ISDN_CHIP_W6692 -#define ISDN_CHIP_W6692 1 -#endif -#else -#define CARD_W6692 0 -#endif - -#ifdef CONFIG_HISAX_NETJET_U -#define CARD_NETJET_U 1 -#ifndef ISDN_CHIP_ICC -#define ISDN_CHIP_ICC 1 -#endif -#ifndef HISAX_UINTERFACE -#define HISAX_UINTERFACE 1 -#endif -#else -#define CARD_NETJET_U 0 -#endif - -#ifdef CONFIG_HISAX_ENTERNOW_PCI -#define CARD_FN_ENTERNOW_PCI 1 -#else -#define CARD_FN_ENTERNOW_PCI 0 -#endif - -#define TEI_PER_CARD 1 - -/* L1 Debug */ -#define L1_DEB_WARN 0x01 -#define L1_DEB_INTSTAT 0x02 -#define L1_DEB_ISAC 0x04 -#define L1_DEB_ISAC_FIFO 0x08 -#define L1_DEB_HSCX 0x10 -#define L1_DEB_HSCX_FIFO 0x20 -#define L1_DEB_LAPD 0x40 -#define L1_DEB_IPAC 0x80 -#define L1_DEB_RECEIVE_FRAME 0x100 -#define L1_DEB_MONITOR 0x200 -#define DEB_DLOG_HEX 0x400 -#define DEB_DLOG_VERBOSE 0x800 - -#define L2FRAME_DEBUG - -#ifdef L2FRAME_DEBUG -extern void Logl2Frame(struct IsdnCardState *cs, struct sk_buff *skb, char *buf, int dir); -#endif - -#include "hisax_cfg.h" - -void init_bcstate(struct IsdnCardState *cs, int bc); - -void setstack_HiSax(struct PStack *st, struct IsdnCardState *cs); -void HiSax_addlist(struct IsdnCardState *sp, struct PStack *st); -void HiSax_rmlist(struct IsdnCardState *sp, struct PStack *st); - -void setstack_l1_B(struct PStack *st); - -void setstack_tei(struct PStack *st); -void setstack_manager(struct PStack *st); - -void setstack_isdnl2(struct PStack *st, char *debug_id); -void releasestack_isdnl2(struct PStack *st); -void setstack_transl2(struct PStack *st); -void releasestack_transl2(struct PStack *st); -void lli_writewakeup(struct PStack *st, int len); - -void setstack_l3dc(struct PStack *st, struct Channel *chanp); -void setstack_l3bc(struct PStack *st, struct Channel *chanp); -void releasestack_isdnl3(struct PStack *st); - -u_char *findie(u_char *p, int size, u_char ie, int wanted_set); -int getcallref(u_char *p); -int newcallref(void); - -int FsmNew(struct Fsm *fsm, struct FsmNode *fnlist, int fncount); -void FsmFree(struct Fsm *fsm); -int FsmEvent(struct FsmInst *fi, int event, void *arg); -void FsmChangeState(struct FsmInst *fi, int newstate); -void FsmInitTimer(struct FsmInst *fi, struct FsmTimer *ft); -int FsmAddTimer(struct FsmTimer *ft, int millisec, int event, - void *arg, int where); -void FsmRestartTimer(struct FsmTimer *ft, int millisec, int event, - void *arg, int where); -void FsmDelTimer(struct FsmTimer *ft, int where); -int jiftime(char *s, long mark); - -int HiSax_command(isdn_ctrl *ic); -int HiSax_writebuf_skb(int id, int chan, int ack, struct sk_buff *skb); -__printf(3, 4) -void HiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, ...); -__printf(3, 0) -void VHiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, va_list args); -void HiSax_reportcard(int cardnr, int sel); -int QuickHex(char *txt, u_char *p, int cnt); -void LogFrame(struct IsdnCardState *cs, u_char *p, int size); -void dlogframe(struct IsdnCardState *cs, struct sk_buff *skb, int dir); -void iecpy(u_char *dest, u_char *iestart, int ieoffset); -#endif /* __KERNEL__ */ - -/* - * Busywait delay for `jiffs' jiffies - */ -#define HZDELAY(jiffs) do { \ - int tout = jiffs; \ - \ - while (tout--) { \ - int loops = USEC_PER_SEC / HZ; \ - while (loops--) \ - udelay(1); \ - } \ - } while (0) - -int ll_run(struct IsdnCardState *cs, int addfeatures); -int CallcNew(void); -void CallcFree(void); -int CallcNewChan(struct IsdnCardState *cs); -void CallcFreeChan(struct IsdnCardState *cs); -int Isdnl1New(void); -void Isdnl1Free(void); -int Isdnl2New(void); -void Isdnl2Free(void); -int Isdnl3New(void); -void Isdnl3Free(void); -void init_tei(struct IsdnCardState *cs, int protocol); -void release_tei(struct IsdnCardState *cs); -char *HiSax_getrev(const char *revision); -int TeiNew(void); -void TeiFree(void); - -#ifdef CONFIG_PCI - -#include <linux/pci.h> - -/* adaptation wrapper for old usage - * WARNING! This is unfit for use in a PCI hotplug environment, - * as the returned PCI device can disappear at any moment in time. - * Callers should be converted to use pci_get_device() instead. - */ -static inline struct pci_dev *hisax_find_pci_device(unsigned int vendor, - unsigned int device, - struct pci_dev *from) -{ - struct pci_dev *pdev; - - pci_dev_get(from); - pdev = pci_get_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from); - pci_dev_put(pdev); - return pdev; -} - -#endif diff --git a/drivers/isdn/hisax/hisax_cfg.h b/drivers/isdn/hisax/hisax_cfg.h deleted file mode 100644 index 487dcfe9e718..000000000000 --- a/drivers/isdn/hisax/hisax_cfg.h +++ /dev/null @@ -1,66 +0,0 @@ -/* $Id: hisax_cfg.h,v 1.1.2.1 2004/01/24 20:47:23 keil Exp $ - * define of the basic HiSax configuration structures - * and pcmcia interface - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#define ISDN_CTYPE_16_0 1 -#define ISDN_CTYPE_8_0 2 -#define ISDN_CTYPE_16_3 3 -#define ISDN_CTYPE_PNP 4 -#define ISDN_CTYPE_A1 5 -#define ISDN_CTYPE_ELSA 6 -#define ISDN_CTYPE_ELSA_PNP 7 -#define ISDN_CTYPE_TELESPCMCIA 8 -#define ISDN_CTYPE_IX1MICROR2 9 -#define ISDN_CTYPE_ELSA_PCMCIA 10 -#define ISDN_CTYPE_DIEHLDIVA 11 -#define ISDN_CTYPE_ASUSCOM 12 -#define ISDN_CTYPE_TELEINT 13 -#define ISDN_CTYPE_TELES3C 14 -#define ISDN_CTYPE_SEDLBAUER 15 -#define ISDN_CTYPE_SPORTSTER 16 -#define ISDN_CTYPE_MIC 17 -#define ISDN_CTYPE_ELSA_PCI 18 -#define ISDN_CTYPE_COMPAQ_ISA 19 -#define ISDN_CTYPE_NETJET_S 20 -#define ISDN_CTYPE_TELESPCI 21 -#define ISDN_CTYPE_SEDLBAUER_PCMCIA 22 -#define ISDN_CTYPE_AMD7930 23 -#define ISDN_CTYPE_NICCY 24 -#define ISDN_CTYPE_S0BOX 25 -#define ISDN_CTYPE_A1_PCMCIA 26 -#define ISDN_CTYPE_FRITZPCI 27 -#define ISDN_CTYPE_SEDLBAUER_FAX 28 -#define ISDN_CTYPE_ISURF 29 -#define ISDN_CTYPE_ACERP10 30 -#define ISDN_CTYPE_HSTSAPHIR 31 -#define ISDN_CTYPE_BKM_A4T 32 -#define ISDN_CTYPE_SCT_QUADRO 33 -#define ISDN_CTYPE_GAZEL 34 -#define ISDN_CTYPE_HFC_PCI 35 -#define ISDN_CTYPE_W6692 36 -#define ISDN_CTYPE_HFC_SX 37 -#define ISDN_CTYPE_NETJET_U 38 -#define ISDN_CTYPE_HFC_SP_PCMCIA 39 -#define ISDN_CTYPE_DYNAMIC 40 -#define ISDN_CTYPE_ENTERNOW 41 -#define ISDN_CTYPE_COUNT 41 - -typedef struct IsdnCardState IsdnCardState_t; -typedef struct IsdnCard IsdnCard_t; - -struct IsdnCard { - int typ; - int protocol; /* EDSS1, 1TR6 or NI1 */ - unsigned long para[4]; - IsdnCardState_t *cs; -}; - -typedef int (*hisax_setup_func_t)(struct IsdnCard *card); - -extern void HiSax_closecard(int); -extern int hisax_init_pcmcia(void *, int *, IsdnCard_t *); diff --git a/drivers/isdn/hisax/hisax_debug.h b/drivers/isdn/hisax/hisax_debug.h deleted file mode 100644 index 7b3093d0856a..000000000000 --- a/drivers/isdn/hisax/hisax_debug.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Common debugging macros for use with the hisax driver - * - * Author Frode Isaksen - * Copyright 2001 by Frode Isaksen <fisaksen@bewan.com> - * 2001 by Kai Germaschewski <kai.germaschewski@gmx.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * How to use: - * - * Before including this file, you need to - * #define __debug_variable my_debug - * where my_debug is a variable in your code which - * determines the debug bitmask. - * - * If CONFIG_HISAX_DEBUG is not set, all macros evaluate to nothing - * - */ - -#ifndef __HISAX_DEBUG_H__ -#define __HISAX_DEBUG_H__ - - -#ifdef CONFIG_HISAX_DEBUG - -#define DBG(level, format, arg...) do { \ - if (level & __debug_variable) \ - printk(KERN_DEBUG "%s: " format "\n" , __func__ , ## arg); \ - } while (0) - -#define DBG_PACKET(level, data, count) \ - if (level & __debug_variable) dump_packet(__func__, data, count) - -#define DBG_SKB(level, skb) \ - if ((level & __debug_variable) && skb) dump_packet(__func__, skb->data, skb->len) - - -static void __attribute__((unused)) -dump_packet(const char *name, const u_char *data, int pkt_len) -{ -#define DUMP_HDR_SIZE 20 -#define DUMP_TLR_SIZE 8 - if (pkt_len) { - int i, len1, len2; - - printk(KERN_DEBUG "%s: length=%d,data=", name, pkt_len); - - if (pkt_len > DUMP_HDR_SIZE + DUMP_TLR_SIZE) { - len1 = DUMP_HDR_SIZE; - len2 = DUMP_TLR_SIZE; - } else { - len1 = pkt_len > DUMP_HDR_SIZE ? DUMP_HDR_SIZE : pkt_len; - len2 = 0; - } - for (i = 0; i < len1; ++i) { - printk("%.2x", data[i]); - } - if (len2) { - printk(".."); - for (i = pkt_len-DUMP_TLR_SIZE; i < pkt_len; ++i) { - printk("%.2x", data[i]); - } - } - printk("\n"); - } -#undef DUMP_HDR_SIZE -#undef DUMP_TLR_SIZE -} - -#else - -#define DBG(level, format, arg...) do {} while (0) -#define DBG_PACKET(level, data, count) do {} while (0) -#define DBG_SKB(level, skb) do {} while (0) - -#endif - -#endif diff --git a/drivers/isdn/hisax/hisax_fcpcipnp.c b/drivers/isdn/hisax/hisax_fcpcipnp.c deleted file mode 100644 index 7a7137d8664b..000000000000 --- a/drivers/isdn/hisax/hisax_fcpcipnp.c +++ /dev/null @@ -1,1024 +0,0 @@ -/* - * Driver for AVM Fritz!PCI, Fritz!PCI v2, Fritz!PnP ISDN cards - * - * Author Kai Germaschewski - * Copyright 2001 by Kai Germaschewski <kai.germaschewski@gmx.de> - * 2001 by Karsten Keil <keil@isdn4linux.de> - * - * based upon Karsten Keil's original avm_pci.c driver - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * Thanks to Wizard Computersysteme GmbH, Bremervoerde and - * SoHaNet Technology GmbH, Berlin - * for supporting the development of this driver - */ - - -/* TODO: - * - * o POWER PC - * o clean up debugging - * o tx_skb at PH_DEACTIVATE time - */ - -#include <linux/module.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/pci.h> -#include <linux/isapnp.h> -#include <linux/kmod.h> -#include <linux/slab.h> -#include <linux/skbuff.h> -#include <linux/netdevice.h> -#include <linux/delay.h> - -#include <asm/io.h> - -#include "hisax_fcpcipnp.h" - -// debugging cruft -#define __debug_variable debug -#include "hisax_debug.h" - -#ifdef CONFIG_HISAX_DEBUG -static int debug = 0; -/* static int hdlcfifosize = 32; */ -module_param(debug, int, 0); -/* module_param(hdlcfifosize, int, 0); */ -#endif - -MODULE_AUTHOR("Kai Germaschewski <kai.germaschewski@gmx.de>/Karsten Keil <kkeil@suse.de>"); -MODULE_DESCRIPTION("AVM Fritz!PCI/PnP ISDN driver"); - -static const struct pci_device_id fcpci_ids[] = { - { .vendor = PCI_VENDOR_ID_AVM, - .device = PCI_DEVICE_ID_AVM_A1, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .driver_data = (unsigned long) "Fritz!Card PCI", - }, - { .vendor = PCI_VENDOR_ID_AVM, - .device = PCI_DEVICE_ID_AVM_A1_V2, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .driver_data = (unsigned long) "Fritz!Card PCI v2" }, - {} -}; - -MODULE_DEVICE_TABLE(pci, fcpci_ids); - -#ifdef CONFIG_PNP -static struct pnp_device_id fcpnp_ids[] = { - { - .id = "AVM0900", - .driver_data = (unsigned long) "Fritz!Card PnP", - }, - { .id = "" } -}; - -MODULE_DEVICE_TABLE(pnp, fcpnp_ids); -#endif - -static int protocol = 2; /* EURO-ISDN Default */ -module_param(protocol, int, 0); -MODULE_LICENSE("GPL"); - -// ---------------------------------------------------------------------- - -#define AVM_INDEX 0x04 -#define AVM_DATA 0x10 - -#define AVM_IDX_HDLC_1 0x00 -#define AVM_IDX_HDLC_2 0x01 -#define AVM_IDX_ISAC_FIFO 0x02 -#define AVM_IDX_ISAC_REG_LOW 0x04 -#define AVM_IDX_ISAC_REG_HIGH 0x06 - -#define AVM_STATUS0 0x02 - -#define AVM_STATUS0_IRQ_ISAC 0x01 -#define AVM_STATUS0_IRQ_HDLC 0x02 -#define AVM_STATUS0_IRQ_TIMER 0x04 -#define AVM_STATUS0_IRQ_MASK 0x07 - -#define AVM_STATUS0_RESET 0x01 -#define AVM_STATUS0_DIS_TIMER 0x02 -#define AVM_STATUS0_RES_TIMER 0x04 -#define AVM_STATUS0_ENA_IRQ 0x08 -#define AVM_STATUS0_TESTBIT 0x10 - -#define AVM_STATUS1 0x03 -#define AVM_STATUS1_ENA_IOM 0x80 - -#define HDLC_FIFO 0x0 -#define HDLC_STATUS 0x4 -#define HDLC_CTRL 0x4 - -#define HDLC_MODE_ITF_FLG 0x01 -#define HDLC_MODE_TRANS 0x02 -#define HDLC_MODE_CCR_7 0x04 -#define HDLC_MODE_CCR_16 0x08 -#define HDLC_MODE_TESTLOOP 0x80 - -#define HDLC_INT_XPR 0x80 -#define HDLC_INT_XDU 0x40 -#define HDLC_INT_RPR 0x20 -#define HDLC_INT_MASK 0xE0 - -#define HDLC_STAT_RME 0x01 -#define HDLC_STAT_RDO 0x10 -#define HDLC_STAT_CRCVFRRAB 0x0E -#define HDLC_STAT_CRCVFR 0x06 -#define HDLC_STAT_RML_MASK 0xff00 - -#define HDLC_CMD_XRS 0x80 -#define HDLC_CMD_XME 0x01 -#define HDLC_CMD_RRS 0x20 -#define HDLC_CMD_XML_MASK 0xff00 - -#define AVM_HDLC_FIFO_1 0x10 -#define AVM_HDLC_FIFO_2 0x18 - -#define AVM_HDLC_STATUS_1 0x14 -#define AVM_HDLC_STATUS_2 0x1c - -#define AVM_ISACSX_INDEX 0x04 -#define AVM_ISACSX_DATA 0x08 - -// ---------------------------------------------------------------------- -// Fritz!PCI - -static unsigned char fcpci_read_isac(struct isac *isac, unsigned char offset) -{ - struct fritz_adapter *adapter = isac->priv; - unsigned char idx = (offset > 0x2f) ? - AVM_IDX_ISAC_REG_HIGH : AVM_IDX_ISAC_REG_LOW; - unsigned char val; - unsigned long flags; - - spin_lock_irqsave(&adapter->hw_lock, flags); - outb(idx, adapter->io + AVM_INDEX); - val = inb(adapter->io + AVM_DATA + (offset & 0xf)); - spin_unlock_irqrestore(&adapter->hw_lock, flags); - DBG(0x1000, " port %#x, value %#x", - offset, val); - return val; -} - -static void fcpci_write_isac(struct isac *isac, unsigned char offset, - unsigned char value) -{ - struct fritz_adapter *adapter = isac->priv; - unsigned char idx = (offset > 0x2f) ? - AVM_IDX_ISAC_REG_HIGH : AVM_IDX_ISAC_REG_LOW; - unsigned long flags; - - DBG(0x1000, " port %#x, value %#x", - offset, value); - spin_lock_irqsave(&adapter->hw_lock, flags); - outb(idx, adapter->io + AVM_INDEX); - outb(value, adapter->io + AVM_DATA + (offset & 0xf)); - spin_unlock_irqrestore(&adapter->hw_lock, flags); -} - -static void fcpci_read_isac_fifo(struct isac *isac, unsigned char *data, - int size) -{ - struct fritz_adapter *adapter = isac->priv; - unsigned long flags; - - spin_lock_irqsave(&adapter->hw_lock, flags); - outb(AVM_IDX_ISAC_FIFO, adapter->io + AVM_INDEX); - insb(adapter->io + AVM_DATA, data, size); - spin_unlock_irqrestore(&adapter->hw_lock, flags); -} - -static void fcpci_write_isac_fifo(struct isac *isac, unsigned char *data, - int size) -{ - struct fritz_adapter *adapter = isac->priv; - unsigned long flags; - - spin_lock_irqsave(&adapter->hw_lock, flags); - outb(AVM_IDX_ISAC_FIFO, adapter->io + AVM_INDEX); - outsb(adapter->io + AVM_DATA, data, size); - spin_unlock_irqrestore(&adapter->hw_lock, flags); -} - -static u32 fcpci_read_hdlc_status(struct fritz_adapter *adapter, int nr) -{ - u32 val; - int idx = nr ? AVM_IDX_HDLC_2 : AVM_IDX_HDLC_1; - unsigned long flags; - - spin_lock_irqsave(&adapter->hw_lock, flags); - outl(idx, adapter->io + AVM_INDEX); - val = inl(adapter->io + AVM_DATA + HDLC_STATUS); - spin_unlock_irqrestore(&adapter->hw_lock, flags); - return val; -} - -static void __fcpci_write_ctrl(struct fritz_bcs *bcs, int which) -{ - struct fritz_adapter *adapter = bcs->adapter; - int idx = bcs->channel ? AVM_IDX_HDLC_2 : AVM_IDX_HDLC_1; - - DBG(0x40, "hdlc %c wr%x ctrl %x", - 'A' + bcs->channel, which, bcs->ctrl.ctrl); - - outl(idx, adapter->io + AVM_INDEX); - outl(bcs->ctrl.ctrl, adapter->io + AVM_DATA + HDLC_CTRL); -} - -static void fcpci_write_ctrl(struct fritz_bcs *bcs, int which) -{ - struct fritz_adapter *adapter = bcs->adapter; - unsigned long flags; - - spin_lock_irqsave(&adapter->hw_lock, flags); - __fcpci_write_ctrl(bcs, which); - spin_unlock_irqrestore(&adapter->hw_lock, flags); -} - -// ---------------------------------------------------------------------- -// Fritz!PCI v2 - -static unsigned char fcpci2_read_isac(struct isac *isac, unsigned char offset) -{ - struct fritz_adapter *adapter = isac->priv; - unsigned char val; - unsigned long flags; - - spin_lock_irqsave(&adapter->hw_lock, flags); - outl(offset, adapter->io + AVM_ISACSX_INDEX); - val = inl(adapter->io + AVM_ISACSX_DATA); - spin_unlock_irqrestore(&adapter->hw_lock, flags); - DBG(0x1000, " port %#x, value %#x", - offset, val); - - return val; -} - -static void fcpci2_write_isac(struct isac *isac, unsigned char offset, - unsigned char value) -{ - struct fritz_adapter *adapter = isac->priv; - unsigned long flags; - - DBG(0x1000, " port %#x, value %#x", - offset, value); - spin_lock_irqsave(&adapter->hw_lock, flags); - outl(offset, adapter->io + AVM_ISACSX_INDEX); - outl(value, adapter->io + AVM_ISACSX_DATA); - spin_unlock_irqrestore(&adapter->hw_lock, flags); -} - -static void fcpci2_read_isac_fifo(struct isac *isac, unsigned char *data, - int size) -{ - struct fritz_adapter *adapter = isac->priv; - int i; - unsigned long flags; - - spin_lock_irqsave(&adapter->hw_lock, flags); - outl(0, adapter->io + AVM_ISACSX_INDEX); - for (i = 0; i < size; i++) - data[i] = inl(adapter->io + AVM_ISACSX_DATA); - spin_unlock_irqrestore(&adapter->hw_lock, flags); -} - -static void fcpci2_write_isac_fifo(struct isac *isac, unsigned char *data, - int size) -{ - struct fritz_adapter *adapter = isac->priv; - int i; - unsigned long flags; - - spin_lock_irqsave(&adapter->hw_lock, flags); - outl(0, adapter->io + AVM_ISACSX_INDEX); - for (i = 0; i < size; i++) - outl(data[i], adapter->io + AVM_ISACSX_DATA); - spin_unlock_irqrestore(&adapter->hw_lock, flags); -} - -static u32 fcpci2_read_hdlc_status(struct fritz_adapter *adapter, int nr) -{ - int offset = nr ? AVM_HDLC_STATUS_2 : AVM_HDLC_STATUS_1; - - return inl(adapter->io + offset); -} - -static void fcpci2_write_ctrl(struct fritz_bcs *bcs, int which) -{ - struct fritz_adapter *adapter = bcs->adapter; - int offset = bcs->channel ? AVM_HDLC_STATUS_2 : AVM_HDLC_STATUS_1; - - DBG(0x40, "hdlc %c wr%x ctrl %x", - 'A' + bcs->channel, which, bcs->ctrl.ctrl); - - outl(bcs->ctrl.ctrl, adapter->io + offset); -} - -// ---------------------------------------------------------------------- -// Fritz!PnP (ISAC access as for Fritz!PCI) - -static u32 fcpnp_read_hdlc_status(struct fritz_adapter *adapter, int nr) -{ - unsigned char idx = nr ? AVM_IDX_HDLC_2 : AVM_IDX_HDLC_1; - u32 val; - unsigned long flags; - - spin_lock_irqsave(&adapter->hw_lock, flags); - outb(idx, adapter->io + AVM_INDEX); - val = inb(adapter->io + AVM_DATA + HDLC_STATUS); - if (val & HDLC_INT_RPR) - val |= inb(adapter->io + AVM_DATA + HDLC_STATUS + 1) << 8; - spin_unlock_irqrestore(&adapter->hw_lock, flags); - return val; -} - -static void __fcpnp_write_ctrl(struct fritz_bcs *bcs, int which) -{ - struct fritz_adapter *adapter = bcs->adapter; - unsigned char idx = bcs->channel ? AVM_IDX_HDLC_2 : AVM_IDX_HDLC_1; - - DBG(0x40, "hdlc %c wr%x ctrl %x", - 'A' + bcs->channel, which, bcs->ctrl.ctrl); - - outb(idx, adapter->io + AVM_INDEX); - if (which & 4) - outb(bcs->ctrl.sr.mode, - adapter->io + AVM_DATA + HDLC_STATUS + 2); - if (which & 2) - outb(bcs->ctrl.sr.xml, - adapter->io + AVM_DATA + HDLC_STATUS + 1); - if (which & 1) - outb(bcs->ctrl.sr.cmd, - adapter->io + AVM_DATA + HDLC_STATUS + 0); -} - -static void fcpnp_write_ctrl(struct fritz_bcs *bcs, int which) -{ - struct fritz_adapter *adapter = bcs->adapter; - unsigned long flags; - - spin_lock_irqsave(&adapter->hw_lock, flags); - __fcpnp_write_ctrl(bcs, which); - spin_unlock_irqrestore(&adapter->hw_lock, flags); -} - -// ---------------------------------------------------------------------- - -static inline void B_L1L2(struct fritz_bcs *bcs, int pr, void *arg) -{ - struct hisax_if *ifc = (struct hisax_if *) &bcs->b_if; - - DBG(2, "pr %#x", pr); - ifc->l1l2(ifc, pr, arg); -} - -static void hdlc_fill_fifo(struct fritz_bcs *bcs) -{ - struct fritz_adapter *adapter = bcs->adapter; - struct sk_buff *skb = bcs->tx_skb; - int count; - unsigned long flags; - unsigned char *p; - - DBG(0x40, "hdlc_fill_fifo"); - - BUG_ON(skb->len == 0); - - bcs->ctrl.sr.cmd &= ~HDLC_CMD_XME; - if (bcs->tx_skb->len > bcs->fifo_size) { - count = bcs->fifo_size; - } else { - count = bcs->tx_skb->len; - if (bcs->mode != L1_MODE_TRANS) - bcs->ctrl.sr.cmd |= HDLC_CMD_XME; - } - DBG(0x40, "hdlc_fill_fifo %d/%d", count, bcs->tx_skb->len); - p = bcs->tx_skb->data; - skb_pull(bcs->tx_skb, count); - bcs->tx_cnt += count; - bcs->ctrl.sr.xml = ((count == bcs->fifo_size) ? 0 : count); - - switch (adapter->type) { - case AVM_FRITZ_PCI: - spin_lock_irqsave(&adapter->hw_lock, flags); - // sets the correct AVM_INDEX, too - __fcpci_write_ctrl(bcs, 3); - outsl(adapter->io + AVM_DATA + HDLC_FIFO, - p, (count + 3) / 4); - spin_unlock_irqrestore(&adapter->hw_lock, flags); - break; - case AVM_FRITZ_PCIV2: - fcpci2_write_ctrl(bcs, 3); - outsl(adapter->io + - (bcs->channel ? AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1), - p, (count + 3) / 4); - break; - case AVM_FRITZ_PNP: - spin_lock_irqsave(&adapter->hw_lock, flags); - // sets the correct AVM_INDEX, too - __fcpnp_write_ctrl(bcs, 3); - outsb(adapter->io + AVM_DATA, p, count); - spin_unlock_irqrestore(&adapter->hw_lock, flags); - break; - } -} - -static inline void hdlc_empty_fifo(struct fritz_bcs *bcs, int count) -{ - struct fritz_adapter *adapter = bcs->adapter; - unsigned char *p; - unsigned char idx = bcs->channel ? AVM_IDX_HDLC_2 : AVM_IDX_HDLC_1; - - DBG(0x10, "hdlc_empty_fifo %d", count); - if (bcs->rcvidx + count > HSCX_BUFMAX) { - DBG(0x10, "hdlc_empty_fifo: incoming packet too large"); - return; - } - p = bcs->rcvbuf + bcs->rcvidx; - bcs->rcvidx += count; - switch (adapter->type) { - case AVM_FRITZ_PCI: - spin_lock(&adapter->hw_lock); - outl(idx, adapter->io + AVM_INDEX); - insl(adapter->io + AVM_DATA + HDLC_FIFO, - p, (count + 3) / 4); - spin_unlock(&adapter->hw_lock); - break; - case AVM_FRITZ_PCIV2: - insl(adapter->io + - (bcs->channel ? AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1), - p, (count + 3) / 4); - break; - case AVM_FRITZ_PNP: - spin_lock(&adapter->hw_lock); - outb(idx, adapter->io + AVM_INDEX); - insb(adapter->io + AVM_DATA, p, count); - spin_unlock(&adapter->hw_lock); - break; - } -} - -static inline void hdlc_rpr_irq(struct fritz_bcs *bcs, u32 stat) -{ - struct fritz_adapter *adapter = bcs->adapter; - struct sk_buff *skb; - int len; - - if (stat & HDLC_STAT_RDO) { - DBG(0x10, "RDO"); - bcs->ctrl.sr.xml = 0; - bcs->ctrl.sr.cmd |= HDLC_CMD_RRS; - adapter->write_ctrl(bcs, 1); - bcs->ctrl.sr.cmd &= ~HDLC_CMD_RRS; - adapter->write_ctrl(bcs, 1); - bcs->rcvidx = 0; - return; - } - - len = (stat & HDLC_STAT_RML_MASK) >> 8; - if (len == 0) - len = bcs->fifo_size; - - hdlc_empty_fifo(bcs, len); - - if ((stat & HDLC_STAT_RME) || (bcs->mode == L1_MODE_TRANS)) { - if (((stat & HDLC_STAT_CRCVFRRAB) == HDLC_STAT_CRCVFR) || - (bcs->mode == L1_MODE_TRANS)) { - skb = dev_alloc_skb(bcs->rcvidx); - if (!skb) { - printk(KERN_WARNING "HDLC: receive out of memory\n"); - } else { - skb_put_data(skb, bcs->rcvbuf, bcs->rcvidx); - DBG_SKB(1, skb); - B_L1L2(bcs, PH_DATA | INDICATION, skb); - } - bcs->rcvidx = 0; - } else { - DBG(0x10, "ch%d invalid frame %#x", - bcs->channel, stat); - bcs->rcvidx = 0; - } - } -} - -static inline void hdlc_xdu_irq(struct fritz_bcs *bcs) -{ - struct fritz_adapter *adapter = bcs->adapter; - - - /* Here we lost an TX interrupt, so - * restart transmitting the whole frame. - */ - bcs->ctrl.sr.xml = 0; - bcs->ctrl.sr.cmd |= HDLC_CMD_XRS; - adapter->write_ctrl(bcs, 1); - bcs->ctrl.sr.cmd &= ~HDLC_CMD_XRS; - - if (!bcs->tx_skb) { - DBG(0x10, "XDU without skb"); - adapter->write_ctrl(bcs, 1); - return; - } - /* only hdlc restarts the frame, transparent mode must continue */ - if (bcs->mode == L1_MODE_HDLC) { - skb_push(bcs->tx_skb, bcs->tx_cnt); - bcs->tx_cnt = 0; - } -} - -static inline void hdlc_xpr_irq(struct fritz_bcs *bcs) -{ - struct sk_buff *skb; - - skb = bcs->tx_skb; - if (!skb) - return; - - if (skb->len) { - hdlc_fill_fifo(bcs); - return; - } - bcs->tx_cnt = 0; - bcs->tx_skb = NULL; - B_L1L2(bcs, PH_DATA | CONFIRM, (void *)(unsigned long)skb->truesize); - dev_kfree_skb_irq(skb); -} - -static void hdlc_irq_one(struct fritz_bcs *bcs, u32 stat) -{ - DBG(0x10, "ch%d stat %#x", bcs->channel, stat); - if (stat & HDLC_INT_RPR) { - DBG(0x10, "RPR"); - hdlc_rpr_irq(bcs, stat); - } - if (stat & HDLC_INT_XDU) { - DBG(0x10, "XDU"); - hdlc_xdu_irq(bcs); - hdlc_xpr_irq(bcs); - return; - } - if (stat & HDLC_INT_XPR) { - DBG(0x10, "XPR"); - hdlc_xpr_irq(bcs); - } -} - -static inline void hdlc_irq(struct fritz_adapter *adapter) -{ - int nr; - u32 stat; - - for (nr = 0; nr < 2; nr++) { - stat = adapter->read_hdlc_status(adapter, nr); - DBG(0x10, "HDLC %c stat %#x", 'A' + nr, stat); - if (stat & HDLC_INT_MASK) - hdlc_irq_one(&adapter->bcs[nr], stat); - } -} - -static void modehdlc(struct fritz_bcs *bcs, int mode) -{ - struct fritz_adapter *adapter = bcs->adapter; - - DBG(0x40, "hdlc %c mode %d --> %d", - 'A' + bcs->channel, bcs->mode, mode); - - if (bcs->mode == mode) - return; - - bcs->fifo_size = 32; - bcs->ctrl.ctrl = 0; - bcs->ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS; - switch (mode) { - case L1_MODE_NULL: - bcs->ctrl.sr.mode = HDLC_MODE_TRANS; - adapter->write_ctrl(bcs, 5); - break; - case L1_MODE_TRANS: - case L1_MODE_HDLC: - bcs->rcvidx = 0; - bcs->tx_cnt = 0; - bcs->tx_skb = NULL; - if (mode == L1_MODE_TRANS) { - bcs->ctrl.sr.mode = HDLC_MODE_TRANS; - } else { - bcs->ctrl.sr.mode = HDLC_MODE_ITF_FLG; - } - adapter->write_ctrl(bcs, 5); - bcs->ctrl.sr.cmd = HDLC_CMD_XRS; - adapter->write_ctrl(bcs, 1); - bcs->ctrl.sr.cmd = 0; - break; - } - bcs->mode = mode; -} - -static void fritz_b_l2l1(struct hisax_if *ifc, int pr, void *arg) -{ - struct fritz_bcs *bcs = ifc->priv; - struct sk_buff *skb = arg; - int mode; - - DBG(0x10, "pr %#x", pr); - - switch (pr) { - case PH_DATA | REQUEST: - BUG_ON(bcs->tx_skb); - bcs->tx_skb = skb; - DBG_SKB(1, skb); - hdlc_fill_fifo(bcs); - break; - case PH_ACTIVATE | REQUEST: - mode = (long) arg; - DBG(4, "B%d,PH_ACTIVATE_REQUEST %d", bcs->channel + 1, mode); - modehdlc(bcs, mode); - B_L1L2(bcs, PH_ACTIVATE | INDICATION, NULL); - break; - case PH_DEACTIVATE | REQUEST: - DBG(4, "B%d,PH_DEACTIVATE_REQUEST", bcs->channel + 1); - modehdlc(bcs, L1_MODE_NULL); - B_L1L2(bcs, PH_DEACTIVATE | INDICATION, NULL); - break; - } -} - -// ---------------------------------------------------------------------- - -static irqreturn_t -fcpci2_irq(int intno, void *dev) -{ - struct fritz_adapter *adapter = dev; - unsigned char val; - - val = inb(adapter->io + AVM_STATUS0); - if (!(val & AVM_STATUS0_IRQ_MASK)) - /* hopefully a shared IRQ reqest */ - return IRQ_NONE; - DBG(2, "STATUS0 %#x", val); - if (val & AVM_STATUS0_IRQ_ISAC) - isacsx_irq(&adapter->isac); - if (val & AVM_STATUS0_IRQ_HDLC) - hdlc_irq(adapter); - if (val & AVM_STATUS0_IRQ_ISAC) - isacsx_irq(&adapter->isac); - return IRQ_HANDLED; -} - -static irqreturn_t -fcpci_irq(int intno, void *dev) -{ - struct fritz_adapter *adapter = dev; - unsigned char sval; - - sval = inb(adapter->io + 2); - if ((sval & AVM_STATUS0_IRQ_MASK) == AVM_STATUS0_IRQ_MASK) - /* possibly a shared IRQ reqest */ - return IRQ_NONE; - DBG(2, "sval %#x", sval); - if (!(sval & AVM_STATUS0_IRQ_ISAC)) - isac_irq(&adapter->isac); - - if (!(sval & AVM_STATUS0_IRQ_HDLC)) - hdlc_irq(adapter); - return IRQ_HANDLED; -} - -// ---------------------------------------------------------------------- - -static inline void fcpci2_init(struct fritz_adapter *adapter) -{ - outb(AVM_STATUS0_RES_TIMER, adapter->io + AVM_STATUS0); - outb(AVM_STATUS0_ENA_IRQ, adapter->io + AVM_STATUS0); - -} - -static inline void fcpci_init(struct fritz_adapter *adapter) -{ - outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER | - AVM_STATUS0_ENA_IRQ, adapter->io + AVM_STATUS0); - - outb(AVM_STATUS1_ENA_IOM | adapter->irq, - adapter->io + AVM_STATUS1); - mdelay(10); -} - -// ---------------------------------------------------------------------- - -static int fcpcipnp_setup(struct fritz_adapter *adapter) -{ - u32 val = 0; - int retval; - - DBG(1, ""); - - isac_init(&adapter->isac); // FIXME is this okay now - - retval = -EBUSY; - if (!request_region(adapter->io, 32, "fcpcipnp")) - goto err; - - switch (adapter->type) { - case AVM_FRITZ_PCIV2: - case AVM_FRITZ_PCI: - val = inl(adapter->io); - break; - case AVM_FRITZ_PNP: - val = inb(adapter->io); - val |= inb(adapter->io + 1) << 8; - break; - } - - DBG(1, "stat %#x Class %X Rev %d", - val, val & 0xff, (val >> 8) & 0xff); - - spin_lock_init(&adapter->hw_lock); - adapter->isac.priv = adapter; - switch (adapter->type) { - case AVM_FRITZ_PCIV2: - adapter->isac.read_isac = &fcpci2_read_isac; - adapter->isac.write_isac = &fcpci2_write_isac; - adapter->isac.read_isac_fifo = &fcpci2_read_isac_fifo; - adapter->isac.write_isac_fifo = &fcpci2_write_isac_fifo; - - adapter->read_hdlc_status = &fcpci2_read_hdlc_status; - adapter->write_ctrl = &fcpci2_write_ctrl; - break; - case AVM_FRITZ_PCI: - adapter->isac.read_isac = &fcpci_read_isac; - adapter->isac.write_isac = &fcpci_write_isac; - adapter->isac.read_isac_fifo = &fcpci_read_isac_fifo; - adapter->isac.write_isac_fifo = &fcpci_write_isac_fifo; - - adapter->read_hdlc_status = &fcpci_read_hdlc_status; - adapter->write_ctrl = &fcpci_write_ctrl; - break; - case AVM_FRITZ_PNP: - adapter->isac.read_isac = &fcpci_read_isac; - adapter->isac.write_isac = &fcpci_write_isac; - adapter->isac.read_isac_fifo = &fcpci_read_isac_fifo; - adapter->isac.write_isac_fifo = &fcpci_write_isac_fifo; - - adapter->read_hdlc_status = &fcpnp_read_hdlc_status; - adapter->write_ctrl = &fcpnp_write_ctrl; - break; - } - - // Reset - outb(0, adapter->io + AVM_STATUS0); - mdelay(10); - outb(AVM_STATUS0_RESET, adapter->io + AVM_STATUS0); - mdelay(10); - outb(0, adapter->io + AVM_STATUS0); - mdelay(10); - - switch (adapter->type) { - case AVM_FRITZ_PCIV2: - retval = request_irq(adapter->irq, fcpci2_irq, IRQF_SHARED, - "fcpcipnp", adapter); - break; - case AVM_FRITZ_PCI: - retval = request_irq(adapter->irq, fcpci_irq, IRQF_SHARED, - "fcpcipnp", adapter); - break; - case AVM_FRITZ_PNP: - retval = request_irq(adapter->irq, fcpci_irq, 0, - "fcpcipnp", adapter); - break; - } - if (retval) - goto err_region; - - switch (adapter->type) { - case AVM_FRITZ_PCIV2: - fcpci2_init(adapter); - isacsx_setup(&adapter->isac); - break; - case AVM_FRITZ_PCI: - case AVM_FRITZ_PNP: - fcpci_init(adapter); - isac_setup(&adapter->isac); - break; - } - val = adapter->read_hdlc_status(adapter, 0); - DBG(0x20, "HDLC A STA %x", val); - val = adapter->read_hdlc_status(adapter, 1); - DBG(0x20, "HDLC B STA %x", val); - - adapter->bcs[0].mode = -1; - adapter->bcs[1].mode = -1; - modehdlc(&adapter->bcs[0], L1_MODE_NULL); - modehdlc(&adapter->bcs[1], L1_MODE_NULL); - - return 0; - -err_region: - release_region(adapter->io, 32); -err: - return retval; -} - -static void fcpcipnp_release(struct fritz_adapter *adapter) -{ - DBG(1, ""); - - outb(0, adapter->io + AVM_STATUS0); - free_irq(adapter->irq, adapter); - release_region(adapter->io, 32); -} - -// ---------------------------------------------------------------------- - -static struct fritz_adapter *new_adapter(void) -{ - struct fritz_adapter *adapter; - struct hisax_b_if *b_if[2]; - int i; - - adapter = kzalloc(sizeof(struct fritz_adapter), GFP_KERNEL); - if (!adapter) - return NULL; - - adapter->isac.hisax_d_if.owner = THIS_MODULE; - adapter->isac.hisax_d_if.ifc.priv = &adapter->isac; - adapter->isac.hisax_d_if.ifc.l2l1 = isac_d_l2l1; - - for (i = 0; i < 2; i++) { - adapter->bcs[i].adapter = adapter; - adapter->bcs[i].channel = i; - adapter->bcs[i].b_if.ifc.priv = &adapter->bcs[i]; - adapter->bcs[i].b_if.ifc.l2l1 = fritz_b_l2l1; - } - - for (i = 0; i < 2; i++) - b_if[i] = &adapter->bcs[i].b_if; - - if (hisax_register(&adapter->isac.hisax_d_if, b_if, "fcpcipnp", - protocol) != 0) { - kfree(adapter); - adapter = NULL; - } - - return adapter; -} - -static void delete_adapter(struct fritz_adapter *adapter) -{ - hisax_unregister(&adapter->isac.hisax_d_if); - kfree(adapter); -} - -static int fcpci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - struct fritz_adapter *adapter; - int retval; - - retval = -ENOMEM; - adapter = new_adapter(); - if (!adapter) - goto err; - - pci_set_drvdata(pdev, adapter); - - if (pdev->device == PCI_DEVICE_ID_AVM_A1_V2) - adapter->type = AVM_FRITZ_PCIV2; - else - adapter->type = AVM_FRITZ_PCI; - - retval = pci_enable_device(pdev); - if (retval) - goto err_free; - - adapter->io = pci_resource_start(pdev, 1); - adapter->irq = pdev->irq; - - printk(KERN_INFO "hisax_fcpcipnp: found adapter %s at %s\n", - (char *) ent->driver_data, pci_name(pdev)); - - retval = fcpcipnp_setup(adapter); - if (retval) - goto err_free; - - return 0; - -err_free: - delete_adapter(adapter); -err: - return retval; -} - -#ifdef CONFIG_PNP -static int fcpnp_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) -{ - struct fritz_adapter *adapter; - int retval; - - if (!pdev) - return (-ENODEV); - - retval = -ENOMEM; - adapter = new_adapter(); - if (!adapter) - goto err; - - pnp_set_drvdata(pdev, adapter); - - adapter->type = AVM_FRITZ_PNP; - - pnp_disable_dev(pdev); - retval = pnp_activate_dev(pdev); - if (retval < 0) { - printk(KERN_WARNING "%s: pnp_activate_dev(%s) ret(%d)\n", __func__, - (char *)dev_id->driver_data, retval); - goto err_free; - } - adapter->io = pnp_port_start(pdev, 0); - adapter->irq = pnp_irq(pdev, 0); - if (!adapter->io || adapter->irq == -1) - goto err_free; - - printk(KERN_INFO "hisax_fcpcipnp: found adapter %s at IO %#x irq %d\n", - (char *) dev_id->driver_data, adapter->io, adapter->irq); - - retval = fcpcipnp_setup(adapter); - if (retval) - goto err_free; - - return 0; - -err_free: - delete_adapter(adapter); -err: - return retval; -} - -static void fcpnp_remove(struct pnp_dev *pdev) -{ - struct fritz_adapter *adapter = pnp_get_drvdata(pdev); - - if (adapter) { - fcpcipnp_release(adapter); - delete_adapter(adapter); - } - pnp_disable_dev(pdev); -} - -static struct pnp_driver fcpnp_driver = { - .name = "fcpnp", - .probe = fcpnp_probe, - .remove = fcpnp_remove, - .id_table = fcpnp_ids, -}; -#endif - -static void fcpci_remove(struct pci_dev *pdev) -{ - struct fritz_adapter *adapter = pci_get_drvdata(pdev); - - fcpcipnp_release(adapter); - pci_disable_device(pdev); - delete_adapter(adapter); -} - -static struct pci_driver fcpci_driver = { - .name = "fcpci", - .probe = fcpci_probe, - .remove = fcpci_remove, - .id_table = fcpci_ids, -}; - -static int __init hisax_fcpcipnp_init(void) -{ - int retval; - - printk(KERN_INFO "hisax_fcpcipnp: Fritz!Card PCI/PCIv2/PnP ISDN driver v0.0.1\n"); - - retval = pci_register_driver(&fcpci_driver); - if (retval) - return retval; -#ifdef CONFIG_PNP - retval = pnp_register_driver(&fcpnp_driver); - if (retval < 0) { - pci_unregister_driver(&fcpci_driver); - return retval; - } -#endif - return 0; -} - -static void __exit hisax_fcpcipnp_exit(void) -{ -#ifdef CONFIG_PNP - pnp_unregister_driver(&fcpnp_driver); -#endif - pci_unregister_driver(&fcpci_driver); -} - -module_init(hisax_fcpcipnp_init); -module_exit(hisax_fcpcipnp_exit); diff --git a/drivers/isdn/hisax/hisax_fcpcipnp.h b/drivers/isdn/hisax/hisax_fcpcipnp.h deleted file mode 100644 index 1f64e9937aa1..000000000000 --- a/drivers/isdn/hisax/hisax_fcpcipnp.h +++ /dev/null @@ -1,58 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#include "hisax_if.h" -#include "hisax_isac.h" -#include <linux/pci.h> - -#define HSCX_BUFMAX 4096 - -enum { - AVM_FRITZ_PCI, - AVM_FRITZ_PNP, - AVM_FRITZ_PCIV2, -}; - -struct hdlc_stat_reg { -#ifdef __BIG_ENDIAN - u_char fill; - u_char mode; - u_char xml; - u_char cmd; -#else - u_char cmd; - u_char xml; - u_char mode; - u_char fill; -#endif -} __attribute__((packed)); - -struct fritz_bcs { - struct hisax_b_if b_if; - struct fritz_adapter *adapter; - int mode; - int channel; - - union { - u_int ctrl; - struct hdlc_stat_reg sr; - } ctrl; - u_int stat; - int rcvidx; - int fifo_size; - u_char rcvbuf[HSCX_BUFMAX]; /* B-Channel receive Buffer */ - - int tx_cnt; /* B-Channel transmit counter */ - struct sk_buff *tx_skb; /* B-Channel transmit Buffer */ -}; - -struct fritz_adapter { - int type; - spinlock_t hw_lock; - unsigned int io; - unsigned int irq; - struct isac isac; - - struct fritz_bcs bcs[2]; - - u32 (*read_hdlc_status) (struct fritz_adapter *adapter, int nr); - void (*write_ctrl) (struct fritz_bcs *bcs, int which); -}; diff --git a/drivers/isdn/hisax/hisax_if.h b/drivers/isdn/hisax/hisax_if.h deleted file mode 100644 index 7098d6bd5ff2..000000000000 --- a/drivers/isdn/hisax/hisax_if.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Interface between low level (hardware) drivers and - * HiSax protocol stack - * - * Author Kai Germaschewski - * Copyright 2001 by Kai Germaschewski <kai.germaschewski@gmx.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#ifndef __HISAX_IF_H__ -#define __HISAX_IF_H__ - -#include <linux/skbuff.h> - -#define REQUEST 0 -#define CONFIRM 1 -#define INDICATION 2 -#define RESPONSE 3 - -#define PH_ACTIVATE 0x0100 -#define PH_DEACTIVATE 0x0110 -#define PH_DATA 0x0120 -#define PH_PULL 0x0130 -#define PH_DATA_E 0x0140 - -#define L1_MODE_NULL 0 -#define L1_MODE_TRANS 1 -#define L1_MODE_HDLC 2 -#define L1_MODE_EXTRN 3 -#define L1_MODE_HDLC_56K 4 -#define L1_MODE_MODEM 7 -#define L1_MODE_V32 8 -#define L1_MODE_FAX 9 - -struct hisax_if { - void *priv; // private to driver - void (*l1l2)(struct hisax_if *, int pr, void *arg); - void (*l2l1)(struct hisax_if *, int pr, void *arg); -}; - -struct hisax_b_if { - struct hisax_if ifc; - - // private to hisax - struct BCState *bcs; -}; - -struct hisax_d_if { - struct hisax_if ifc; - - // private to hisax - struct module *owner; - struct IsdnCardState *cs; - struct hisax_b_if *b_if[2]; - struct sk_buff_head erq; - unsigned long ph_state; -}; - -int hisax_register(struct hisax_d_if *hisax_if, struct hisax_b_if *b_if[], - char *name, int protocol); -void hisax_unregister(struct hisax_d_if *hisax_if); - -#endif diff --git a/drivers/isdn/hisax/hisax_isac.c b/drivers/isdn/hisax/hisax_isac.c deleted file mode 100644 index 0f36375478c5..000000000000 --- a/drivers/isdn/hisax/hisax_isac.c +++ /dev/null @@ -1,895 +0,0 @@ -/* - * Driver for ISAC-S and ISAC-SX - * ISDN Subscriber Access Controller for Terminals - * - * Author Kai Germaschewski - * Copyright 2001 by Kai Germaschewski <kai.germaschewski@gmx.de> - * 2001 by Karsten Keil <keil@isdn4linux.de> - * - * based upon Karsten Keil's original isac.c driver - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * Thanks to Wizard Computersysteme GmbH, Bremervoerde and - * SoHaNet Technology GmbH, Berlin - * for supporting the development of this driver - */ - -/* TODO: - * specifically handle level vs edge triggered? - */ - -#include <linux/module.h> -#include <linux/gfp.h> -#include <linux/init.h> -#include <linux/netdevice.h> -#include "hisax_isac.h" - -// debugging cruft - -#define __debug_variable debug -#include "hisax_debug.h" - -#ifdef CONFIG_HISAX_DEBUG -static int debug = 1; -module_param(debug, int, 0); - -static char *ISACVer[] = { - "2086/2186 V1.1", - "2085 B1", - "2085 B2", - "2085 V2.3" -}; -#endif - -MODULE_AUTHOR("Kai Germaschewski <kai.germaschewski@gmx.de>/Karsten Keil <kkeil@suse.de>"); -MODULE_DESCRIPTION("ISAC/ISAC-SX driver"); -MODULE_LICENSE("GPL"); - -#define DBG_WARN 0x0001 -#define DBG_IRQ 0x0002 -#define DBG_L1M 0x0004 -#define DBG_PR 0x0008 -#define DBG_RFIFO 0x0100 -#define DBG_RPACKET 0x0200 -#define DBG_XFIFO 0x1000 -#define DBG_XPACKET 0x2000 - -// we need to distinguish ISAC-S and ISAC-SX -#define TYPE_ISAC 0x00 -#define TYPE_ISACSX 0x01 - -// registers etc. -#define ISAC_MASK 0x20 -#define ISAC_ISTA 0x20 -#define ISAC_ISTA_EXI 0x01 -#define ISAC_ISTA_SIN 0x02 -#define ISAC_ISTA_CISQ 0x04 -#define ISAC_ISTA_XPR 0x10 -#define ISAC_ISTA_RSC 0x20 -#define ISAC_ISTA_RPF 0x40 -#define ISAC_ISTA_RME 0x80 - -#define ISAC_STAR 0x21 -#define ISAC_CMDR 0x21 -#define ISAC_CMDR_XRES 0x01 -#define ISAC_CMDR_XME 0x02 -#define ISAC_CMDR_XTF 0x08 -#define ISAC_CMDR_RRES 0x40 -#define ISAC_CMDR_RMC 0x80 - -#define ISAC_EXIR 0x24 -#define ISAC_EXIR_MOS 0x04 -#define ISAC_EXIR_XDU 0x40 -#define ISAC_EXIR_XMR 0x80 - -#define ISAC_ADF2 0x39 -#define ISAC_SPCR 0x30 -#define ISAC_ADF1 0x38 - -#define ISAC_CIR0 0x31 -#define ISAC_CIX0 0x31 -#define ISAC_CIR0_CIC0 0x02 -#define ISAC_CIR0_CIC1 0x01 - -#define ISAC_CIR1 0x33 -#define ISAC_CIX1 0x33 -#define ISAC_STCR 0x37 -#define ISAC_MODE 0x22 - -#define ISAC_RSTA 0x27 -#define ISAC_RSTA_RDO 0x40 -#define ISAC_RSTA_CRC 0x20 -#define ISAC_RSTA_RAB 0x10 - -#define ISAC_RBCL 0x25 -#define ISAC_RBCH 0x2A -#define ISAC_TIMR 0x23 -#define ISAC_SQXR 0x3b -#define ISAC_MOSR 0x3a -#define ISAC_MOCR 0x3a -#define ISAC_MOR0 0x32 -#define ISAC_MOX0 0x32 -#define ISAC_MOR1 0x34 -#define ISAC_MOX1 0x34 - -#define ISAC_RBCH_XAC 0x80 - -#define ISAC_CMD_TIM 0x0 -#define ISAC_CMD_RES 0x1 -#define ISAC_CMD_SSP 0x2 -#define ISAC_CMD_SCP 0x3 -#define ISAC_CMD_AR8 0x8 -#define ISAC_CMD_AR10 0x9 -#define ISAC_CMD_ARL 0xa -#define ISAC_CMD_DI 0xf - -#define ISACSX_MASK 0x60 -#define ISACSX_ISTA 0x60 -#define ISACSX_ISTA_ICD 0x01 -#define ISACSX_ISTA_CIC 0x10 - -#define ISACSX_MASKD 0x20 -#define ISACSX_ISTAD 0x20 -#define ISACSX_ISTAD_XDU 0x04 -#define ISACSX_ISTAD_XMR 0x08 -#define ISACSX_ISTAD_XPR 0x10 -#define ISACSX_ISTAD_RFO 0x20 -#define ISACSX_ISTAD_RPF 0x40 -#define ISACSX_ISTAD_RME 0x80 - -#define ISACSX_CMDRD 0x21 -#define ISACSX_CMDRD_XRES 0x01 -#define ISACSX_CMDRD_XME 0x02 -#define ISACSX_CMDRD_XTF 0x08 -#define ISACSX_CMDRD_RRES 0x40 -#define ISACSX_CMDRD_RMC 0x80 - -#define ISACSX_MODED 0x22 - -#define ISACSX_RBCLD 0x26 - -#define ISACSX_RSTAD 0x28 -#define ISACSX_RSTAD_RAB 0x10 -#define ISACSX_RSTAD_CRC 0x20 -#define ISACSX_RSTAD_RDO 0x40 -#define ISACSX_RSTAD_VFR 0x80 - -#define ISACSX_CIR0 0x2e -#define ISACSX_CIR0_CIC0 0x08 -#define ISACSX_CIX0 0x2e - -#define ISACSX_TR_CONF0 0x30 - -#define ISACSX_TR_CONF2 0x32 - -static struct Fsm l1fsm; - -enum { - ST_L1_RESET, - ST_L1_F3_PDOWN, - ST_L1_F3_PUP, - ST_L1_F3_PEND_DEACT, - ST_L1_F4, - ST_L1_F5, - ST_L1_F6, - ST_L1_F7, - ST_L1_F8, -}; - -#define L1_STATE_COUNT (ST_L1_F8 + 1) - -static char *strL1State[] = -{ - "ST_L1_RESET", - "ST_L1_F3_PDOWN", - "ST_L1_F3_PUP", - "ST_L1_F3_PEND_DEACT", - "ST_L1_F4", - "ST_L1_F5", - "ST_L1_F6", - "ST_L1_F7", - "ST_L1_F8", -}; - -enum { - EV_PH_DR, // 0000 - EV_PH_RES, // 0001 - EV_PH_TMA, // 0010 - EV_PH_SLD, // 0011 - EV_PH_RSY, // 0100 - EV_PH_DR6, // 0101 - EV_PH_EI, // 0110 - EV_PH_PU, // 0111 - EV_PH_AR, // 1000 - EV_PH_9, // 1001 - EV_PH_ARL, // 1010 - EV_PH_CVR, // 1011 - EV_PH_AI8, // 1100 - EV_PH_AI10, // 1101 - EV_PH_AIL, // 1110 - EV_PH_DC, // 1111 - EV_PH_ACTIVATE_REQ, - EV_PH_DEACTIVATE_REQ, - EV_TIMER3, -}; - -#define L1_EVENT_COUNT (EV_TIMER3 + 1) - -static char *strL1Event[] = -{ - "EV_PH_DR", // 0000 - "EV_PH_RES", // 0001 - "EV_PH_TMA", // 0010 - "EV_PH_SLD", // 0011 - "EV_PH_RSY", // 0100 - "EV_PH_DR6", // 0101 - "EV_PH_EI", // 0110 - "EV_PH_PU", // 0111 - "EV_PH_AR", // 1000 - "EV_PH_9", // 1001 - "EV_PH_ARL", // 1010 - "EV_PH_CVR", // 1011 - "EV_PH_AI8", // 1100 - "EV_PH_AI10", // 1101 - "EV_PH_AIL", // 1110 - "EV_PH_DC", // 1111 - "EV_PH_ACTIVATE_REQ", - "EV_PH_DEACTIVATE_REQ", - "EV_TIMER3", -}; - -static inline void D_L1L2(struct isac *isac, int pr, void *arg) -{ - struct hisax_if *ifc = (struct hisax_if *) &isac->hisax_d_if; - - DBG(DBG_PR, "pr %#x", pr); - ifc->l1l2(ifc, pr, arg); -} - -static void ph_command(struct isac *isac, unsigned int command) -{ - DBG(DBG_L1M, "ph_command %#x", command); - switch (isac->type) { - case TYPE_ISAC: - isac->write_isac(isac, ISAC_CIX0, (command << 2) | 3); - break; - case TYPE_ISACSX: - isac->write_isac(isac, ISACSX_CIX0, (command << 4) | (7 << 1)); - break; - } -} - -// ---------------------------------------------------------------------- - -static void l1_di(struct FsmInst *fi, int event, void *arg) -{ - struct isac *isac = fi->userdata; - - FsmChangeState(fi, ST_L1_RESET); - ph_command(isac, ISAC_CMD_DI); -} - -static void l1_di_deact_ind(struct FsmInst *fi, int event, void *arg) -{ - struct isac *isac = fi->userdata; - - FsmChangeState(fi, ST_L1_RESET); - D_L1L2(isac, PH_DEACTIVATE | INDICATION, NULL); - ph_command(isac, ISAC_CMD_DI); -} - -static void l1_go_f3pdown(struct FsmInst *fi, int event, void *arg) -{ - FsmChangeState(fi, ST_L1_F3_PDOWN); -} - -static void l1_go_f3pend_deact_ind(struct FsmInst *fi, int event, void *arg) -{ - struct isac *isac = fi->userdata; - - FsmChangeState(fi, ST_L1_F3_PEND_DEACT); - D_L1L2(isac, PH_DEACTIVATE | INDICATION, NULL); - ph_command(isac, ISAC_CMD_DI); -} - -static void l1_go_f3pend(struct FsmInst *fi, int event, void *arg) -{ - struct isac *isac = fi->userdata; - - FsmChangeState(fi, ST_L1_F3_PEND_DEACT); - ph_command(isac, ISAC_CMD_DI); -} - -static void l1_go_f4(struct FsmInst *fi, int event, void *arg) -{ - FsmChangeState(fi, ST_L1_F4); -} - -static void l1_go_f5(struct FsmInst *fi, int event, void *arg) -{ - FsmChangeState(fi, ST_L1_F5); -} - -static void l1_go_f6(struct FsmInst *fi, int event, void *arg) -{ - FsmChangeState(fi, ST_L1_F6); -} - -static void l1_go_f6_deact_ind(struct FsmInst *fi, int event, void *arg) -{ - struct isac *isac = fi->userdata; - - FsmChangeState(fi, ST_L1_F6); - D_L1L2(isac, PH_DEACTIVATE | INDICATION, NULL); -} - -static void l1_go_f7_act_ind(struct FsmInst *fi, int event, void *arg) -{ - struct isac *isac = fi->userdata; - - FsmDelTimer(&isac->timer, 0); - FsmChangeState(fi, ST_L1_F7); - ph_command(isac, ISAC_CMD_AR8); - D_L1L2(isac, PH_ACTIVATE | INDICATION, NULL); -} - -static void l1_go_f8(struct FsmInst *fi, int event, void *arg) -{ - FsmChangeState(fi, ST_L1_F8); -} - -static void l1_go_f8_deact_ind(struct FsmInst *fi, int event, void *arg) -{ - struct isac *isac = fi->userdata; - - FsmChangeState(fi, ST_L1_F8); - D_L1L2(isac, PH_DEACTIVATE | INDICATION, NULL); -} - -static void l1_ar8(struct FsmInst *fi, int event, void *arg) -{ - struct isac *isac = fi->userdata; - - FsmRestartTimer(&isac->timer, TIMER3_VALUE, EV_TIMER3, NULL, 2); - ph_command(isac, ISAC_CMD_AR8); -} - -static void l1_timer3(struct FsmInst *fi, int event, void *arg) -{ - struct isac *isac = fi->userdata; - - ph_command(isac, ISAC_CMD_DI); - D_L1L2(isac, PH_DEACTIVATE | INDICATION, NULL); -} - -// state machines according to data sheet PSB 2186 / 3186 - -static struct FsmNode L1FnList[] __initdata = -{ - {ST_L1_RESET, EV_PH_RES, l1_di}, - {ST_L1_RESET, EV_PH_EI, l1_di}, - {ST_L1_RESET, EV_PH_DC, l1_go_f3pdown}, - {ST_L1_RESET, EV_PH_AR, l1_go_f6}, - {ST_L1_RESET, EV_PH_AI8, l1_go_f7_act_ind}, - - {ST_L1_F3_PDOWN, EV_PH_RES, l1_di}, - {ST_L1_F3_PDOWN, EV_PH_EI, l1_di}, - {ST_L1_F3_PDOWN, EV_PH_AR, l1_go_f6}, - {ST_L1_F3_PDOWN, EV_PH_RSY, l1_go_f5}, - {ST_L1_F3_PDOWN, EV_PH_PU, l1_go_f4}, - {ST_L1_F3_PDOWN, EV_PH_AI8, l1_go_f7_act_ind}, - {ST_L1_F3_PDOWN, EV_PH_ACTIVATE_REQ, l1_ar8}, - {ST_L1_F3_PDOWN, EV_TIMER3, l1_timer3}, - - {ST_L1_F3_PEND_DEACT, EV_PH_RES, l1_di}, - {ST_L1_F3_PEND_DEACT, EV_PH_EI, l1_di}, - {ST_L1_F3_PEND_DEACT, EV_PH_DC, l1_go_f3pdown}, - {ST_L1_F3_PEND_DEACT, EV_PH_RSY, l1_go_f5}, - {ST_L1_F3_PEND_DEACT, EV_PH_AR, l1_go_f6}, - {ST_L1_F3_PEND_DEACT, EV_PH_AI8, l1_go_f7_act_ind}, - - {ST_L1_F4, EV_PH_RES, l1_di}, - {ST_L1_F4, EV_PH_EI, l1_di}, - {ST_L1_F4, EV_PH_RSY, l1_go_f5}, - {ST_L1_F4, EV_PH_AI8, l1_go_f7_act_ind}, - {ST_L1_F4, EV_TIMER3, l1_timer3}, - {ST_L1_F4, EV_PH_DC, l1_go_f3pdown}, - - {ST_L1_F5, EV_PH_RES, l1_di}, - {ST_L1_F5, EV_PH_EI, l1_di}, - {ST_L1_F5, EV_PH_AR, l1_go_f6}, - {ST_L1_F5, EV_PH_AI8, l1_go_f7_act_ind}, - {ST_L1_F5, EV_TIMER3, l1_timer3}, - {ST_L1_F5, EV_PH_DR, l1_go_f3pend}, - {ST_L1_F5, EV_PH_DC, l1_go_f3pdown}, - - {ST_L1_F6, EV_PH_RES, l1_di}, - {ST_L1_F6, EV_PH_EI, l1_di}, - {ST_L1_F6, EV_PH_RSY, l1_go_f8}, - {ST_L1_F6, EV_PH_AI8, l1_go_f7_act_ind}, - {ST_L1_F6, EV_PH_DR6, l1_go_f3pend}, - {ST_L1_F6, EV_TIMER3, l1_timer3}, - {ST_L1_F6, EV_PH_DC, l1_go_f3pdown}, - - {ST_L1_F7, EV_PH_RES, l1_di_deact_ind}, - {ST_L1_F7, EV_PH_EI, l1_di_deact_ind}, - {ST_L1_F7, EV_PH_AR, l1_go_f6_deact_ind}, - {ST_L1_F7, EV_PH_RSY, l1_go_f8_deact_ind}, - {ST_L1_F7, EV_PH_DR, l1_go_f3pend_deact_ind}, - - {ST_L1_F8, EV_PH_RES, l1_di}, - {ST_L1_F8, EV_PH_EI, l1_di}, - {ST_L1_F8, EV_PH_AR, l1_go_f6}, - {ST_L1_F8, EV_PH_DR, l1_go_f3pend}, - {ST_L1_F8, EV_PH_AI8, l1_go_f7_act_ind}, - {ST_L1_F8, EV_TIMER3, l1_timer3}, - {ST_L1_F8, EV_PH_DC, l1_go_f3pdown}, -}; - -static void l1m_debug(struct FsmInst *fi, char *fmt, ...) -{ - va_list args; - char buf[256]; - - va_start(args, fmt); - vsnprintf(buf, sizeof(buf), fmt, args); - DBG(DBG_L1M, "%s", buf); - va_end(args); -} - -static void isac_version(struct isac *cs) -{ - int val; - - val = cs->read_isac(cs, ISAC_RBCH); - DBG(1, "ISAC version (%x): %s", val, ISACVer[(val >> 5) & 3]); -} - -static void isac_empty_fifo(struct isac *isac, int count) -{ - // this also works for isacsx, since - // CMDR(D) register works the same - u_char *ptr; - - DBG(DBG_IRQ, "count %d", count); - - if ((isac->rcvidx + count) >= MAX_DFRAME_LEN_L1) { - DBG(DBG_WARN, "overrun %d", isac->rcvidx + count); - isac->write_isac(isac, ISAC_CMDR, ISAC_CMDR_RMC); - isac->rcvidx = 0; - return; - } - ptr = isac->rcvbuf + isac->rcvidx; - isac->rcvidx += count; - isac->read_isac_fifo(isac, ptr, count); - isac->write_isac(isac, ISAC_CMDR, ISAC_CMDR_RMC); - DBG_PACKET(DBG_RFIFO, ptr, count); -} - -static void isac_fill_fifo(struct isac *isac) -{ - // this also works for isacsx, since - // CMDR(D) register works the same - - int count; - unsigned char cmd; - u_char *ptr; - - BUG_ON(!isac->tx_skb); - - count = isac->tx_skb->len; - BUG_ON(count <= 0); - - DBG(DBG_IRQ, "count %d", count); - - if (count > 0x20) { - count = 0x20; - cmd = ISAC_CMDR_XTF; - } else { - cmd = ISAC_CMDR_XTF | ISAC_CMDR_XME; - } - - ptr = isac->tx_skb->data; - skb_pull(isac->tx_skb, count); - isac->tx_cnt += count; - DBG_PACKET(DBG_XFIFO, ptr, count); - isac->write_isac_fifo(isac, ptr, count); - isac->write_isac(isac, ISAC_CMDR, cmd); -} - -static void isac_retransmit(struct isac *isac) -{ - if (!isac->tx_skb) { - DBG(DBG_WARN, "no skb"); - return; - } - skb_push(isac->tx_skb, isac->tx_cnt); - isac->tx_cnt = 0; -} - - -static inline void isac_cisq_interrupt(struct isac *isac) -{ - unsigned char val; - - val = isac->read_isac(isac, ISAC_CIR0); - DBG(DBG_IRQ, "CIR0 %#x", val); - if (val & ISAC_CIR0_CIC0) { - DBG(DBG_IRQ, "CODR0 %#x", (val >> 2) & 0xf); - FsmEvent(&isac->l1m, (val >> 2) & 0xf, NULL); - } - if (val & ISAC_CIR0_CIC1) { - val = isac->read_isac(isac, ISAC_CIR1); - DBG(DBG_WARN, "ISAC CIR1 %#x", val); - } -} - -static inline void isac_rme_interrupt(struct isac *isac) -{ - unsigned char val; - int count; - struct sk_buff *skb; - - val = isac->read_isac(isac, ISAC_RSTA); - if ((val & (ISAC_RSTA_RDO | ISAC_RSTA_CRC | ISAC_RSTA_RAB)) - != ISAC_RSTA_CRC) { - DBG(DBG_WARN, "RSTA %#x, dropped", val); - isac->write_isac(isac, ISAC_CMDR, ISAC_CMDR_RMC); - goto out; - } - - count = isac->read_isac(isac, ISAC_RBCL) & 0x1f; - DBG(DBG_IRQ, "RBCL %#x", count); - if (count == 0) - count = 0x20; - - isac_empty_fifo(isac, count); - count = isac->rcvidx; - if (count < 1) { - DBG(DBG_WARN, "count %d < 1", count); - goto out; - } - - skb = alloc_skb(count, GFP_ATOMIC); - if (!skb) { - DBG(DBG_WARN, "no memory, dropping\n"); - goto out; - } - skb_put_data(skb, isac->rcvbuf, count); - DBG_SKB(DBG_RPACKET, skb); - D_L1L2(isac, PH_DATA | INDICATION, skb); -out: - isac->rcvidx = 0; -} - -static inline void isac_xpr_interrupt(struct isac *isac) -{ - if (!isac->tx_skb) - return; - - if (isac->tx_skb->len > 0) { - isac_fill_fifo(isac); - return; - } - dev_kfree_skb_irq(isac->tx_skb); - isac->tx_cnt = 0; - isac->tx_skb = NULL; - D_L1L2(isac, PH_DATA | CONFIRM, NULL); -} - -static inline void isac_exi_interrupt(struct isac *isac) -{ - unsigned char val; - - val = isac->read_isac(isac, ISAC_EXIR); - DBG(2, "EXIR %#x", val); - - if (val & ISAC_EXIR_XMR) { - DBG(DBG_WARN, "ISAC XMR"); - isac_retransmit(isac); - } - if (val & ISAC_EXIR_XDU) { - DBG(DBG_WARN, "ISAC XDU"); - isac_retransmit(isac); - } - if (val & ISAC_EXIR_MOS) { /* MOS */ - DBG(DBG_WARN, "MOS"); - val = isac->read_isac(isac, ISAC_MOSR); - DBG(2, "ISAC MOSR %#x", val); - } -} - -void isac_irq(struct isac *isac) -{ - unsigned char val; - - val = isac->read_isac(isac, ISAC_ISTA); - DBG(DBG_IRQ, "ISTA %#x", val); - - if (val & ISAC_ISTA_EXI) { - DBG(DBG_IRQ, "EXI"); - isac_exi_interrupt(isac); - } - if (val & ISAC_ISTA_XPR) { - DBG(DBG_IRQ, "XPR"); - isac_xpr_interrupt(isac); - } - if (val & ISAC_ISTA_RME) { - DBG(DBG_IRQ, "RME"); - isac_rme_interrupt(isac); - } - if (val & ISAC_ISTA_RPF) { - DBG(DBG_IRQ, "RPF"); - isac_empty_fifo(isac, 0x20); - } - if (val & ISAC_ISTA_CISQ) { - DBG(DBG_IRQ, "CISQ"); - isac_cisq_interrupt(isac); - } - if (val & ISAC_ISTA_RSC) { - DBG(DBG_WARN, "RSC"); - } - if (val & ISAC_ISTA_SIN) { - DBG(DBG_WARN, "SIN"); - } - isac->write_isac(isac, ISAC_MASK, 0xff); - isac->write_isac(isac, ISAC_MASK, 0x00); -} - -// ====================================================================== - -static inline void isacsx_cic_interrupt(struct isac *isac) -{ - unsigned char val; - - val = isac->read_isac(isac, ISACSX_CIR0); - DBG(DBG_IRQ, "CIR0 %#x", val); - if (val & ISACSX_CIR0_CIC0) { - DBG(DBG_IRQ, "CODR0 %#x", val >> 4); - FsmEvent(&isac->l1m, val >> 4, NULL); - } -} - -static inline void isacsx_rme_interrupt(struct isac *isac) -{ - int count; - struct sk_buff *skb; - unsigned char val; - - val = isac->read_isac(isac, ISACSX_RSTAD); - if ((val & (ISACSX_RSTAD_VFR | - ISACSX_RSTAD_RDO | - ISACSX_RSTAD_CRC | - ISACSX_RSTAD_RAB)) - != (ISACSX_RSTAD_VFR | ISACSX_RSTAD_CRC)) { - DBG(DBG_WARN, "RSTAD %#x, dropped", val); - isac->write_isac(isac, ISACSX_CMDRD, ISACSX_CMDRD_RMC); - goto out; - } - - count = isac->read_isac(isac, ISACSX_RBCLD) & 0x1f; - DBG(DBG_IRQ, "RBCLD %#x", count); - if (count == 0) - count = 0x20; - - isac_empty_fifo(isac, count); - // strip trailing status byte - count = isac->rcvidx - 1; - if (count < 1) { - DBG(DBG_WARN, "count %d < 1", count); - goto out; - } - - skb = dev_alloc_skb(count); - if (!skb) { - DBG(DBG_WARN, "no memory, dropping"); - goto out; - } - skb_put_data(skb, isac->rcvbuf, count); - DBG_SKB(DBG_RPACKET, skb); - D_L1L2(isac, PH_DATA | INDICATION, skb); -out: - isac->rcvidx = 0; -} - -static inline void isacsx_xpr_interrupt(struct isac *isac) -{ - if (!isac->tx_skb) - return; - - if (isac->tx_skb->len > 0) { - isac_fill_fifo(isac); - return; - } - dev_kfree_skb_irq(isac->tx_skb); - isac->tx_skb = NULL; - isac->tx_cnt = 0; - D_L1L2(isac, PH_DATA | CONFIRM, NULL); -} - -static inline void isacsx_icd_interrupt(struct isac *isac) -{ - unsigned char val; - - val = isac->read_isac(isac, ISACSX_ISTAD); - DBG(DBG_IRQ, "ISTAD %#x", val); - if (val & ISACSX_ISTAD_XDU) { - DBG(DBG_WARN, "ISTAD XDU"); - isac_retransmit(isac); - } - if (val & ISACSX_ISTAD_XMR) { - DBG(DBG_WARN, "ISTAD XMR"); - isac_retransmit(isac); - } - if (val & ISACSX_ISTAD_XPR) { - DBG(DBG_IRQ, "ISTAD XPR"); - isacsx_xpr_interrupt(isac); - } - if (val & ISACSX_ISTAD_RFO) { - DBG(DBG_WARN, "ISTAD RFO"); - isac->write_isac(isac, ISACSX_CMDRD, ISACSX_CMDRD_RMC); - } - if (val & ISACSX_ISTAD_RME) { - DBG(DBG_IRQ, "ISTAD RME"); - isacsx_rme_interrupt(isac); - } - if (val & ISACSX_ISTAD_RPF) { - DBG(DBG_IRQ, "ISTAD RPF"); - isac_empty_fifo(isac, 0x20); - } -} - -void isacsx_irq(struct isac *isac) -{ - unsigned char val; - - val = isac->read_isac(isac, ISACSX_ISTA); - DBG(DBG_IRQ, "ISTA %#x", val); - - if (val & ISACSX_ISTA_ICD) - isacsx_icd_interrupt(isac); - if (val & ISACSX_ISTA_CIC) - isacsx_cic_interrupt(isac); -} - -void isac_init(struct isac *isac) -{ - isac->tx_skb = NULL; - isac->l1m.fsm = &l1fsm; - isac->l1m.state = ST_L1_RESET; -#ifdef CONFIG_HISAX_DEBUG - isac->l1m.debug = 1; -#else - isac->l1m.debug = 0; -#endif - isac->l1m.userdata = isac; - isac->l1m.printdebug = l1m_debug; - FsmInitTimer(&isac->l1m, &isac->timer); -} - -void isac_setup(struct isac *isac) -{ - int val, eval; - - isac->type = TYPE_ISAC; - isac_version(isac); - - ph_command(isac, ISAC_CMD_RES); - - isac->write_isac(isac, ISAC_MASK, 0xff); - isac->mocr = 0xaa; - if (test_bit(ISAC_IOM1, &isac->flags)) { - /* IOM 1 Mode */ - isac->write_isac(isac, ISAC_ADF2, 0x0); - isac->write_isac(isac, ISAC_SPCR, 0xa); - isac->write_isac(isac, ISAC_ADF1, 0x2); - isac->write_isac(isac, ISAC_STCR, 0x70); - isac->write_isac(isac, ISAC_MODE, 0xc9); - } else { - /* IOM 2 Mode */ - if (!isac->adf2) - isac->adf2 = 0x80; - isac->write_isac(isac, ISAC_ADF2, isac->adf2); - isac->write_isac(isac, ISAC_SQXR, 0x2f); - isac->write_isac(isac, ISAC_SPCR, 0x00); - isac->write_isac(isac, ISAC_STCR, 0x70); - isac->write_isac(isac, ISAC_MODE, 0xc9); - isac->write_isac(isac, ISAC_TIMR, 0x00); - isac->write_isac(isac, ISAC_ADF1, 0x00); - } - val = isac->read_isac(isac, ISAC_STAR); - DBG(2, "ISAC STAR %x", val); - val = isac->read_isac(isac, ISAC_MODE); - DBG(2, "ISAC MODE %x", val); - val = isac->read_isac(isac, ISAC_ADF2); - DBG(2, "ISAC ADF2 %x", val); - val = isac->read_isac(isac, ISAC_ISTA); - DBG(2, "ISAC ISTA %x", val); - if (val & 0x01) { - eval = isac->read_isac(isac, ISAC_EXIR); - DBG(2, "ISAC EXIR %x", eval); - } - val = isac->read_isac(isac, ISAC_CIR0); - DBG(2, "ISAC CIR0 %x", val); - FsmEvent(&isac->l1m, (val >> 2) & 0xf, NULL); - - isac->write_isac(isac, ISAC_MASK, 0x0); - // RESET Receiver and Transmitter - isac->write_isac(isac, ISAC_CMDR, ISAC_CMDR_XRES | ISAC_CMDR_RRES); -} - -void isacsx_setup(struct isac *isac) -{ - isac->type = TYPE_ISACSX; - // clear LDD - isac->write_isac(isac, ISACSX_TR_CONF0, 0x00); - // enable transmitter - isac->write_isac(isac, ISACSX_TR_CONF2, 0x00); - // transparent mode 0, RAC, stop/go - isac->write_isac(isac, ISACSX_MODED, 0xc9); - // all HDLC IRQ unmasked - isac->write_isac(isac, ISACSX_MASKD, 0x03); - // unmask ICD, CID IRQs - isac->write_isac(isac, ISACSX_MASK, - ~(ISACSX_ISTA_ICD | ISACSX_ISTA_CIC)); -} - -void isac_d_l2l1(struct hisax_if *hisax_d_if, int pr, void *arg) -{ - struct isac *isac = hisax_d_if->priv; - struct sk_buff *skb = arg; - - DBG(DBG_PR, "pr %#x", pr); - - switch (pr) { - case PH_ACTIVATE | REQUEST: - FsmEvent(&isac->l1m, EV_PH_ACTIVATE_REQ, NULL); - break; - case PH_DEACTIVATE | REQUEST: - FsmEvent(&isac->l1m, EV_PH_DEACTIVATE_REQ, NULL); - break; - case PH_DATA | REQUEST: - DBG(DBG_PR, "PH_DATA REQUEST len %d", skb->len); - DBG_SKB(DBG_XPACKET, skb); - if (isac->l1m.state != ST_L1_F7) { - DBG(1, "L1 wrong state %d\n", isac->l1m.state); - dev_kfree_skb(skb); - break; - } - BUG_ON(isac->tx_skb); - - isac->tx_skb = skb; - isac_fill_fifo(isac); - break; - } -} - -static int __init hisax_isac_init(void) -{ - printk(KERN_INFO "hisax_isac: ISAC-S/ISAC-SX ISDN driver v0.1.0\n"); - - l1fsm.state_count = L1_STATE_COUNT; - l1fsm.event_count = L1_EVENT_COUNT; - l1fsm.strState = strL1State; - l1fsm.strEvent = strL1Event; - return FsmNew(&l1fsm, L1FnList, ARRAY_SIZE(L1FnList)); -} - -static void __exit hisax_isac_exit(void) -{ - FsmFree(&l1fsm); -} - -EXPORT_SYMBOL(isac_init); -EXPORT_SYMBOL(isac_d_l2l1); - -EXPORT_SYMBOL(isacsx_setup); -EXPORT_SYMBOL(isacsx_irq); - -EXPORT_SYMBOL(isac_setup); -EXPORT_SYMBOL(isac_irq); - -module_init(hisax_isac_init); -module_exit(hisax_isac_exit); diff --git a/drivers/isdn/hisax/hisax_isac.h b/drivers/isdn/hisax/hisax_isac.h deleted file mode 100644 index d7301da97991..000000000000 --- a/drivers/isdn/hisax/hisax_isac.h +++ /dev/null @@ -1,46 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __HISAX_ISAC_H__ -#define __HISAX_ISAC_H__ - -#include <linux/kernel.h> -#include "fsm.h" -#include "hisax_if.h" - -#define TIMER3_VALUE 7000 -#define MAX_DFRAME_LEN_L1 300 - -#define ISAC_IOM1 0 - -struct isac { - void *priv; - - u_long flags; - struct hisax_d_if hisax_d_if; - struct FsmInst l1m; - struct FsmTimer timer; - u_char mocr; - u_char adf2; - int type; - - u_char rcvbuf[MAX_DFRAME_LEN_L1]; - int rcvidx; - - struct sk_buff *tx_skb; - int tx_cnt; - - u_char (*read_isac) (struct isac *, u_char); - void (*write_isac) (struct isac *, u_char, u_char); - void (*read_isac_fifo) (struct isac *, u_char *, int); - void (*write_isac_fifo)(struct isac *, u_char *, int); -}; - -void isac_init(struct isac *isac); -void isac_d_l2l1(struct hisax_if *hisax_d_if, int pr, void *arg); - -void isac_setup(struct isac *isac); -void isac_irq(struct isac *isac); - -void isacsx_setup(struct isac *isac); -void isacsx_irq(struct isac *isac); - -#endif diff --git a/drivers/isdn/hisax/hscx.c b/drivers/isdn/hisax/hscx.c deleted file mode 100644 index 3e305fec0ed9..000000000000 --- a/drivers/isdn/hisax/hscx.c +++ /dev/null @@ -1,277 +0,0 @@ -/* $Id: hscx.c,v 1.24.2.4 2004/01/24 20:47:23 keil Exp $ - * - * HSCX specific routines - * - * Author Karsten Keil - * Copyright by Karsten Keil <keil@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/init.h> -#include "hisax.h" -#include "hscx.h" -#include "isac.h" -#include "isdnl1.h" -#include <linux/interrupt.h> -#include <linux/slab.h> - -static char *HSCXVer[] = -{"A1", "?1", "A2", "?3", "A3", "V2.1", "?6", "?7", - "?8", "?9", "?10", "?11", "?12", "?13", "?14", "???"}; - -int -HscxVersion(struct IsdnCardState *cs, char *s) -{ - int verA, verB; - - verA = cs->BC_Read_Reg(cs, 0, HSCX_VSTR) & 0xf; - verB = cs->BC_Read_Reg(cs, 1, HSCX_VSTR) & 0xf; - printk(KERN_INFO "%s HSCX version A: %s B: %s\n", s, - HSCXVer[verA], HSCXVer[verB]); - if ((verA == 0) | (verA == 0xf) | (verB == 0) | (verB == 0xf)) - return (1); - else - return (0); -} - -void -modehscx(struct BCState *bcs, int mode, int bc) -{ - struct IsdnCardState *cs = bcs->cs; - int hscx = bcs->hw.hscx.hscx; - - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "hscx %c mode %d ichan %d", - 'A' + hscx, mode, bc); - bcs->mode = mode; - bcs->channel = bc; - cs->BC_Write_Reg(cs, hscx, HSCX_XAD1, 0xFF); - cs->BC_Write_Reg(cs, hscx, HSCX_XAD2, 0xFF); - cs->BC_Write_Reg(cs, hscx, HSCX_RAH2, 0xFF); - cs->BC_Write_Reg(cs, hscx, HSCX_XBCH, 0x0); - cs->BC_Write_Reg(cs, hscx, HSCX_RLCR, 0x0); - cs->BC_Write_Reg(cs, hscx, HSCX_CCR1, - test_bit(HW_IPAC, &cs->HW_Flags) ? 0x82 : 0x85); - cs->BC_Write_Reg(cs, hscx, HSCX_CCR2, 0x30); - cs->BC_Write_Reg(cs, hscx, HSCX_XCCR, 7); - cs->BC_Write_Reg(cs, hscx, HSCX_RCCR, 7); - - /* Switch IOM 1 SSI */ - if (test_bit(HW_IOM1, &cs->HW_Flags) && (hscx == 0)) - bc = 1 - bc; - - if (bc == 0) { - cs->BC_Write_Reg(cs, hscx, HSCX_TSAX, - test_bit(HW_IOM1, &cs->HW_Flags) ? 0x7 : bcs->hw.hscx.tsaxr0); - cs->BC_Write_Reg(cs, hscx, HSCX_TSAR, - test_bit(HW_IOM1, &cs->HW_Flags) ? 0x7 : bcs->hw.hscx.tsaxr0); - } else { - cs->BC_Write_Reg(cs, hscx, HSCX_TSAX, bcs->hw.hscx.tsaxr1); - cs->BC_Write_Reg(cs, hscx, HSCX_TSAR, bcs->hw.hscx.tsaxr1); - } - switch (mode) { - case (L1_MODE_NULL): - cs->BC_Write_Reg(cs, hscx, HSCX_TSAX, 0x1f); - cs->BC_Write_Reg(cs, hscx, HSCX_TSAR, 0x1f); - cs->BC_Write_Reg(cs, hscx, HSCX_MODE, 0x84); - break; - case (L1_MODE_TRANS): - cs->BC_Write_Reg(cs, hscx, HSCX_MODE, 0xe4); - break; - case (L1_MODE_HDLC): - cs->BC_Write_Reg(cs, hscx, HSCX_CCR1, - test_bit(HW_IPAC, &cs->HW_Flags) ? 0x8a : 0x8d); - cs->BC_Write_Reg(cs, hscx, HSCX_MODE, 0x8c); - break; - } - if (mode) - cs->BC_Write_Reg(cs, hscx, HSCX_CMDR, 0x41); - cs->BC_Write_Reg(cs, hscx, HSCX_ISTA, 0x00); -} - -void -hscx_l2l1(struct PStack *st, int pr, void *arg) -{ - struct BCState *bcs = st->l1.bcs; - u_long flags; - struct sk_buff *skb = arg; - - switch (pr) { - case (PH_DATA | REQUEST): - spin_lock_irqsave(&bcs->cs->lock, flags); - if (bcs->tx_skb) { - skb_queue_tail(&bcs->squeue, skb); - } else { - bcs->tx_skb = skb; - test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); - bcs->hw.hscx.count = 0; - bcs->cs->BC_Send_Data(bcs); - } - spin_unlock_irqrestore(&bcs->cs->lock, flags); - break; - case (PH_PULL | INDICATION): - spin_lock_irqsave(&bcs->cs->lock, flags); - if (bcs->tx_skb) { - printk(KERN_WARNING "hscx_l2l1: this shouldn't happen\n"); - } else { - test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); - bcs->tx_skb = skb; - bcs->hw.hscx.count = 0; - bcs->cs->BC_Send_Data(bcs); - } - spin_unlock_irqrestore(&bcs->cs->lock, flags); - break; - case (PH_PULL | REQUEST): - if (!bcs->tx_skb) { - test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); - } else - test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - break; - case (PH_ACTIVATE | REQUEST): - spin_lock_irqsave(&bcs->cs->lock, flags); - test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag); - modehscx(bcs, st->l1.mode, st->l1.bc); - spin_unlock_irqrestore(&bcs->cs->lock, flags); - l1_msg_b(st, pr, arg); - break; - case (PH_DEACTIVATE | REQUEST): - l1_msg_b(st, pr, arg); - break; - case (PH_DEACTIVATE | CONFIRM): - spin_lock_irqsave(&bcs->cs->lock, flags); - test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag); - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - modehscx(bcs, 0, st->l1.bc); - spin_unlock_irqrestore(&bcs->cs->lock, flags); - st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL); - break; - } -} - -static void -close_hscxstate(struct BCState *bcs) -{ - modehscx(bcs, 0, bcs->channel); - if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) { - kfree(bcs->hw.hscx.rcvbuf); - bcs->hw.hscx.rcvbuf = NULL; - kfree(bcs->blog); - bcs->blog = NULL; - skb_queue_purge(&bcs->rqueue); - skb_queue_purge(&bcs->squeue); - if (bcs->tx_skb) { - dev_kfree_skb_any(bcs->tx_skb); - bcs->tx_skb = NULL; - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - } - } -} - -int -open_hscxstate(struct IsdnCardState *cs, struct BCState *bcs) -{ - if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { - if (!(bcs->hw.hscx.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) { - printk(KERN_WARNING - "HiSax: No memory for hscx.rcvbuf\n"); - test_and_clear_bit(BC_FLG_INIT, &bcs->Flag); - return (1); - } - if (!(bcs->blog = kmalloc(MAX_BLOG_SPACE, GFP_ATOMIC))) { - printk(KERN_WARNING - "HiSax: No memory for bcs->blog\n"); - test_and_clear_bit(BC_FLG_INIT, &bcs->Flag); - kfree(bcs->hw.hscx.rcvbuf); - bcs->hw.hscx.rcvbuf = NULL; - return (2); - } - skb_queue_head_init(&bcs->rqueue); - skb_queue_head_init(&bcs->squeue); - } - bcs->tx_skb = NULL; - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - bcs->event = 0; - bcs->hw.hscx.rcvidx = 0; - bcs->tx_cnt = 0; - return (0); -} - -static int -setstack_hscx(struct PStack *st, struct BCState *bcs) -{ - bcs->channel = st->l1.bc; - if (open_hscxstate(st->l1.hardware, bcs)) - return (-1); - st->l1.bcs = bcs; - st->l2.l2l1 = hscx_l2l1; - setstack_manager(st); - bcs->st = st; - setstack_l1_B(st); - return (0); -} - -void -clear_pending_hscx_ints(struct IsdnCardState *cs) -{ - int val, eval; - - val = cs->BC_Read_Reg(cs, 1, HSCX_ISTA); - debugl1(cs, "HSCX B ISTA %x", val); - if (val & 0x01) { - eval = cs->BC_Read_Reg(cs, 1, HSCX_EXIR); - debugl1(cs, "HSCX B EXIR %x", eval); - } - if (val & 0x02) { - eval = cs->BC_Read_Reg(cs, 0, HSCX_EXIR); - debugl1(cs, "HSCX A EXIR %x", eval); - } - val = cs->BC_Read_Reg(cs, 0, HSCX_ISTA); - debugl1(cs, "HSCX A ISTA %x", val); - val = cs->BC_Read_Reg(cs, 1, HSCX_STAR); - debugl1(cs, "HSCX B STAR %x", val); - val = cs->BC_Read_Reg(cs, 0, HSCX_STAR); - debugl1(cs, "HSCX A STAR %x", val); - /* disable all IRQ */ - cs->BC_Write_Reg(cs, 0, HSCX_MASK, 0xFF); - cs->BC_Write_Reg(cs, 1, HSCX_MASK, 0xFF); -} - -void -inithscx(struct IsdnCardState *cs) -{ - cs->bcs[0].BC_SetStack = setstack_hscx; - cs->bcs[1].BC_SetStack = setstack_hscx; - cs->bcs[0].BC_Close = close_hscxstate; - cs->bcs[1].BC_Close = close_hscxstate; - cs->bcs[0].hw.hscx.hscx = 0; - cs->bcs[1].hw.hscx.hscx = 1; - cs->bcs[0].hw.hscx.tsaxr0 = 0x2f; - cs->bcs[0].hw.hscx.tsaxr1 = 3; - cs->bcs[1].hw.hscx.tsaxr0 = 0x2f; - cs->bcs[1].hw.hscx.tsaxr1 = 3; - modehscx(cs->bcs, 0, 0); - modehscx(cs->bcs + 1, 0, 0); -} - -void -inithscxisac(struct IsdnCardState *cs, int part) -{ - if (part & 1) { - clear_pending_isac_ints(cs); - clear_pending_hscx_ints(cs); - initisac(cs); - inithscx(cs); - } - if (part & 2) { - /* Reenable all IRQ */ - cs->writeisac(cs, ISAC_MASK, 0); - cs->BC_Write_Reg(cs, 0, HSCX_MASK, 0); - cs->BC_Write_Reg(cs, 1, HSCX_MASK, 0); - /* RESET Receiver and Transmitter */ - cs->writeisac(cs, ISAC_CMDR, 0x41); - } -} diff --git a/drivers/isdn/hisax/hscx.h b/drivers/isdn/hisax/hscx.h deleted file mode 100644 index 1148b4bbe711..000000000000 --- a/drivers/isdn/hisax/hscx.h +++ /dev/null @@ -1,41 +0,0 @@ -/* $Id: hscx.h,v 1.8.2.2 2004/01/12 22:52:26 keil Exp $ - * - * HSCX specific defines - * - * Author Karsten Keil - * Copyright by Karsten Keil <keil@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -/* All Registers original Siemens Spec */ - -#define HSCX_ISTA 0x20 -#define HSCX_CCR1 0x2f -#define HSCX_CCR2 0x2c -#define HSCX_TSAR 0x31 -#define HSCX_TSAX 0x30 -#define HSCX_XCCR 0x32 -#define HSCX_RCCR 0x33 -#define HSCX_MODE 0x22 -#define HSCX_CMDR 0x21 -#define HSCX_EXIR 0x24 -#define HSCX_XAD1 0x24 -#define HSCX_XAD2 0x25 -#define HSCX_RAH2 0x27 -#define HSCX_RSTA 0x27 -#define HSCX_TIMR 0x23 -#define HSCX_STAR 0x21 -#define HSCX_RBCL 0x25 -#define HSCX_XBCH 0x2d -#define HSCX_VSTR 0x2e -#define HSCX_RLCR 0x2e -#define HSCX_MASK 0x20 - -extern int HscxVersion(struct IsdnCardState *cs, char *s); -extern void modehscx(struct BCState *bcs, int mode, int bc); -extern void clear_pending_hscx_ints(struct IsdnCardState *cs); -extern void inithscx(struct IsdnCardState *cs); -extern void inithscxisac(struct IsdnCardState *cs, int part); diff --git a/drivers/isdn/hisax/hscx_irq.c b/drivers/isdn/hisax/hscx_irq.c deleted file mode 100644 index 0d7e783c8bef..000000000000 --- a/drivers/isdn/hisax/hscx_irq.c +++ /dev/null @@ -1,294 +0,0 @@ -/* $Id: hscx_irq.c,v 1.18.2.3 2004/02/11 13:21:34 keil Exp $ - * - * low level b-channel stuff for Siemens HSCX - * - * Author Karsten Keil - * Copyright by Karsten Keil <keil@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * This is an include file for fast inline IRQ stuff - * - */ - - -static inline void -waitforCEC(struct IsdnCardState *cs, int hscx) -{ - int to = 50; - - while ((READHSCX(cs, hscx, HSCX_STAR) & 0x04) && to) { - udelay(1); - to--; - } - if (!to) - printk(KERN_WARNING "HiSax: waitforCEC timeout\n"); -} - - -static inline void -waitforXFW(struct IsdnCardState *cs, int hscx) -{ - int to = 50; - - while (((READHSCX(cs, hscx, HSCX_STAR) & 0x44) != 0x40) && to) { - udelay(1); - to--; - } - if (!to) - printk(KERN_WARNING "HiSax: waitforXFW timeout\n"); -} - -static inline void -WriteHSCXCMDR(struct IsdnCardState *cs, int hscx, u_char data) -{ - waitforCEC(cs, hscx); - WRITEHSCX(cs, hscx, HSCX_CMDR, data); -} - - - -static void -hscx_empty_fifo(struct BCState *bcs, int count) -{ - u_char *ptr; - struct IsdnCardState *cs = bcs->cs; - - if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) - debugl1(cs, "hscx_empty_fifo"); - - if (bcs->hw.hscx.rcvidx + count > HSCX_BUFMAX) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "hscx_empty_fifo: incoming packet too large"); - WriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x80); - bcs->hw.hscx.rcvidx = 0; - return; - } - ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx; - bcs->hw.hscx.rcvidx += count; - READHSCXFIFO(cs, bcs->hw.hscx.hscx, ptr, count); - WriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x80); - if (cs->debug & L1_DEB_HSCX_FIFO) { - char *t = bcs->blog; - - t += sprintf(t, "hscx_empty_fifo %c cnt %d", - bcs->hw.hscx.hscx ? 'B' : 'A', count); - QuickHex(t, ptr, count); - debugl1(cs, "%s", bcs->blog); - } -} - -static void -hscx_fill_fifo(struct BCState *bcs) -{ - struct IsdnCardState *cs = bcs->cs; - int more, count; - int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags) ? 64 : 32; - u_char *ptr; - - if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) - debugl1(cs, "hscx_fill_fifo"); - - if (!bcs->tx_skb) - return; - if (bcs->tx_skb->len <= 0) - return; - - more = (bcs->mode == L1_MODE_TRANS) ? 1 : 0; - if (bcs->tx_skb->len > fifo_size) { - more = !0; - count = fifo_size; - } else - count = bcs->tx_skb->len; - - waitforXFW(cs, bcs->hw.hscx.hscx); - ptr = bcs->tx_skb->data; - skb_pull(bcs->tx_skb, count); - bcs->tx_cnt -= count; - bcs->hw.hscx.count += count; - WRITEHSCXFIFO(cs, bcs->hw.hscx.hscx, ptr, count); - WriteHSCXCMDR(cs, bcs->hw.hscx.hscx, more ? 0x8 : 0xa); - if (cs->debug & L1_DEB_HSCX_FIFO) { - char *t = bcs->blog; - - t += sprintf(t, "hscx_fill_fifo %c cnt %d", - bcs->hw.hscx.hscx ? 'B' : 'A', count); - QuickHex(t, ptr, count); - debugl1(cs, "%s", bcs->blog); - } -} - -static void -hscx_interrupt(struct IsdnCardState *cs, u_char val, u_char hscx) -{ - u_char r; - struct BCState *bcs = cs->bcs + hscx; - struct sk_buff *skb; - int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags) ? 64 : 32; - int count; - - if (!test_bit(BC_FLG_INIT, &bcs->Flag)) - return; - - if (val & 0x80) { /* RME */ - r = READHSCX(cs, hscx, HSCX_RSTA); - if ((r & 0xf0) != 0xa0) { - if (!(r & 0x80)) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "HSCX invalid frame"); -#ifdef ERROR_STATISTIC - bcs->err_inv++; -#endif - } - if ((r & 0x40) && bcs->mode) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "HSCX RDO mode=%d", - bcs->mode); -#ifdef ERROR_STATISTIC - bcs->err_rdo++; -#endif - } - if (!(r & 0x20)) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "HSCX CRC error"); -#ifdef ERROR_STATISTIC - bcs->err_crc++; -#endif - } - WriteHSCXCMDR(cs, hscx, 0x80); - } else { - count = READHSCX(cs, hscx, HSCX_RBCL) & ( - test_bit(HW_IPAC, &cs->HW_Flags) ? 0x3f : 0x1f); - if (count == 0) - count = fifo_size; - hscx_empty_fifo(bcs, count); - if ((count = bcs->hw.hscx.rcvidx - 1) > 0) { - if (cs->debug & L1_DEB_HSCX_FIFO) - debugl1(cs, "HX Frame %d", count); - if (!(skb = dev_alloc_skb(count))) - printk(KERN_WARNING "HSCX: receive out of memory\n"); - else { - skb_put_data(skb, bcs->hw.hscx.rcvbuf, - count); - skb_queue_tail(&bcs->rqueue, skb); - } - } - } - bcs->hw.hscx.rcvidx = 0; - schedule_event(bcs, B_RCVBUFREADY); - } - if (val & 0x40) { /* RPF */ - hscx_empty_fifo(bcs, fifo_size); - if (bcs->mode == L1_MODE_TRANS) { - /* receive audio data */ - if (!(skb = dev_alloc_skb(fifo_size))) - printk(KERN_WARNING "HiSax: receive out of memory\n"); - else { - skb_put_data(skb, bcs->hw.hscx.rcvbuf, - fifo_size); - skb_queue_tail(&bcs->rqueue, skb); - } - bcs->hw.hscx.rcvidx = 0; - schedule_event(bcs, B_RCVBUFREADY); - } - } - if (val & 0x10) { /* XPR */ - if (bcs->tx_skb) { - if (bcs->tx_skb->len) { - hscx_fill_fifo(bcs); - return; - } else { - if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) && - (PACKET_NOACK != bcs->tx_skb->pkt_type)) { - u_long flags; - spin_lock_irqsave(&bcs->aclock, flags); - bcs->ackcnt += bcs->hw.hscx.count; - spin_unlock_irqrestore(&bcs->aclock, flags); - schedule_event(bcs, B_ACKPENDING); - } - dev_kfree_skb_irq(bcs->tx_skb); - bcs->hw.hscx.count = 0; - bcs->tx_skb = NULL; - } - } - if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) { - bcs->hw.hscx.count = 0; - test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); - hscx_fill_fifo(bcs); - } else { - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - schedule_event(bcs, B_XMTBUFREADY); - } - } -} - -static void -hscx_int_main(struct IsdnCardState *cs, u_char val) -{ - - u_char exval; - struct BCState *bcs; - - if (val & 0x01) { - bcs = cs->bcs + 1; - exval = READHSCX(cs, 1, HSCX_EXIR); - if (exval & 0x40) { - if (bcs->mode == 1) - hscx_fill_fifo(bcs); - else { -#ifdef ERROR_STATISTIC - bcs->err_tx++; -#endif - /* Here we lost an TX interrupt, so - * restart transmitting the whole frame. - */ - if (bcs->tx_skb) { - skb_push(bcs->tx_skb, bcs->hw.hscx.count); - bcs->tx_cnt += bcs->hw.hscx.count; - bcs->hw.hscx.count = 0; - } - WriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x01); - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "HSCX B EXIR %x Lost TX", exval); - } - } else if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "HSCX B EXIR %x", exval); - } - if (val & 0xf8) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "HSCX B interrupt %x", val); - hscx_interrupt(cs, val, 1); - } - if (val & 0x02) { - bcs = cs->bcs; - exval = READHSCX(cs, 0, HSCX_EXIR); - if (exval & 0x40) { - if (bcs->mode == L1_MODE_TRANS) - hscx_fill_fifo(bcs); - else { - /* Here we lost an TX interrupt, so - * restart transmitting the whole frame. - */ -#ifdef ERROR_STATISTIC - bcs->err_tx++; -#endif - if (bcs->tx_skb) { - skb_push(bcs->tx_skb, bcs->hw.hscx.count); - bcs->tx_cnt += bcs->hw.hscx.count; - bcs->hw.hscx.count = 0; - } - WriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x01); - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "HSCX A EXIR %x Lost TX", exval); - } - } else if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "HSCX A EXIR %x", exval); - } - if (val & 0x04) { - exval = READHSCX(cs, 0, HSCX_ISTA); - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "HSCX A interrupt %x", exval); - hscx_interrupt(cs, exval, 0); - } -} diff --git a/drivers/isdn/hisax/icc.c b/drivers/isdn/hisax/icc.c deleted file mode 100644 index 831dd1bb81ef..000000000000 --- a/drivers/isdn/hisax/icc.c +++ /dev/null @@ -1,680 +0,0 @@ -/* $Id: icc.c,v 1.8.2.3 2004/01/13 14:31:25 keil Exp $ - * - * ICC specific routines - * - * Author Matt Henderson & Guy Ellis - * Copyright by Traverse Technologies Pty Ltd, www.travers.com.au - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * 1999.6.25 Initial implementation of routines for Siemens ISDN - * Communication Controller PEB 2070 based on the ISAC routines - * written by Karsten Keil. - * - */ - -#include <linux/init.h> -#include "hisax.h" -#include "icc.h" -// #include "arcofi.h" -#include "isdnl1.h" -#include <linux/interrupt.h> -#include <linux/slab.h> - -#define DBUSY_TIMER_VALUE 80 -#define ARCOFI_USE 0 - -static char *ICCVer[] = -{"2070 A1/A3", "2070 B1", "2070 B2/B3", "2070 V2.4"}; - -void -ICCVersion(struct IsdnCardState *cs, char *s) -{ - int val; - - val = cs->readisac(cs, ICC_RBCH); - printk(KERN_INFO "%s ICC version (%x): %s\n", s, val, ICCVer[(val >> 5) & 3]); -} - -static void -ph_command(struct IsdnCardState *cs, unsigned int command) -{ - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "ph_command %x", command); - cs->writeisac(cs, ICC_CIX0, (command << 2) | 3); -} - - -static void -icc_new_ph(struct IsdnCardState *cs) -{ - switch (cs->dc.icc.ph_state) { - case (ICC_IND_EI1): - ph_command(cs, ICC_CMD_DI); - l1_msg(cs, HW_RESET | INDICATION, NULL); - break; - case (ICC_IND_DC): - l1_msg(cs, HW_DEACTIVATE | CONFIRM, NULL); - break; - case (ICC_IND_DR): - l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL); - break; - case (ICC_IND_PU): - l1_msg(cs, HW_POWERUP | CONFIRM, NULL); - break; - case (ICC_IND_FJ): - l1_msg(cs, HW_RSYNC | INDICATION, NULL); - break; - case (ICC_IND_AR): - l1_msg(cs, HW_INFO2 | INDICATION, NULL); - break; - case (ICC_IND_AI): - l1_msg(cs, HW_INFO4 | INDICATION, NULL); - break; - default: - break; - } -} - -static void -icc_bh(struct work_struct *work) -{ - struct IsdnCardState *cs = - container_of(work, struct IsdnCardState, tqueue); - struct PStack *stptr; - - if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) { - if (cs->debug) - debugl1(cs, "D-Channel Busy cleared"); - stptr = cs->stlist; - while (stptr != NULL) { - stptr->l1.l1l2(stptr, PH_PAUSE | CONFIRM, NULL); - stptr = stptr->next; - } - } - if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) - icc_new_ph(cs); - if (test_and_clear_bit(D_RCVBUFREADY, &cs->event)) - DChannel_proc_rcv(cs); - if (test_and_clear_bit(D_XMTBUFREADY, &cs->event)) - DChannel_proc_xmt(cs); -#if ARCOFI_USE - if (!test_bit(HW_ARCOFI, &cs->HW_Flags)) - return; - if (test_and_clear_bit(D_RX_MON1, &cs->event)) - arcofi_fsm(cs, ARCOFI_RX_END, NULL); - if (test_and_clear_bit(D_TX_MON1, &cs->event)) - arcofi_fsm(cs, ARCOFI_TX_END, NULL); -#endif -} - -static void -icc_empty_fifo(struct IsdnCardState *cs, int count) -{ - u_char *ptr; - - if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO)) - debugl1(cs, "icc_empty_fifo"); - - if ((cs->rcvidx + count) >= MAX_DFRAME_LEN_L1) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "icc_empty_fifo overrun %d", - cs->rcvidx + count); - cs->writeisac(cs, ICC_CMDR, 0x80); - cs->rcvidx = 0; - return; - } - ptr = cs->rcvbuf + cs->rcvidx; - cs->rcvidx += count; - cs->readisacfifo(cs, ptr, count); - cs->writeisac(cs, ICC_CMDR, 0x80); - if (cs->debug & L1_DEB_ISAC_FIFO) { - char *t = cs->dlog; - - t += sprintf(t, "icc_empty_fifo cnt %d", count); - QuickHex(t, ptr, count); - debugl1(cs, "%s", cs->dlog); - } -} - -static void -icc_fill_fifo(struct IsdnCardState *cs) -{ - int count, more; - u_char *ptr; - - if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO)) - debugl1(cs, "icc_fill_fifo"); - - if (!cs->tx_skb) - return; - - count = cs->tx_skb->len; - if (count <= 0) - return; - - more = 0; - if (count > 32) { - more = !0; - count = 32; - } - ptr = cs->tx_skb->data; - skb_pull(cs->tx_skb, count); - cs->tx_cnt += count; - cs->writeisacfifo(cs, ptr, count); - cs->writeisac(cs, ICC_CMDR, more ? 0x8 : 0xa); - if (test_and_set_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) { - debugl1(cs, "icc_fill_fifo dbusytimer running"); - del_timer(&cs->dbusytimer); - } - cs->dbusytimer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000); - add_timer(&cs->dbusytimer); - if (cs->debug & L1_DEB_ISAC_FIFO) { - char *t = cs->dlog; - - t += sprintf(t, "icc_fill_fifo cnt %d", count); - QuickHex(t, ptr, count); - debugl1(cs, "%s", cs->dlog); - } -} - -void -icc_interrupt(struct IsdnCardState *cs, u_char val) -{ - u_char exval, v1; - struct sk_buff *skb; - unsigned int count; - - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "ICC interrupt %x", val); - if (val & 0x80) { /* RME */ - exval = cs->readisac(cs, ICC_RSTA); - if ((exval & 0x70) != 0x20) { - if (exval & 0x40) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "ICC RDO"); -#ifdef ERROR_STATISTIC - cs->err_rx++; -#endif - } - if (!(exval & 0x20)) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "ICC CRC error"); -#ifdef ERROR_STATISTIC - cs->err_crc++; -#endif - } - cs->writeisac(cs, ICC_CMDR, 0x80); - } else { - count = cs->readisac(cs, ICC_RBCL) & 0x1f; - if (count == 0) - count = 32; - icc_empty_fifo(cs, count); - if ((count = cs->rcvidx) > 0) { - cs->rcvidx = 0; - if (!(skb = alloc_skb(count, GFP_ATOMIC))) - printk(KERN_WARNING "HiSax: D receive out of memory\n"); - else { - skb_put_data(skb, cs->rcvbuf, count); - skb_queue_tail(&cs->rq, skb); - } - } - } - cs->rcvidx = 0; - schedule_event(cs, D_RCVBUFREADY); - } - if (val & 0x40) { /* RPF */ - icc_empty_fifo(cs, 32); - } - if (val & 0x20) { /* RSC */ - /* never */ - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "ICC RSC interrupt"); - } - if (val & 0x10) { /* XPR */ - if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) - del_timer(&cs->dbusytimer); - if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags)) - schedule_event(cs, D_CLEARBUSY); - if (cs->tx_skb) { - if (cs->tx_skb->len) { - icc_fill_fifo(cs); - goto afterXPR; - } else { - dev_kfree_skb_irq(cs->tx_skb); - cs->tx_cnt = 0; - cs->tx_skb = NULL; - } - } - if ((cs->tx_skb = skb_dequeue(&cs->sq))) { - cs->tx_cnt = 0; - icc_fill_fifo(cs); - } else - schedule_event(cs, D_XMTBUFREADY); - } -afterXPR: - if (val & 0x04) { /* CISQ */ - exval = cs->readisac(cs, ICC_CIR0); - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "ICC CIR0 %02X", exval); - if (exval & 2) { - cs->dc.icc.ph_state = (exval >> 2) & 0xf; - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "ph_state change %x", cs->dc.icc.ph_state); - schedule_event(cs, D_L1STATECHANGE); - } - if (exval & 1) { - exval = cs->readisac(cs, ICC_CIR1); - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "ICC CIR1 %02X", exval); - } - } - if (val & 0x02) { /* SIN */ - /* never */ - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "ICC SIN interrupt"); - } - if (val & 0x01) { /* EXI */ - exval = cs->readisac(cs, ICC_EXIR); - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "ICC EXIR %02x", exval); - if (exval & 0x80) { /* XMR */ - debugl1(cs, "ICC XMR"); - printk(KERN_WARNING "HiSax: ICC XMR\n"); - } - if (exval & 0x40) { /* XDU */ - debugl1(cs, "ICC XDU"); - printk(KERN_WARNING "HiSax: ICC XDU\n"); -#ifdef ERROR_STATISTIC - cs->err_tx++; -#endif - if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) - del_timer(&cs->dbusytimer); - if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags)) - schedule_event(cs, D_CLEARBUSY); - if (cs->tx_skb) { /* Restart frame */ - skb_push(cs->tx_skb, cs->tx_cnt); - cs->tx_cnt = 0; - icc_fill_fifo(cs); - } else { - printk(KERN_WARNING "HiSax: ICC XDU no skb\n"); - debugl1(cs, "ICC XDU no skb"); - } - } - if (exval & 0x04) { /* MOS */ - v1 = cs->readisac(cs, ICC_MOSR); - if (cs->debug & L1_DEB_MONITOR) - debugl1(cs, "ICC MOSR %02x", v1); -#if ARCOFI_USE - if (v1 & 0x08) { - if (!cs->dc.icc.mon_rx) { - if (!(cs->dc.icc.mon_rx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC))) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "ICC MON RX out of memory!"); - cs->dc.icc.mocr &= 0xf0; - cs->dc.icc.mocr |= 0x0a; - cs->writeisac(cs, ICC_MOCR, cs->dc.icc.mocr); - goto afterMONR0; - } else - cs->dc.icc.mon_rxp = 0; - } - if (cs->dc.icc.mon_rxp >= MAX_MON_FRAME) { - cs->dc.icc.mocr &= 0xf0; - cs->dc.icc.mocr |= 0x0a; - cs->writeisac(cs, ICC_MOCR, cs->dc.icc.mocr); - cs->dc.icc.mon_rxp = 0; - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "ICC MON RX overflow!"); - goto afterMONR0; - } - cs->dc.icc.mon_rx[cs->dc.icc.mon_rxp++] = cs->readisac(cs, ICC_MOR0); - if (cs->debug & L1_DEB_MONITOR) - debugl1(cs, "ICC MOR0 %02x", cs->dc.icc.mon_rx[cs->dc.icc.mon_rxp - 1]); - if (cs->dc.icc.mon_rxp == 1) { - cs->dc.icc.mocr |= 0x04; - cs->writeisac(cs, ICC_MOCR, cs->dc.icc.mocr); - } - } - afterMONR0: - if (v1 & 0x80) { - if (!cs->dc.icc.mon_rx) { - if (!(cs->dc.icc.mon_rx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC))) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "ICC MON RX out of memory!"); - cs->dc.icc.mocr &= 0x0f; - cs->dc.icc.mocr |= 0xa0; - cs->writeisac(cs, ICC_MOCR, cs->dc.icc.mocr); - goto afterMONR1; - } else - cs->dc.icc.mon_rxp = 0; - } - if (cs->dc.icc.mon_rxp >= MAX_MON_FRAME) { - cs->dc.icc.mocr &= 0x0f; - cs->dc.icc.mocr |= 0xa0; - cs->writeisac(cs, ICC_MOCR, cs->dc.icc.mocr); - cs->dc.icc.mon_rxp = 0; - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "ICC MON RX overflow!"); - goto afterMONR1; - } - cs->dc.icc.mon_rx[cs->dc.icc.mon_rxp++] = cs->readisac(cs, ICC_MOR1); - if (cs->debug & L1_DEB_MONITOR) - debugl1(cs, "ICC MOR1 %02x", cs->dc.icc.mon_rx[cs->dc.icc.mon_rxp - 1]); - cs->dc.icc.mocr |= 0x40; - cs->writeisac(cs, ICC_MOCR, cs->dc.icc.mocr); - } - afterMONR1: - if (v1 & 0x04) { - cs->dc.icc.mocr &= 0xf0; - cs->writeisac(cs, ICC_MOCR, cs->dc.icc.mocr); - cs->dc.icc.mocr |= 0x0a; - cs->writeisac(cs, ICC_MOCR, cs->dc.icc.mocr); - schedule_event(cs, D_RX_MON0); - } - if (v1 & 0x40) { - cs->dc.icc.mocr &= 0x0f; - cs->writeisac(cs, ICC_MOCR, cs->dc.icc.mocr); - cs->dc.icc.mocr |= 0xa0; - cs->writeisac(cs, ICC_MOCR, cs->dc.icc.mocr); - schedule_event(cs, D_RX_MON1); - } - if (v1 & 0x02) { - if ((!cs->dc.icc.mon_tx) || (cs->dc.icc.mon_txc && - (cs->dc.icc.mon_txp >= cs->dc.icc.mon_txc) && - !(v1 & 0x08))) { - cs->dc.icc.mocr &= 0xf0; - cs->writeisac(cs, ICC_MOCR, cs->dc.icc.mocr); - cs->dc.icc.mocr |= 0x0a; - cs->writeisac(cs, ICC_MOCR, cs->dc.icc.mocr); - if (cs->dc.icc.mon_txc && - (cs->dc.icc.mon_txp >= cs->dc.icc.mon_txc)) - schedule_event(cs, D_TX_MON0); - goto AfterMOX0; - } - if (cs->dc.icc.mon_txc && (cs->dc.icc.mon_txp >= cs->dc.icc.mon_txc)) { - schedule_event(cs, D_TX_MON0); - goto AfterMOX0; - } - cs->writeisac(cs, ICC_MOX0, - cs->dc.icc.mon_tx[cs->dc.icc.mon_txp++]); - if (cs->debug & L1_DEB_MONITOR) - debugl1(cs, "ICC %02x -> MOX0", cs->dc.icc.mon_tx[cs->dc.icc.mon_txp - 1]); - } - AfterMOX0: - if (v1 & 0x20) { - if ((!cs->dc.icc.mon_tx) || (cs->dc.icc.mon_txc && - (cs->dc.icc.mon_txp >= cs->dc.icc.mon_txc) && - !(v1 & 0x80))) { - cs->dc.icc.mocr &= 0x0f; - cs->writeisac(cs, ICC_MOCR, cs->dc.icc.mocr); - cs->dc.icc.mocr |= 0xa0; - cs->writeisac(cs, ICC_MOCR, cs->dc.icc.mocr); - if (cs->dc.icc.mon_txc && - (cs->dc.icc.mon_txp >= cs->dc.icc.mon_txc)) - schedule_event(cs, D_TX_MON1); - goto AfterMOX1; - } - if (cs->dc.icc.mon_txc && (cs->dc.icc.mon_txp >= cs->dc.icc.mon_txc)) { - schedule_event(cs, D_TX_MON1); - goto AfterMOX1; - } - cs->writeisac(cs, ICC_MOX1, - cs->dc.icc.mon_tx[cs->dc.icc.mon_txp++]); - if (cs->debug & L1_DEB_MONITOR) - debugl1(cs, "ICC %02x -> MOX1", cs->dc.icc.mon_tx[cs->dc.icc.mon_txp - 1]); - } - AfterMOX1: ; -#endif - } - } -} - -static void -ICC_l1hw(struct PStack *st, int pr, void *arg) -{ - struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware; - struct sk_buff *skb = arg; - u_long flags; - int val; - - switch (pr) { - case (PH_DATA | REQUEST): - if (cs->debug & DEB_DLOG_HEX) - LogFrame(cs, skb->data, skb->len); - if (cs->debug & DEB_DLOG_VERBOSE) - dlogframe(cs, skb, 0); - spin_lock_irqsave(&cs->lock, flags); - if (cs->tx_skb) { - skb_queue_tail(&cs->sq, skb); -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - Logl2Frame(cs, skb, "PH_DATA Queued", 0); -#endif - } else { - cs->tx_skb = skb; - cs->tx_cnt = 0; -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - Logl2Frame(cs, skb, "PH_DATA", 0); -#endif - icc_fill_fifo(cs); - } - spin_unlock_irqrestore(&cs->lock, flags); - break; - case (PH_PULL | INDICATION): - spin_lock_irqsave(&cs->lock, flags); - if (cs->tx_skb) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, " l2l1 tx_skb exist this shouldn't happen"); - skb_queue_tail(&cs->sq, skb); - spin_unlock_irqrestore(&cs->lock, flags); - break; - } - if (cs->debug & DEB_DLOG_HEX) - LogFrame(cs, skb->data, skb->len); - if (cs->debug & DEB_DLOG_VERBOSE) - dlogframe(cs, skb, 0); - cs->tx_skb = skb; - cs->tx_cnt = 0; -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - Logl2Frame(cs, skb, "PH_DATA_PULLED", 0); -#endif - icc_fill_fifo(cs); - spin_unlock_irqrestore(&cs->lock, flags); - break; - case (PH_PULL | REQUEST): -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - debugl1(cs, "-> PH_REQUEST_PULL"); -#endif - if (!cs->tx_skb) { - test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); - } else - test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - break; - case (HW_RESET | REQUEST): - spin_lock_irqsave(&cs->lock, flags); - if ((cs->dc.icc.ph_state == ICC_IND_EI1) || - (cs->dc.icc.ph_state == ICC_IND_DR)) - ph_command(cs, ICC_CMD_DI); - else - ph_command(cs, ICC_CMD_RES); - spin_unlock_irqrestore(&cs->lock, flags); - break; - case (HW_ENABLE | REQUEST): - spin_lock_irqsave(&cs->lock, flags); - ph_command(cs, ICC_CMD_DI); - spin_unlock_irqrestore(&cs->lock, flags); - break; - case (HW_INFO1 | REQUEST): - spin_lock_irqsave(&cs->lock, flags); - ph_command(cs, ICC_CMD_AR); - spin_unlock_irqrestore(&cs->lock, flags); - break; - case (HW_INFO3 | REQUEST): - spin_lock_irqsave(&cs->lock, flags); - ph_command(cs, ICC_CMD_AI); - spin_unlock_irqrestore(&cs->lock, flags); - break; - case (HW_TESTLOOP | REQUEST): - spin_lock_irqsave(&cs->lock, flags); - val = 0; - if (1 & (long) arg) - val |= 0x0c; - if (2 & (long) arg) - val |= 0x3; - if (test_bit(HW_IOM1, &cs->HW_Flags)) { - /* IOM 1 Mode */ - if (!val) { - cs->writeisac(cs, ICC_SPCR, 0xa); - cs->writeisac(cs, ICC_ADF1, 0x2); - } else { - cs->writeisac(cs, ICC_SPCR, val); - cs->writeisac(cs, ICC_ADF1, 0xa); - } - } else { - /* IOM 2 Mode */ - cs->writeisac(cs, ICC_SPCR, val); - if (val) - cs->writeisac(cs, ICC_ADF1, 0x8); - else - cs->writeisac(cs, ICC_ADF1, 0x0); - } - spin_unlock_irqrestore(&cs->lock, flags); - break; - case (HW_DEACTIVATE | RESPONSE): - skb_queue_purge(&cs->rq); - skb_queue_purge(&cs->sq); - if (cs->tx_skb) { - dev_kfree_skb_any(cs->tx_skb); - cs->tx_skb = NULL; - } - if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) - del_timer(&cs->dbusytimer); - if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags)) - schedule_event(cs, D_CLEARBUSY); - break; - default: - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "icc_l1hw unknown %04x", pr); - break; - } -} - -static void -setstack_icc(struct PStack *st, struct IsdnCardState *cs) -{ - st->l1.l1hw = ICC_l1hw; -} - -static void -DC_Close_icc(struct IsdnCardState *cs) { - kfree(cs->dc.icc.mon_rx); - cs->dc.icc.mon_rx = NULL; - kfree(cs->dc.icc.mon_tx); - cs->dc.icc.mon_tx = NULL; -} - -static void -dbusy_timer_handler(struct timer_list *t) -{ - struct IsdnCardState *cs = from_timer(cs, t, dbusytimer); - struct PStack *stptr; - int rbch, star; - - if (test_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) { - rbch = cs->readisac(cs, ICC_RBCH); - star = cs->readisac(cs, ICC_STAR); - if (cs->debug) - debugl1(cs, "D-Channel Busy RBCH %02x STAR %02x", - rbch, star); - if (rbch & ICC_RBCH_XAC) { /* D-Channel Busy */ - test_and_set_bit(FLG_L1_DBUSY, &cs->HW_Flags); - stptr = cs->stlist; - while (stptr != NULL) { - stptr->l1.l1l2(stptr, PH_PAUSE | INDICATION, NULL); - stptr = stptr->next; - } - } else { - /* discard frame; reset transceiver */ - test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags); - if (cs->tx_skb) { - dev_kfree_skb_any(cs->tx_skb); - cs->tx_cnt = 0; - cs->tx_skb = NULL; - } else { - printk(KERN_WARNING "HiSax: ICC D-Channel Busy no skb\n"); - debugl1(cs, "D-Channel Busy no skb"); - } - cs->writeisac(cs, ICC_CMDR, 0x01); /* Transmitter reset */ - cs->irq_func(cs->irq, cs); - } - } -} - -void -initicc(struct IsdnCardState *cs) -{ - cs->setstack_d = setstack_icc; - cs->DC_Close = DC_Close_icc; - cs->dc.icc.mon_tx = NULL; - cs->dc.icc.mon_rx = NULL; - cs->writeisac(cs, ICC_MASK, 0xff); - cs->dc.icc.mocr = 0xaa; - if (test_bit(HW_IOM1, &cs->HW_Flags)) { - /* IOM 1 Mode */ - cs->writeisac(cs, ICC_ADF2, 0x0); - cs->writeisac(cs, ICC_SPCR, 0xa); - cs->writeisac(cs, ICC_ADF1, 0x2); - cs->writeisac(cs, ICC_STCR, 0x70); - cs->writeisac(cs, ICC_MODE, 0xc9); - } else { - /* IOM 2 Mode */ - if (!cs->dc.icc.adf2) - cs->dc.icc.adf2 = 0x80; - cs->writeisac(cs, ICC_ADF2, cs->dc.icc.adf2); - cs->writeisac(cs, ICC_SQXR, 0xa0); - cs->writeisac(cs, ICC_SPCR, 0x20); - cs->writeisac(cs, ICC_STCR, 0x70); - cs->writeisac(cs, ICC_MODE, 0xca); - cs->writeisac(cs, ICC_TIMR, 0x00); - cs->writeisac(cs, ICC_ADF1, 0x20); - } - ph_command(cs, ICC_CMD_RES); - cs->writeisac(cs, ICC_MASK, 0x0); - ph_command(cs, ICC_CMD_DI); -} - -void -clear_pending_icc_ints(struct IsdnCardState *cs) -{ - int val, eval; - - val = cs->readisac(cs, ICC_STAR); - debugl1(cs, "ICC STAR %x", val); - val = cs->readisac(cs, ICC_MODE); - debugl1(cs, "ICC MODE %x", val); - val = cs->readisac(cs, ICC_ADF2); - debugl1(cs, "ICC ADF2 %x", val); - val = cs->readisac(cs, ICC_ISTA); - debugl1(cs, "ICC ISTA %x", val); - if (val & 0x01) { - eval = cs->readisac(cs, ICC_EXIR); - debugl1(cs, "ICC EXIR %x", eval); - } - val = cs->readisac(cs, ICC_CIR0); - debugl1(cs, "ICC CIR0 %x", val); - cs->dc.icc.ph_state = (val >> 2) & 0xf; - schedule_event(cs, D_L1STATECHANGE); - /* Disable all IRQ */ - cs->writeisac(cs, ICC_MASK, 0xFF); -} - -void setup_icc(struct IsdnCardState *cs) -{ - INIT_WORK(&cs->tqueue, icc_bh); - timer_setup(&cs->dbusytimer, dbusy_timer_handler, 0); -} diff --git a/drivers/isdn/hisax/icc.h b/drivers/isdn/hisax/icc.h deleted file mode 100644 index f367df5d3669..000000000000 --- a/drivers/isdn/hisax/icc.h +++ /dev/null @@ -1,72 +0,0 @@ -/* $Id: icc.h,v 1.4.2.2 2004/01/12 22:52:26 keil Exp $ - * - * ICC specific routines - * - * Author Matt Henderson & Guy Ellis - * Copyright by Traverse Technologies Pty Ltd, www.travers.com.au - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * 1999.7.14 Initial implementation of routines for Siemens ISDN - * Communication Controller PEB 2070 based on the ISAC routines - * written by Karsten Keil. - */ - -/* All Registers original Siemens Spec */ - -#define ICC_MASK 0x20 -#define ICC_ISTA 0x20 -#define ICC_STAR 0x21 -#define ICC_CMDR 0x21 -#define ICC_EXIR 0x24 -#define ICC_ADF2 0x39 -#define ICC_SPCR 0x30 -#define ICC_ADF1 0x38 -#define ICC_CIR0 0x31 -#define ICC_CIX0 0x31 -#define ICC_CIR1 0x33 -#define ICC_CIX1 0x33 -#define ICC_STCR 0x37 -#define ICC_MODE 0x22 -#define ICC_RSTA 0x27 -#define ICC_RBCL 0x25 -#define ICC_RBCH 0x2A -#define ICC_TIMR 0x23 -#define ICC_SQXR 0x3b -#define ICC_MOSR 0x3a -#define ICC_MOCR 0x3a -#define ICC_MOR0 0x32 -#define ICC_MOX0 0x32 -#define ICC_MOR1 0x34 -#define ICC_MOX1 0x34 - -#define ICC_RBCH_XAC 0x80 - -#define ICC_CMD_TIM 0x0 -#define ICC_CMD_RES 0x1 -#define ICC_CMD_DU 0x3 -#define ICC_CMD_EI1 0x4 -#define ICC_CMD_SSP 0x5 -#define ICC_CMD_DT 0x6 -#define ICC_CMD_AR 0x8 -#define ICC_CMD_ARL 0xA -#define ICC_CMD_AI 0xC -#define ICC_CMD_DI 0xF - -#define ICC_IND_DR 0x0 -#define ICC_IND_FJ 0x2 -#define ICC_IND_EI1 0x4 -#define ICC_IND_INT 0x6 -#define ICC_IND_PU 0x7 -#define ICC_IND_AR 0x8 -#define ICC_IND_ARL 0xA -#define ICC_IND_AI 0xC -#define ICC_IND_AIL 0xE -#define ICC_IND_DC 0xF - -extern void ICCVersion(struct IsdnCardState *cs, char *s); -extern void initicc(struct IsdnCardState *cs); -extern void icc_interrupt(struct IsdnCardState *cs, u_char val); -extern void clear_pending_icc_ints(struct IsdnCardState *cs); -extern void setup_icc(struct IsdnCardState *); diff --git a/drivers/isdn/hisax/ipac.h b/drivers/isdn/hisax/ipac.h deleted file mode 100644 index 4f937f02ee34..000000000000 --- a/drivers/isdn/hisax/ipac.h +++ /dev/null @@ -1,29 +0,0 @@ -/* $Id: ipac.h,v 1.7.2.2 2004/01/12 22:52:26 keil Exp $ - * - * IPAC specific defines - * - * Author Karsten Keil - * Copyright by Karsten Keil <keil@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -/* All Registers original Siemens Spec */ - -#define IPAC_CONF 0xC0 -#define IPAC_MASK 0xC1 -#define IPAC_ISTA 0xC1 -#define IPAC_ID 0xC2 -#define IPAC_ACFG 0xC3 -#define IPAC_AOE 0xC4 -#define IPAC_ARX 0xC5 -#define IPAC_ATX 0xC5 -#define IPAC_PITA1 0xC6 -#define IPAC_PITA2 0xC7 -#define IPAC_POTA1 0xC8 -#define IPAC_POTA2 0xC9 -#define IPAC_PCFG 0xCA -#define IPAC_SCFG 0xCB -#define IPAC_TIMR2 0xCC diff --git a/drivers/isdn/hisax/ipacx.c b/drivers/isdn/hisax/ipacx.c deleted file mode 100644 index c7086c1534bd..000000000000 --- a/drivers/isdn/hisax/ipacx.c +++ /dev/null @@ -1,913 +0,0 @@ -/* - * - * IPACX specific routines - * - * Author Joerg Petersohn - * Derived from hisax_isac.c, isac.c, hscx.c and others - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/init.h> -#include "hisax_if.h" -#include "hisax.h" -#include "isdnl1.h" -#include "ipacx.h" - -#define DBUSY_TIMER_VALUE 80 -#define TIMER3_VALUE 7000 -#define MAX_DFRAME_LEN_L1 300 -#define B_FIFO_SIZE 64 -#define D_FIFO_SIZE 32 - - -// ipacx interrupt mask values -#define _MASK_IMASK 0x2E // global mask -#define _MASKB_IMASK 0x0B -#define _MASKD_IMASK 0x03 // all on - -//---------------------------------------------------------- -// local function declarations -//---------------------------------------------------------- -static void ph_command(struct IsdnCardState *cs, unsigned int command); -static inline void cic_int(struct IsdnCardState *cs); -static void dch_l2l1(struct PStack *st, int pr, void *arg); -static void dbusy_timer_handler(struct timer_list *t); -static void dch_empty_fifo(struct IsdnCardState *cs, int count); -static void dch_fill_fifo(struct IsdnCardState *cs); -static inline void dch_int(struct IsdnCardState *cs); -static void dch_setstack(struct PStack *st, struct IsdnCardState *cs); -static void dch_init(struct IsdnCardState *cs); -static void bch_l2l1(struct PStack *st, int pr, void *arg); -static void bch_empty_fifo(struct BCState *bcs, int count); -static void bch_fill_fifo(struct BCState *bcs); -static void bch_int(struct IsdnCardState *cs, u_char hscx); -static void bch_mode(struct BCState *bcs, int mode, int bc); -static void bch_close_state(struct BCState *bcs); -static int bch_open_state(struct IsdnCardState *cs, struct BCState *bcs); -static int bch_setstack(struct PStack *st, struct BCState *bcs); -static void bch_init(struct IsdnCardState *cs, int hscx); -static void clear_pending_ints(struct IsdnCardState *cs); - -//---------------------------------------------------------- -// Issue Layer 1 command to chip -//---------------------------------------------------------- -static void -ph_command(struct IsdnCardState *cs, unsigned int command) -{ - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "ph_command (%#x) in (%#x)", command, - cs->dc.isac.ph_state); -//################################### -// printk(KERN_INFO "ph_command (%#x)\n", command); -//################################### - cs->writeisac(cs, IPACX_CIX0, (command << 4) | 0x0E); -} - -//---------------------------------------------------------- -// Transceiver interrupt handler -//---------------------------------------------------------- -static inline void -cic_int(struct IsdnCardState *cs) -{ - u_char event; - - event = cs->readisac(cs, IPACX_CIR0) >> 4; - if (cs->debug & L1_DEB_ISAC) debugl1(cs, "cic_int(event=%#x)", event); -//######################################### -// printk(KERN_INFO "cic_int(%x)\n", event); -//######################################### - cs->dc.isac.ph_state = event; - schedule_event(cs, D_L1STATECHANGE); -} - -//========================================================== -// D channel functions -//========================================================== - -//---------------------------------------------------------- -// Command entry point -//---------------------------------------------------------- -static void -dch_l2l1(struct PStack *st, int pr, void *arg) -{ - struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware; - struct sk_buff *skb = arg; - u_char cda1_cr; - - switch (pr) { - case (PH_DATA | REQUEST): - if (cs->debug & DEB_DLOG_HEX) LogFrame(cs, skb->data, skb->len); - if (cs->debug & DEB_DLOG_VERBOSE) dlogframe(cs, skb, 0); - if (cs->tx_skb) { - skb_queue_tail(&cs->sq, skb); -#ifdef L2FRAME_DEBUG - if (cs->debug & L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA Queued", 0); -#endif - } else { - cs->tx_skb = skb; - cs->tx_cnt = 0; -#ifdef L2FRAME_DEBUG - if (cs->debug & L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA", 0); -#endif - dch_fill_fifo(cs); - } - break; - - case (PH_PULL | INDICATION): - if (cs->tx_skb) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, " l2l1 tx_skb exist this shouldn't happen"); - skb_queue_tail(&cs->sq, skb); - break; - } - if (cs->debug & DEB_DLOG_HEX) LogFrame(cs, skb->data, skb->len); - if (cs->debug & DEB_DLOG_VERBOSE) dlogframe(cs, skb, 0); - cs->tx_skb = skb; - cs->tx_cnt = 0; -#ifdef L2FRAME_DEBUG - if (cs->debug & L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA_PULLED", 0); -#endif - dch_fill_fifo(cs); - break; - - case (PH_PULL | REQUEST): -#ifdef L2FRAME_DEBUG - if (cs->debug & L1_DEB_LAPD) debugl1(cs, "-> PH_REQUEST_PULL"); -#endif - if (!cs->tx_skb) { - clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); - } else - set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - break; - - case (HW_RESET | REQUEST): - case (HW_ENABLE | REQUEST): - if ((cs->dc.isac.ph_state == IPACX_IND_RES) || - (cs->dc.isac.ph_state == IPACX_IND_DR) || - (cs->dc.isac.ph_state == IPACX_IND_DC)) - ph_command(cs, IPACX_CMD_TIM); - else - ph_command(cs, IPACX_CMD_RES); - break; - - case (HW_INFO3 | REQUEST): - ph_command(cs, IPACX_CMD_AR8); - break; - - case (HW_TESTLOOP | REQUEST): - cs->writeisac(cs, IPACX_CDA_TSDP10, 0x80); // Timeslot 0 is B1 - cs->writeisac(cs, IPACX_CDA_TSDP11, 0x81); // Timeslot 0 is B1 - cda1_cr = cs->readisac(cs, IPACX_CDA1_CR); - (void) cs->readisac(cs, IPACX_CDA2_CR); - if ((long)arg & 1) { // loop B1 - cs->writeisac(cs, IPACX_CDA1_CR, cda1_cr | 0x0a); - } - else { // B1 off - cs->writeisac(cs, IPACX_CDA1_CR, cda1_cr & ~0x0a); - } - if ((long)arg & 2) { // loop B2 - cs->writeisac(cs, IPACX_CDA1_CR, cda1_cr | 0x14); - } - else { // B2 off - cs->writeisac(cs, IPACX_CDA1_CR, cda1_cr & ~0x14); - } - break; - - case (HW_DEACTIVATE | RESPONSE): - skb_queue_purge(&cs->rq); - skb_queue_purge(&cs->sq); - if (cs->tx_skb) { - dev_kfree_skb_any(cs->tx_skb); - cs->tx_skb = NULL; - } - if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) - del_timer(&cs->dbusytimer); - break; - - default: - if (cs->debug & L1_DEB_WARN) debugl1(cs, "dch_l2l1 unknown %04x", pr); - break; - } -} - -//---------------------------------------------------------- -//---------------------------------------------------------- -static void -dbusy_timer_handler(struct timer_list *t) -{ - struct IsdnCardState *cs = from_timer(cs, t, dbusytimer); - struct PStack *st; - int rbchd, stard; - - if (test_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) { - rbchd = cs->readisac(cs, IPACX_RBCHD); - stard = cs->readisac(cs, IPACX_STARD); - if (cs->debug) - debugl1(cs, "D-Channel Busy RBCHD %02x STARD %02x", rbchd, stard); - if (!(stard & 0x40)) { // D-Channel Busy - set_bit(FLG_L1_DBUSY, &cs->HW_Flags); - for (st = cs->stlist; st; st = st->next) { - st->l1.l1l2(st, PH_PAUSE | INDICATION, NULL); // flow control on - } - } else { - // seems we lost an interrupt; reset transceiver */ - clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags); - if (cs->tx_skb) { - dev_kfree_skb_any(cs->tx_skb); - cs->tx_cnt = 0; - cs->tx_skb = NULL; - } else { - printk(KERN_WARNING "HiSax: ISAC D-Channel Busy no skb\n"); - debugl1(cs, "D-Channel Busy no skb"); - } - cs->writeisac(cs, IPACX_CMDRD, 0x01); // Tx reset, generates XPR - } - } -} - -//---------------------------------------------------------- -// Fill buffer from receive FIFO -//---------------------------------------------------------- -static void -dch_empty_fifo(struct IsdnCardState *cs, int count) -{ - u_char *ptr; - - if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO)) - debugl1(cs, "dch_empty_fifo()"); - - // message too large, remove - if ((cs->rcvidx + count) >= MAX_DFRAME_LEN_L1) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "dch_empty_fifo() incoming message too large"); - cs->writeisac(cs, IPACX_CMDRD, 0x80); // RMC - cs->rcvidx = 0; - return; - } - - ptr = cs->rcvbuf + cs->rcvidx; - cs->rcvidx += count; - - cs->readisacfifo(cs, ptr, count); - cs->writeisac(cs, IPACX_CMDRD, 0x80); // RMC - - if (cs->debug & L1_DEB_ISAC_FIFO) { - char *t = cs->dlog; - - t += sprintf(t, "dch_empty_fifo() cnt %d", count); - QuickHex(t, ptr, count); - debugl1(cs, "%s", cs->dlog); - } -} - -//---------------------------------------------------------- -// Fill transmit FIFO -//---------------------------------------------------------- -static void -dch_fill_fifo(struct IsdnCardState *cs) -{ - int count; - u_char cmd, *ptr; - - if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO)) - debugl1(cs, "dch_fill_fifo()"); - - if (!cs->tx_skb) return; - count = cs->tx_skb->len; - if (count <= 0) return; - - if (count > D_FIFO_SIZE) { - count = D_FIFO_SIZE; - cmd = 0x08; // XTF - } else { - cmd = 0x0A; // XTF | XME - } - - ptr = cs->tx_skb->data; - skb_pull(cs->tx_skb, count); - cs->tx_cnt += count; - cs->writeisacfifo(cs, ptr, count); - cs->writeisac(cs, IPACX_CMDRD, cmd); - - // set timeout for transmission contol - if (test_and_set_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) { - debugl1(cs, "dch_fill_fifo dbusytimer running"); - del_timer(&cs->dbusytimer); - } - cs->dbusytimer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000); - add_timer(&cs->dbusytimer); - - if (cs->debug & L1_DEB_ISAC_FIFO) { - char *t = cs->dlog; - - t += sprintf(t, "dch_fill_fifo() cnt %d", count); - QuickHex(t, ptr, count); - debugl1(cs, "%s", cs->dlog); - } -} - -//---------------------------------------------------------- -// D channel interrupt handler -//---------------------------------------------------------- -static inline void -dch_int(struct IsdnCardState *cs) -{ - struct sk_buff *skb; - u_char istad, rstad; - int count; - - istad = cs->readisac(cs, IPACX_ISTAD); -//############################################## -// printk(KERN_WARNING "dch_int(istad=%02x)\n", istad); -//############################################## - - if (istad & 0x80) { // RME - rstad = cs->readisac(cs, IPACX_RSTAD); - if ((rstad & 0xf0) != 0xa0) { // !(VFR && !RDO && CRC && !RAB) - if (!(rstad & 0x80)) - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "dch_int(): invalid frame"); - if ((rstad & 0x40)) - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "dch_int(): RDO"); - if (!(rstad & 0x20)) - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "dch_int(): CRC error"); - cs->writeisac(cs, IPACX_CMDRD, 0x80); // RMC - } else { // received frame ok - count = cs->readisac(cs, IPACX_RBCLD); - if (count) count--; // RSTAB is last byte - count &= D_FIFO_SIZE - 1; - if (count == 0) count = D_FIFO_SIZE; - dch_empty_fifo(cs, count); - if ((count = cs->rcvidx) > 0) { - cs->rcvidx = 0; - if (!(skb = dev_alloc_skb(count))) - printk(KERN_WARNING "HiSax dch_int(): receive out of memory\n"); - else { - skb_put_data(skb, cs->rcvbuf, count); - skb_queue_tail(&cs->rq, skb); - } - } - } - cs->rcvidx = 0; - schedule_event(cs, D_RCVBUFREADY); - } - - if (istad & 0x40) { // RPF - dch_empty_fifo(cs, D_FIFO_SIZE); - } - - if (istad & 0x20) { // RFO - if (cs->debug & L1_DEB_WARN) debugl1(cs, "dch_int(): RFO"); - cs->writeisac(cs, IPACX_CMDRD, 0x40); //RRES - } - - if (istad & 0x10) { // XPR - if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) - del_timer(&cs->dbusytimer); - if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags)) - schedule_event(cs, D_CLEARBUSY); - if (cs->tx_skb) { - if (cs->tx_skb->len) { - dch_fill_fifo(cs); - goto afterXPR; - } - else { - dev_kfree_skb_irq(cs->tx_skb); - cs->tx_skb = NULL; - cs->tx_cnt = 0; - } - } - if ((cs->tx_skb = skb_dequeue(&cs->sq))) { - cs->tx_cnt = 0; - dch_fill_fifo(cs); - } - else { - schedule_event(cs, D_XMTBUFREADY); - } - } -afterXPR: - - if (istad & 0x0C) { // XDU or XMR - if (cs->debug & L1_DEB_WARN) debugl1(cs, "dch_int(): XDU"); - if (cs->tx_skb) { - skb_push(cs->tx_skb, cs->tx_cnt); // retransmit - cs->tx_cnt = 0; - dch_fill_fifo(cs); - } else { - printk(KERN_WARNING "HiSax: ISAC XDU no skb\n"); - debugl1(cs, "ISAC XDU no skb"); - } - } -} - -//---------------------------------------------------------- -//---------------------------------------------------------- -static void -dch_setstack(struct PStack *st, struct IsdnCardState *cs) -{ - st->l1.l1hw = dch_l2l1; -} - -//---------------------------------------------------------- -//---------------------------------------------------------- -static void -dch_init(struct IsdnCardState *cs) -{ - printk(KERN_INFO "HiSax: IPACX ISDN driver v0.1.0\n"); - - cs->setstack_d = dch_setstack; - - timer_setup(&cs->dbusytimer, dbusy_timer_handler, 0); - - cs->writeisac(cs, IPACX_TR_CONF0, 0x00); // clear LDD - cs->writeisac(cs, IPACX_TR_CONF2, 0x00); // enable transmitter - cs->writeisac(cs, IPACX_MODED, 0xC9); // transparent mode 0, RAC, stop/go - cs->writeisac(cs, IPACX_MON_CR, 0x00); // disable monitor channel -} - - -//========================================================== -// B channel functions -//========================================================== - -//---------------------------------------------------------- -// Entry point for commands -//---------------------------------------------------------- -static void -bch_l2l1(struct PStack *st, int pr, void *arg) -{ - struct BCState *bcs = st->l1.bcs; - struct sk_buff *skb = arg; - u_long flags; - - switch (pr) { - case (PH_DATA | REQUEST): - spin_lock_irqsave(&bcs->cs->lock, flags); - if (bcs->tx_skb) { - skb_queue_tail(&bcs->squeue, skb); - } else { - bcs->tx_skb = skb; - set_bit(BC_FLG_BUSY, &bcs->Flag); - bcs->hw.hscx.count = 0; - bch_fill_fifo(bcs); - } - spin_unlock_irqrestore(&bcs->cs->lock, flags); - break; - case (PH_PULL | INDICATION): - spin_lock_irqsave(&bcs->cs->lock, flags); - if (bcs->tx_skb) { - printk(KERN_WARNING "HiSax bch_l2l1(): this shouldn't happen\n"); - } else { - set_bit(BC_FLG_BUSY, &bcs->Flag); - bcs->tx_skb = skb; - bcs->hw.hscx.count = 0; - bch_fill_fifo(bcs); - } - spin_unlock_irqrestore(&bcs->cs->lock, flags); - break; - case (PH_PULL | REQUEST): - if (!bcs->tx_skb) { - clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); - } else - set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - break; - case (PH_ACTIVATE | REQUEST): - spin_lock_irqsave(&bcs->cs->lock, flags); - set_bit(BC_FLG_ACTIV, &bcs->Flag); - bch_mode(bcs, st->l1.mode, st->l1.bc); - spin_unlock_irqrestore(&bcs->cs->lock, flags); - l1_msg_b(st, pr, arg); - break; - case (PH_DEACTIVATE | REQUEST): - l1_msg_b(st, pr, arg); - break; - case (PH_DEACTIVATE | CONFIRM): - spin_lock_irqsave(&bcs->cs->lock, flags); - clear_bit(BC_FLG_ACTIV, &bcs->Flag); - clear_bit(BC_FLG_BUSY, &bcs->Flag); - bch_mode(bcs, 0, st->l1.bc); - spin_unlock_irqrestore(&bcs->cs->lock, flags); - st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL); - break; - } -} - -//---------------------------------------------------------- -// Read B channel fifo to receive buffer -//---------------------------------------------------------- -static void -bch_empty_fifo(struct BCState *bcs, int count) -{ - u_char *ptr, hscx; - struct IsdnCardState *cs; - int cnt; - - cs = bcs->cs; - hscx = bcs->hw.hscx.hscx; - if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) - debugl1(cs, "bch_empty_fifo()"); - - // message too large, remove - if (bcs->hw.hscx.rcvidx + count > HSCX_BUFMAX) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "bch_empty_fifo() incoming packet too large"); - cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x80); // RMC - bcs->hw.hscx.rcvidx = 0; - return; - } - - ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx; - cnt = count; - while (cnt--) *ptr++ = cs->BC_Read_Reg(cs, hscx, IPACX_RFIFOB); - cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x80); // RMC - - ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx; - bcs->hw.hscx.rcvidx += count; - - if (cs->debug & L1_DEB_HSCX_FIFO) { - char *t = bcs->blog; - - t += sprintf(t, "bch_empty_fifo() B-%d cnt %d", hscx, count); - QuickHex(t, ptr, count); - debugl1(cs, "%s", bcs->blog); - } -} - -//---------------------------------------------------------- -// Fill buffer to transmit FIFO -//---------------------------------------------------------- -static void -bch_fill_fifo(struct BCState *bcs) -{ - struct IsdnCardState *cs; - int more, count, cnt; - u_char *ptr, *p, hscx; - - cs = bcs->cs; - if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) - debugl1(cs, "bch_fill_fifo()"); - - if (!bcs->tx_skb) return; - if (bcs->tx_skb->len <= 0) return; - - hscx = bcs->hw.hscx.hscx; - more = (bcs->mode == L1_MODE_TRANS) ? 1 : 0; - if (bcs->tx_skb->len > B_FIFO_SIZE) { - more = 1; - count = B_FIFO_SIZE; - } else { - count = bcs->tx_skb->len; - } - cnt = count; - - p = ptr = bcs->tx_skb->data; - skb_pull(bcs->tx_skb, count); - bcs->tx_cnt -= count; - bcs->hw.hscx.count += count; - while (cnt--) cs->BC_Write_Reg(cs, hscx, IPACX_XFIFOB, *p++); - cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, (more ? 0x08 : 0x0a)); - - if (cs->debug & L1_DEB_HSCX_FIFO) { - char *t = bcs->blog; - - t += sprintf(t, "%s() B-%d cnt %d", __func__, hscx, count); - QuickHex(t, ptr, count); - debugl1(cs, "%s", bcs->blog); - } -} - -//---------------------------------------------------------- -// B channel interrupt handler -//---------------------------------------------------------- -static void -bch_int(struct IsdnCardState *cs, u_char hscx) -{ - u_char istab; - struct BCState *bcs; - struct sk_buff *skb; - int count; - u_char rstab; - - bcs = cs->bcs + hscx; - istab = cs->BC_Read_Reg(cs, hscx, IPACX_ISTAB); -//############################################## -// printk(KERN_WARNING "bch_int(istab=%02x)\n", istab); -//############################################## - if (!test_bit(BC_FLG_INIT, &bcs->Flag)) return; - - if (istab & 0x80) { // RME - rstab = cs->BC_Read_Reg(cs, hscx, IPACX_RSTAB); - if ((rstab & 0xf0) != 0xa0) { // !(VFR && !RDO && CRC && !RAB) - if (!(rstab & 0x80)) - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "bch_int() B-%d: invalid frame", hscx); - if ((rstab & 0x40) && (bcs->mode != L1_MODE_NULL)) - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "bch_int() B-%d: RDO mode=%d", hscx, bcs->mode); - if (!(rstab & 0x20)) - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "bch_int() B-%d: CRC error", hscx); - cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x80); // RMC - } - else { // received frame ok - count = cs->BC_Read_Reg(cs, hscx, IPACX_RBCLB) & (B_FIFO_SIZE - 1); - if (count == 0) count = B_FIFO_SIZE; - bch_empty_fifo(bcs, count); - if ((count = bcs->hw.hscx.rcvidx - 1) > 0) { - if (cs->debug & L1_DEB_HSCX_FIFO) - debugl1(cs, "bch_int Frame %d", count); - if (!(skb = dev_alloc_skb(count))) - printk(KERN_WARNING "HiSax bch_int(): receive frame out of memory\n"); - else { - skb_put_data(skb, bcs->hw.hscx.rcvbuf, - count); - skb_queue_tail(&bcs->rqueue, skb); - } - } - } - bcs->hw.hscx.rcvidx = 0; - schedule_event(bcs, B_RCVBUFREADY); - } - - if (istab & 0x40) { // RPF - bch_empty_fifo(bcs, B_FIFO_SIZE); - - if (bcs->mode == L1_MODE_TRANS) { // queue every chunk - // receive transparent audio data - if (!(skb = dev_alloc_skb(B_FIFO_SIZE))) - printk(KERN_WARNING "HiSax bch_int(): receive transparent out of memory\n"); - else { - skb_put_data(skb, bcs->hw.hscx.rcvbuf, - B_FIFO_SIZE); - skb_queue_tail(&bcs->rqueue, skb); - } - bcs->hw.hscx.rcvidx = 0; - schedule_event(bcs, B_RCVBUFREADY); - } - } - - if (istab & 0x20) { // RFO - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "bch_int() B-%d: RFO error", hscx); - cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x40); // RRES - } - - if (istab & 0x10) { // XPR - if (bcs->tx_skb) { - if (bcs->tx_skb->len) { - bch_fill_fifo(bcs); - goto afterXPR; - } else { - if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) && - (PACKET_NOACK != bcs->tx_skb->pkt_type)) { - u_long flags; - spin_lock_irqsave(&bcs->aclock, flags); - bcs->ackcnt += bcs->hw.hscx.count; - spin_unlock_irqrestore(&bcs->aclock, flags); - schedule_event(bcs, B_ACKPENDING); - } - } - dev_kfree_skb_irq(bcs->tx_skb); - bcs->hw.hscx.count = 0; - bcs->tx_skb = NULL; - } - if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) { - bcs->hw.hscx.count = 0; - set_bit(BC_FLG_BUSY, &bcs->Flag); - bch_fill_fifo(bcs); - } else { - clear_bit(BC_FLG_BUSY, &bcs->Flag); - schedule_event(bcs, B_XMTBUFREADY); - } - } -afterXPR: - - if (istab & 0x04) { // XDU - if (bcs->mode == L1_MODE_TRANS) { - bch_fill_fifo(bcs); - } - else { - if (bcs->tx_skb) { // restart transmitting the whole frame - skb_push(bcs->tx_skb, bcs->hw.hscx.count); - bcs->tx_cnt += bcs->hw.hscx.count; - bcs->hw.hscx.count = 0; - } - cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x01); // XRES - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "bch_int() B-%d XDU error", hscx); - } - } -} - -//---------------------------------------------------------- -//---------------------------------------------------------- -static void -bch_mode(struct BCState *bcs, int mode, int bc) -{ - struct IsdnCardState *cs = bcs->cs; - int hscx = bcs->hw.hscx.hscx; - - bc = bc ? 1 : 0; // in case bc is greater than 1 - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "mode_bch() switch B-%d mode %d chan %d", hscx, mode, bc); - bcs->mode = mode; - bcs->channel = bc; - - // map controller to according timeslot - if (!hscx) - { - cs->writeisac(cs, IPACX_BCHA_TSDP_BC1, 0x80 | bc); - cs->writeisac(cs, IPACX_BCHA_CR, 0x88); - } - else - { - cs->writeisac(cs, IPACX_BCHB_TSDP_BC1, 0x80 | bc); - cs->writeisac(cs, IPACX_BCHB_CR, 0x88); - } - - switch (mode) { - case (L1_MODE_NULL): - cs->BC_Write_Reg(cs, hscx, IPACX_MODEB, 0xC0); // rec off - cs->BC_Write_Reg(cs, hscx, IPACX_EXMB, 0x30); // std adj. - cs->BC_Write_Reg(cs, hscx, IPACX_MASKB, 0xFF); // ints off - cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x41); // validate adjustments - break; - case (L1_MODE_TRANS): - cs->BC_Write_Reg(cs, hscx, IPACX_MODEB, 0x88); // ext transp mode - cs->BC_Write_Reg(cs, hscx, IPACX_EXMB, 0x00); // xxx00000 - cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x41); // validate adjustments - cs->BC_Write_Reg(cs, hscx, IPACX_MASKB, _MASKB_IMASK); - break; - case (L1_MODE_HDLC): - cs->BC_Write_Reg(cs, hscx, IPACX_MODEB, 0xC8); // transp mode 0 - cs->BC_Write_Reg(cs, hscx, IPACX_EXMB, 0x01); // idle=hdlc flags crc enabled - cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x41); // validate adjustments - cs->BC_Write_Reg(cs, hscx, IPACX_MASKB, _MASKB_IMASK); - break; - } -} - -//---------------------------------------------------------- -//---------------------------------------------------------- -static void -bch_close_state(struct BCState *bcs) -{ - bch_mode(bcs, 0, bcs->channel); - if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) { - kfree(bcs->hw.hscx.rcvbuf); - bcs->hw.hscx.rcvbuf = NULL; - kfree(bcs->blog); - bcs->blog = NULL; - skb_queue_purge(&bcs->rqueue); - skb_queue_purge(&bcs->squeue); - if (bcs->tx_skb) { - dev_kfree_skb_any(bcs->tx_skb); - bcs->tx_skb = NULL; - clear_bit(BC_FLG_BUSY, &bcs->Flag); - } - } -} - -//---------------------------------------------------------- -//---------------------------------------------------------- -static int -bch_open_state(struct IsdnCardState *cs, struct BCState *bcs) -{ - if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { - if (!(bcs->hw.hscx.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) { - printk(KERN_WARNING - "HiSax open_bchstate(): No memory for hscx.rcvbuf\n"); - clear_bit(BC_FLG_INIT, &bcs->Flag); - return (1); - } - if (!(bcs->blog = kmalloc(MAX_BLOG_SPACE, GFP_ATOMIC))) { - printk(KERN_WARNING - "HiSax open_bchstate: No memory for bcs->blog\n"); - clear_bit(BC_FLG_INIT, &bcs->Flag); - kfree(bcs->hw.hscx.rcvbuf); - bcs->hw.hscx.rcvbuf = NULL; - return (2); - } - skb_queue_head_init(&bcs->rqueue); - skb_queue_head_init(&bcs->squeue); - } - bcs->tx_skb = NULL; - clear_bit(BC_FLG_BUSY, &bcs->Flag); - bcs->event = 0; - bcs->hw.hscx.rcvidx = 0; - bcs->tx_cnt = 0; - return (0); -} - -//---------------------------------------------------------- -//---------------------------------------------------------- -static int -bch_setstack(struct PStack *st, struct BCState *bcs) -{ - bcs->channel = st->l1.bc; - if (bch_open_state(st->l1.hardware, bcs)) return (-1); - st->l1.bcs = bcs; - st->l2.l2l1 = bch_l2l1; - setstack_manager(st); - bcs->st = st; - setstack_l1_B(st); - return (0); -} - -//---------------------------------------------------------- -//---------------------------------------------------------- -static void -bch_init(struct IsdnCardState *cs, int hscx) -{ - cs->bcs[hscx].BC_SetStack = bch_setstack; - cs->bcs[hscx].BC_Close = bch_close_state; - cs->bcs[hscx].hw.hscx.hscx = hscx; - cs->bcs[hscx].cs = cs; - bch_mode(cs->bcs + hscx, 0, hscx); -} - - -//========================================================== -// Shared functions -//========================================================== - -//---------------------------------------------------------- -// Main interrupt handler -//---------------------------------------------------------- -void -interrupt_ipacx(struct IsdnCardState *cs) -{ - u_char ista; - - while ((ista = cs->readisac(cs, IPACX_ISTA))) { -//################################################# -// printk(KERN_WARNING "interrupt_ipacx(ista=%02x)\n", ista); -//################################################# - if (ista & 0x80) bch_int(cs, 0); // B channel interrupts - if (ista & 0x40) bch_int(cs, 1); - - if (ista & 0x01) dch_int(cs); // D channel - if (ista & 0x10) cic_int(cs); // Layer 1 state - } -} - -//---------------------------------------------------------- -// Clears chip interrupt status -//---------------------------------------------------------- -static void -clear_pending_ints(struct IsdnCardState *cs) -{ - int ista; - - // all interrupts off - cs->writeisac(cs, IPACX_MASK, 0xff); - cs->writeisac(cs, IPACX_MASKD, 0xff); - cs->BC_Write_Reg(cs, 0, IPACX_MASKB, 0xff); - cs->BC_Write_Reg(cs, 1, IPACX_MASKB, 0xff); - - ista = cs->readisac(cs, IPACX_ISTA); - if (ista & 0x80) cs->BC_Read_Reg(cs, 0, IPACX_ISTAB); - if (ista & 0x40) cs->BC_Read_Reg(cs, 1, IPACX_ISTAB); - if (ista & 0x10) cs->readisac(cs, IPACX_CIR0); - if (ista & 0x01) cs->readisac(cs, IPACX_ISTAD); -} - -//---------------------------------------------------------- -// Does chip configuration work -// Work to do depends on bit mask in part -//---------------------------------------------------------- -void -init_ipacx(struct IsdnCardState *cs, int part) -{ - if (part & 1) { // initialise chip -//################################################## -// printk(KERN_INFO "init_ipacx(%x)\n", part); -//################################################## - clear_pending_ints(cs); - bch_init(cs, 0); - bch_init(cs, 1); - dch_init(cs); - } - if (part & 2) { // reenable all interrupts and start chip - cs->BC_Write_Reg(cs, 0, IPACX_MASKB, _MASKB_IMASK); - cs->BC_Write_Reg(cs, 1, IPACX_MASKB, _MASKB_IMASK); - cs->writeisac(cs, IPACX_MASKD, _MASKD_IMASK); - cs->writeisac(cs, IPACX_MASK, _MASK_IMASK); // global mask register - - // reset HDLC Transmitters/receivers - cs->writeisac(cs, IPACX_CMDRD, 0x41); - cs->BC_Write_Reg(cs, 0, IPACX_CMDRB, 0x41); - cs->BC_Write_Reg(cs, 1, IPACX_CMDRB, 0x41); - ph_command(cs, IPACX_CMD_RES); - } -} - -//----------------- end of file ----------------------- diff --git a/drivers/isdn/hisax/ipacx.h b/drivers/isdn/hisax/ipacx.h deleted file mode 100644 index e8a22e8f34b6..000000000000 --- a/drivers/isdn/hisax/ipacx.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * - * IPACX specific defines - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -/* All Registers original Siemens Spec */ - -#ifndef INCLUDE_IPACX_H -#define INCLUDE_IPACX_H - -/* D-channel registers */ -#define IPACX_RFIFOD 0x00 /* RD */ -#define IPACX_XFIFOD 0x00 /* WR */ -#define IPACX_ISTAD 0x20 /* RD */ -#define IPACX_MASKD 0x20 /* WR */ -#define IPACX_STARD 0x21 /* RD */ -#define IPACX_CMDRD 0x21 /* WR */ -#define IPACX_MODED 0x22 /* RD/WR */ -#define IPACX_EXMD1 0x23 /* RD/WR */ -#define IPACX_TIMR1 0x24 /* RD/WR */ -#define IPACX_SAP1 0x25 /* WR */ -#define IPACX_SAP2 0x26 /* WR */ -#define IPACX_RBCLD 0x26 /* RD */ -#define IPACX_RBCHD 0x27 /* RD */ -#define IPACX_TEI1 0x27 /* WR */ -#define IPACX_TEI2 0x28 /* WR */ -#define IPACX_RSTAD 0x28 /* RD */ -#define IPACX_TMD 0x29 /* RD/WR */ -#define IPACX_CIR0 0x2E /* RD */ -#define IPACX_CIX0 0x2E /* WR */ -#define IPACX_CIR1 0x2F /* RD */ -#define IPACX_CIX1 0x2F /* WR */ - -/* Transceiver registers */ -#define IPACX_TR_CONF0 0x30 /* RD/WR */ -#define IPACX_TR_CONF1 0x31 /* RD/WR */ -#define IPACX_TR_CONF2 0x32 /* RD/WR */ -#define IPACX_TR_STA 0x33 /* RD */ -#define IPACX_TR_CMD 0x34 /* RD/WR */ -#define IPACX_SQRR1 0x35 /* RD */ -#define IPACX_SQXR1 0x35 /* WR */ -#define IPACX_SQRR2 0x36 /* RD */ -#define IPACX_SQXR2 0x36 /* WR */ -#define IPACX_SQRR3 0x37 /* RD */ -#define IPACX_SQXR3 0x37 /* WR */ -#define IPACX_ISTATR 0x38 /* RD */ -#define IPACX_MASKTR 0x39 /* RD/WR */ -#define IPACX_TR_MODE 0x3A /* RD/WR */ -#define IPACX_ACFG1 0x3C /* RD/WR */ -#define IPACX_ACFG2 0x3D /* RD/WR */ -#define IPACX_AOE 0x3E /* RD/WR */ -#define IPACX_ARX 0x3F /* RD */ -#define IPACX_ATX 0x3F /* WR */ - -/* IOM: Timeslot, DPS, CDA */ -#define IPACX_CDA10 0x40 /* RD/WR */ -#define IPACX_CDA11 0x41 /* RD/WR */ -#define IPACX_CDA20 0x42 /* RD/WR */ -#define IPACX_CDA21 0x43 /* RD/WR */ -#define IPACX_CDA_TSDP10 0x44 /* RD/WR */ -#define IPACX_CDA_TSDP11 0x45 /* RD/WR */ -#define IPACX_CDA_TSDP20 0x46 /* RD/WR */ -#define IPACX_CDA_TSDP21 0x47 /* RD/WR */ -#define IPACX_BCHA_TSDP_BC1 0x48 /* RD/WR */ -#define IPACX_BCHA_TSDP_BC2 0x49 /* RD/WR */ -#define IPACX_BCHB_TSDP_BC1 0x4A /* RD/WR */ -#define IPACX_BCHB_TSDP_BC2 0x4B /* RD/WR */ -#define IPACX_TR_TSDP_BC1 0x4C /* RD/WR */ -#define IPACX_TR_TSDP_BC2 0x4D /* RD/WR */ -#define IPACX_CDA1_CR 0x4E /* RD/WR */ -#define IPACX_CDA2_CR 0x4F /* RD/WR */ - -/* IOM: Contol, Sync transfer, Monitor */ -#define IPACX_TR_CR 0x50 /* RD/WR */ -#define IPACX_TRC_CR 0x50 /* RD/WR */ -#define IPACX_BCHA_CR 0x51 /* RD/WR */ -#define IPACX_BCHB_CR 0x52 /* RD/WR */ -#define IPACX_DCI_CR 0x53 /* RD/WR */ -#define IPACX_DCIC_CR 0x53 /* RD/WR */ -#define IPACX_MON_CR 0x54 /* RD/WR */ -#define IPACX_SDS1_CR 0x55 /* RD/WR */ -#define IPACX_SDS2_CR 0x56 /* RD/WR */ -#define IPACX_IOM_CR 0x57 /* RD/WR */ -#define IPACX_STI 0x58 /* RD */ -#define IPACX_ASTI 0x58 /* WR */ -#define IPACX_MSTI 0x59 /* RD/WR */ -#define IPACX_SDS_CONF 0x5A /* RD/WR */ -#define IPACX_MCDA 0x5B /* RD */ -#define IPACX_MOR 0x5C /* RD */ -#define IPACX_MOX 0x5C /* WR */ -#define IPACX_MOSR 0x5D /* RD */ -#define IPACX_MOCR 0x5E /* RD/WR */ -#define IPACX_MSTA 0x5F /* RD */ -#define IPACX_MCONF 0x5F /* WR */ - -/* Interrupt and general registers */ -#define IPACX_ISTA 0x60 /* RD */ -#define IPACX_MASK 0x60 /* WR */ -#define IPACX_AUXI 0x61 /* RD */ -#define IPACX_AUXM 0x61 /* WR */ -#define IPACX_MODE1 0x62 /* RD/WR */ -#define IPACX_MODE2 0x63 /* RD/WR */ -#define IPACX_ID 0x64 /* RD */ -#define IPACX_SRES 0x64 /* WR */ -#define IPACX_TIMR2 0x65 /* RD/WR */ - -/* B-channel registers */ -#define IPACX_OFF_B1 0x70 -#define IPACX_OFF_B2 0x80 - -#define IPACX_ISTAB 0x00 /* RD */ -#define IPACX_MASKB 0x00 /* WR */ -#define IPACX_STARB 0x01 /* RD */ -#define IPACX_CMDRB 0x01 /* WR */ -#define IPACX_MODEB 0x02 /* RD/WR */ -#define IPACX_EXMB 0x03 /* RD/WR */ -#define IPACX_RAH1 0x05 /* WR */ -#define IPACX_RAH2 0x06 /* WR */ -#define IPACX_RBCLB 0x06 /* RD */ -#define IPACX_RBCHB 0x07 /* RD */ -#define IPACX_RAL1 0x07 /* WR */ -#define IPACX_RAL2 0x08 /* WR */ -#define IPACX_RSTAB 0x08 /* RD */ -#define IPACX_TMB 0x09 /* RD/WR */ -#define IPACX_RFIFOB 0x0A /*- RD */ -#define IPACX_XFIFOB 0x0A /*- WR */ - -/* Layer 1 Commands */ -#define IPACX_CMD_TIM 0x0 -#define IPACX_CMD_RES 0x1 -#define IPACX_CMD_SSP 0x2 -#define IPACX_CMD_SCP 0x3 -#define IPACX_CMD_AR8 0x8 -#define IPACX_CMD_AR10 0x9 -#define IPACX_CMD_ARL 0xa -#define IPACX_CMD_DI 0xf - -/* Layer 1 Indications */ -#define IPACX_IND_DR 0x0 -#define IPACX_IND_RES 0x1 -#define IPACX_IND_TMA 0x2 -#define IPACX_IND_SLD 0x3 -#define IPACX_IND_RSY 0x4 -#define IPACX_IND_DR6 0x5 -#define IPACX_IND_PU 0x7 -#define IPACX_IND_AR 0x8 -#define IPACX_IND_ARL 0xa -#define IPACX_IND_CVR 0xb -#define IPACX_IND_AI8 0xc -#define IPACX_IND_AI10 0xd -#define IPACX_IND_AIL 0xe -#define IPACX_IND_DC 0xf - -extern void init_ipacx(struct IsdnCardState *, int); -extern void interrupt_ipacx(struct IsdnCardState *); -extern void setup_isac(struct IsdnCardState *); - -#endif diff --git a/drivers/isdn/hisax/isac.c b/drivers/isdn/hisax/isac.c deleted file mode 100644 index bd40e0671ded..000000000000 --- a/drivers/isdn/hisax/isac.c +++ /dev/null @@ -1,681 +0,0 @@ -/* $Id: isac.c,v 1.31.2.3 2004/01/13 14:31:25 keil Exp $ - * - * ISAC specific routines - * - * Author Karsten Keil - * Copyright by Karsten Keil <keil@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * For changes and modifications please read - * Documentation/isdn/HiSax.cert - * - */ - -#include "hisax.h" -#include "isac.h" -#include "arcofi.h" -#include "isdnl1.h" -#include <linux/interrupt.h> -#include <linux/slab.h> -#include <linux/init.h> - -#define DBUSY_TIMER_VALUE 80 -#define ARCOFI_USE 1 - -static char *ISACVer[] = -{"2086/2186 V1.1", "2085 B1", "2085 B2", - "2085 V2.3"}; - -void ISACVersion(struct IsdnCardState *cs, char *s) -{ - int val; - - val = cs->readisac(cs, ISAC_RBCH); - printk(KERN_INFO "%s ISAC version (%x): %s\n", s, val, ISACVer[(val >> 5) & 3]); -} - -static void -ph_command(struct IsdnCardState *cs, unsigned int command) -{ - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "ph_command %x", command); - cs->writeisac(cs, ISAC_CIX0, (command << 2) | 3); -} - - -static void -isac_new_ph(struct IsdnCardState *cs) -{ - switch (cs->dc.isac.ph_state) { - case (ISAC_IND_RS): - case (ISAC_IND_EI): - ph_command(cs, ISAC_CMD_DUI); - l1_msg(cs, HW_RESET | INDICATION, NULL); - break; - case (ISAC_IND_DID): - l1_msg(cs, HW_DEACTIVATE | CONFIRM, NULL); - break; - case (ISAC_IND_DR): - l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL); - break; - case (ISAC_IND_PU): - l1_msg(cs, HW_POWERUP | CONFIRM, NULL); - break; - case (ISAC_IND_RSY): - l1_msg(cs, HW_RSYNC | INDICATION, NULL); - break; - case (ISAC_IND_ARD): - l1_msg(cs, HW_INFO2 | INDICATION, NULL); - break; - case (ISAC_IND_AI8): - l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL); - break; - case (ISAC_IND_AI10): - l1_msg(cs, HW_INFO4_P10 | INDICATION, NULL); - break; - default: - break; - } -} - -static void -isac_bh(struct work_struct *work) -{ - struct IsdnCardState *cs = - container_of(work, struct IsdnCardState, tqueue); - struct PStack *stptr; - - if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) { - if (cs->debug) - debugl1(cs, "D-Channel Busy cleared"); - stptr = cs->stlist; - while (stptr != NULL) { - stptr->l1.l1l2(stptr, PH_PAUSE | CONFIRM, NULL); - stptr = stptr->next; - } - } - if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) - isac_new_ph(cs); - if (test_and_clear_bit(D_RCVBUFREADY, &cs->event)) - DChannel_proc_rcv(cs); - if (test_and_clear_bit(D_XMTBUFREADY, &cs->event)) - DChannel_proc_xmt(cs); -#if ARCOFI_USE - if (!test_bit(HW_ARCOFI, &cs->HW_Flags)) - return; - if (test_and_clear_bit(D_RX_MON1, &cs->event)) - arcofi_fsm(cs, ARCOFI_RX_END, NULL); - if (test_and_clear_bit(D_TX_MON1, &cs->event)) - arcofi_fsm(cs, ARCOFI_TX_END, NULL); -#endif -} - -static void -isac_empty_fifo(struct IsdnCardState *cs, int count) -{ - u_char *ptr; - - if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO)) - debugl1(cs, "isac_empty_fifo"); - - if ((cs->rcvidx + count) >= MAX_DFRAME_LEN_L1) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "isac_empty_fifo overrun %d", - cs->rcvidx + count); - cs->writeisac(cs, ISAC_CMDR, 0x80); - cs->rcvidx = 0; - return; - } - ptr = cs->rcvbuf + cs->rcvidx; - cs->rcvidx += count; - cs->readisacfifo(cs, ptr, count); - cs->writeisac(cs, ISAC_CMDR, 0x80); - if (cs->debug & L1_DEB_ISAC_FIFO) { - char *t = cs->dlog; - - t += sprintf(t, "isac_empty_fifo cnt %d", count); - QuickHex(t, ptr, count); - debugl1(cs, "%s", cs->dlog); - } -} - -static void -isac_fill_fifo(struct IsdnCardState *cs) -{ - int count, more; - u_char *ptr; - - if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO)) - debugl1(cs, "isac_fill_fifo"); - - if (!cs->tx_skb) - return; - - count = cs->tx_skb->len; - if (count <= 0) - return; - - more = 0; - if (count > 32) { - more = !0; - count = 32; - } - ptr = cs->tx_skb->data; - skb_pull(cs->tx_skb, count); - cs->tx_cnt += count; - cs->writeisacfifo(cs, ptr, count); - cs->writeisac(cs, ISAC_CMDR, more ? 0x8 : 0xa); - if (test_and_set_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) { - debugl1(cs, "isac_fill_fifo dbusytimer running"); - del_timer(&cs->dbusytimer); - } - cs->dbusytimer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000); - add_timer(&cs->dbusytimer); - if (cs->debug & L1_DEB_ISAC_FIFO) { - char *t = cs->dlog; - - t += sprintf(t, "isac_fill_fifo cnt %d", count); - QuickHex(t, ptr, count); - debugl1(cs, "%s", cs->dlog); - } -} - -void -isac_interrupt(struct IsdnCardState *cs, u_char val) -{ - u_char exval, v1; - struct sk_buff *skb; - unsigned int count; - - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "ISAC interrupt %x", val); - if (val & 0x80) { /* RME */ - exval = cs->readisac(cs, ISAC_RSTA); - if ((exval & 0x70) != 0x20) { - if (exval & 0x40) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "ISAC RDO"); -#ifdef ERROR_STATISTIC - cs->err_rx++; -#endif - } - if (!(exval & 0x20)) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "ISAC CRC error"); -#ifdef ERROR_STATISTIC - cs->err_crc++; -#endif - } - cs->writeisac(cs, ISAC_CMDR, 0x80); - } else { - count = cs->readisac(cs, ISAC_RBCL) & 0x1f; - if (count == 0) - count = 32; - isac_empty_fifo(cs, count); - count = cs->rcvidx; - if (count > 0) { - cs->rcvidx = 0; - skb = alloc_skb(count, GFP_ATOMIC); - if (!skb) - printk(KERN_WARNING "HiSax: D receive out of memory\n"); - else { - skb_put_data(skb, cs->rcvbuf, count); - skb_queue_tail(&cs->rq, skb); - } - } - } - cs->rcvidx = 0; - schedule_event(cs, D_RCVBUFREADY); - } - if (val & 0x40) { /* RPF */ - isac_empty_fifo(cs, 32); - } - if (val & 0x20) { /* RSC */ - /* never */ - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "ISAC RSC interrupt"); - } - if (val & 0x10) { /* XPR */ - if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) - del_timer(&cs->dbusytimer); - if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags)) - schedule_event(cs, D_CLEARBUSY); - if (cs->tx_skb) { - if (cs->tx_skb->len) { - isac_fill_fifo(cs); - goto afterXPR; - } else { - dev_kfree_skb_irq(cs->tx_skb); - cs->tx_cnt = 0; - cs->tx_skb = NULL; - } - } - cs->tx_skb = skb_dequeue(&cs->sq); - if (cs->tx_skb) { - cs->tx_cnt = 0; - isac_fill_fifo(cs); - } else - schedule_event(cs, D_XMTBUFREADY); - } -afterXPR: - if (val & 0x04) { /* CISQ */ - exval = cs->readisac(cs, ISAC_CIR0); - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "ISAC CIR0 %02X", exval); - if (exval & 2) { - cs->dc.isac.ph_state = (exval >> 2) & 0xf; - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "ph_state change %x", cs->dc.isac.ph_state); - schedule_event(cs, D_L1STATECHANGE); - } - if (exval & 1) { - exval = cs->readisac(cs, ISAC_CIR1); - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "ISAC CIR1 %02X", exval); - } - } - if (val & 0x02) { /* SIN */ - /* never */ - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "ISAC SIN interrupt"); - } - if (val & 0x01) { /* EXI */ - exval = cs->readisac(cs, ISAC_EXIR); - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "ISAC EXIR %02x", exval); - if (exval & 0x80) { /* XMR */ - debugl1(cs, "ISAC XMR"); - printk(KERN_WARNING "HiSax: ISAC XMR\n"); - } - if (exval & 0x40) { /* XDU */ - debugl1(cs, "ISAC XDU"); - printk(KERN_WARNING "HiSax: ISAC XDU\n"); -#ifdef ERROR_STATISTIC - cs->err_tx++; -#endif - if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) - del_timer(&cs->dbusytimer); - if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags)) - schedule_event(cs, D_CLEARBUSY); - if (cs->tx_skb) { /* Restart frame */ - skb_push(cs->tx_skb, cs->tx_cnt); - cs->tx_cnt = 0; - isac_fill_fifo(cs); - } else { - printk(KERN_WARNING "HiSax: ISAC XDU no skb\n"); - debugl1(cs, "ISAC XDU no skb"); - } - } - if (exval & 0x04) { /* MOS */ - v1 = cs->readisac(cs, ISAC_MOSR); - if (cs->debug & L1_DEB_MONITOR) - debugl1(cs, "ISAC MOSR %02x", v1); -#if ARCOFI_USE - if (v1 & 0x08) { - if (!cs->dc.isac.mon_rx) { - cs->dc.isac.mon_rx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC); - if (!cs->dc.isac.mon_rx) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "ISAC MON RX out of memory!"); - cs->dc.isac.mocr &= 0xf0; - cs->dc.isac.mocr |= 0x0a; - cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); - goto afterMONR0; - } else - cs->dc.isac.mon_rxp = 0; - } - if (cs->dc.isac.mon_rxp >= MAX_MON_FRAME) { - cs->dc.isac.mocr &= 0xf0; - cs->dc.isac.mocr |= 0x0a; - cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); - cs->dc.isac.mon_rxp = 0; - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "ISAC MON RX overflow!"); - goto afterMONR0; - } - cs->dc.isac.mon_rx[cs->dc.isac.mon_rxp++] = cs->readisac(cs, ISAC_MOR0); - if (cs->debug & L1_DEB_MONITOR) - debugl1(cs, "ISAC MOR0 %02x", cs->dc.isac.mon_rx[cs->dc.isac.mon_rxp - 1]); - if (cs->dc.isac.mon_rxp == 1) { - cs->dc.isac.mocr |= 0x04; - cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); - } - } - afterMONR0: - if (v1 & 0x80) { - if (!cs->dc.isac.mon_rx) { - cs->dc.isac.mon_rx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC); - if (!cs->dc.isac.mon_rx) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "ISAC MON RX out of memory!"); - cs->dc.isac.mocr &= 0x0f; - cs->dc.isac.mocr |= 0xa0; - cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); - goto afterMONR1; - } else - cs->dc.isac.mon_rxp = 0; - } - if (cs->dc.isac.mon_rxp >= MAX_MON_FRAME) { - cs->dc.isac.mocr &= 0x0f; - cs->dc.isac.mocr |= 0xa0; - cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); - cs->dc.isac.mon_rxp = 0; - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "ISAC MON RX overflow!"); - goto afterMONR1; - } - cs->dc.isac.mon_rx[cs->dc.isac.mon_rxp++] = cs->readisac(cs, ISAC_MOR1); - if (cs->debug & L1_DEB_MONITOR) - debugl1(cs, "ISAC MOR1 %02x", cs->dc.isac.mon_rx[cs->dc.isac.mon_rxp - 1]); - cs->dc.isac.mocr |= 0x40; - cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); - } - afterMONR1: - if (v1 & 0x04) { - cs->dc.isac.mocr &= 0xf0; - cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); - cs->dc.isac.mocr |= 0x0a; - cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); - schedule_event(cs, D_RX_MON0); - } - if (v1 & 0x40) { - cs->dc.isac.mocr &= 0x0f; - cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); - cs->dc.isac.mocr |= 0xa0; - cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); - schedule_event(cs, D_RX_MON1); - } - if (v1 & 0x02) { - if ((!cs->dc.isac.mon_tx) || (cs->dc.isac.mon_txc && - (cs->dc.isac.mon_txp >= cs->dc.isac.mon_txc) && - !(v1 & 0x08))) { - cs->dc.isac.mocr &= 0xf0; - cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); - cs->dc.isac.mocr |= 0x0a; - cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); - if (cs->dc.isac.mon_txc && - (cs->dc.isac.mon_txp >= cs->dc.isac.mon_txc)) - schedule_event(cs, D_TX_MON0); - goto AfterMOX0; - } - if (cs->dc.isac.mon_txc && (cs->dc.isac.mon_txp >= cs->dc.isac.mon_txc)) { - schedule_event(cs, D_TX_MON0); - goto AfterMOX0; - } - cs->writeisac(cs, ISAC_MOX0, - cs->dc.isac.mon_tx[cs->dc.isac.mon_txp++]); - if (cs->debug & L1_DEB_MONITOR) - debugl1(cs, "ISAC %02x -> MOX0", cs->dc.isac.mon_tx[cs->dc.isac.mon_txp - 1]); - } - AfterMOX0: - if (v1 & 0x20) { - if ((!cs->dc.isac.mon_tx) || (cs->dc.isac.mon_txc && - (cs->dc.isac.mon_txp >= cs->dc.isac.mon_txc) && - !(v1 & 0x80))) { - cs->dc.isac.mocr &= 0x0f; - cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); - cs->dc.isac.mocr |= 0xa0; - cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); - if (cs->dc.isac.mon_txc && - (cs->dc.isac.mon_txp >= cs->dc.isac.mon_txc)) - schedule_event(cs, D_TX_MON1); - goto AfterMOX1; - } - if (cs->dc.isac.mon_txc && (cs->dc.isac.mon_txp >= cs->dc.isac.mon_txc)) { - schedule_event(cs, D_TX_MON1); - goto AfterMOX1; - } - cs->writeisac(cs, ISAC_MOX1, - cs->dc.isac.mon_tx[cs->dc.isac.mon_txp++]); - if (cs->debug & L1_DEB_MONITOR) - debugl1(cs, "ISAC %02x -> MOX1", cs->dc.isac.mon_tx[cs->dc.isac.mon_txp - 1]); - } - AfterMOX1:; -#endif - } - } -} - -static void -ISAC_l1hw(struct PStack *st, int pr, void *arg) -{ - struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware; - struct sk_buff *skb = arg; - u_long flags; - int val; - - switch (pr) { - case (PH_DATA | REQUEST): - if (cs->debug & DEB_DLOG_HEX) - LogFrame(cs, skb->data, skb->len); - if (cs->debug & DEB_DLOG_VERBOSE) - dlogframe(cs, skb, 0); - spin_lock_irqsave(&cs->lock, flags); - if (cs->tx_skb) { - skb_queue_tail(&cs->sq, skb); -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - Logl2Frame(cs, skb, "PH_DATA Queued", 0); -#endif - } else { - cs->tx_skb = skb; - cs->tx_cnt = 0; -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - Logl2Frame(cs, skb, "PH_DATA", 0); -#endif - isac_fill_fifo(cs); - } - spin_unlock_irqrestore(&cs->lock, flags); - break; - case (PH_PULL | INDICATION): - spin_lock_irqsave(&cs->lock, flags); - if (cs->tx_skb) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, " l2l1 tx_skb exist this shouldn't happen"); - skb_queue_tail(&cs->sq, skb); - } else { - if (cs->debug & DEB_DLOG_HEX) - LogFrame(cs, skb->data, skb->len); - if (cs->debug & DEB_DLOG_VERBOSE) - dlogframe(cs, skb, 0); - cs->tx_skb = skb; - cs->tx_cnt = 0; -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - Logl2Frame(cs, skb, "PH_DATA_PULLED", 0); -#endif - isac_fill_fifo(cs); - } - spin_unlock_irqrestore(&cs->lock, flags); - break; - case (PH_PULL | REQUEST): -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - debugl1(cs, "-> PH_REQUEST_PULL"); -#endif - if (!cs->tx_skb) { - test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); - } else - test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - break; - case (HW_RESET | REQUEST): - spin_lock_irqsave(&cs->lock, flags); - if ((cs->dc.isac.ph_state == ISAC_IND_EI) || - (cs->dc.isac.ph_state == ISAC_IND_DR) || - (cs->dc.isac.ph_state == ISAC_IND_RS)) - ph_command(cs, ISAC_CMD_TIM); - else - ph_command(cs, ISAC_CMD_RS); - spin_unlock_irqrestore(&cs->lock, flags); - break; - case (HW_ENABLE | REQUEST): - spin_lock_irqsave(&cs->lock, flags); - ph_command(cs, ISAC_CMD_TIM); - spin_unlock_irqrestore(&cs->lock, flags); - break; - case (HW_INFO3 | REQUEST): - spin_lock_irqsave(&cs->lock, flags); - ph_command(cs, ISAC_CMD_AR8); - spin_unlock_irqrestore(&cs->lock, flags); - break; - case (HW_TESTLOOP | REQUEST): - spin_lock_irqsave(&cs->lock, flags); - val = 0; - if (1 & (long) arg) - val |= 0x0c; - if (2 & (long) arg) - val |= 0x3; - if (test_bit(HW_IOM1, &cs->HW_Flags)) { - /* IOM 1 Mode */ - if (!val) { - cs->writeisac(cs, ISAC_SPCR, 0xa); - cs->writeisac(cs, ISAC_ADF1, 0x2); - } else { - cs->writeisac(cs, ISAC_SPCR, val); - cs->writeisac(cs, ISAC_ADF1, 0xa); - } - } else { - /* IOM 2 Mode */ - cs->writeisac(cs, ISAC_SPCR, val); - if (val) - cs->writeisac(cs, ISAC_ADF1, 0x8); - else - cs->writeisac(cs, ISAC_ADF1, 0x0); - } - spin_unlock_irqrestore(&cs->lock, flags); - break; - case (HW_DEACTIVATE | RESPONSE): - skb_queue_purge(&cs->rq); - skb_queue_purge(&cs->sq); - if (cs->tx_skb) { - dev_kfree_skb_any(cs->tx_skb); - cs->tx_skb = NULL; - } - if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) - del_timer(&cs->dbusytimer); - if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags)) - schedule_event(cs, D_CLEARBUSY); - break; - default: - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "isac_l1hw unknown %04x", pr); - break; - } -} - -static void -setstack_isac(struct PStack *st, struct IsdnCardState *cs) -{ - st->l1.l1hw = ISAC_l1hw; -} - -static void -DC_Close_isac(struct IsdnCardState *cs) -{ - kfree(cs->dc.isac.mon_rx); - cs->dc.isac.mon_rx = NULL; - kfree(cs->dc.isac.mon_tx); - cs->dc.isac.mon_tx = NULL; -} - -static void -dbusy_timer_handler(struct timer_list *t) -{ - struct IsdnCardState *cs = from_timer(cs, t, dbusytimer); - struct PStack *stptr; - int rbch, star; - - if (test_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) { - rbch = cs->readisac(cs, ISAC_RBCH); - star = cs->readisac(cs, ISAC_STAR); - if (cs->debug) - debugl1(cs, "D-Channel Busy RBCH %02x STAR %02x", - rbch, star); - if (rbch & ISAC_RBCH_XAC) { /* D-Channel Busy */ - test_and_set_bit(FLG_L1_DBUSY, &cs->HW_Flags); - stptr = cs->stlist; - while (stptr != NULL) { - stptr->l1.l1l2(stptr, PH_PAUSE | INDICATION, NULL); - stptr = stptr->next; - } - } else { - /* discard frame; reset transceiver */ - test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags); - if (cs->tx_skb) { - dev_kfree_skb_any(cs->tx_skb); - cs->tx_cnt = 0; - cs->tx_skb = NULL; - } else { - printk(KERN_WARNING "HiSax: ISAC D-Channel Busy no skb\n"); - debugl1(cs, "D-Channel Busy no skb"); - } - cs->writeisac(cs, ISAC_CMDR, 0x01); /* Transmitter reset */ - cs->irq_func(cs->irq, cs); - } - } -} - -void initisac(struct IsdnCardState *cs) -{ - cs->setstack_d = setstack_isac; - cs->DC_Close = DC_Close_isac; - cs->dc.isac.mon_tx = NULL; - cs->dc.isac.mon_rx = NULL; - cs->writeisac(cs, ISAC_MASK, 0xff); - cs->dc.isac.mocr = 0xaa; - if (test_bit(HW_IOM1, &cs->HW_Flags)) { - /* IOM 1 Mode */ - cs->writeisac(cs, ISAC_ADF2, 0x0); - cs->writeisac(cs, ISAC_SPCR, 0xa); - cs->writeisac(cs, ISAC_ADF1, 0x2); - cs->writeisac(cs, ISAC_STCR, 0x70); - cs->writeisac(cs, ISAC_MODE, 0xc9); - } else { - /* IOM 2 Mode */ - if (!cs->dc.isac.adf2) - cs->dc.isac.adf2 = 0x80; - cs->writeisac(cs, ISAC_ADF2, cs->dc.isac.adf2); - cs->writeisac(cs, ISAC_SQXR, 0x2f); - cs->writeisac(cs, ISAC_SPCR, 0x00); - cs->writeisac(cs, ISAC_STCR, 0x70); - cs->writeisac(cs, ISAC_MODE, 0xc9); - cs->writeisac(cs, ISAC_TIMR, 0x00); - cs->writeisac(cs, ISAC_ADF1, 0x00); - } - ph_command(cs, ISAC_CMD_RS); - cs->writeisac(cs, ISAC_MASK, 0x0); -} - -void clear_pending_isac_ints(struct IsdnCardState *cs) -{ - int val, eval; - - val = cs->readisac(cs, ISAC_STAR); - debugl1(cs, "ISAC STAR %x", val); - val = cs->readisac(cs, ISAC_MODE); - debugl1(cs, "ISAC MODE %x", val); - val = cs->readisac(cs, ISAC_ADF2); - debugl1(cs, "ISAC ADF2 %x", val); - val = cs->readisac(cs, ISAC_ISTA); - debugl1(cs, "ISAC ISTA %x", val); - if (val & 0x01) { - eval = cs->readisac(cs, ISAC_EXIR); - debugl1(cs, "ISAC EXIR %x", eval); - } - val = cs->readisac(cs, ISAC_CIR0); - debugl1(cs, "ISAC CIR0 %x", val); - cs->dc.isac.ph_state = (val >> 2) & 0xf; - schedule_event(cs, D_L1STATECHANGE); - /* Disable all IRQ */ - cs->writeisac(cs, ISAC_MASK, 0xFF); -} - -void setup_isac(struct IsdnCardState *cs) -{ - INIT_WORK(&cs->tqueue, isac_bh); - timer_setup(&cs->dbusytimer, dbusy_timer_handler, 0); -} diff --git a/drivers/isdn/hisax/isac.h b/drivers/isdn/hisax/isac.h deleted file mode 100644 index 04f16b91b822..000000000000 --- a/drivers/isdn/hisax/isac.h +++ /dev/null @@ -1,70 +0,0 @@ -/* $Id: isac.h,v 1.9.2.2 2004/01/12 22:52:27 keil Exp $ - * - * ISAC specific defines - * - * Author Karsten Keil - * Copyright by Karsten Keil <keil@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -/* All Registers original Siemens Spec */ - -#define ISAC_MASK 0x20 -#define ISAC_ISTA 0x20 -#define ISAC_STAR 0x21 -#define ISAC_CMDR 0x21 -#define ISAC_EXIR 0x24 -#define ISAC_ADF2 0x39 -#define ISAC_SPCR 0x30 -#define ISAC_ADF1 0x38 -#define ISAC_CIR0 0x31 -#define ISAC_CIX0 0x31 -#define ISAC_CIR1 0x33 -#define ISAC_CIX1 0x33 -#define ISAC_STCR 0x37 -#define ISAC_MODE 0x22 -#define ISAC_RSTA 0x27 -#define ISAC_RBCL 0x25 -#define ISAC_RBCH 0x2A -#define ISAC_TIMR 0x23 -#define ISAC_SQXR 0x3b -#define ISAC_MOSR 0x3a -#define ISAC_MOCR 0x3a -#define ISAC_MOR0 0x32 -#define ISAC_MOX0 0x32 -#define ISAC_MOR1 0x34 -#define ISAC_MOX1 0x34 - -#define ISAC_RBCH_XAC 0x80 - -#define ISAC_CMD_TIM 0x0 -#define ISAC_CMD_RS 0x1 -#define ISAC_CMD_SCZ 0x4 -#define ISAC_CMD_SSZ 0x2 -#define ISAC_CMD_AR8 0x8 -#define ISAC_CMD_AR10 0x9 -#define ISAC_CMD_ARL 0xA -#define ISAC_CMD_DUI 0xF - -#define ISAC_IND_RS 0x1 -#define ISAC_IND_PU 0x7 -#define ISAC_IND_DR 0x0 -#define ISAC_IND_SD 0x2 -#define ISAC_IND_DIS 0x3 -#define ISAC_IND_EI 0x6 -#define ISAC_IND_RSY 0x4 -#define ISAC_IND_ARD 0x8 -#define ISAC_IND_TI 0xA -#define ISAC_IND_ATI 0xB -#define ISAC_IND_AI8 0xC -#define ISAC_IND_AI10 0xD -#define ISAC_IND_DID 0xF - -extern void ISACVersion(struct IsdnCardState *, char *); -extern void setup_isac(struct IsdnCardState *); -extern void initisac(struct IsdnCardState *); -extern void isac_interrupt(struct IsdnCardState *, u_char); -extern void clear_pending_isac_ints(struct IsdnCardState *); diff --git a/drivers/isdn/hisax/isar.c b/drivers/isdn/hisax/isar.c deleted file mode 100644 index 82c1879f5664..000000000000 --- a/drivers/isdn/hisax/isar.c +++ /dev/null @@ -1,1910 +0,0 @@ -/* $Id: isar.c,v 1.22.2.6 2004/02/11 13:21:34 keil Exp $ - * - * isar.c ISAR (Siemens PSB 7110) specific routines - * - * Author Karsten Keil (keil@isdn4linux.de) - * - * This file is (c) under GNU General Public License - * - */ - -#include <linux/init.h> -#include "hisax.h" -#include "isar.h" -#include "isdnl1.h" -#include <linux/interrupt.h> -#include <linux/slab.h> - -#define DBG_LOADFIRM 0 -#define DUMP_MBOXFRAME 2 - -#define DLE 0x10 -#define ETX 0x03 - -#define FAXMODCNT 13 -static const u_char faxmodulation[] = {3, 24, 48, 72, 73, 74, 96, 97, 98, 121, 122, 145, 146}; -static u_int modmask = 0x1fff; -static int frm_extra_delay = 2; -static int para_TOA = 6; -static const u_char *FC1_CMD[] = {"FAE", "FTS", "FRS", "FTM", "FRM", "FTH", "FRH", "CTRL"}; - -static void isar_setup(struct IsdnCardState *cs); -static void isar_pump_cmd(struct BCState *bcs, u_char cmd, u_char para); -static void ll_deliver_faxstat(struct BCState *bcs, u_char status); - -static inline int -waitforHIA(struct IsdnCardState *cs, int timeout) -{ - - while ((cs->BC_Read_Reg(cs, 0, ISAR_HIA) & 1) && timeout) { - udelay(1); - timeout--; - } - if (!timeout) - printk(KERN_WARNING "HiSax: ISAR waitforHIA timeout\n"); - return (timeout); -} - - -static int -sendmsg(struct IsdnCardState *cs, u_char his, u_char creg, u_char len, - u_char *msg) -{ - int i; - - if (!waitforHIA(cs, 4000)) - return (0); -#if DUMP_MBOXFRAME - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "sendmsg(%02x,%02x,%d)", his, creg, len); -#endif - cs->BC_Write_Reg(cs, 0, ISAR_CTRL_H, creg); - cs->BC_Write_Reg(cs, 0, ISAR_CTRL_L, len); - cs->BC_Write_Reg(cs, 0, ISAR_WADR, 0); - if (msg && len) { - cs->BC_Write_Reg(cs, 1, ISAR_MBOX, msg[0]); - for (i = 1; i < len; i++) - cs->BC_Write_Reg(cs, 2, ISAR_MBOX, msg[i]); -#if DUMP_MBOXFRAME > 1 - if (cs->debug & L1_DEB_HSCX_FIFO) { - char tmp[256], *t; - - i = len; - while (i > 0) { - t = tmp; - t += sprintf(t, "sendmbox cnt %d", len); - QuickHex(t, &msg[len-i], (i > 64) ? 64 : i); - debugl1(cs, "%s", tmp); - i -= 64; - } - } -#endif - } - cs->BC_Write_Reg(cs, 1, ISAR_HIS, his); - waitforHIA(cs, 10000); - return (1); -} - -/* Call only with IRQ disabled !!! */ -static inline void -rcv_mbox(struct IsdnCardState *cs, struct isar_reg *ireg, u_char *msg) -{ - int i; - - cs->BC_Write_Reg(cs, 1, ISAR_RADR, 0); - if (msg && ireg->clsb) { - msg[0] = cs->BC_Read_Reg(cs, 1, ISAR_MBOX); - for (i = 1; i < ireg->clsb; i++) - msg[i] = cs->BC_Read_Reg(cs, 2, ISAR_MBOX); -#if DUMP_MBOXFRAME > 1 - if (cs->debug & L1_DEB_HSCX_FIFO) { - char tmp[256], *t; - - i = ireg->clsb; - while (i > 0) { - t = tmp; - t += sprintf(t, "rcv_mbox cnt %d", ireg->clsb); - QuickHex(t, &msg[ireg->clsb - i], (i > 64) ? 64 : i); - debugl1(cs, "%s", tmp); - i -= 64; - } - } -#endif - } - cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0); -} - -/* Call only with IRQ disabled !!! */ -static inline void -get_irq_infos(struct IsdnCardState *cs, struct isar_reg *ireg) -{ - ireg->iis = cs->BC_Read_Reg(cs, 1, ISAR_IIS); - ireg->cmsb = cs->BC_Read_Reg(cs, 1, ISAR_CTRL_H); - ireg->clsb = cs->BC_Read_Reg(cs, 1, ISAR_CTRL_L); -#if DUMP_MBOXFRAME - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "irq_stat(%02x,%02x,%d)", ireg->iis, ireg->cmsb, - ireg->clsb); -#endif -} - -static int -waitrecmsg(struct IsdnCardState *cs, u_char *len, - u_char *msg, int maxdelay) -{ - int timeout = 0; - struct isar_reg *ir = cs->bcs[0].hw.isar.reg; - - - while ((!(cs->BC_Read_Reg(cs, 0, ISAR_IRQBIT) & ISAR_IRQSTA)) && - (timeout++ < maxdelay)) - udelay(1); - if (timeout > maxdelay) { - printk(KERN_WARNING"isar recmsg IRQSTA timeout\n"); - return (0); - } - get_irq_infos(cs, ir); - rcv_mbox(cs, ir, msg); - *len = ir->clsb; - return (1); -} - -int -ISARVersion(struct IsdnCardState *cs, char *s) -{ - int ver; - u_char msg[] = ISAR_MSG_HWVER; - u_char tmp[64]; - u_char len; - u_long flags; - int debug; - - cs->cardmsg(cs, CARD_RESET, NULL); - spin_lock_irqsave(&cs->lock, flags); - /* disable ISAR IRQ */ - cs->BC_Write_Reg(cs, 0, ISAR_IRQBIT, 0); - debug = cs->debug; - cs->debug &= ~(L1_DEB_HSCX | L1_DEB_HSCX_FIFO); - if (!sendmsg(cs, ISAR_HIS_VNR, 0, 3, msg)) { - spin_unlock_irqrestore(&cs->lock, flags); - return (-1); - } - if (!waitrecmsg(cs, &len, tmp, 100000)) { - spin_unlock_irqrestore(&cs->lock, flags); - return (-2); - } - cs->debug = debug; - if (cs->bcs[0].hw.isar.reg->iis == ISAR_IIS_VNR) { - if (len == 1) { - ver = tmp[0] & 0xf; - printk(KERN_INFO "%s ISAR version %d\n", s, ver); - } else - ver = -3; - } else - ver = -4; - spin_unlock_irqrestore(&cs->lock, flags); - return (ver); -} - -static int -isar_load_firmware(struct IsdnCardState *cs, u_char __user *buf) -{ - int cfu_ret, ret, size, cnt, debug; - u_char len, nom, noc; - u_short sadr, left, *sp; - u_char __user *p = buf; - u_char *msg, *tmpmsg, *mp, tmp[64]; - u_long flags; - struct isar_reg *ireg = cs->bcs[0].hw.isar.reg; - - struct {u_short sadr; - u_short len; - u_short d_key; - } blk_head; - -#define BLK_HEAD_SIZE 6 - if (1 != (ret = ISARVersion(cs, "Testing"))) { - printk(KERN_ERR"isar_load_firmware wrong isar version %d\n", ret); - return (1); - } - debug = cs->debug; -#if DBG_LOADFIRM < 2 - cs->debug &= ~(L1_DEB_HSCX | L1_DEB_HSCX_FIFO); -#endif - - cfu_ret = copy_from_user(&size, p, sizeof(int)); - if (cfu_ret) { - printk(KERN_ERR "isar_load_firmware copy_from_user ret %d\n", cfu_ret); - return -EFAULT; - } - p += sizeof(int); - printk(KERN_DEBUG"isar_load_firmware size: %d\n", size); - cnt = 0; - /* disable ISAR IRQ */ - cs->BC_Write_Reg(cs, 0, ISAR_IRQBIT, 0); - if (!(msg = kmalloc(256, GFP_KERNEL))) { - printk(KERN_ERR"isar_load_firmware no buffer\n"); - return (1); - } - if (!(tmpmsg = kmalloc(256, GFP_KERNEL))) { - printk(KERN_ERR"isar_load_firmware no tmp buffer\n"); - kfree(msg); - return (1); - } - spin_lock_irqsave(&cs->lock, flags); - /* disable ISAR IRQ */ - cs->BC_Write_Reg(cs, 0, ISAR_IRQBIT, 0); - spin_unlock_irqrestore(&cs->lock, flags); - while (cnt < size) { - if ((ret = copy_from_user(&blk_head, p, BLK_HEAD_SIZE))) { - printk(KERN_ERR"isar_load_firmware copy_from_user ret %d\n", ret); - goto reterror; - } -#ifdef __BIG_ENDIAN - sadr = (blk_head.sadr & 0xff) * 256 + blk_head.sadr / 256; - blk_head.sadr = sadr; - sadr = (blk_head.len & 0xff) * 256 + blk_head.len / 256; - blk_head.len = sadr; - sadr = (blk_head.d_key & 0xff) * 256 + blk_head.d_key / 256; - blk_head.d_key = sadr; -#endif /* __BIG_ENDIAN */ - cnt += BLK_HEAD_SIZE; - p += BLK_HEAD_SIZE; - printk(KERN_DEBUG"isar firmware block (%#x,%5d,%#x)\n", - blk_head.sadr, blk_head.len, blk_head.d_key & 0xff); - sadr = blk_head.sadr; - left = blk_head.len; - spin_lock_irqsave(&cs->lock, flags); - if (!sendmsg(cs, ISAR_HIS_DKEY, blk_head.d_key & 0xff, 0, NULL)) { - printk(KERN_ERR"isar sendmsg dkey failed\n"); - ret = 1; goto reterr_unlock; - } - if (!waitrecmsg(cs, &len, tmp, 100000)) { - printk(KERN_ERR"isar waitrecmsg dkey failed\n"); - ret = 1; goto reterr_unlock; - } - if ((ireg->iis != ISAR_IIS_DKEY) || ireg->cmsb || len) { - printk(KERN_ERR"isar wrong dkey response (%x,%x,%x)\n", - ireg->iis, ireg->cmsb, len); - ret = 1; goto reterr_unlock; - } - spin_unlock_irqrestore(&cs->lock, flags); - while (left > 0) { - if (left > 126) - noc = 126; - else - noc = left; - nom = 2 * noc; - mp = msg; - *mp++ = sadr / 256; - *mp++ = sadr % 256; - left -= noc; - *mp++ = noc; - if ((ret = copy_from_user(tmpmsg, p, nom))) { - printk(KERN_ERR"isar_load_firmware copy_from_user ret %d\n", ret); - goto reterror; - } - p += nom; - cnt += nom; - nom += 3; - sp = (u_short *)tmpmsg; -#if DBG_LOADFIRM - printk(KERN_DEBUG"isar: load %3d words at %04x left %d\n", - noc, sadr, left); -#endif - sadr += noc; - while (noc) { -#ifdef __BIG_ENDIAN - *mp++ = *sp % 256; - *mp++ = *sp / 256; -#else - *mp++ = *sp / 256; - *mp++ = *sp % 256; -#endif /* __BIG_ENDIAN */ - sp++; - noc--; - } - spin_lock_irqsave(&cs->lock, flags); - if (!sendmsg(cs, ISAR_HIS_FIRM, 0, nom, msg)) { - printk(KERN_ERR"isar sendmsg prog failed\n"); - ret = 1; goto reterr_unlock; - } - if (!waitrecmsg(cs, &len, tmp, 100000)) { - printk(KERN_ERR"isar waitrecmsg prog failed\n"); - ret = 1; goto reterr_unlock; - } - if ((ireg->iis != ISAR_IIS_FIRM) || ireg->cmsb || len) { - printk(KERN_ERR"isar wrong prog response (%x,%x,%x)\n", - ireg->iis, ireg->cmsb, len); - ret = 1; goto reterr_unlock; - } - spin_unlock_irqrestore(&cs->lock, flags); - } - printk(KERN_DEBUG"isar firmware block %5d words loaded\n", - blk_head.len); - } - /* 10ms delay */ - cnt = 10; - while (cnt--) - udelay(1000); - msg[0] = 0xff; - msg[1] = 0xfe; - ireg->bstat = 0; - spin_lock_irqsave(&cs->lock, flags); - if (!sendmsg(cs, ISAR_HIS_STDSP, 0, 2, msg)) { - printk(KERN_ERR"isar sendmsg start dsp failed\n"); - ret = 1; goto reterr_unlock; - } - if (!waitrecmsg(cs, &len, tmp, 100000)) { - printk(KERN_ERR"isar waitrecmsg start dsp failed\n"); - ret = 1; goto reterr_unlock; - } - if ((ireg->iis != ISAR_IIS_STDSP) || ireg->cmsb || len) { - printk(KERN_ERR"isar wrong start dsp response (%x,%x,%x)\n", - ireg->iis, ireg->cmsb, len); - ret = 1; goto reterr_unlock; - } else - printk(KERN_DEBUG"isar start dsp success\n"); - /* NORMAL mode entered */ - /* Enable IRQs of ISAR */ - cs->BC_Write_Reg(cs, 0, ISAR_IRQBIT, ISAR_IRQSTA); - spin_unlock_irqrestore(&cs->lock, flags); - cnt = 1000; /* max 1s */ - while ((!ireg->bstat) && cnt) { - udelay(1000); - cnt--; - } - if (!cnt) { - printk(KERN_ERR"isar no general status event received\n"); - ret = 1; goto reterror; - } else { - printk(KERN_DEBUG"isar general status event %x\n", - ireg->bstat); - } - /* 10ms delay */ - cnt = 10; - while (cnt--) - udelay(1000); - spin_lock_irqsave(&cs->lock, flags); - ireg->iis = 0; - if (!sendmsg(cs, ISAR_HIS_DIAG, ISAR_CTRL_STST, 0, NULL)) { - printk(KERN_ERR"isar sendmsg self tst failed\n"); - ret = 1; goto reterr_unlock; - } - cnt = 10000; /* max 100 ms */ - spin_unlock_irqrestore(&cs->lock, flags); - while ((ireg->iis != ISAR_IIS_DIAG) && cnt) { - udelay(10); - cnt--; - } - udelay(1000); - if (!cnt) { - printk(KERN_ERR"isar no self tst response\n"); - ret = 1; goto reterror; - } - if ((ireg->cmsb == ISAR_CTRL_STST) && (ireg->clsb == 1) - && (ireg->par[0] == 0)) { - printk(KERN_DEBUG"isar selftest OK\n"); - } else { - printk(KERN_DEBUG"isar selftest not OK %x/%x/%x\n", - ireg->cmsb, ireg->clsb, ireg->par[0]); - ret = 1; goto reterror; - } - spin_lock_irqsave(&cs->lock, flags); - ireg->iis = 0; - if (!sendmsg(cs, ISAR_HIS_DIAG, ISAR_CTRL_SWVER, 0, NULL)) { - printk(KERN_ERR"isar RQST SVN failed\n"); - ret = 1; goto reterr_unlock; - } - spin_unlock_irqrestore(&cs->lock, flags); - cnt = 30000; /* max 300 ms */ - while ((ireg->iis != ISAR_IIS_DIAG) && cnt) { - udelay(10); - cnt--; - } - udelay(1000); - if (!cnt) { - printk(KERN_ERR"isar no SVN response\n"); - ret = 1; goto reterror; - } else { - if ((ireg->cmsb == ISAR_CTRL_SWVER) && (ireg->clsb == 1)) - printk(KERN_DEBUG"isar software version %#x\n", - ireg->par[0]); - else { - printk(KERN_ERR"isar wrong swver response (%x,%x) cnt(%d)\n", - ireg->cmsb, ireg->clsb, cnt); - ret = 1; goto reterror; - } - } - spin_lock_irqsave(&cs->lock, flags); - cs->debug = debug; - isar_setup(cs); - - ret = 0; -reterr_unlock: - spin_unlock_irqrestore(&cs->lock, flags); -reterror: - cs->debug = debug; - if (ret) - /* disable ISAR IRQ */ - cs->BC_Write_Reg(cs, 0, ISAR_IRQBIT, 0); - kfree(msg); - kfree(tmpmsg); - return (ret); -} - -#define B_LL_NOCARRIER 8 -#define B_LL_CONNECT 9 -#define B_LL_OK 10 - -static void -isar_bh(struct work_struct *work) -{ - struct BCState *bcs = container_of(work, struct BCState, tqueue); - - BChannel_bh(work); - if (test_and_clear_bit(B_LL_NOCARRIER, &bcs->event)) - ll_deliver_faxstat(bcs, ISDN_FAX_CLASS1_NOCARR); - if (test_and_clear_bit(B_LL_CONNECT, &bcs->event)) - ll_deliver_faxstat(bcs, ISDN_FAX_CLASS1_CONNECT); - if (test_and_clear_bit(B_LL_OK, &bcs->event)) - ll_deliver_faxstat(bcs, ISDN_FAX_CLASS1_OK); -} - -static void -send_DLE_ETX(struct BCState *bcs) -{ - u_char dleetx[2] = {DLE, ETX}; - struct sk_buff *skb; - - if ((skb = dev_alloc_skb(2))) { - skb_put_data(skb, dleetx, 2); - skb_queue_tail(&bcs->rqueue, skb); - schedule_event(bcs, B_RCVBUFREADY); - } else { - printk(KERN_WARNING "HiSax: skb out of memory\n"); - } -} - -static inline int -dle_count(unsigned char *buf, int len) -{ - int count = 0; - - while (len--) - if (*buf++ == DLE) - count++; - return count; -} - -static inline void -insert_dle(unsigned char *dest, unsigned char *src, int count) { - /* <DLE> in input stream have to be flagged as <DLE><DLE> */ - while (count--) { - *dest++ = *src; - if (*src++ == DLE) - *dest++ = DLE; - } -} - -static void -isar_rcv_frame(struct IsdnCardState *cs, struct BCState *bcs) -{ - u_char *ptr; - struct sk_buff *skb; - struct isar_reg *ireg = bcs->hw.isar.reg; - - if (!ireg->clsb) { - debugl1(cs, "isar zero len frame"); - cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0); - return; - } - switch (bcs->mode) { - case L1_MODE_NULL: - debugl1(cs, "isar mode 0 spurious IIS_RDATA %x/%x/%x", - ireg->iis, ireg->cmsb, ireg->clsb); - printk(KERN_WARNING"isar mode 0 spurious IIS_RDATA %x/%x/%x\n", - ireg->iis, ireg->cmsb, ireg->clsb); - cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0); - break; - case L1_MODE_TRANS: - case L1_MODE_V32: - if ((skb = dev_alloc_skb(ireg->clsb))) { - rcv_mbox(cs, ireg, (u_char *)skb_put(skb, ireg->clsb)); - skb_queue_tail(&bcs->rqueue, skb); - schedule_event(bcs, B_RCVBUFREADY); - } else { - printk(KERN_WARNING "HiSax: skb out of memory\n"); - cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0); - } - break; - case L1_MODE_HDLC: - if ((bcs->hw.isar.rcvidx + ireg->clsb) > HSCX_BUFMAX) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "isar_rcv_frame: incoming packet too large"); - cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0); - bcs->hw.isar.rcvidx = 0; - } else if (ireg->cmsb & HDLC_ERROR) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "isar frame error %x len %d", - ireg->cmsb, ireg->clsb); -#ifdef ERROR_STATISTIC - if (ireg->cmsb & HDLC_ERR_RER) - bcs->err_inv++; - if (ireg->cmsb & HDLC_ERR_CER) - bcs->err_crc++; -#endif - bcs->hw.isar.rcvidx = 0; - cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0); - } else { - if (ireg->cmsb & HDLC_FSD) - bcs->hw.isar.rcvidx = 0; - ptr = bcs->hw.isar.rcvbuf + bcs->hw.isar.rcvidx; - bcs->hw.isar.rcvidx += ireg->clsb; - rcv_mbox(cs, ireg, ptr); - if (ireg->cmsb & HDLC_FED) { - if (bcs->hw.isar.rcvidx < 3) { /* last 2 bytes are the FCS */ - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "isar frame to short %d", - bcs->hw.isar.rcvidx); - } else if (!(skb = dev_alloc_skb(bcs->hw.isar.rcvidx - 2))) { - printk(KERN_WARNING "ISAR: receive out of memory\n"); - } else { - skb_put_data(skb, bcs->hw.isar.rcvbuf, - bcs->hw.isar.rcvidx - 2); - skb_queue_tail(&bcs->rqueue, skb); - schedule_event(bcs, B_RCVBUFREADY); - } - bcs->hw.isar.rcvidx = 0; - } - } - break; - case L1_MODE_FAX: - if (bcs->hw.isar.state != STFAX_ACTIV) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "isar_rcv_frame: not ACTIV"); - cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0); - bcs->hw.isar.rcvidx = 0; - break; - } - if (bcs->hw.isar.cmd == PCTRL_CMD_FRM) { - rcv_mbox(cs, ireg, bcs->hw.isar.rcvbuf); - bcs->hw.isar.rcvidx = ireg->clsb + - dle_count(bcs->hw.isar.rcvbuf, ireg->clsb); - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "isar_rcv_frame: raw(%d) dle(%d)", - ireg->clsb, bcs->hw.isar.rcvidx); - if ((skb = dev_alloc_skb(bcs->hw.isar.rcvidx))) { - insert_dle((u_char *)skb_put(skb, bcs->hw.isar.rcvidx), - bcs->hw.isar.rcvbuf, ireg->clsb); - skb_queue_tail(&bcs->rqueue, skb); - schedule_event(bcs, B_RCVBUFREADY); - if (ireg->cmsb & SART_NMD) { /* ABORT */ - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "isar_rcv_frame: no more data"); - bcs->hw.isar.rcvidx = 0; - send_DLE_ETX(bcs); - sendmsg(cs, SET_DPS(bcs->hw.isar.dpath) | - ISAR_HIS_PUMPCTRL, PCTRL_CMD_ESC, - 0, NULL); - bcs->hw.isar.state = STFAX_ESCAPE; - schedule_event(bcs, B_LL_NOCARRIER); - } - } else { - printk(KERN_WARNING "HiSax: skb out of memory\n"); - } - break; - } - if (bcs->hw.isar.cmd != PCTRL_CMD_FRH) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "isar_rcv_frame: unknown fax mode %x", - bcs->hw.isar.cmd); - cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0); - bcs->hw.isar.rcvidx = 0; - break; - } - /* PCTRL_CMD_FRH */ - if ((bcs->hw.isar.rcvidx + ireg->clsb) > HSCX_BUFMAX) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "isar_rcv_frame: incoming packet too large"); - cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0); - bcs->hw.isar.rcvidx = 0; - } else if (ireg->cmsb & HDLC_ERROR) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "isar frame error %x len %d", - ireg->cmsb, ireg->clsb); - bcs->hw.isar.rcvidx = 0; - cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0); - } else { - if (ireg->cmsb & HDLC_FSD) { - bcs->hw.isar.rcvidx = 0; - } - ptr = bcs->hw.isar.rcvbuf + bcs->hw.isar.rcvidx; - bcs->hw.isar.rcvidx += ireg->clsb; - rcv_mbox(cs, ireg, ptr); - if (ireg->cmsb & HDLC_FED) { - int len = bcs->hw.isar.rcvidx + - dle_count(bcs->hw.isar.rcvbuf, bcs->hw.isar.rcvidx); - if (bcs->hw.isar.rcvidx < 3) { /* last 2 bytes are the FCS */ - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "isar frame to short %d", - bcs->hw.isar.rcvidx); - printk(KERN_WARNING "ISAR: frame to short %d\n", - bcs->hw.isar.rcvidx); - } else if (!(skb = dev_alloc_skb(len))) { - printk(KERN_WARNING "ISAR: receive out of memory\n"); - } else { - insert_dle((u_char *)skb_put(skb, len), - bcs->hw.isar.rcvbuf, - bcs->hw.isar.rcvidx); - skb_queue_tail(&bcs->rqueue, skb); - schedule_event(bcs, B_RCVBUFREADY); - send_DLE_ETX(bcs); - schedule_event(bcs, B_LL_OK); - test_and_clear_bit(BC_FLG_FRH_WAIT, &bcs->Flag); - } - bcs->hw.isar.rcvidx = 0; - } - } - if (ireg->cmsb & SART_NMD) { /* ABORT */ - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "isar_rcv_frame: no more data"); - bcs->hw.isar.rcvidx = 0; - sendmsg(cs, SET_DPS(bcs->hw.isar.dpath) | - ISAR_HIS_PUMPCTRL, PCTRL_CMD_ESC, 0, NULL); - bcs->hw.isar.state = STFAX_ESCAPE; - if (test_and_clear_bit(BC_FLG_FRH_WAIT, &bcs->Flag)) { - send_DLE_ETX(bcs); - schedule_event(bcs, B_LL_NOCARRIER); - } - } - break; - default: - printk(KERN_ERR"isar_rcv_frame mode (%x)error\n", bcs->mode); - cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0); - break; - } -} - -void -isar_fill_fifo(struct BCState *bcs) -{ - struct IsdnCardState *cs = bcs->cs; - int count; - u_char msb; - u_char *ptr; - - if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) - debugl1(cs, "isar_fill_fifo"); - if (!bcs->tx_skb) - return; - if (bcs->tx_skb->len <= 0) - return; - if (!(bcs->hw.isar.reg->bstat & - (bcs->hw.isar.dpath == 1 ? BSTAT_RDM1 : BSTAT_RDM2))) - return; - if (bcs->tx_skb->len > bcs->hw.isar.mml) { - msb = 0; - count = bcs->hw.isar.mml; - } else { - count = bcs->tx_skb->len; - msb = HDLC_FED; - } - ptr = bcs->tx_skb->data; - if (!bcs->hw.isar.txcnt) { - msb |= HDLC_FST; - if ((bcs->mode == L1_MODE_FAX) && - (bcs->hw.isar.cmd == PCTRL_CMD_FTH)) { - if (bcs->tx_skb->len > 1) { - if ((ptr[0] == 0xff) && (ptr[1] == 0x13)) - /* last frame */ - test_and_set_bit(BC_FLG_LASTDATA, - &bcs->Flag); - } - } - } - skb_pull(bcs->tx_skb, count); - bcs->tx_cnt -= count; - bcs->hw.isar.txcnt += count; - switch (bcs->mode) { - case L1_MODE_NULL: - printk(KERN_ERR"isar_fill_fifo wrong mode 0\n"); - break; - case L1_MODE_TRANS: - case L1_MODE_V32: - sendmsg(cs, SET_DPS(bcs->hw.isar.dpath) | ISAR_HIS_SDATA, - 0, count, ptr); - break; - case L1_MODE_HDLC: - sendmsg(cs, SET_DPS(bcs->hw.isar.dpath) | ISAR_HIS_SDATA, - msb, count, ptr); - break; - case L1_MODE_FAX: - if (bcs->hw.isar.state != STFAX_ACTIV) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "isar_fill_fifo: not ACTIV"); - } else if (bcs->hw.isar.cmd == PCTRL_CMD_FTH) { - sendmsg(cs, SET_DPS(bcs->hw.isar.dpath) | ISAR_HIS_SDATA, - msb, count, ptr); - } else if (bcs->hw.isar.cmd == PCTRL_CMD_FTM) { - sendmsg(cs, SET_DPS(bcs->hw.isar.dpath) | ISAR_HIS_SDATA, - 0, count, ptr); - } else { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "isar_fill_fifo: not FTH/FTM"); - } - break; - default: - if (cs->debug) - debugl1(cs, "isar_fill_fifo mode(%x) error", bcs->mode); - printk(KERN_ERR"isar_fill_fifo mode(%x) error\n", bcs->mode); - break; - } -} - -static inline -struct BCState *sel_bcs_isar(struct IsdnCardState *cs, u_char dpath) -{ - if ((!dpath) || (dpath == 3)) - return (NULL); - if (cs->bcs[0].hw.isar.dpath == dpath) - return (&cs->bcs[0]); - if (cs->bcs[1].hw.isar.dpath == dpath) - return (&cs->bcs[1]); - return (NULL); -} - -static void -send_frames(struct BCState *bcs) -{ - if (bcs->tx_skb) { - if (bcs->tx_skb->len) { - isar_fill_fifo(bcs); - return; - } else { - if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) && - (PACKET_NOACK != bcs->tx_skb->pkt_type)) { - u_long flags; - spin_lock_irqsave(&bcs->aclock, flags); - bcs->ackcnt += bcs->hw.isar.txcnt; - spin_unlock_irqrestore(&bcs->aclock, flags); - schedule_event(bcs, B_ACKPENDING); - } - if (bcs->mode == L1_MODE_FAX) { - if (bcs->hw.isar.cmd == PCTRL_CMD_FTH) { - if (test_bit(BC_FLG_LASTDATA, &bcs->Flag)) { - test_and_set_bit(BC_FLG_NMD_DATA, &bcs->Flag); - } - } else if (bcs->hw.isar.cmd == PCTRL_CMD_FTM) { - if (test_bit(BC_FLG_DLEETX, &bcs->Flag)) { - test_and_set_bit(BC_FLG_LASTDATA, &bcs->Flag); - test_and_set_bit(BC_FLG_NMD_DATA, &bcs->Flag); - } - } - } - dev_kfree_skb_any(bcs->tx_skb); - bcs->hw.isar.txcnt = 0; - bcs->tx_skb = NULL; - } - } - if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) { - bcs->hw.isar.txcnt = 0; - test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); - isar_fill_fifo(bcs); - } else { - if (test_and_clear_bit(BC_FLG_DLEETX, &bcs->Flag)) { - if (test_and_clear_bit(BC_FLG_LASTDATA, &bcs->Flag)) { - if (test_and_clear_bit(BC_FLG_NMD_DATA, &bcs->Flag)) { - u_char dummy = 0; - sendmsg(bcs->cs, SET_DPS(bcs->hw.isar.dpath) | - ISAR_HIS_SDATA, 0x01, 1, &dummy); - } - test_and_set_bit(BC_FLG_LL_OK, &bcs->Flag); - } else { - schedule_event(bcs, B_LL_CONNECT); - } - } - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - schedule_event(bcs, B_XMTBUFREADY); - } -} - -static inline void -check_send(struct IsdnCardState *cs, u_char rdm) -{ - struct BCState *bcs; - - if (rdm & BSTAT_RDM1) { - if ((bcs = sel_bcs_isar(cs, 1))) { - if (bcs->mode) { - send_frames(bcs); - } - } - } - if (rdm & BSTAT_RDM2) { - if ((bcs = sel_bcs_isar(cs, 2))) { - if (bcs->mode) { - send_frames(bcs); - } - } - } - -} - -static const char *dmril[] = {"NO SPEED", "1200/75", "NODEF2", "75/1200", - "NODEF4", "300", "600", "1200", "2400", - "4800", "7200", "9600nt", "9600t", "12000", - "14400", "WRONG"}; -static const char *dmrim[] = {"NO MOD", "NO DEF", "V32/V32b", "V22", "V21", - "Bell103", "V23", "Bell202", "V17", "V29", - "V27ter"}; - -static void -isar_pump_status_rsp(struct BCState *bcs, struct isar_reg *ireg) { - struct IsdnCardState *cs = bcs->cs; - u_char ril = ireg->par[0]; - u_char rim; - - if (!test_and_clear_bit(ISAR_RATE_REQ, &bcs->hw.isar.reg->Flags)) - return; - if (ril > 14) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "wrong pstrsp ril=%d", ril); - ril = 15; - } - switch (ireg->par[1]) { - case 0: - rim = 0; - break; - case 0x20: - rim = 2; - break; - case 0x40: - rim = 3; - break; - case 0x41: - rim = 4; - break; - case 0x51: - rim = 5; - break; - case 0x61: - rim = 6; - break; - case 0x71: - rim = 7; - break; - case 0x82: - rim = 8; - break; - case 0x92: - rim = 9; - break; - case 0xa2: - rim = 10; - break; - default: - rim = 1; - break; - } - sprintf(bcs->hw.isar.conmsg, "%s %s", dmril[ril], dmrim[rim]); - bcs->conmsg = bcs->hw.isar.conmsg; - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "pump strsp %s", bcs->conmsg); -} - -static void -isar_pump_statev_modem(struct BCState *bcs, u_char devt) { - struct IsdnCardState *cs = bcs->cs; - u_char dps = SET_DPS(bcs->hw.isar.dpath); - - switch (devt) { - case PSEV_10MS_TIMER: - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "pump stev TIMER"); - break; - case PSEV_CON_ON: - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "pump stev CONNECT"); - l1_msg_b(bcs->st, PH_ACTIVATE | REQUEST, NULL); - break; - case PSEV_CON_OFF: - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "pump stev NO CONNECT"); - sendmsg(cs, dps | ISAR_HIS_PSTREQ, 0, 0, NULL); - l1_msg_b(bcs->st, PH_DEACTIVATE | REQUEST, NULL); - break; - case PSEV_V24_OFF: - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "pump stev V24 OFF"); - break; - case PSEV_CTS_ON: - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "pump stev CTS ON"); - break; - case PSEV_CTS_OFF: - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "pump stev CTS OFF"); - break; - case PSEV_DCD_ON: - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "pump stev CARRIER ON"); - test_and_set_bit(ISAR_RATE_REQ, &bcs->hw.isar.reg->Flags); - sendmsg(cs, dps | ISAR_HIS_PSTREQ, 0, 0, NULL); - break; - case PSEV_DCD_OFF: - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "pump stev CARRIER OFF"); - break; - case PSEV_DSR_ON: - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "pump stev DSR ON"); - break; - case PSEV_DSR_OFF: - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "pump stev DSR_OFF"); - break; - case PSEV_REM_RET: - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "pump stev REMOTE RETRAIN"); - break; - case PSEV_REM_REN: - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "pump stev REMOTE RENEGOTIATE"); - break; - case PSEV_GSTN_CLR: - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "pump stev GSTN CLEAR"); - break; - default: - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "unknown pump stev %x", devt); - break; - } -} - -static void -ll_deliver_faxstat(struct BCState *bcs, u_char status) -{ - isdn_ctrl ic; - struct Channel *chanp = (struct Channel *) bcs->st->lli.userdata; - - if (bcs->cs->debug & L1_DEB_HSCX) - debugl1(bcs->cs, "HL->LL FAXIND %x", status); - ic.driver = bcs->cs->myid; - ic.command = ISDN_STAT_FAXIND; - ic.arg = chanp->chan; - ic.parm.aux.cmd = status; - bcs->cs->iif.statcallb(&ic); -} - -static void -isar_pump_statev_fax(struct BCState *bcs, u_char devt) { - struct IsdnCardState *cs = bcs->cs; - u_char dps = SET_DPS(bcs->hw.isar.dpath); - u_char p1; - - switch (devt) { - case PSEV_10MS_TIMER: - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "pump stev TIMER"); - break; - case PSEV_RSP_READY: - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "pump stev RSP_READY"); - bcs->hw.isar.state = STFAX_READY; - l1_msg_b(bcs->st, PH_ACTIVATE | REQUEST, NULL); - if (test_bit(BC_FLG_ORIG, &bcs->Flag)) { - isar_pump_cmd(bcs, ISDN_FAX_CLASS1_FRH, 3); - } else { - isar_pump_cmd(bcs, ISDN_FAX_CLASS1_FTH, 3); - } - break; - case PSEV_LINE_TX_H: - if (bcs->hw.isar.state == STFAX_LINE) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "pump stev LINE_TX_H"); - bcs->hw.isar.state = STFAX_CONT; - sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, PCTRL_CMD_CONT, 0, NULL); - } else { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "pump stev LINE_TX_H wrong st %x", - bcs->hw.isar.state); - } - break; - case PSEV_LINE_RX_H: - if (bcs->hw.isar.state == STFAX_LINE) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "pump stev LINE_RX_H"); - bcs->hw.isar.state = STFAX_CONT; - sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, PCTRL_CMD_CONT, 0, NULL); - } else { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "pump stev LINE_RX_H wrong st %x", - bcs->hw.isar.state); - } - break; - case PSEV_LINE_TX_B: - if (bcs->hw.isar.state == STFAX_LINE) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "pump stev LINE_TX_B"); - bcs->hw.isar.state = STFAX_CONT; - sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, PCTRL_CMD_CONT, 0, NULL); - } else { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "pump stev LINE_TX_B wrong st %x", - bcs->hw.isar.state); - } - break; - case PSEV_LINE_RX_B: - if (bcs->hw.isar.state == STFAX_LINE) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "pump stev LINE_RX_B"); - bcs->hw.isar.state = STFAX_CONT; - sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, PCTRL_CMD_CONT, 0, NULL); - } else { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "pump stev LINE_RX_B wrong st %x", - bcs->hw.isar.state); - } - break; - case PSEV_RSP_CONN: - if (bcs->hw.isar.state == STFAX_CONT) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "pump stev RSP_CONN"); - bcs->hw.isar.state = STFAX_ACTIV; - test_and_set_bit(ISAR_RATE_REQ, &bcs->hw.isar.reg->Flags); - sendmsg(cs, dps | ISAR_HIS_PSTREQ, 0, 0, NULL); - if (bcs->hw.isar.cmd == PCTRL_CMD_FTH) { - /* 1s Flags before data */ - if (test_and_set_bit(BC_FLG_FTI_RUN, &bcs->Flag)) - del_timer(&bcs->hw.isar.ftimer); - /* 1000 ms */ - bcs->hw.isar.ftimer.expires = - jiffies + ((1000 * HZ) / 1000); - test_and_set_bit(BC_FLG_LL_CONN, - &bcs->Flag); - add_timer(&bcs->hw.isar.ftimer); - } else { - schedule_event(bcs, B_LL_CONNECT); - } - } else { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "pump stev RSP_CONN wrong st %x", - bcs->hw.isar.state); - } - break; - case PSEV_FLAGS_DET: - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "pump stev FLAGS_DET"); - break; - case PSEV_RSP_DISC: - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "pump stev RSP_DISC"); - if (bcs->hw.isar.state == STFAX_ESCAPE) { - p1 = 5; - switch (bcs->hw.isar.newcmd) { - case 0: - bcs->hw.isar.state = STFAX_READY; - break; - case PCTRL_CMD_FTM: - p1 = 2; - /* fall through */ - case PCTRL_CMD_FTH: - sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, - PCTRL_CMD_SILON, 1, &p1); - bcs->hw.isar.state = STFAX_SILDET; - break; - case PCTRL_CMD_FRM: - if (frm_extra_delay) - mdelay(frm_extra_delay); - /* fall through */ - case PCTRL_CMD_FRH: - p1 = bcs->hw.isar.mod = bcs->hw.isar.newmod; - bcs->hw.isar.newmod = 0; - bcs->hw.isar.cmd = bcs->hw.isar.newcmd; - bcs->hw.isar.newcmd = 0; - sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, - bcs->hw.isar.cmd, 1, &p1); - bcs->hw.isar.state = STFAX_LINE; - bcs->hw.isar.try_mod = 3; - break; - default: - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "RSP_DISC unknown newcmd %x", bcs->hw.isar.newcmd); - break; - } - } else if (bcs->hw.isar.state == STFAX_ACTIV) { - if (test_and_clear_bit(BC_FLG_LL_OK, &bcs->Flag)) { - schedule_event(bcs, B_LL_OK); - } else if (bcs->hw.isar.cmd == PCTRL_CMD_FRM) { - send_DLE_ETX(bcs); - schedule_event(bcs, B_LL_NOCARRIER); - } else { - ll_deliver_faxstat(bcs, ISDN_FAX_CLASS1_FCERROR); - } - bcs->hw.isar.state = STFAX_READY; - } else { - bcs->hw.isar.state = STFAX_READY; - ll_deliver_faxstat(bcs, ISDN_FAX_CLASS1_FCERROR); - } - break; - case PSEV_RSP_SILDET: - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "pump stev RSP_SILDET"); - if (bcs->hw.isar.state == STFAX_SILDET) { - p1 = bcs->hw.isar.mod = bcs->hw.isar.newmod; - bcs->hw.isar.newmod = 0; - bcs->hw.isar.cmd = bcs->hw.isar.newcmd; - bcs->hw.isar.newcmd = 0; - sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, - bcs->hw.isar.cmd, 1, &p1); - bcs->hw.isar.state = STFAX_LINE; - bcs->hw.isar.try_mod = 3; - } - break; - case PSEV_RSP_SILOFF: - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "pump stev RSP_SILOFF"); - break; - case PSEV_RSP_FCERR: - if (bcs->hw.isar.state == STFAX_LINE) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "pump stev RSP_FCERR try %d", - bcs->hw.isar.try_mod); - if (bcs->hw.isar.try_mod--) { - sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, - bcs->hw.isar.cmd, 1, - &bcs->hw.isar.mod); - break; - } - } - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "pump stev RSP_FCERR"); - bcs->hw.isar.state = STFAX_ESCAPE; - sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, PCTRL_CMD_ESC, 0, NULL); - ll_deliver_faxstat(bcs, ISDN_FAX_CLASS1_FCERROR); - break; - default: - break; - } -} - -static char debbuf[128]; - -void -isar_int_main(struct IsdnCardState *cs) -{ - struct isar_reg *ireg = cs->bcs[0].hw.isar.reg; - struct BCState *bcs; - - get_irq_infos(cs, ireg); - switch (ireg->iis & ISAR_IIS_MSCMSD) { - case ISAR_IIS_RDATA: - if ((bcs = sel_bcs_isar(cs, ireg->iis >> 6))) { - isar_rcv_frame(cs, bcs); - } else { - debugl1(cs, "isar spurious IIS_RDATA %x/%x/%x", - ireg->iis, ireg->cmsb, ireg->clsb); - cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0); - } - break; - case ISAR_IIS_GSTEV: - cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0); - ireg->bstat |= ireg->cmsb; - check_send(cs, ireg->cmsb); - break; - case ISAR_IIS_BSTEV: -#ifdef ERROR_STATISTIC - if ((bcs = sel_bcs_isar(cs, ireg->iis >> 6))) { - if (ireg->cmsb == BSTEV_TBO) - bcs->err_tx++; - if (ireg->cmsb == BSTEV_RBO) - bcs->err_rdo++; - } -#endif - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "Buffer STEV dpath%d msb(%x)", - ireg->iis >> 6, ireg->cmsb); - cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0); - break; - case ISAR_IIS_PSTEV: - if ((bcs = sel_bcs_isar(cs, ireg->iis >> 6))) { - rcv_mbox(cs, ireg, (u_char *)ireg->par); - if (bcs->mode == L1_MODE_V32) { - isar_pump_statev_modem(bcs, ireg->cmsb); - } else if (bcs->mode == L1_MODE_FAX) { - isar_pump_statev_fax(bcs, ireg->cmsb); - } else if (ireg->cmsb == PSEV_10MS_TIMER) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "pump stev TIMER"); - } else { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "isar IIS_PSTEV pmode %d stat %x", - bcs->mode, ireg->cmsb); - } - } else { - debugl1(cs, "isar spurious IIS_PSTEV %x/%x/%x", - ireg->iis, ireg->cmsb, ireg->clsb); - cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0); - } - break; - case ISAR_IIS_PSTRSP: - if ((bcs = sel_bcs_isar(cs, ireg->iis >> 6))) { - rcv_mbox(cs, ireg, (u_char *)ireg->par); - isar_pump_status_rsp(bcs, ireg); - } else { - debugl1(cs, "isar spurious IIS_PSTRSP %x/%x/%x", - ireg->iis, ireg->cmsb, ireg->clsb); - cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0); - } - break; - case ISAR_IIS_DIAG: - case ISAR_IIS_BSTRSP: - case ISAR_IIS_IOM2RSP: - rcv_mbox(cs, ireg, (u_char *)ireg->par); - if ((cs->debug & (L1_DEB_HSCX | L1_DEB_HSCX_FIFO)) - == L1_DEB_HSCX) { - u_char *tp = debbuf; - - tp += sprintf(debbuf, "msg iis(%x) msb(%x)", - ireg->iis, ireg->cmsb); - QuickHex(tp, (u_char *)ireg->par, ireg->clsb); - debugl1(cs, "%s", debbuf); - } - break; - case ISAR_IIS_INVMSG: - rcv_mbox(cs, ireg, debbuf); - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "invalid msg his:%x", - ireg->cmsb); - break; - default: - rcv_mbox(cs, ireg, debbuf); - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "unhandled msg iis(%x) ctrl(%x/%x)", - ireg->iis, ireg->cmsb, ireg->clsb); - break; - } -} - -static void -ftimer_handler(struct timer_list *t) { - struct BCState *bcs = from_timer(bcs, t, hw.isar.ftimer); - if (bcs->cs->debug) - debugl1(bcs->cs, "ftimer flags %04lx", - bcs->Flag); - test_and_clear_bit(BC_FLG_FTI_RUN, &bcs->Flag); - if (test_and_clear_bit(BC_FLG_LL_CONN, &bcs->Flag)) { - schedule_event(bcs, B_LL_CONNECT); - } - if (test_and_clear_bit(BC_FLG_FTI_FTS, &bcs->Flag)) { - schedule_event(bcs, B_LL_OK); - } -} - -static void -setup_pump(struct BCState *bcs) { - struct IsdnCardState *cs = bcs->cs; - u_char dps = SET_DPS(bcs->hw.isar.dpath); - u_char ctrl, param[6]; - - switch (bcs->mode) { - case L1_MODE_NULL: - case L1_MODE_TRANS: - case L1_MODE_HDLC: - sendmsg(cs, dps | ISAR_HIS_PUMPCFG, PMOD_BYPASS, 0, NULL); - break; - case L1_MODE_V32: - ctrl = PMOD_DATAMODEM; - if (test_bit(BC_FLG_ORIG, &bcs->Flag)) { - ctrl |= PCTRL_ORIG; - param[5] = PV32P6_CTN; - } else { - param[5] = PV32P6_ATN; - } - param[0] = para_TOA; /* 6 db */ - param[1] = PV32P2_V23R | PV32P2_V22A | PV32P2_V22B | - PV32P2_V22C | PV32P2_V21 | PV32P2_BEL; - param[2] = PV32P3_AMOD | PV32P3_V32B | PV32P3_V23B; - param[3] = PV32P4_UT144; - param[4] = PV32P5_UT144; - sendmsg(cs, dps | ISAR_HIS_PUMPCFG, ctrl, 6, param); - break; - case L1_MODE_FAX: - ctrl = PMOD_FAX; - if (test_bit(BC_FLG_ORIG, &bcs->Flag)) { - ctrl |= PCTRL_ORIG; - param[1] = PFAXP2_CTN; - } else { - param[1] = PFAXP2_ATN; - } - param[0] = para_TOA; /* 6 db */ - sendmsg(cs, dps | ISAR_HIS_PUMPCFG, ctrl, 2, param); - bcs->hw.isar.state = STFAX_NULL; - bcs->hw.isar.newcmd = 0; - bcs->hw.isar.newmod = 0; - test_and_set_bit(BC_FLG_FTI_RUN, &bcs->Flag); - break; - } - udelay(1000); - sendmsg(cs, dps | ISAR_HIS_PSTREQ, 0, 0, NULL); - udelay(1000); -} - -static void -setup_sart(struct BCState *bcs) { - struct IsdnCardState *cs = bcs->cs; - u_char dps = SET_DPS(bcs->hw.isar.dpath); - u_char ctrl, param[2]; - - switch (bcs->mode) { - case L1_MODE_NULL: - sendmsg(cs, dps | ISAR_HIS_SARTCFG, SMODE_DISABLE, 0, - NULL); - break; - case L1_MODE_TRANS: - sendmsg(cs, dps | ISAR_HIS_SARTCFG, SMODE_BINARY, 2, - "\0\0"); - break; - case L1_MODE_HDLC: - param[0] = 0; - sendmsg(cs, dps | ISAR_HIS_SARTCFG, SMODE_HDLC, 1, - param); - break; - case L1_MODE_V32: - ctrl = SMODE_V14 | SCTRL_HDMC_BOTH; - param[0] = S_P1_CHS_8; - param[1] = S_P2_BFT_DEF; - sendmsg(cs, dps | ISAR_HIS_SARTCFG, ctrl, 2, - param); - break; - case L1_MODE_FAX: - /* SART must not configured with FAX */ - break; - } - udelay(1000); - sendmsg(cs, dps | ISAR_HIS_BSTREQ, 0, 0, NULL); - udelay(1000); -} - -static void -setup_iom2(struct BCState *bcs) { - struct IsdnCardState *cs = bcs->cs; - u_char dps = SET_DPS(bcs->hw.isar.dpath); - u_char cmsb = IOM_CTRL_ENA, msg[5] = {IOM_P1_TXD, 0, 0, 0, 0}; - - if (bcs->channel) - msg[1] = msg[3] = 1; - switch (bcs->mode) { - case L1_MODE_NULL: - cmsb = 0; - /* dummy slot */ - msg[1] = msg[3] = bcs->hw.isar.dpath + 2; - break; - case L1_MODE_TRANS: - case L1_MODE_HDLC: - break; - case L1_MODE_V32: - case L1_MODE_FAX: - cmsb |= IOM_CTRL_ALAW | IOM_CTRL_RCV; - break; - } - sendmsg(cs, dps | ISAR_HIS_IOM2CFG, cmsb, 5, msg); - udelay(1000); - sendmsg(cs, dps | ISAR_HIS_IOM2REQ, 0, 0, NULL); - udelay(1000); -} - -static int -modeisar(struct BCState *bcs, int mode, int bc) -{ - struct IsdnCardState *cs = bcs->cs; - - /* Here we are selecting the best datapath for requested mode */ - if (bcs->mode == L1_MODE_NULL) { /* New Setup */ - bcs->channel = bc; - switch (mode) { - case L1_MODE_NULL: /* init */ - if (!bcs->hw.isar.dpath) - /* no init for dpath 0 */ - return (0); - break; - case L1_MODE_TRANS: - case L1_MODE_HDLC: - /* best is datapath 2 */ - if (!test_and_set_bit(ISAR_DP2_USE, - &bcs->hw.isar.reg->Flags)) - bcs->hw.isar.dpath = 2; - else if (!test_and_set_bit(ISAR_DP1_USE, - &bcs->hw.isar.reg->Flags)) - bcs->hw.isar.dpath = 1; - else { - printk(KERN_WARNING"isar modeisar both paths in use\n"); - return (1); - } - break; - case L1_MODE_V32: - case L1_MODE_FAX: - /* only datapath 1 */ - if (!test_and_set_bit(ISAR_DP1_USE, - &bcs->hw.isar.reg->Flags)) - bcs->hw.isar.dpath = 1; - else { - printk(KERN_WARNING"isar modeisar analog functions only with DP1\n"); - debugl1(cs, "isar modeisar analog functions only with DP1"); - return (1); - } - break; - } - } - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "isar dp%d mode %d->%d ichan %d", - bcs->hw.isar.dpath, bcs->mode, mode, bc); - bcs->mode = mode; - setup_pump(bcs); - setup_iom2(bcs); - setup_sart(bcs); - if (bcs->mode == L1_MODE_NULL) { - /* Clear resources */ - if (bcs->hw.isar.dpath == 1) - test_and_clear_bit(ISAR_DP1_USE, &bcs->hw.isar.reg->Flags); - else if (bcs->hw.isar.dpath == 2) - test_and_clear_bit(ISAR_DP2_USE, &bcs->hw.isar.reg->Flags); - bcs->hw.isar.dpath = 0; - } - return (0); -} - -static void -isar_pump_cmd(struct BCState *bcs, u_char cmd, u_char para) -{ - struct IsdnCardState *cs = bcs->cs; - u_char dps = SET_DPS(bcs->hw.isar.dpath); - u_char ctrl = 0, nom = 0, p1 = 0; - - switch (cmd) { - case ISDN_FAX_CLASS1_FTM: - test_and_clear_bit(BC_FLG_FRH_WAIT, &bcs->Flag); - if (bcs->hw.isar.state == STFAX_READY) { - p1 = para; - ctrl = PCTRL_CMD_FTM; - nom = 1; - bcs->hw.isar.state = STFAX_LINE; - bcs->hw.isar.cmd = ctrl; - bcs->hw.isar.mod = para; - bcs->hw.isar.newmod = 0; - bcs->hw.isar.newcmd = 0; - bcs->hw.isar.try_mod = 3; - } else if ((bcs->hw.isar.state == STFAX_ACTIV) && - (bcs->hw.isar.cmd == PCTRL_CMD_FTM) && - (bcs->hw.isar.mod == para)) { - ll_deliver_faxstat(bcs, ISDN_FAX_CLASS1_CONNECT); - } else { - bcs->hw.isar.newmod = para; - bcs->hw.isar.newcmd = PCTRL_CMD_FTM; - nom = 0; - ctrl = PCTRL_CMD_ESC; - bcs->hw.isar.state = STFAX_ESCAPE; - } - break; - case ISDN_FAX_CLASS1_FTH: - test_and_clear_bit(BC_FLG_FRH_WAIT, &bcs->Flag); - if (bcs->hw.isar.state == STFAX_READY) { - p1 = para; - ctrl = PCTRL_CMD_FTH; - nom = 1; - bcs->hw.isar.state = STFAX_LINE; - bcs->hw.isar.cmd = ctrl; - bcs->hw.isar.mod = para; - bcs->hw.isar.newmod = 0; - bcs->hw.isar.newcmd = 0; - bcs->hw.isar.try_mod = 3; - } else if ((bcs->hw.isar.state == STFAX_ACTIV) && - (bcs->hw.isar.cmd == PCTRL_CMD_FTH) && - (bcs->hw.isar.mod == para)) { - ll_deliver_faxstat(bcs, ISDN_FAX_CLASS1_CONNECT); - } else { - bcs->hw.isar.newmod = para; - bcs->hw.isar.newcmd = PCTRL_CMD_FTH; - nom = 0; - ctrl = PCTRL_CMD_ESC; - bcs->hw.isar.state = STFAX_ESCAPE; - } - break; - case ISDN_FAX_CLASS1_FRM: - test_and_clear_bit(BC_FLG_FRH_WAIT, &bcs->Flag); - if (bcs->hw.isar.state == STFAX_READY) { - p1 = para; - ctrl = PCTRL_CMD_FRM; - nom = 1; - bcs->hw.isar.state = STFAX_LINE; - bcs->hw.isar.cmd = ctrl; - bcs->hw.isar.mod = para; - bcs->hw.isar.newmod = 0; - bcs->hw.isar.newcmd = 0; - bcs->hw.isar.try_mod = 3; - } else if ((bcs->hw.isar.state == STFAX_ACTIV) && - (bcs->hw.isar.cmd == PCTRL_CMD_FRM) && - (bcs->hw.isar.mod == para)) { - ll_deliver_faxstat(bcs, ISDN_FAX_CLASS1_CONNECT); - } else { - bcs->hw.isar.newmod = para; - bcs->hw.isar.newcmd = PCTRL_CMD_FRM; - nom = 0; - ctrl = PCTRL_CMD_ESC; - bcs->hw.isar.state = STFAX_ESCAPE; - } - break; - case ISDN_FAX_CLASS1_FRH: - test_and_set_bit(BC_FLG_FRH_WAIT, &bcs->Flag); - if (bcs->hw.isar.state == STFAX_READY) { - p1 = para; - ctrl = PCTRL_CMD_FRH; - nom = 1; - bcs->hw.isar.state = STFAX_LINE; - bcs->hw.isar.cmd = ctrl; - bcs->hw.isar.mod = para; - bcs->hw.isar.newmod = 0; - bcs->hw.isar.newcmd = 0; - bcs->hw.isar.try_mod = 3; - } else if ((bcs->hw.isar.state == STFAX_ACTIV) && - (bcs->hw.isar.cmd == PCTRL_CMD_FRH) && - (bcs->hw.isar.mod == para)) { - ll_deliver_faxstat(bcs, ISDN_FAX_CLASS1_CONNECT); - } else { - bcs->hw.isar.newmod = para; - bcs->hw.isar.newcmd = PCTRL_CMD_FRH; - nom = 0; - ctrl = PCTRL_CMD_ESC; - bcs->hw.isar.state = STFAX_ESCAPE; - } - break; - case ISDN_FAXPUMP_HALT: - bcs->hw.isar.state = STFAX_NULL; - nom = 0; - ctrl = PCTRL_CMD_HALT; - break; - } - if (ctrl) - sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, ctrl, nom, &p1); -} - -static void -isar_setup(struct IsdnCardState *cs) -{ - u_char msg; - int i; - - /* Dpath 1, 2 */ - msg = 61; - for (i = 0; i < 2; i++) { - /* Buffer Config */ - sendmsg(cs, (i ? ISAR_HIS_DPS2 : ISAR_HIS_DPS1) | - ISAR_HIS_P12CFG, 4, 1, &msg); - cs->bcs[i].hw.isar.mml = msg; - cs->bcs[i].mode = 0; - cs->bcs[i].hw.isar.dpath = i + 1; - modeisar(&cs->bcs[i], 0, 0); - INIT_WORK(&cs->bcs[i].tqueue, isar_bh); - } -} - -static void -isar_l2l1(struct PStack *st, int pr, void *arg) -{ - struct BCState *bcs = st->l1.bcs; - struct sk_buff *skb = arg; - int ret; - u_long flags; - - switch (pr) { - case (PH_DATA | REQUEST): - spin_lock_irqsave(&bcs->cs->lock, flags); - if (bcs->tx_skb) { - skb_queue_tail(&bcs->squeue, skb); - } else { - bcs->tx_skb = skb; - test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); - if (bcs->cs->debug & L1_DEB_HSCX) - debugl1(bcs->cs, "DRQ set BC_FLG_BUSY"); - bcs->hw.isar.txcnt = 0; - bcs->cs->BC_Send_Data(bcs); - } - spin_unlock_irqrestore(&bcs->cs->lock, flags); - break; - case (PH_PULL | INDICATION): - spin_lock_irqsave(&bcs->cs->lock, flags); - if (bcs->tx_skb) { - printk(KERN_WARNING "isar_l2l1: this shouldn't happen\n"); - } else { - test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); - if (bcs->cs->debug & L1_DEB_HSCX) - debugl1(bcs->cs, "PUI set BC_FLG_BUSY"); - bcs->tx_skb = skb; - bcs->hw.isar.txcnt = 0; - bcs->cs->BC_Send_Data(bcs); - } - spin_unlock_irqrestore(&bcs->cs->lock, flags); - break; - case (PH_PULL | REQUEST): - if (!bcs->tx_skb) { - test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); - } else - test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - break; - case (PH_ACTIVATE | REQUEST): - spin_lock_irqsave(&bcs->cs->lock, flags); - test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag); - bcs->hw.isar.conmsg[0] = 0; - if (test_bit(FLG_ORIG, &st->l2.flag)) - test_and_set_bit(BC_FLG_ORIG, &bcs->Flag); - else - test_and_clear_bit(BC_FLG_ORIG, &bcs->Flag); - switch (st->l1.mode) { - case L1_MODE_TRANS: - case L1_MODE_HDLC: - ret = modeisar(bcs, st->l1.mode, st->l1.bc); - spin_unlock_irqrestore(&bcs->cs->lock, flags); - if (ret) - l1_msg_b(st, PH_DEACTIVATE | REQUEST, arg); - else - l1_msg_b(st, PH_ACTIVATE | REQUEST, arg); - break; - case L1_MODE_V32: - case L1_MODE_FAX: - ret = modeisar(bcs, st->l1.mode, st->l1.bc); - spin_unlock_irqrestore(&bcs->cs->lock, flags); - if (ret) - l1_msg_b(st, PH_DEACTIVATE | REQUEST, arg); - break; - default: - spin_unlock_irqrestore(&bcs->cs->lock, flags); - break; - } - break; - case (PH_DEACTIVATE | REQUEST): - l1_msg_b(st, pr, arg); - break; - case (PH_DEACTIVATE | CONFIRM): - spin_lock_irqsave(&bcs->cs->lock, flags); - switch (st->l1.mode) { - case L1_MODE_TRANS: - case L1_MODE_HDLC: - case L1_MODE_V32: - break; - case L1_MODE_FAX: - isar_pump_cmd(bcs, ISDN_FAXPUMP_HALT, 0); - break; - } - test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag); - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - if (bcs->cs->debug & L1_DEB_HSCX) - debugl1(bcs->cs, "PDAC clear BC_FLG_BUSY"); - modeisar(bcs, 0, st->l1.bc); - spin_unlock_irqrestore(&bcs->cs->lock, flags); - st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL); - break; - } -} - -static void -close_isarstate(struct BCState *bcs) -{ - modeisar(bcs, 0, bcs->channel); - if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) { - kfree(bcs->hw.isar.rcvbuf); - bcs->hw.isar.rcvbuf = NULL; - skb_queue_purge(&bcs->rqueue); - skb_queue_purge(&bcs->squeue); - if (bcs->tx_skb) { - dev_kfree_skb_any(bcs->tx_skb); - bcs->tx_skb = NULL; - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - if (bcs->cs->debug & L1_DEB_HSCX) - debugl1(bcs->cs, "closeisar clear BC_FLG_BUSY"); - } - } - del_timer(&bcs->hw.isar.ftimer); -} - -static int -open_isarstate(struct IsdnCardState *cs, struct BCState *bcs) -{ - if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { - if (!(bcs->hw.isar.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) { - printk(KERN_WARNING - "HiSax: No memory for isar.rcvbuf\n"); - return (1); - } - skb_queue_head_init(&bcs->rqueue); - skb_queue_head_init(&bcs->squeue); - } - bcs->tx_skb = NULL; - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "openisar clear BC_FLG_BUSY"); - bcs->event = 0; - bcs->hw.isar.rcvidx = 0; - bcs->tx_cnt = 0; - return (0); -} - -static int -setstack_isar(struct PStack *st, struct BCState *bcs) -{ - bcs->channel = st->l1.bc; - if (open_isarstate(st->l1.hardware, bcs)) - return (-1); - st->l1.bcs = bcs; - st->l2.l2l1 = isar_l2l1; - setstack_manager(st); - bcs->st = st; - setstack_l1_B(st); - return (0); -} - -int -isar_auxcmd(struct IsdnCardState *cs, isdn_ctrl *ic) { - u_long adr; - int features, i; - struct BCState *bcs; - - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "isar_auxcmd cmd/ch %x/%ld", ic->command, ic->arg); - switch (ic->command) { - case (ISDN_CMD_FAXCMD): - bcs = cs->channel[ic->arg].bcs; - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "isar_auxcmd cmd/subcmd %d/%d", - ic->parm.aux.cmd, ic->parm.aux.subcmd); - switch (ic->parm.aux.cmd) { - case ISDN_FAX_CLASS1_CTRL: - if (ic->parm.aux.subcmd == ETX) - test_and_set_bit(BC_FLG_DLEETX, - &bcs->Flag); - break; - case ISDN_FAX_CLASS1_FTS: - if (ic->parm.aux.subcmd == AT_QUERY) { - ic->command = ISDN_STAT_FAXIND; - ic->parm.aux.cmd = ISDN_FAX_CLASS1_OK; - cs->iif.statcallb(ic); - return (0); - } else if (ic->parm.aux.subcmd == AT_EQ_QUERY) { - strcpy(ic->parm.aux.para, "0-255"); - ic->command = ISDN_STAT_FAXIND; - ic->parm.aux.cmd = ISDN_FAX_CLASS1_QUERY; - cs->iif.statcallb(ic); - return (0); - } else if (ic->parm.aux.subcmd == AT_EQ_VALUE) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "isar_auxcmd %s=%d", - FC1_CMD[ic->parm.aux.cmd], ic->parm.aux.para[0]); - if (bcs->hw.isar.state == STFAX_READY) { - if (!ic->parm.aux.para[0]) { - ic->command = ISDN_STAT_FAXIND; - ic->parm.aux.cmd = ISDN_FAX_CLASS1_OK; - cs->iif.statcallb(ic); - return (0); - } - if (!test_and_set_bit(BC_FLG_FTI_RUN, &bcs->Flag)) { - /* n*10 ms */ - bcs->hw.isar.ftimer.expires = - jiffies + ((ic->parm.aux.para[0] * 10 * HZ) / 1000); - test_and_set_bit(BC_FLG_FTI_FTS, &bcs->Flag); - add_timer(&bcs->hw.isar.ftimer); - return (0); - } else { - if (cs->debug) - debugl1(cs, "isar FTS=%d and FTI busy", - ic->parm.aux.para[0]); - } - } else { - if (cs->debug) - debugl1(cs, "isar FTS=%d and isar.state not ready(%x)", - ic->parm.aux.para[0], bcs->hw.isar.state); - } - ic->command = ISDN_STAT_FAXIND; - ic->parm.aux.cmd = ISDN_FAX_CLASS1_ERROR; - cs->iif.statcallb(ic); - } - break; - case ISDN_FAX_CLASS1_FRM: - case ISDN_FAX_CLASS1_FRH: - case ISDN_FAX_CLASS1_FTM: - case ISDN_FAX_CLASS1_FTH: - if (ic->parm.aux.subcmd == AT_QUERY) { - sprintf(ic->parm.aux.para, - "%d", bcs->hw.isar.mod); - ic->command = ISDN_STAT_FAXIND; - ic->parm.aux.cmd = ISDN_FAX_CLASS1_QUERY; - cs->iif.statcallb(ic); - return (0); - } else if (ic->parm.aux.subcmd == AT_EQ_QUERY) { - char *p = ic->parm.aux.para; - for (i = 0; i < FAXMODCNT; i++) - if ((1 << i) & modmask) - p += sprintf(p, "%d,", faxmodulation[i]); - p--; - *p = 0; - ic->command = ISDN_STAT_FAXIND; - ic->parm.aux.cmd = ISDN_FAX_CLASS1_QUERY; - cs->iif.statcallb(ic); - return (0); - } else if (ic->parm.aux.subcmd == AT_EQ_VALUE) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "isar_auxcmd %s=%d", - FC1_CMD[ic->parm.aux.cmd], ic->parm.aux.para[0]); - for (i = 0; i < FAXMODCNT; i++) - if (faxmodulation[i] == ic->parm.aux.para[0]) - break; - if ((i < FAXMODCNT) && ((1 << i) & modmask) && - test_bit(BC_FLG_INIT, &bcs->Flag)) { - isar_pump_cmd(bcs, - ic->parm.aux.cmd, - ic->parm.aux.para[0]); - return (0); - } - } - /* wrong modulation or not activ */ - /* fall through */ - default: - ic->command = ISDN_STAT_FAXIND; - ic->parm.aux.cmd = ISDN_FAX_CLASS1_ERROR; - cs->iif.statcallb(ic); - } - break; - case (ISDN_CMD_IOCTL): - switch (ic->arg) { - case 9: /* load firmware */ - features = ISDN_FEATURE_L2_MODEM | - ISDN_FEATURE_L2_FAX | - ISDN_FEATURE_L3_FCLASS1; - memcpy(&adr, ic->parm.num, sizeof(ulong)); - if (isar_load_firmware(cs, (u_char __user *)adr)) - return (1); - else - ll_run(cs, features); - break; - case 20: - features = *(unsigned int *) ic->parm.num; - printk(KERN_DEBUG "HiSax: max modulation old(%04x) new(%04x)\n", - modmask, features); - modmask = features; - break; - case 21: - features = *(unsigned int *) ic->parm.num; - printk(KERN_DEBUG "HiSax: FRM extra delay old(%d) new(%d) ms\n", - frm_extra_delay, features); - if (features >= 0) - frm_extra_delay = features; - break; - case 22: - features = *(unsigned int *) ic->parm.num; - printk(KERN_DEBUG "HiSax: TOA old(%d) new(%d) db\n", - para_TOA, features); - if (features >= 0 && features < 32) - para_TOA = features; - break; - default: - printk(KERN_DEBUG "HiSax: invalid ioctl %d\n", - (int) ic->arg); - return (-EINVAL); - } - break; - default: - return (-EINVAL); - } - return (0); -} - -void initisar(struct IsdnCardState *cs) -{ - cs->bcs[0].BC_SetStack = setstack_isar; - cs->bcs[1].BC_SetStack = setstack_isar; - cs->bcs[0].BC_Close = close_isarstate; - cs->bcs[1].BC_Close = close_isarstate; - timer_setup(&cs->bcs[0].hw.isar.ftimer, ftimer_handler, 0); - timer_setup(&cs->bcs[1].hw.isar.ftimer, ftimer_handler, 0); -} diff --git a/drivers/isdn/hisax/isar.h b/drivers/isdn/hisax/isar.h deleted file mode 100644 index 0f4d101faf37..000000000000 --- a/drivers/isdn/hisax/isar.h +++ /dev/null @@ -1,222 +0,0 @@ -/* $Id: isar.h,v 1.11.2.2 2004/01/12 22:52:27 keil Exp $ - * - * ISAR (Siemens PSB 7110) specific defines - * - * Author Karsten Keil - * Copyright by Karsten Keil <keil@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#define ISAR_IRQMSK 0x04 -#define ISAR_IRQSTA 0x04 -#define ISAR_IRQBIT 0x75 -#define ISAR_CTRL_H 0x61 -#define ISAR_CTRL_L 0x60 -#define ISAR_IIS 0x58 -#define ISAR_IIA 0x58 -#define ISAR_HIS 0x50 -#define ISAR_HIA 0x50 -#define ISAR_MBOX 0x4c -#define ISAR_WADR 0x4a -#define ISAR_RADR 0x48 - -#define ISAR_HIS_VNR 0x14 -#define ISAR_HIS_DKEY 0x02 -#define ISAR_HIS_FIRM 0x1e -#define ISAR_HIS_STDSP 0x08 -#define ISAR_HIS_DIAG 0x05 -#define ISAR_HIS_WAITSTATE 0x27 -#define ISAR_HIS_TIMERIRQ 0x25 -#define ISAR_HIS_P0CFG 0x3c -#define ISAR_HIS_P12CFG 0x24 -#define ISAR_HIS_SARTCFG 0x25 -#define ISAR_HIS_PUMPCFG 0x26 -#define ISAR_HIS_PUMPCTRL 0x2a -#define ISAR_HIS_IOM2CFG 0x27 -#define ISAR_HIS_IOM2REQ 0x07 -#define ISAR_HIS_IOM2CTRL 0x2b -#define ISAR_HIS_BSTREQ 0x0c -#define ISAR_HIS_PSTREQ 0x0e -#define ISAR_HIS_SDATA 0x20 -#define ISAR_HIS_DPS1 0x40 -#define ISAR_HIS_DPS2 0x80 -#define SET_DPS(x) ((x << 6) & 0xc0) - -#define ISAR_CMD_TIMERIRQ_OFF 0x20 -#define ISAR_CMD_TIMERIRQ_ON 0x21 - - -#define ISAR_IIS_MSCMSD 0x3f -#define ISAR_IIS_VNR 0x15 -#define ISAR_IIS_DKEY 0x03 -#define ISAR_IIS_FIRM 0x1f -#define ISAR_IIS_STDSP 0x09 -#define ISAR_IIS_DIAG 0x25 -#define ISAR_IIS_GSTEV 0x00 -#define ISAR_IIS_BSTEV 0x28 -#define ISAR_IIS_BSTRSP 0x2c -#define ISAR_IIS_PSTRSP 0x2e -#define ISAR_IIS_PSTEV 0x2a -#define ISAR_IIS_IOM2RSP 0x27 -#define ISAR_IIS_RDATA 0x20 -#define ISAR_IIS_INVMSG 0x3f - -#define ISAR_CTRL_SWVER 0x10 -#define ISAR_CTRL_STST 0x40 - -#define ISAR_MSG_HWVER {0x20, 0, 1} - -#define ISAR_DP1_USE 1 -#define ISAR_DP2_USE 2 -#define ISAR_RATE_REQ 3 - -#define PMOD_DISABLE 0 -#define PMOD_FAX 1 -#define PMOD_DATAMODEM 2 -#define PMOD_HALFDUPLEX 3 -#define PMOD_V110 4 -#define PMOD_DTMF 5 -#define PMOD_DTMF_TRANS 6 -#define PMOD_BYPASS 7 - -#define PCTRL_ORIG 0x80 -#define PV32P2_V23R 0x40 -#define PV32P2_V22A 0x20 -#define PV32P2_V22B 0x10 -#define PV32P2_V22C 0x08 -#define PV32P2_V21 0x02 -#define PV32P2_BEL 0x01 - -// LSB MSB in ISAR doc wrong !!! Arghhh -#define PV32P3_AMOD 0x80 -#define PV32P3_V32B 0x02 -#define PV32P3_V23B 0x01 -#define PV32P4_48 0x11 -#define PV32P5_48 0x05 -#define PV32P4_UT48 0x11 -#define PV32P5_UT48 0x0d -#define PV32P4_96 0x11 -#define PV32P5_96 0x03 -#define PV32P4_UT96 0x11 -#define PV32P5_UT96 0x0f -#define PV32P4_B96 0x91 -#define PV32P5_B96 0x0b -#define PV32P4_UTB96 0xd1 -#define PV32P5_UTB96 0x0f -#define PV32P4_120 0xb1 -#define PV32P5_120 0x09 -#define PV32P4_UT120 0xf1 -#define PV32P5_UT120 0x0f -#define PV32P4_144 0x99 -#define PV32P5_144 0x09 -#define PV32P4_UT144 0xf9 -#define PV32P5_UT144 0x0f -#define PV32P6_CTN 0x01 -#define PV32P6_ATN 0x02 - -#define PFAXP2_CTN 0x01 -#define PFAXP2_ATN 0x04 - -#define PSEV_10MS_TIMER 0x02 -#define PSEV_CON_ON 0x18 -#define PSEV_CON_OFF 0x19 -#define PSEV_V24_OFF 0x20 -#define PSEV_CTS_ON 0x21 -#define PSEV_CTS_OFF 0x22 -#define PSEV_DCD_ON 0x23 -#define PSEV_DCD_OFF 0x24 -#define PSEV_DSR_ON 0x25 -#define PSEV_DSR_OFF 0x26 -#define PSEV_REM_RET 0xcc -#define PSEV_REM_REN 0xcd -#define PSEV_GSTN_CLR 0xd4 - -#define PSEV_RSP_READY 0xbc -#define PSEV_LINE_TX_H 0xb3 -#define PSEV_LINE_TX_B 0xb2 -#define PSEV_LINE_RX_H 0xb1 -#define PSEV_LINE_RX_B 0xb0 -#define PSEV_RSP_CONN 0xb5 -#define PSEV_RSP_DISC 0xb7 -#define PSEV_RSP_FCERR 0xb9 -#define PSEV_RSP_SILDET 0xbe -#define PSEV_RSP_SILOFF 0xab -#define PSEV_FLAGS_DET 0xba - -#define PCTRL_CMD_FTH 0xa7 -#define PCTRL_CMD_FRH 0xa5 -#define PCTRL_CMD_FTM 0xa8 -#define PCTRL_CMD_FRM 0xa6 -#define PCTRL_CMD_SILON 0xac -#define PCTRL_CMD_CONT 0xa2 -#define PCTRL_CMD_ESC 0xa4 -#define PCTRL_CMD_SILOFF 0xab -#define PCTRL_CMD_HALT 0xa9 - -#define PCTRL_LOC_RET 0xcf -#define PCTRL_LOC_REN 0xce - -#define SMODE_DISABLE 0 -#define SMODE_V14 2 -#define SMODE_HDLC 3 -#define SMODE_BINARY 4 -#define SMODE_FSK_V14 5 - -#define SCTRL_HDMC_BOTH 0x00 -#define SCTRL_HDMC_DTX 0x80 -#define SCTRL_HDMC_DRX 0x40 -#define S_P1_OVSP 0x40 -#define S_P1_SNP 0x20 -#define S_P1_EOP 0x10 -#define S_P1_EDP 0x08 -#define S_P1_NSB 0x04 -#define S_P1_CHS_8 0x03 -#define S_P1_CHS_7 0x02 -#define S_P1_CHS_6 0x01 -#define S_P1_CHS_5 0x00 - -#define S_P2_BFT_DEF 0x10 - -#define IOM_CTRL_ENA 0x80 -#define IOM_CTRL_NOPCM 0x00 -#define IOM_CTRL_ALAW 0x02 -#define IOM_CTRL_ULAW 0x04 -#define IOM_CTRL_RCV 0x01 - -#define IOM_P1_TXD 0x10 - -#define HDLC_FED 0x40 -#define HDLC_FSD 0x20 -#define HDLC_FST 0x20 -#define HDLC_ERROR 0x1c -#define HDLC_ERR_FAD 0x10 -#define HDLC_ERR_RER 0x08 -#define HDLC_ERR_CER 0x04 -#define SART_NMD 0x01 - -#define BSTAT_RDM0 0x1 -#define BSTAT_RDM1 0x2 -#define BSTAT_RDM2 0x4 -#define BSTAT_RDM3 0x8 -#define BSTEV_TBO 0x1f -#define BSTEV_RBO 0x2f - -/* FAX State Machine */ -#define STFAX_NULL 0 -#define STFAX_READY 1 -#define STFAX_LINE 2 -#define STFAX_CONT 3 -#define STFAX_ACTIV 4 -#define STFAX_ESCAPE 5 -#define STFAX_SILDET 6 - -#define ISDN_FAXPUMP_HALT 100 - -extern int ISARVersion(struct IsdnCardState *cs, char *s); -extern void isar_int_main(struct IsdnCardState *cs); -extern void initisar(struct IsdnCardState *cs); -extern void isar_fill_fifo(struct BCState *bcs); -extern int isar_auxcmd(struct IsdnCardState *cs, isdn_ctrl *ic); diff --git a/drivers/isdn/hisax/isdnl1.c b/drivers/isdn/hisax/isdnl1.c deleted file mode 100644 index a560842c0e48..000000000000 --- a/drivers/isdn/hisax/isdnl1.c +++ /dev/null @@ -1,930 +0,0 @@ -/* $Id: isdnl1.c,v 2.46.2.5 2004/02/11 13:21:34 keil Exp $ - * - * common low level stuff for Siemens Chipsetbased isdn cards - * - * Author Karsten Keil - * based on the teles driver from Jan den Ouden - * Copyright by Karsten Keil <keil@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * For changes and modifications please read - * Documentation/isdn/HiSax.cert - * - * Thanks to Jan den Ouden - * Fritz Elfert - * Beat Doebeli - * - */ - -#include <linux/init.h> -#include <linux/gfp.h> -#include "hisax.h" -#include "isdnl1.h" - -const char *l1_revision = "$Revision: 2.46.2.5 $"; - -#define TIMER3_VALUE 7000 - -static struct Fsm l1fsm_b; -static struct Fsm l1fsm_s; - -enum { - ST_L1_F2, - ST_L1_F3, - ST_L1_F4, - ST_L1_F5, - ST_L1_F6, - ST_L1_F7, - ST_L1_F8, -}; - -#define L1S_STATE_COUNT (ST_L1_F8 + 1) - -static char *strL1SState[] = -{ - "ST_L1_F2", - "ST_L1_F3", - "ST_L1_F4", - "ST_L1_F5", - "ST_L1_F6", - "ST_L1_F7", - "ST_L1_F8", -}; - -#ifdef HISAX_UINTERFACE -static -struct Fsm l1fsm_u = -{NULL, 0, 0, NULL, NULL}; - -enum { - ST_L1_RESET, - ST_L1_DEACT, - ST_L1_SYNC2, - ST_L1_TRANS, -}; - -#define L1U_STATE_COUNT (ST_L1_TRANS + 1) - -static char *strL1UState[] = -{ - "ST_L1_RESET", - "ST_L1_DEACT", - "ST_L1_SYNC2", - "ST_L1_TRANS", -}; -#endif - -enum { - ST_L1_NULL, - ST_L1_WAIT_ACT, - ST_L1_WAIT_DEACT, - ST_L1_ACTIV, -}; - -#define L1B_STATE_COUNT (ST_L1_ACTIV + 1) - -static char *strL1BState[] = -{ - "ST_L1_NULL", - "ST_L1_WAIT_ACT", - "ST_L1_WAIT_DEACT", - "ST_L1_ACTIV", -}; - -enum { - EV_PH_ACTIVATE, - EV_PH_DEACTIVATE, - EV_RESET_IND, - EV_DEACT_CNF, - EV_DEACT_IND, - EV_POWER_UP, - EV_RSYNC_IND, - EV_INFO2_IND, - EV_INFO4_IND, - EV_TIMER_DEACT, - EV_TIMER_ACT, - EV_TIMER3, -}; - -#define L1_EVENT_COUNT (EV_TIMER3 + 1) - -static char *strL1Event[] = -{ - "EV_PH_ACTIVATE", - "EV_PH_DEACTIVATE", - "EV_RESET_IND", - "EV_DEACT_CNF", - "EV_DEACT_IND", - "EV_POWER_UP", - "EV_RSYNC_IND", - "EV_INFO2_IND", - "EV_INFO4_IND", - "EV_TIMER_DEACT", - "EV_TIMER_ACT", - "EV_TIMER3", -}; - -void -debugl1(struct IsdnCardState *cs, char *fmt, ...) -{ - va_list args; - char tmp[8]; - - va_start(args, fmt); - sprintf(tmp, "Card%d ", cs->cardnr + 1); - VHiSax_putstatus(cs, tmp, fmt, args); - va_end(args); -} - -static void -l1m_debug(struct FsmInst *fi, char *fmt, ...) -{ - va_list args; - struct PStack *st = fi->userdata; - struct IsdnCardState *cs = st->l1.hardware; - char tmp[8]; - - va_start(args, fmt); - sprintf(tmp, "Card%d ", cs->cardnr + 1); - VHiSax_putstatus(cs, tmp, fmt, args); - va_end(args); -} - -static void -L1activated(struct IsdnCardState *cs) -{ - struct PStack *st; - - st = cs->stlist; - while (st) { - if (test_and_clear_bit(FLG_L1_ACTIVATING, &st->l1.Flags)) - st->l1.l1l2(st, PH_ACTIVATE | CONFIRM, NULL); - else - st->l1.l1l2(st, PH_ACTIVATE | INDICATION, NULL); - st = st->next; - } -} - -static void -L1deactivated(struct IsdnCardState *cs) -{ - struct PStack *st; - - st = cs->stlist; - while (st) { - if (test_bit(FLG_L1_DBUSY, &cs->HW_Flags)) - st->l1.l1l2(st, PH_PAUSE | CONFIRM, NULL); - st->l1.l1l2(st, PH_DEACTIVATE | INDICATION, NULL); - st = st->next; - } - test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags); -} - -void -DChannel_proc_xmt(struct IsdnCardState *cs) -{ - struct PStack *stptr; - - if (cs->tx_skb) - return; - - stptr = cs->stlist; - while (stptr != NULL) { - if (test_and_clear_bit(FLG_L1_PULL_REQ, &stptr->l1.Flags)) { - stptr->l1.l1l2(stptr, PH_PULL | CONFIRM, NULL); - break; - } else - stptr = stptr->next; - } -} - -void -DChannel_proc_rcv(struct IsdnCardState *cs) -{ - struct sk_buff *skb, *nskb; - struct PStack *stptr = cs->stlist; - int found, tei, sapi; - - if (stptr) - if (test_bit(FLG_L1_ACTTIMER, &stptr->l1.Flags)) - FsmEvent(&stptr->l1.l1m, EV_TIMER_ACT, NULL); - while ((skb = skb_dequeue(&cs->rq))) { -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - Logl2Frame(cs, skb, "PH_DATA", 1); -#endif - stptr = cs->stlist; - if (skb->len < 3) { - debugl1(cs, "D-channel frame too short(%d)", skb->len); - dev_kfree_skb(skb); - return; - } - if ((skb->data[0] & 1) || !(skb->data[1] & 1)) { - debugl1(cs, "D-channel frame wrong EA0/EA1"); - dev_kfree_skb(skb); - return; - } - sapi = skb->data[0] >> 2; - tei = skb->data[1] >> 1; - if (cs->debug & DEB_DLOG_HEX) - LogFrame(cs, skb->data, skb->len); - if (cs->debug & DEB_DLOG_VERBOSE) - dlogframe(cs, skb, 1); - if (tei == GROUP_TEI) { - if (sapi == CTRL_SAPI) { /* sapi 0 */ - while (stptr != NULL) { - if ((nskb = skb_clone(skb, GFP_ATOMIC))) - stptr->l1.l1l2(stptr, PH_DATA | INDICATION, nskb); - else - printk(KERN_WARNING "HiSax: isdn broadcast buffer shortage\n"); - stptr = stptr->next; - } - } else if (sapi == TEI_SAPI) { - while (stptr != NULL) { - if ((nskb = skb_clone(skb, GFP_ATOMIC))) - stptr->l1.l1tei(stptr, PH_DATA | INDICATION, nskb); - else - printk(KERN_WARNING "HiSax: tei broadcast buffer shortage\n"); - stptr = stptr->next; - } - } - dev_kfree_skb(skb); - } else if (sapi == CTRL_SAPI) { /* sapi 0 */ - found = 0; - while (stptr != NULL) - if (tei == stptr->l2.tei) { - stptr->l1.l1l2(stptr, PH_DATA | INDICATION, skb); - found = !0; - break; - } else - stptr = stptr->next; - if (!found) - dev_kfree_skb(skb); - } else - dev_kfree_skb(skb); - } -} - -static void -BChannel_proc_xmt(struct BCState *bcs) -{ - struct PStack *st = bcs->st; - - if (test_bit(BC_FLG_BUSY, &bcs->Flag)) { - debugl1(bcs->cs, "BC_BUSY Error"); - return; - } - - if (test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags)) - st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); - if (!test_bit(BC_FLG_ACTIV, &bcs->Flag)) { - if (!test_bit(BC_FLG_BUSY, &bcs->Flag) && - skb_queue_empty(&bcs->squeue)) { - st->l2.l2l1(st, PH_DEACTIVATE | CONFIRM, NULL); - } - } -} - -static void -BChannel_proc_rcv(struct BCState *bcs) -{ - struct sk_buff *skb; - - if (bcs->st->l1.l1m.state == ST_L1_WAIT_ACT) { - FsmDelTimer(&bcs->st->l1.timer, 4); - FsmEvent(&bcs->st->l1.l1m, EV_TIMER_ACT, NULL); - } - while ((skb = skb_dequeue(&bcs->rqueue))) { - bcs->st->l1.l1l2(bcs->st, PH_DATA | INDICATION, skb); - } -} - -static void -BChannel_proc_ack(struct BCState *bcs) -{ - u_long flags; - int ack; - - spin_lock_irqsave(&bcs->aclock, flags); - ack = bcs->ackcnt; - bcs->ackcnt = 0; - spin_unlock_irqrestore(&bcs->aclock, flags); - if (ack) - lli_writewakeup(bcs->st, ack); -} - -void -BChannel_bh(struct work_struct *work) -{ - struct BCState *bcs = container_of(work, struct BCState, tqueue); - - if (!bcs) - return; - if (test_and_clear_bit(B_RCVBUFREADY, &bcs->event)) - BChannel_proc_rcv(bcs); - if (test_and_clear_bit(B_XMTBUFREADY, &bcs->event)) - BChannel_proc_xmt(bcs); - if (test_and_clear_bit(B_ACKPENDING, &bcs->event)) - BChannel_proc_ack(bcs); -} - -void -HiSax_addlist(struct IsdnCardState *cs, - struct PStack *st) -{ - st->next = cs->stlist; - cs->stlist = st; -} - -void -HiSax_rmlist(struct IsdnCardState *cs, - struct PStack *st) -{ - struct PStack *p; - - FsmDelTimer(&st->l1.timer, 0); - if (cs->stlist == st) - cs->stlist = st->next; - else { - p = cs->stlist; - while (p) - if (p->next == st) { - p->next = st->next; - return; - } else - p = p->next; - } -} - -void -init_bcstate(struct IsdnCardState *cs, int bc) -{ - struct BCState *bcs = cs->bcs + bc; - - bcs->cs = cs; - bcs->channel = bc; - INIT_WORK(&bcs->tqueue, BChannel_bh); - spin_lock_init(&bcs->aclock); - bcs->BC_SetStack = NULL; - bcs->BC_Close = NULL; - bcs->Flag = 0; -} - -#ifdef L2FRAME_DEBUG /* psa */ - -static char * -l2cmd(u_char cmd) -{ - switch (cmd & ~0x10) { - case 1: - return "RR"; - case 5: - return "RNR"; - case 9: - return "REJ"; - case 0x6f: - return "SABME"; - case 0x0f: - return "DM"; - case 3: - return "UI"; - case 0x43: - return "DISC"; - case 0x63: - return "UA"; - case 0x87: - return "FRMR"; - case 0xaf: - return "XID"; - default: - if (!(cmd & 1)) - return "I"; - else - return "invalid command"; - } -} - -static char tmpdeb[32]; - -static char * -l2frames(u_char *ptr) -{ - switch (ptr[2] & ~0x10) { - case 1: - case 5: - case 9: - sprintf(tmpdeb, "%s[%d](nr %d)", l2cmd(ptr[2]), ptr[3] & 1, ptr[3] >> 1); - break; - case 0x6f: - case 0x0f: - case 3: - case 0x43: - case 0x63: - case 0x87: - case 0xaf: - sprintf(tmpdeb, "%s[%d]", l2cmd(ptr[2]), (ptr[2] & 0x10) >> 4); - break; - default: - if (!(ptr[2] & 1)) { - sprintf(tmpdeb, "I[%d](ns %d, nr %d)", ptr[3] & 1, ptr[2] >> 1, ptr[3] >> 1); - break; - } else - return "invalid command"; - } - - - return tmpdeb; -} - -void -Logl2Frame(struct IsdnCardState *cs, struct sk_buff *skb, char *buf, int dir) -{ - u_char *ptr; - - ptr = skb->data; - - if (ptr[0] & 1 || !(ptr[1] & 1)) - debugl1(cs, "Address not LAPD"); - else - debugl1(cs, "%s %s: %s%c (sapi %d, tei %d)", - (dir ? "<-" : "->"), buf, l2frames(ptr), - ((ptr[0] & 2) >> 1) == dir ? 'C' : 'R', ptr[0] >> 2, ptr[1] >> 1); -} -#endif - -static void -l1_reset(struct FsmInst *fi, int event, void *arg) -{ - FsmChangeState(fi, ST_L1_F3); -} - -static void -l1_deact_cnf(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - FsmChangeState(fi, ST_L1_F3); - if (test_bit(FLG_L1_ACTIVATING, &st->l1.Flags)) - st->l1.l1hw(st, HW_ENABLE | REQUEST, NULL); -} - -static void -l1_deact_req_s(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - FsmChangeState(fi, ST_L1_F3); - FsmRestartTimer(&st->l1.timer, 550, EV_TIMER_DEACT, NULL, 2); - test_and_set_bit(FLG_L1_DEACTTIMER, &st->l1.Flags); -} - -static void -l1_power_up_s(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - if (test_bit(FLG_L1_ACTIVATING, &st->l1.Flags)) { - FsmChangeState(fi, ST_L1_F4); - st->l1.l1hw(st, HW_INFO3 | REQUEST, NULL); - FsmRestartTimer(&st->l1.timer, TIMER3_VALUE, EV_TIMER3, NULL, 2); - test_and_set_bit(FLG_L1_T3RUN, &st->l1.Flags); - } else - FsmChangeState(fi, ST_L1_F3); -} - -static void -l1_go_F5(struct FsmInst *fi, int event, void *arg) -{ - FsmChangeState(fi, ST_L1_F5); -} - -static void -l1_go_F8(struct FsmInst *fi, int event, void *arg) -{ - FsmChangeState(fi, ST_L1_F8); -} - -static void -l1_info2_ind(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - -#ifdef HISAX_UINTERFACE - if (test_bit(FLG_L1_UINT, &st->l1.Flags)) - FsmChangeState(fi, ST_L1_SYNC2); - else -#endif - FsmChangeState(fi, ST_L1_F6); - st->l1.l1hw(st, HW_INFO3 | REQUEST, NULL); -} - -static void -l1_info4_ind(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - -#ifdef HISAX_UINTERFACE - if (test_bit(FLG_L1_UINT, &st->l1.Flags)) - FsmChangeState(fi, ST_L1_TRANS); - else -#endif - FsmChangeState(fi, ST_L1_F7); - st->l1.l1hw(st, HW_INFO3 | REQUEST, NULL); - if (test_and_clear_bit(FLG_L1_DEACTTIMER, &st->l1.Flags)) - FsmDelTimer(&st->l1.timer, 4); - if (!test_bit(FLG_L1_ACTIVATED, &st->l1.Flags)) { - if (test_and_clear_bit(FLG_L1_T3RUN, &st->l1.Flags)) - FsmDelTimer(&st->l1.timer, 3); - FsmRestartTimer(&st->l1.timer, 110, EV_TIMER_ACT, NULL, 2); - test_and_set_bit(FLG_L1_ACTTIMER, &st->l1.Flags); - } -} - -static void -l1_timer3(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - test_and_clear_bit(FLG_L1_T3RUN, &st->l1.Flags); - if (test_and_clear_bit(FLG_L1_ACTIVATING, &st->l1.Flags)) - L1deactivated(st->l1.hardware); - -#ifdef HISAX_UINTERFACE - if (!test_bit(FLG_L1_UINT, &st->l1.Flags)) -#endif - if (st->l1.l1m.state != ST_L1_F6) { - FsmChangeState(fi, ST_L1_F3); - st->l1.l1hw(st, HW_ENABLE | REQUEST, NULL); - } -} - -static void -l1_timer_act(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - test_and_clear_bit(FLG_L1_ACTTIMER, &st->l1.Flags); - test_and_set_bit(FLG_L1_ACTIVATED, &st->l1.Flags); - L1activated(st->l1.hardware); -} - -static void -l1_timer_deact(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - test_and_clear_bit(FLG_L1_DEACTTIMER, &st->l1.Flags); - test_and_clear_bit(FLG_L1_ACTIVATED, &st->l1.Flags); - L1deactivated(st->l1.hardware); - st->l1.l1hw(st, HW_DEACTIVATE | RESPONSE, NULL); -} - -static void -l1_activate_s(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - st->l1.l1hw(st, HW_RESET | REQUEST, NULL); -} - -static void -l1_activate_no(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - if ((!test_bit(FLG_L1_DEACTTIMER, &st->l1.Flags)) && (!test_bit(FLG_L1_T3RUN, &st->l1.Flags))) { - test_and_clear_bit(FLG_L1_ACTIVATING, &st->l1.Flags); - L1deactivated(st->l1.hardware); - } -} - -static struct FsmNode L1SFnList[] __initdata = -{ - {ST_L1_F3, EV_PH_ACTIVATE, l1_activate_s}, - {ST_L1_F6, EV_PH_ACTIVATE, l1_activate_no}, - {ST_L1_F8, EV_PH_ACTIVATE, l1_activate_no}, - {ST_L1_F3, EV_RESET_IND, l1_reset}, - {ST_L1_F4, EV_RESET_IND, l1_reset}, - {ST_L1_F5, EV_RESET_IND, l1_reset}, - {ST_L1_F6, EV_RESET_IND, l1_reset}, - {ST_L1_F7, EV_RESET_IND, l1_reset}, - {ST_L1_F8, EV_RESET_IND, l1_reset}, - {ST_L1_F3, EV_DEACT_CNF, l1_deact_cnf}, - {ST_L1_F4, EV_DEACT_CNF, l1_deact_cnf}, - {ST_L1_F5, EV_DEACT_CNF, l1_deact_cnf}, - {ST_L1_F6, EV_DEACT_CNF, l1_deact_cnf}, - {ST_L1_F7, EV_DEACT_CNF, l1_deact_cnf}, - {ST_L1_F8, EV_DEACT_CNF, l1_deact_cnf}, - {ST_L1_F6, EV_DEACT_IND, l1_deact_req_s}, - {ST_L1_F7, EV_DEACT_IND, l1_deact_req_s}, - {ST_L1_F8, EV_DEACT_IND, l1_deact_req_s}, - {ST_L1_F3, EV_POWER_UP, l1_power_up_s}, - {ST_L1_F4, EV_RSYNC_IND, l1_go_F5}, - {ST_L1_F6, EV_RSYNC_IND, l1_go_F8}, - {ST_L1_F7, EV_RSYNC_IND, l1_go_F8}, - {ST_L1_F3, EV_INFO2_IND, l1_info2_ind}, - {ST_L1_F4, EV_INFO2_IND, l1_info2_ind}, - {ST_L1_F5, EV_INFO2_IND, l1_info2_ind}, - {ST_L1_F7, EV_INFO2_IND, l1_info2_ind}, - {ST_L1_F8, EV_INFO2_IND, l1_info2_ind}, - {ST_L1_F3, EV_INFO4_IND, l1_info4_ind}, - {ST_L1_F4, EV_INFO4_IND, l1_info4_ind}, - {ST_L1_F5, EV_INFO4_IND, l1_info4_ind}, - {ST_L1_F6, EV_INFO4_IND, l1_info4_ind}, - {ST_L1_F8, EV_INFO4_IND, l1_info4_ind}, - {ST_L1_F3, EV_TIMER3, l1_timer3}, - {ST_L1_F4, EV_TIMER3, l1_timer3}, - {ST_L1_F5, EV_TIMER3, l1_timer3}, - {ST_L1_F6, EV_TIMER3, l1_timer3}, - {ST_L1_F8, EV_TIMER3, l1_timer3}, - {ST_L1_F7, EV_TIMER_ACT, l1_timer_act}, - {ST_L1_F3, EV_TIMER_DEACT, l1_timer_deact}, - {ST_L1_F4, EV_TIMER_DEACT, l1_timer_deact}, - {ST_L1_F5, EV_TIMER_DEACT, l1_timer_deact}, - {ST_L1_F6, EV_TIMER_DEACT, l1_timer_deact}, - {ST_L1_F7, EV_TIMER_DEACT, l1_timer_deact}, - {ST_L1_F8, EV_TIMER_DEACT, l1_timer_deact}, -}; - -#ifdef HISAX_UINTERFACE -static void -l1_deact_req_u(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - FsmChangeState(fi, ST_L1_RESET); - FsmRestartTimer(&st->l1.timer, 550, EV_TIMER_DEACT, NULL, 2); - test_and_set_bit(FLG_L1_DEACTTIMER, &st->l1.Flags); - st->l1.l1hw(st, HW_ENABLE | REQUEST, NULL); -} - -static void -l1_power_up_u(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - FsmRestartTimer(&st->l1.timer, TIMER3_VALUE, EV_TIMER3, NULL, 2); - test_and_set_bit(FLG_L1_T3RUN, &st->l1.Flags); -} - -static void -l1_info0_ind(struct FsmInst *fi, int event, void *arg) -{ - FsmChangeState(fi, ST_L1_DEACT); -} - -static void -l1_activate_u(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - st->l1.l1hw(st, HW_INFO1 | REQUEST, NULL); -} - -static struct FsmNode L1UFnList[] __initdata = -{ - {ST_L1_RESET, EV_DEACT_IND, l1_deact_req_u}, - {ST_L1_DEACT, EV_DEACT_IND, l1_deact_req_u}, - {ST_L1_SYNC2, EV_DEACT_IND, l1_deact_req_u}, - {ST_L1_TRANS, EV_DEACT_IND, l1_deact_req_u}, - {ST_L1_DEACT, EV_PH_ACTIVATE, l1_activate_u}, - {ST_L1_DEACT, EV_POWER_UP, l1_power_up_u}, - {ST_L1_DEACT, EV_INFO2_IND, l1_info2_ind}, - {ST_L1_TRANS, EV_INFO2_IND, l1_info2_ind}, - {ST_L1_RESET, EV_DEACT_CNF, l1_info0_ind}, - {ST_L1_DEACT, EV_INFO4_IND, l1_info4_ind}, - {ST_L1_SYNC2, EV_INFO4_IND, l1_info4_ind}, - {ST_L1_RESET, EV_INFO4_IND, l1_info4_ind}, - {ST_L1_DEACT, EV_TIMER3, l1_timer3}, - {ST_L1_SYNC2, EV_TIMER3, l1_timer3}, - {ST_L1_TRANS, EV_TIMER_ACT, l1_timer_act}, - {ST_L1_DEACT, EV_TIMER_DEACT, l1_timer_deact}, - {ST_L1_SYNC2, EV_TIMER_DEACT, l1_timer_deact}, - {ST_L1_RESET, EV_TIMER_DEACT, l1_timer_deact}, -}; - -#endif - -static void -l1b_activate(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - FsmChangeState(fi, ST_L1_WAIT_ACT); - FsmRestartTimer(&st->l1.timer, st->l1.delay, EV_TIMER_ACT, NULL, 2); -} - -static void -l1b_deactivate(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - FsmChangeState(fi, ST_L1_WAIT_DEACT); - FsmRestartTimer(&st->l1.timer, 10, EV_TIMER_DEACT, NULL, 2); -} - -static void -l1b_timer_act(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - FsmChangeState(fi, ST_L1_ACTIV); - st->l1.l1l2(st, PH_ACTIVATE | CONFIRM, NULL); -} - -static void -l1b_timer_deact(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - FsmChangeState(fi, ST_L1_NULL); - st->l2.l2l1(st, PH_DEACTIVATE | CONFIRM, NULL); -} - -static struct FsmNode L1BFnList[] __initdata = -{ - {ST_L1_NULL, EV_PH_ACTIVATE, l1b_activate}, - {ST_L1_WAIT_ACT, EV_TIMER_ACT, l1b_timer_act}, - {ST_L1_ACTIV, EV_PH_DEACTIVATE, l1b_deactivate}, - {ST_L1_WAIT_DEACT, EV_TIMER_DEACT, l1b_timer_deact}, -}; - -int __init -Isdnl1New(void) -{ - int retval; - - l1fsm_s.state_count = L1S_STATE_COUNT; - l1fsm_s.event_count = L1_EVENT_COUNT; - l1fsm_s.strEvent = strL1Event; - l1fsm_s.strState = strL1SState; - retval = FsmNew(&l1fsm_s, L1SFnList, ARRAY_SIZE(L1SFnList)); - if (retval) - return retval; - - l1fsm_b.state_count = L1B_STATE_COUNT; - l1fsm_b.event_count = L1_EVENT_COUNT; - l1fsm_b.strEvent = strL1Event; - l1fsm_b.strState = strL1BState; - retval = FsmNew(&l1fsm_b, L1BFnList, ARRAY_SIZE(L1BFnList)); - if (retval) { - FsmFree(&l1fsm_s); - return retval; - } -#ifdef HISAX_UINTERFACE - l1fsm_u.state_count = L1U_STATE_COUNT; - l1fsm_u.event_count = L1_EVENT_COUNT; - l1fsm_u.strEvent = strL1Event; - l1fsm_u.strState = strL1UState; - retval = FsmNew(&l1fsm_u, L1UFnList, ARRAY_SIZE(L1UFnList)); - if (retval) { - FsmFree(&l1fsm_s); - FsmFree(&l1fsm_b); - return retval; - } -#endif - return 0; -} - -void Isdnl1Free(void) -{ -#ifdef HISAX_UINTERFACE - FsmFree(&l1fsm_u); -#endif - FsmFree(&l1fsm_s); - FsmFree(&l1fsm_b); -} - -static void -dch_l2l1(struct PStack *st, int pr, void *arg) -{ - struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware; - - switch (pr) { - case (PH_DATA | REQUEST): - case (PH_PULL | REQUEST): - case (PH_PULL | INDICATION): - st->l1.l1hw(st, pr, arg); - break; - case (PH_ACTIVATE | REQUEST): - if (cs->debug) - debugl1(cs, "PH_ACTIVATE_REQ %s", - st->l1.l1m.fsm->strState[st->l1.l1m.state]); - if (test_bit(FLG_L1_ACTIVATED, &st->l1.Flags)) - st->l1.l1l2(st, PH_ACTIVATE | CONFIRM, NULL); - else { - test_and_set_bit(FLG_L1_ACTIVATING, &st->l1.Flags); - FsmEvent(&st->l1.l1m, EV_PH_ACTIVATE, arg); - } - break; - case (PH_TESTLOOP | REQUEST): - if (1 & (long) arg) - debugl1(cs, "PH_TEST_LOOP B1"); - if (2 & (long) arg) - debugl1(cs, "PH_TEST_LOOP B2"); - if (!(3 & (long) arg)) - debugl1(cs, "PH_TEST_LOOP DISABLED"); - st->l1.l1hw(st, HW_TESTLOOP | REQUEST, arg); - break; - default: - if (cs->debug) - debugl1(cs, "dch_l2l1 msg %04X unhandled", pr); - break; - } -} - -void -l1_msg(struct IsdnCardState *cs, int pr, void *arg) { - struct PStack *st; - - st = cs->stlist; - - while (st) { - switch (pr) { - case (HW_RESET | INDICATION): - FsmEvent(&st->l1.l1m, EV_RESET_IND, arg); - break; - case (HW_DEACTIVATE | CONFIRM): - FsmEvent(&st->l1.l1m, EV_DEACT_CNF, arg); - break; - case (HW_DEACTIVATE | INDICATION): - FsmEvent(&st->l1.l1m, EV_DEACT_IND, arg); - break; - case (HW_POWERUP | CONFIRM): - FsmEvent(&st->l1.l1m, EV_POWER_UP, arg); - break; - case (HW_RSYNC | INDICATION): - FsmEvent(&st->l1.l1m, EV_RSYNC_IND, arg); - break; - case (HW_INFO2 | INDICATION): - FsmEvent(&st->l1.l1m, EV_INFO2_IND, arg); - break; - case (HW_INFO4_P8 | INDICATION): - case (HW_INFO4_P10 | INDICATION): - FsmEvent(&st->l1.l1m, EV_INFO4_IND, arg); - break; - default: - if (cs->debug) - debugl1(cs, "%s %04X unhandled", __func__, pr); - break; - } - st = st->next; - } -} - -void -l1_msg_b(struct PStack *st, int pr, void *arg) { - switch (pr) { - case (PH_ACTIVATE | REQUEST): - FsmEvent(&st->l1.l1m, EV_PH_ACTIVATE, NULL); - break; - case (PH_DEACTIVATE | REQUEST): - FsmEvent(&st->l1.l1m, EV_PH_DEACTIVATE, NULL); - break; - } -} - -void -setstack_HiSax(struct PStack *st, struct IsdnCardState *cs) -{ - st->l1.hardware = cs; - st->protocol = cs->protocol; - st->l1.l1m.fsm = &l1fsm_s; - st->l1.l1m.state = ST_L1_F3; - st->l1.Flags = 0; -#ifdef HISAX_UINTERFACE - if (test_bit(FLG_HW_L1_UINT, &cs->HW_Flags)) { - st->l1.l1m.fsm = &l1fsm_u; - st->l1.l1m.state = ST_L1_RESET; - st->l1.Flags = FLG_L1_UINT; - } -#endif - st->l1.l1m.debug = cs->debug; - st->l1.l1m.userdata = st; - st->l1.l1m.userint = 0; - st->l1.l1m.printdebug = l1m_debug; - FsmInitTimer(&st->l1.l1m, &st->l1.timer); - setstack_tei(st); - setstack_manager(st); - st->l1.stlistp = &(cs->stlist); - st->l2.l2l1 = dch_l2l1; - if (cs->setstack_d) - cs->setstack_d(st, cs); -} - -void -setstack_l1_B(struct PStack *st) -{ - struct IsdnCardState *cs = st->l1.hardware; - - st->l1.l1m.fsm = &l1fsm_b; - st->l1.l1m.state = ST_L1_NULL; - st->l1.l1m.debug = cs->debug; - st->l1.l1m.userdata = st; - st->l1.l1m.userint = 0; - st->l1.l1m.printdebug = l1m_debug; - st->l1.Flags = 0; - FsmInitTimer(&st->l1.l1m, &st->l1.timer); -} diff --git a/drivers/isdn/hisax/isdnl1.h b/drivers/isdn/hisax/isdnl1.h deleted file mode 100644 index 66ddcab19bba..000000000000 --- a/drivers/isdn/hisax/isdnl1.h +++ /dev/null @@ -1,32 +0,0 @@ -/* $Id: isdnl1.h,v 2.12.2.3 2004/02/11 13:21:34 keil Exp $ - * - * Layer 1 defines - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#define D_RCVBUFREADY 0 -#define D_XMTBUFREADY 1 -#define D_L1STATECHANGE 2 -#define D_CLEARBUSY 3 -#define D_RX_MON0 4 -#define D_RX_MON1 5 -#define D_TX_MON0 6 -#define D_TX_MON1 7 -#define E_RCVBUFREADY 8 - -#define B_RCVBUFREADY 0 -#define B_XMTBUFREADY 1 -#define B_ACKPENDING 2 - -__printf(2, 3) -void debugl1(struct IsdnCardState *cs, char *fmt, ...); -void DChannel_proc_xmt(struct IsdnCardState *cs); -void DChannel_proc_rcv(struct IsdnCardState *cs); -void l1_msg(struct IsdnCardState *cs, int pr, void *arg); -void l1_msg_b(struct PStack *st, int pr, void *arg); -void Logl2Frame(struct IsdnCardState *cs, struct sk_buff *skb, char *buf, - int dir); -void BChannel_bh(struct work_struct *work); diff --git a/drivers/isdn/hisax/isdnl2.c b/drivers/isdn/hisax/isdnl2.c deleted file mode 100644 index 1a40ed04cb52..000000000000 --- a/drivers/isdn/hisax/isdnl2.c +++ /dev/null @@ -1,1839 +0,0 @@ -/* $Id: isdnl2.c,v 2.30.2.4 2004/02/11 13:21:34 keil Exp $ - * - * Author Karsten Keil - * based on the teles driver from Jan den Ouden - * Copyright by Karsten Keil <keil@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * For changes and modifications please read - * Documentation/isdn/HiSax.cert - * - * Thanks to Jan den Ouden - * Fritz Elfert - * - */ - -#include <linux/init.h> -#include <linux/gfp.h> -#include "hisax.h" -#include "isdnl2.h" - -const char *l2_revision = "$Revision: 2.30.2.4 $"; - -static void l2m_debug(struct FsmInst *fi, char *fmt, ...); - -static struct Fsm l2fsm; - -enum { - ST_L2_1, - ST_L2_2, - ST_L2_3, - ST_L2_4, - ST_L2_5, - ST_L2_6, - ST_L2_7, - ST_L2_8, -}; - -#define L2_STATE_COUNT (ST_L2_8 + 1) - -static char *strL2State[] = -{ - "ST_L2_1", - "ST_L2_2", - "ST_L2_3", - "ST_L2_4", - "ST_L2_5", - "ST_L2_6", - "ST_L2_7", - "ST_L2_8", -}; - -enum { - EV_L2_UI, - EV_L2_SABME, - EV_L2_DISC, - EV_L2_DM, - EV_L2_UA, - EV_L2_FRMR, - EV_L2_SUPER, - EV_L2_I, - EV_L2_DL_DATA, - EV_L2_ACK_PULL, - EV_L2_DL_UNIT_DATA, - EV_L2_DL_ESTABLISH_REQ, - EV_L2_DL_RELEASE_REQ, - EV_L2_MDL_ASSIGN, - EV_L2_MDL_REMOVE, - EV_L2_MDL_ERROR, - EV_L1_DEACTIVATE, - EV_L2_T200, - EV_L2_T203, - EV_L2_SET_OWN_BUSY, - EV_L2_CLEAR_OWN_BUSY, - EV_L2_FRAME_ERROR, -}; - -#define L2_EVENT_COUNT (EV_L2_FRAME_ERROR + 1) - -static char *strL2Event[] = -{ - "EV_L2_UI", - "EV_L2_SABME", - "EV_L2_DISC", - "EV_L2_DM", - "EV_L2_UA", - "EV_L2_FRMR", - "EV_L2_SUPER", - "EV_L2_I", - "EV_L2_DL_DATA", - "EV_L2_ACK_PULL", - "EV_L2_DL_UNIT_DATA", - "EV_L2_DL_ESTABLISH_REQ", - "EV_L2_DL_RELEASE_REQ", - "EV_L2_MDL_ASSIGN", - "EV_L2_MDL_REMOVE", - "EV_L2_MDL_ERROR", - "EV_L1_DEACTIVATE", - "EV_L2_T200", - "EV_L2_T203", - "EV_L2_SET_OWN_BUSY", - "EV_L2_CLEAR_OWN_BUSY", - "EV_L2_FRAME_ERROR", -}; - -static int l2addrsize(struct Layer2 *l2); - -static void -set_peer_busy(struct Layer2 *l2) { - test_and_set_bit(FLG_PEER_BUSY, &l2->flag); - if (!skb_queue_empty(&l2->i_queue) || - !skb_queue_empty(&l2->ui_queue)) - test_and_set_bit(FLG_L2BLOCK, &l2->flag); -} - -static void -clear_peer_busy(struct Layer2 *l2) { - if (test_and_clear_bit(FLG_PEER_BUSY, &l2->flag)) - test_and_clear_bit(FLG_L2BLOCK, &l2->flag); -} - -static void -InitWin(struct Layer2 *l2) -{ - int i; - - for (i = 0; i < MAX_WINDOW; i++) - l2->windowar[i] = NULL; -} - -static int -freewin1(struct Layer2 *l2) -{ - int i, cnt = 0; - - for (i = 0; i < MAX_WINDOW; i++) { - if (l2->windowar[i]) { - cnt++; - dev_kfree_skb(l2->windowar[i]); - l2->windowar[i] = NULL; - } - } - return cnt; -} - -static inline void -freewin(struct PStack *st) -{ - freewin1(&st->l2); -} - -static void -ReleaseWin(struct Layer2 *l2) -{ - int cnt; - - if ((cnt = freewin1(l2))) - printk(KERN_WARNING "isdl2 freed %d skbuffs in release\n", cnt); -} - -static inline unsigned int -cansend(struct PStack *st) -{ - unsigned int p1; - - if (test_bit(FLG_MOD128, &st->l2.flag)) - p1 = (st->l2.vs - st->l2.va) % 128; - else - p1 = (st->l2.vs - st->l2.va) % 8; - return ((p1 < st->l2.window) && !test_bit(FLG_PEER_BUSY, &st->l2.flag)); -} - -static inline void -clear_exception(struct Layer2 *l2) -{ - test_and_clear_bit(FLG_ACK_PEND, &l2->flag); - test_and_clear_bit(FLG_REJEXC, &l2->flag); - test_and_clear_bit(FLG_OWN_BUSY, &l2->flag); - clear_peer_busy(l2); -} - -static inline int -l2headersize(struct Layer2 *l2, int ui) -{ - return (((test_bit(FLG_MOD128, &l2->flag) && (!ui)) ? 2 : 1) + - (test_bit(FLG_LAPD, &l2->flag) ? 2 : 1)); -} - -inline int -l2addrsize(struct Layer2 *l2) -{ - return (test_bit(FLG_LAPD, &l2->flag) ? 2 : 1); -} - -static int -sethdraddr(struct Layer2 *l2, u_char *header, int rsp) -{ - u_char *ptr = header; - int crbit = rsp; - - if (test_bit(FLG_LAPD, &l2->flag)) { - *ptr++ = (l2->sap << 2) | (rsp ? 2 : 0); - *ptr++ = (l2->tei << 1) | 1; - return (2); - } else { - if (test_bit(FLG_ORIG, &l2->flag)) - crbit = !crbit; - if (crbit) - *ptr++ = 1; - else - *ptr++ = 3; - return (1); - } -} - -static inline void -enqueue_super(struct PStack *st, - struct sk_buff *skb) -{ - if (test_bit(FLG_LAPB, &st->l2.flag)) - st->l1.bcs->tx_cnt += skb->len; - st->l2.l2l1(st, PH_DATA | REQUEST, skb); -} - -#define enqueue_ui(a, b) enqueue_super(a, b) - -static inline int -IsUI(u_char *data) -{ - return ((data[0] & 0xef) == UI); -} - -static inline int -IsUA(u_char *data) -{ - return ((data[0] & 0xef) == UA); -} - -static inline int -IsDM(u_char *data) -{ - return ((data[0] & 0xef) == DM); -} - -static inline int -IsDISC(u_char *data) -{ - return ((data[0] & 0xef) == DISC); -} - -static inline int -IsSFrame(u_char *data, struct PStack *st) -{ - register u_char d = *data; - - if (!test_bit(FLG_MOD128, &st->l2.flag)) - d &= 0xf; - return (((d & 0xf3) == 1) && ((d & 0x0c) != 0x0c)); -} - -static inline int -IsSABME(u_char *data, struct PStack *st) -{ - u_char d = data[0] & ~0x10; - - return (test_bit(FLG_MOD128, &st->l2.flag) ? d == SABME : d == SABM); -} - -static inline int -IsREJ(u_char *data, struct PStack *st) -{ - return (test_bit(FLG_MOD128, &st->l2.flag) ? data[0] == REJ : (data[0] & 0xf) == REJ); -} - -static inline int -IsFRMR(u_char *data) -{ - return ((data[0] & 0xef) == FRMR); -} - -static inline int -IsRNR(u_char *data, struct PStack *st) -{ - return (test_bit(FLG_MOD128, &st->l2.flag) ? data[0] == RNR : (data[0] & 0xf) == RNR); -} - -static int -iframe_error(struct PStack *st, struct sk_buff *skb) -{ - int i = l2addrsize(&st->l2) + (test_bit(FLG_MOD128, &st->l2.flag) ? 2 : 1); - int rsp = *skb->data & 0x2; - - if (test_bit(FLG_ORIG, &st->l2.flag)) - rsp = !rsp; - - if (rsp) - return 'L'; - - - if (skb->len < i) - return 'N'; - - if ((skb->len - i) > st->l2.maxlen) - return 'O'; - - - return 0; -} - -static int -super_error(struct PStack *st, struct sk_buff *skb) -{ - if (skb->len != l2addrsize(&st->l2) + - (test_bit(FLG_MOD128, &st->l2.flag) ? 2 : 1)) - return 'N'; - - return 0; -} - -static int -unnum_error(struct PStack *st, struct sk_buff *skb, int wantrsp) -{ - int rsp = (*skb->data & 0x2) >> 1; - if (test_bit(FLG_ORIG, &st->l2.flag)) - rsp = !rsp; - - if (rsp != wantrsp) - return 'L'; - - if (skb->len != l2addrsize(&st->l2) + 1) - return 'N'; - - return 0; -} - -static int -UI_error(struct PStack *st, struct sk_buff *skb) -{ - int rsp = *skb->data & 0x2; - if (test_bit(FLG_ORIG, &st->l2.flag)) - rsp = !rsp; - - if (rsp) - return 'L'; - - if (skb->len > st->l2.maxlen + l2addrsize(&st->l2) + 1) - return 'O'; - - return 0; -} - -static int -FRMR_error(struct PStack *st, struct sk_buff *skb) -{ - int headers = l2addrsize(&st->l2) + 1; - u_char *datap = skb->data + headers; - int rsp = *skb->data & 0x2; - - if (test_bit(FLG_ORIG, &st->l2.flag)) - rsp = !rsp; - - if (!rsp) - return 'L'; - - if (test_bit(FLG_MOD128, &st->l2.flag)) { - if (skb->len < headers + 5) - return 'N'; - else - l2m_debug(&st->l2.l2m, "FRMR information %2x %2x %2x %2x %2x", - datap[0], datap[1], datap[2], - datap[3], datap[4]); - } else { - if (skb->len < headers + 3) - return 'N'; - else - l2m_debug(&st->l2.l2m, "FRMR information %2x %2x %2x", - datap[0], datap[1], datap[2]); - } - - return 0; -} - -static unsigned int -legalnr(struct PStack *st, unsigned int nr) -{ - struct Layer2 *l2 = &st->l2; - - if (test_bit(FLG_MOD128, &l2->flag)) - return ((nr - l2->va) % 128) <= ((l2->vs - l2->va) % 128); - else - return ((nr - l2->va) % 8) <= ((l2->vs - l2->va) % 8); -} - -static void -setva(struct PStack *st, unsigned int nr) -{ - struct Layer2 *l2 = &st->l2; - int len; - u_long flags; - - spin_lock_irqsave(&l2->lock, flags); - while (l2->va != nr) { - (l2->va)++; - if (test_bit(FLG_MOD128, &l2->flag)) - l2->va %= 128; - else - l2->va %= 8; - len = l2->windowar[l2->sow]->len; - if (PACKET_NOACK == l2->windowar[l2->sow]->pkt_type) - len = -1; - dev_kfree_skb(l2->windowar[l2->sow]); - l2->windowar[l2->sow] = NULL; - l2->sow = (l2->sow + 1) % l2->window; - spin_unlock_irqrestore(&l2->lock, flags); - if (test_bit(FLG_LLI_L2WAKEUP, &st->lli.flag) && (len >= 0)) - lli_writewakeup(st, len); - spin_lock_irqsave(&l2->lock, flags); - } - spin_unlock_irqrestore(&l2->lock, flags); -} - -static void -send_uframe(struct PStack *st, u_char cmd, u_char cr) -{ - struct sk_buff *skb; - u_char tmp[MAX_HEADER_LEN]; - int i; - - i = sethdraddr(&st->l2, tmp, cr); - tmp[i++] = cmd; - if (!(skb = alloc_skb(i, GFP_ATOMIC))) { - printk(KERN_WARNING "isdl2 can't alloc sbbuff for send_uframe\n"); - return; - } - skb_put_data(skb, tmp, i); - enqueue_super(st, skb); -} - -static inline u_char -get_PollFlag(struct PStack *st, struct sk_buff *skb) -{ - return (skb->data[l2addrsize(&(st->l2))] & 0x10); -} - -static inline u_char -get_PollFlagFree(struct PStack *st, struct sk_buff *skb) -{ - u_char PF; - - PF = get_PollFlag(st, skb); - dev_kfree_skb(skb); - return (PF); -} - -static inline void -start_t200(struct PStack *st, int i) -{ - FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, i); - test_and_set_bit(FLG_T200_RUN, &st->l2.flag); -} - -static inline void -restart_t200(struct PStack *st, int i) -{ - FsmRestartTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, i); - test_and_set_bit(FLG_T200_RUN, &st->l2.flag); -} - -static inline void -stop_t200(struct PStack *st, int i) -{ - if (test_and_clear_bit(FLG_T200_RUN, &st->l2.flag)) - FsmDelTimer(&st->l2.t200, i); -} - -static inline void -st5_dl_release_l2l3(struct PStack *st) -{ - int pr; - - if (test_and_clear_bit(FLG_PEND_REL, &st->l2.flag)) - pr = DL_RELEASE | CONFIRM; - else - pr = DL_RELEASE | INDICATION; - - st->l2.l2l3(st, pr, NULL); -} - -static inline void -lapb_dl_release_l2l3(struct PStack *st, int f) -{ - if (test_bit(FLG_LAPB, &st->l2.flag)) - st->l2.l2l1(st, PH_DEACTIVATE | REQUEST, NULL); - st->l2.l2l3(st, DL_RELEASE | f, NULL); -} - -static void -establishlink(struct FsmInst *fi) -{ - struct PStack *st = fi->userdata; - u_char cmd; - - clear_exception(&st->l2); - st->l2.rc = 0; - cmd = (test_bit(FLG_MOD128, &st->l2.flag) ? SABME : SABM) | 0x10; - send_uframe(st, cmd, CMD); - FsmDelTimer(&st->l2.t203, 1); - restart_t200(st, 1); - test_and_clear_bit(FLG_PEND_REL, &st->l2.flag); - freewin(st); - FsmChangeState(fi, ST_L2_5); -} - -static void -l2_mdl_error_ua(struct FsmInst *fi, int event, void *arg) -{ - struct sk_buff *skb = arg; - struct PStack *st = fi->userdata; - - if (get_PollFlagFree(st, skb)) - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'C'); - else - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'D'); -} - -static void -l2_mdl_error_dm(struct FsmInst *fi, int event, void *arg) -{ - struct sk_buff *skb = arg; - struct PStack *st = fi->userdata; - - if (get_PollFlagFree(st, skb)) - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'B'); - else { - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'E'); - establishlink(fi); - test_and_clear_bit(FLG_L3_INIT, &st->l2.flag); - } -} - -static void -l2_st8_mdl_error_dm(struct FsmInst *fi, int event, void *arg) -{ - struct sk_buff *skb = arg; - struct PStack *st = fi->userdata; - - if (get_PollFlagFree(st, skb)) - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'B'); - else { - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'E'); - } - establishlink(fi); - test_and_clear_bit(FLG_L3_INIT, &st->l2.flag); -} - -static void -l2_go_st3(struct FsmInst *fi, int event, void *arg) -{ - FsmChangeState(fi, ST_L2_3); -} - -static void -l2_mdl_assign(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - FsmChangeState(fi, ST_L2_3); - st->l2.l2tei(st, MDL_ASSIGN | INDICATION, NULL); -} - -static void -l2_queue_ui_assign(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - struct sk_buff *skb = arg; - - skb_queue_tail(&st->l2.ui_queue, skb); - FsmChangeState(fi, ST_L2_2); - st->l2.l2tei(st, MDL_ASSIGN | INDICATION, NULL); -} - -static void -l2_queue_ui(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - struct sk_buff *skb = arg; - - skb_queue_tail(&st->l2.ui_queue, skb); -} - -static void -tx_ui(struct PStack *st) -{ - struct sk_buff *skb; - u_char header[MAX_HEADER_LEN]; - int i; - - i = sethdraddr(&(st->l2), header, CMD); - header[i++] = UI; - while ((skb = skb_dequeue(&st->l2.ui_queue))) { - memcpy(skb_push(skb, i), header, i); - enqueue_ui(st, skb); - } -} - -static void -l2_send_ui(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - struct sk_buff *skb = arg; - - skb_queue_tail(&st->l2.ui_queue, skb); - tx_ui(st); -} - -static void -l2_got_ui(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - struct sk_buff *skb = arg; - - skb_pull(skb, l2headersize(&st->l2, 1)); - st->l2.l2l3(st, DL_UNIT_DATA | INDICATION, skb); -/* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - * in states 1-3 for broadcast - */ - - -} - -static void -l2_establish(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - establishlink(fi); - test_and_set_bit(FLG_L3_INIT, &st->l2.flag); -} - -static void -l2_discard_i_setl3(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - skb_queue_purge(&st->l2.i_queue); - test_and_set_bit(FLG_L3_INIT, &st->l2.flag); - test_and_clear_bit(FLG_PEND_REL, &st->l2.flag); -} - -static void -l2_l3_reestablish(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - skb_queue_purge(&st->l2.i_queue); - establishlink(fi); - test_and_set_bit(FLG_L3_INIT, &st->l2.flag); -} - -static void -l2_release(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - st->l2.l2l3(st, DL_RELEASE | CONFIRM, NULL); -} - -static void -l2_pend_rel(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - test_and_set_bit(FLG_PEND_REL, &st->l2.flag); -} - -static void -l2_disconnect(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - skb_queue_purge(&st->l2.i_queue); - freewin(st); - FsmChangeState(fi, ST_L2_6); - st->l2.rc = 0; - send_uframe(st, DISC | 0x10, CMD); - FsmDelTimer(&st->l2.t203, 1); - restart_t200(st, 2); -} - -static void -l2_start_multi(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - struct sk_buff *skb = arg; - - send_uframe(st, UA | get_PollFlagFree(st, skb), RSP); - - clear_exception(&st->l2); - st->l2.vs = 0; - st->l2.va = 0; - st->l2.vr = 0; - st->l2.sow = 0; - FsmChangeState(fi, ST_L2_7); - FsmAddTimer(&st->l2.t203, st->l2.T203, EV_L2_T203, NULL, 3); - - st->l2.l2l3(st, DL_ESTABLISH | INDICATION, NULL); -} - -static void -l2_send_UA(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - struct sk_buff *skb = arg; - - send_uframe(st, UA | get_PollFlagFree(st, skb), RSP); -} - -static void -l2_send_DM(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - struct sk_buff *skb = arg; - - send_uframe(st, DM | get_PollFlagFree(st, skb), RSP); -} - -static void -l2_restart_multi(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - struct sk_buff *skb = arg; - int est = 0, state; - - state = fi->state; - - send_uframe(st, UA | get_PollFlagFree(st, skb), RSP); - - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'F'); - - if (st->l2.vs != st->l2.va) { - skb_queue_purge(&st->l2.i_queue); - est = 1; - } - - clear_exception(&st->l2); - st->l2.vs = 0; - st->l2.va = 0; - st->l2.vr = 0; - st->l2.sow = 0; - FsmChangeState(fi, ST_L2_7); - stop_t200(st, 3); - FsmRestartTimer(&st->l2.t203, st->l2.T203, EV_L2_T203, NULL, 3); - - if (est) - st->l2.l2l3(st, DL_ESTABLISH | INDICATION, NULL); - - if ((ST_L2_7 == state) || (ST_L2_8 == state)) - if (!skb_queue_empty(&st->l2.i_queue) && cansend(st)) - st->l2.l2l1(st, PH_PULL | REQUEST, NULL); -} - -static void -l2_stop_multi(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - struct sk_buff *skb = arg; - - FsmChangeState(fi, ST_L2_4); - FsmDelTimer(&st->l2.t203, 3); - stop_t200(st, 4); - - send_uframe(st, UA | get_PollFlagFree(st, skb), RSP); - - skb_queue_purge(&st->l2.i_queue); - freewin(st); - lapb_dl_release_l2l3(st, INDICATION); -} - -static void -l2_connected(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - struct sk_buff *skb = arg; - int pr = -1; - - if (!get_PollFlag(st, skb)) { - l2_mdl_error_ua(fi, event, arg); - return; - } - dev_kfree_skb(skb); - - if (test_and_clear_bit(FLG_PEND_REL, &st->l2.flag)) - l2_disconnect(fi, event, arg); - - if (test_and_clear_bit(FLG_L3_INIT, &st->l2.flag)) { - pr = DL_ESTABLISH | CONFIRM; - } else if (st->l2.vs != st->l2.va) { - skb_queue_purge(&st->l2.i_queue); - pr = DL_ESTABLISH | INDICATION; - } - - stop_t200(st, 5); - - st->l2.vr = 0; - st->l2.vs = 0; - st->l2.va = 0; - st->l2.sow = 0; - FsmChangeState(fi, ST_L2_7); - FsmAddTimer(&st->l2.t203, st->l2.T203, EV_L2_T203, NULL, 4); - - if (pr != -1) - st->l2.l2l3(st, pr, NULL); - - if (!skb_queue_empty(&st->l2.i_queue) && cansend(st)) - st->l2.l2l1(st, PH_PULL | REQUEST, NULL); -} - -static void -l2_released(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - struct sk_buff *skb = arg; - - if (!get_PollFlag(st, skb)) { - l2_mdl_error_ua(fi, event, arg); - return; - } - dev_kfree_skb(skb); - - stop_t200(st, 6); - lapb_dl_release_l2l3(st, CONFIRM); - FsmChangeState(fi, ST_L2_4); -} - -static void -l2_reestablish(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - struct sk_buff *skb = arg; - - if (!get_PollFlagFree(st, skb)) { - establishlink(fi); - test_and_set_bit(FLG_L3_INIT, &st->l2.flag); - } -} - -static void -l2_st5_dm_release(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - struct sk_buff *skb = arg; - - if (get_PollFlagFree(st, skb)) { - stop_t200(st, 7); - if (!test_bit(FLG_L3_INIT, &st->l2.flag)) - skb_queue_purge(&st->l2.i_queue); - if (test_bit(FLG_LAPB, &st->l2.flag)) - st->l2.l2l1(st, PH_DEACTIVATE | REQUEST, NULL); - st5_dl_release_l2l3(st); - FsmChangeState(fi, ST_L2_4); - } -} - -static void -l2_st6_dm_release(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - struct sk_buff *skb = arg; - - if (get_PollFlagFree(st, skb)) { - stop_t200(st, 8); - lapb_dl_release_l2l3(st, CONFIRM); - FsmChangeState(fi, ST_L2_4); - } -} - -static inline void -enquiry_cr(struct PStack *st, u_char typ, u_char cr, u_char pf) -{ - struct sk_buff *skb; - struct Layer2 *l2; - u_char tmp[MAX_HEADER_LEN]; - int i; - - l2 = &st->l2; - i = sethdraddr(l2, tmp, cr); - if (test_bit(FLG_MOD128, &l2->flag)) { - tmp[i++] = typ; - tmp[i++] = (l2->vr << 1) | (pf ? 1 : 0); - } else - tmp[i++] = (l2->vr << 5) | typ | (pf ? 0x10 : 0); - if (!(skb = alloc_skb(i, GFP_ATOMIC))) { - printk(KERN_WARNING "isdl2 can't alloc sbbuff for enquiry_cr\n"); - return; - } - skb_put_data(skb, tmp, i); - enqueue_super(st, skb); -} - -static inline void -enquiry_response(struct PStack *st) -{ - if (test_bit(FLG_OWN_BUSY, &st->l2.flag)) - enquiry_cr(st, RNR, RSP, 1); - else - enquiry_cr(st, RR, RSP, 1); - test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag); -} - -static inline void -transmit_enquiry(struct PStack *st) -{ - if (test_bit(FLG_OWN_BUSY, &st->l2.flag)) - enquiry_cr(st, RNR, CMD, 1); - else - enquiry_cr(st, RR, CMD, 1); - test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag); - start_t200(st, 9); -} - - -static void -nrerrorrecovery(struct FsmInst *fi) -{ - struct PStack *st = fi->userdata; - - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'J'); - establishlink(fi); - test_and_clear_bit(FLG_L3_INIT, &st->l2.flag); -} - -static void -invoke_retransmission(struct PStack *st, unsigned int nr) -{ - struct Layer2 *l2 = &st->l2; - u_int p1; - u_long flags; - - spin_lock_irqsave(&l2->lock, flags); - if (l2->vs != nr) { - while (l2->vs != nr) { - (l2->vs)--; - if (test_bit(FLG_MOD128, &l2->flag)) { - l2->vs %= 128; - p1 = (l2->vs - l2->va) % 128; - } else { - l2->vs %= 8; - p1 = (l2->vs - l2->va) % 8; - } - p1 = (p1 + l2->sow) % l2->window; - if (test_bit(FLG_LAPB, &l2->flag)) - st->l1.bcs->tx_cnt += l2->windowar[p1]->len + l2headersize(l2, 0); - skb_queue_head(&l2->i_queue, l2->windowar[p1]); - l2->windowar[p1] = NULL; - } - spin_unlock_irqrestore(&l2->lock, flags); - st->l2.l2l1(st, PH_PULL | REQUEST, NULL); - return; - } - spin_unlock_irqrestore(&l2->lock, flags); -} - -static void -l2_st7_got_super(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - struct sk_buff *skb = arg; - int PollFlag, rsp, typ = RR; - unsigned int nr; - struct Layer2 *l2 = &st->l2; - - rsp = *skb->data & 0x2; - if (test_bit(FLG_ORIG, &l2->flag)) - rsp = !rsp; - - skb_pull(skb, l2addrsize(l2)); - if (IsRNR(skb->data, st)) { - set_peer_busy(l2); - typ = RNR; - } else - clear_peer_busy(l2); - if (IsREJ(skb->data, st)) - typ = REJ; - - if (test_bit(FLG_MOD128, &l2->flag)) { - PollFlag = (skb->data[1] & 0x1) == 0x1; - nr = skb->data[1] >> 1; - } else { - PollFlag = (skb->data[0] & 0x10); - nr = (skb->data[0] >> 5) & 0x7; - } - dev_kfree_skb(skb); - - if (PollFlag) { - if (rsp) - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'A'); - else - enquiry_response(st); - } - if (legalnr(st, nr)) { - if (typ == REJ) { - setva(st, nr); - invoke_retransmission(st, nr); - stop_t200(st, 10); - if (FsmAddTimer(&st->l2.t203, st->l2.T203, - EV_L2_T203, NULL, 6)) - l2m_debug(&st->l2.l2m, "Restart T203 ST7 REJ"); - } else if ((nr == l2->vs) && (typ == RR)) { - setva(st, nr); - stop_t200(st, 11); - FsmRestartTimer(&st->l2.t203, st->l2.T203, - EV_L2_T203, NULL, 7); - } else if ((l2->va != nr) || (typ == RNR)) { - setva(st, nr); - if (typ != RR) FsmDelTimer(&st->l2.t203, 9); - restart_t200(st, 12); - } - if (!skb_queue_empty(&st->l2.i_queue) && (typ == RR)) - st->l2.l2l1(st, PH_PULL | REQUEST, NULL); - } else - nrerrorrecovery(fi); -} - -static void -l2_feed_i_if_reest(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - struct sk_buff *skb = arg; - - if (test_bit(FLG_LAPB, &st->l2.flag)) - st->l1.bcs->tx_cnt += skb->len + l2headersize(&st->l2, 0); - if (!test_bit(FLG_L3_INIT, &st->l2.flag)) - skb_queue_tail(&st->l2.i_queue, skb); - else - dev_kfree_skb(skb); -} - -static void -l2_feed_i_pull(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - struct sk_buff *skb = arg; - - if (test_bit(FLG_LAPB, &st->l2.flag)) - st->l1.bcs->tx_cnt += skb->len + l2headersize(&st->l2, 0); - skb_queue_tail(&st->l2.i_queue, skb); - st->l2.l2l1(st, PH_PULL | REQUEST, NULL); -} - -static void -l2_feed_iqueue(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - struct sk_buff *skb = arg; - - if (test_bit(FLG_LAPB, &st->l2.flag)) - st->l1.bcs->tx_cnt += skb->len + l2headersize(&st->l2, 0); - skb_queue_tail(&st->l2.i_queue, skb); -} - -static void -l2_got_iframe(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - struct sk_buff *skb = arg; - struct Layer2 *l2 = &(st->l2); - int PollFlag, ns, i; - unsigned int nr; - - i = l2addrsize(l2); - if (test_bit(FLG_MOD128, &l2->flag)) { - PollFlag = ((skb->data[i + 1] & 0x1) == 0x1); - ns = skb->data[i] >> 1; - nr = (skb->data[i + 1] >> 1) & 0x7f; - } else { - PollFlag = (skb->data[i] & 0x10); - ns = (skb->data[i] >> 1) & 0x7; - nr = (skb->data[i] >> 5) & 0x7; - } - if (test_bit(FLG_OWN_BUSY, &l2->flag)) { - dev_kfree_skb(skb); - if (PollFlag) enquiry_response(st); - } else if (l2->vr == ns) { - (l2->vr)++; - if (test_bit(FLG_MOD128, &l2->flag)) - l2->vr %= 128; - else - l2->vr %= 8; - test_and_clear_bit(FLG_REJEXC, &l2->flag); - - if (PollFlag) - enquiry_response(st); - else - test_and_set_bit(FLG_ACK_PEND, &l2->flag); - skb_pull(skb, l2headersize(l2, 0)); - st->l2.l2l3(st, DL_DATA | INDICATION, skb); - } else { - /* n(s)!=v(r) */ - dev_kfree_skb(skb); - if (test_and_set_bit(FLG_REJEXC, &l2->flag)) { - if (PollFlag) - enquiry_response(st); - } else { - enquiry_cr(st, REJ, RSP, PollFlag); - test_and_clear_bit(FLG_ACK_PEND, &l2->flag); - } - } - - if (legalnr(st, nr)) { - if (!test_bit(FLG_PEER_BUSY, &st->l2.flag) && (fi->state == ST_L2_7)) { - if (nr == st->l2.vs) { - stop_t200(st, 13); - FsmRestartTimer(&st->l2.t203, st->l2.T203, - EV_L2_T203, NULL, 7); - } else if (nr != st->l2.va) - restart_t200(st, 14); - } - setva(st, nr); - } else { - nrerrorrecovery(fi); - return; - } - - if (!skb_queue_empty(&st->l2.i_queue) && (fi->state == ST_L2_7)) - st->l2.l2l1(st, PH_PULL | REQUEST, NULL); - if (test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag)) - enquiry_cr(st, RR, RSP, 0); -} - -static void -l2_got_tei(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - st->l2.tei = (long) arg; - - if (fi->state == ST_L2_3) { - establishlink(fi); - test_and_set_bit(FLG_L3_INIT, &st->l2.flag); - } else - FsmChangeState(fi, ST_L2_4); - if (!skb_queue_empty(&st->l2.ui_queue)) - tx_ui(st); -} - -static void -l2_st5_tout_200(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - if (test_bit(FLG_LAPD, &st->l2.flag) && - test_bit(FLG_DCHAN_BUSY, &st->l2.flag)) { - FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 9); - } else if (st->l2.rc == st->l2.N200) { - FsmChangeState(fi, ST_L2_4); - test_and_clear_bit(FLG_T200_RUN, &st->l2.flag); - skb_queue_purge(&st->l2.i_queue); - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'G'); - if (test_bit(FLG_LAPB, &st->l2.flag)) - st->l2.l2l1(st, PH_DEACTIVATE | REQUEST, NULL); - st5_dl_release_l2l3(st); - } else { - st->l2.rc++; - FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 9); - send_uframe(st, (test_bit(FLG_MOD128, &st->l2.flag) ? SABME : SABM) - | 0x10, CMD); - } -} - -static void -l2_st6_tout_200(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - if (test_bit(FLG_LAPD, &st->l2.flag) && - test_bit(FLG_DCHAN_BUSY, &st->l2.flag)) { - FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 9); - } else if (st->l2.rc == st->l2.N200) { - FsmChangeState(fi, ST_L2_4); - test_and_clear_bit(FLG_T200_RUN, &st->l2.flag); - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'H'); - lapb_dl_release_l2l3(st, CONFIRM); - } else { - st->l2.rc++; - FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, - NULL, 9); - send_uframe(st, DISC | 0x10, CMD); - } -} - -static void -l2_st7_tout_200(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - if (test_bit(FLG_LAPD, &st->l2.flag) && - test_bit(FLG_DCHAN_BUSY, &st->l2.flag)) { - FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 9); - return; - } - test_and_clear_bit(FLG_T200_RUN, &st->l2.flag); - st->l2.rc = 0; - FsmChangeState(fi, ST_L2_8); - - transmit_enquiry(st); - st->l2.rc++; -} - -static void -l2_st8_tout_200(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - if (test_bit(FLG_LAPD, &st->l2.flag) && - test_bit(FLG_DCHAN_BUSY, &st->l2.flag)) { - FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 9); - return; - } - test_and_clear_bit(FLG_T200_RUN, &st->l2.flag); - if (st->l2.rc == st->l2.N200) { - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'I'); - establishlink(fi); - test_and_clear_bit(FLG_L3_INIT, &st->l2.flag); - } else { - transmit_enquiry(st); - st->l2.rc++; - } -} - -static void -l2_st7_tout_203(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - if (test_bit(FLG_LAPD, &st->l2.flag) && - test_bit(FLG_DCHAN_BUSY, &st->l2.flag)) { - FsmAddTimer(&st->l2.t203, st->l2.T203, EV_L2_T203, NULL, 9); - return; - } - FsmChangeState(fi, ST_L2_8); - transmit_enquiry(st); - st->l2.rc = 0; -} - -static void -l2_pull_iqueue(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - struct sk_buff *skb, *nskb; - struct Layer2 *l2 = &st->l2; - u_char header[MAX_HEADER_LEN]; - int i, hdr_space_needed; - int unsigned p1; - u_long flags; - - if (!cansend(st)) - return; - - skb = skb_dequeue(&l2->i_queue); - if (!skb) - return; - - hdr_space_needed = l2headersize(l2, 0); - nskb = skb_realloc_headroom(skb, hdr_space_needed); - if (!nskb) { - skb_queue_head(&l2->i_queue, skb); - return; - } - spin_lock_irqsave(&l2->lock, flags); - if (test_bit(FLG_MOD128, &l2->flag)) - p1 = (l2->vs - l2->va) % 128; - else - p1 = (l2->vs - l2->va) % 8; - p1 = (p1 + l2->sow) % l2->window; - if (l2->windowar[p1]) { - printk(KERN_WARNING "isdnl2 try overwrite ack queue entry %d\n", - p1); - dev_kfree_skb(l2->windowar[p1]); - } - l2->windowar[p1] = skb; - - i = sethdraddr(&st->l2, header, CMD); - - if (test_bit(FLG_MOD128, &l2->flag)) { - header[i++] = l2->vs << 1; - header[i++] = l2->vr << 1; - l2->vs = (l2->vs + 1) % 128; - } else { - header[i++] = (l2->vr << 5) | (l2->vs << 1); - l2->vs = (l2->vs + 1) % 8; - } - spin_unlock_irqrestore(&l2->lock, flags); - memcpy(skb_push(nskb, i), header, i); - st->l2.l2l1(st, PH_PULL | INDICATION, nskb); - test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag); - if (!test_and_set_bit(FLG_T200_RUN, &st->l2.flag)) { - FsmDelTimer(&st->l2.t203, 13); - FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 11); - } - if (!skb_queue_empty(&l2->i_queue) && cansend(st)) - st->l2.l2l1(st, PH_PULL | REQUEST, NULL); -} - -static void -l2_st8_got_super(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - struct sk_buff *skb = arg; - int PollFlag, rsp, rnr = 0; - unsigned int nr; - struct Layer2 *l2 = &st->l2; - - rsp = *skb->data & 0x2; - if (test_bit(FLG_ORIG, &l2->flag)) - rsp = !rsp; - - skb_pull(skb, l2addrsize(l2)); - - if (IsRNR(skb->data, st)) { - set_peer_busy(l2); - rnr = 1; - } else - clear_peer_busy(l2); - - if (test_bit(FLG_MOD128, &l2->flag)) { - PollFlag = (skb->data[1] & 0x1) == 0x1; - nr = skb->data[1] >> 1; - } else { - PollFlag = (skb->data[0] & 0x10); - nr = (skb->data[0] >> 5) & 0x7; - } - dev_kfree_skb(skb); - - if (rsp && PollFlag) { - if (legalnr(st, nr)) { - if (rnr) { - restart_t200(st, 15); - } else { - stop_t200(st, 16); - FsmAddTimer(&l2->t203, l2->T203, - EV_L2_T203, NULL, 5); - setva(st, nr); - } - invoke_retransmission(st, nr); - FsmChangeState(fi, ST_L2_7); - if (!skb_queue_empty(&l2->i_queue) && cansend(st)) - st->l2.l2l1(st, PH_PULL | REQUEST, NULL); - } else - nrerrorrecovery(fi); - } else { - if (!rsp && PollFlag) - enquiry_response(st); - if (legalnr(st, nr)) { - setva(st, nr); - } else - nrerrorrecovery(fi); - } -} - -static void -l2_got_FRMR(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - struct sk_buff *skb = arg; - - skb_pull(skb, l2addrsize(&st->l2) + 1); - - if (!(skb->data[0] & 1) || ((skb->data[0] & 3) == 1) || /* I or S */ - (IsUA(skb->data) && (fi->state == ST_L2_7))) { - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'K'); - establishlink(fi); - test_and_clear_bit(FLG_L3_INIT, &st->l2.flag); - } - dev_kfree_skb(skb); -} - -static void -l2_st24_tei_remove(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - skb_queue_purge(&st->l2.ui_queue); - st->l2.tei = -1; - FsmChangeState(fi, ST_L2_1); -} - -static void -l2_st3_tei_remove(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - skb_queue_purge(&st->l2.ui_queue); - st->l2.tei = -1; - st->l2.l2l3(st, DL_RELEASE | INDICATION, NULL); - FsmChangeState(fi, ST_L2_1); -} - -static void -l2_st5_tei_remove(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - skb_queue_purge(&st->l2.i_queue); - skb_queue_purge(&st->l2.ui_queue); - freewin(st); - st->l2.tei = -1; - stop_t200(st, 17); - st5_dl_release_l2l3(st); - FsmChangeState(fi, ST_L2_1); -} - -static void -l2_st6_tei_remove(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - skb_queue_purge(&st->l2.ui_queue); - st->l2.tei = -1; - stop_t200(st, 18); - st->l2.l2l3(st, DL_RELEASE | CONFIRM, NULL); - FsmChangeState(fi, ST_L2_1); -} - -static void -l2_tei_remove(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - skb_queue_purge(&st->l2.i_queue); - skb_queue_purge(&st->l2.ui_queue); - freewin(st); - st->l2.tei = -1; - stop_t200(st, 17); - FsmDelTimer(&st->l2.t203, 19); - st->l2.l2l3(st, DL_RELEASE | INDICATION, NULL); - FsmChangeState(fi, ST_L2_1); -} - -static void -l2_st14_persistent_da(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - skb_queue_purge(&st->l2.i_queue); - skb_queue_purge(&st->l2.ui_queue); - if (test_and_clear_bit(FLG_ESTAB_PEND, &st->l2.flag)) - st->l2.l2l3(st, DL_RELEASE | INDICATION, NULL); -} - -static void -l2_st5_persistent_da(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - skb_queue_purge(&st->l2.i_queue); - skb_queue_purge(&st->l2.ui_queue); - freewin(st); - stop_t200(st, 19); - st5_dl_release_l2l3(st); - FsmChangeState(fi, ST_L2_4); -} - -static void -l2_st6_persistent_da(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - skb_queue_purge(&st->l2.ui_queue); - stop_t200(st, 20); - st->l2.l2l3(st, DL_RELEASE | CONFIRM, NULL); - FsmChangeState(fi, ST_L2_4); -} - -static void -l2_persistent_da(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - skb_queue_purge(&st->l2.i_queue); - skb_queue_purge(&st->l2.ui_queue); - freewin(st); - stop_t200(st, 19); - FsmDelTimer(&st->l2.t203, 19); - st->l2.l2l3(st, DL_RELEASE | INDICATION, NULL); - FsmChangeState(fi, ST_L2_4); -} - -static void -l2_set_own_busy(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - if (!test_and_set_bit(FLG_OWN_BUSY, &st->l2.flag)) { - enquiry_cr(st, RNR, RSP, 0); - test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag); - } -} - -static void -l2_clear_own_busy(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - if (!test_and_clear_bit(FLG_OWN_BUSY, &st->l2.flag)) { - enquiry_cr(st, RR, RSP, 0); - test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag); - } -} - -static void -l2_frame_error(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - st->ma.layer(st, MDL_ERROR | INDICATION, arg); -} - -static void -l2_frame_error_reest(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - st->ma.layer(st, MDL_ERROR | INDICATION, arg); - establishlink(fi); - test_and_clear_bit(FLG_L3_INIT, &st->l2.flag); -} - -static struct FsmNode L2FnList[] __initdata = -{ - {ST_L2_1, EV_L2_DL_ESTABLISH_REQ, l2_mdl_assign}, - {ST_L2_2, EV_L2_DL_ESTABLISH_REQ, l2_go_st3}, - {ST_L2_4, EV_L2_DL_ESTABLISH_REQ, l2_establish}, - {ST_L2_5, EV_L2_DL_ESTABLISH_REQ, l2_discard_i_setl3}, - {ST_L2_7, EV_L2_DL_ESTABLISH_REQ, l2_l3_reestablish}, - {ST_L2_8, EV_L2_DL_ESTABLISH_REQ, l2_l3_reestablish}, - {ST_L2_4, EV_L2_DL_RELEASE_REQ, l2_release}, - {ST_L2_5, EV_L2_DL_RELEASE_REQ, l2_pend_rel}, - {ST_L2_7, EV_L2_DL_RELEASE_REQ, l2_disconnect}, - {ST_L2_8, EV_L2_DL_RELEASE_REQ, l2_disconnect}, - {ST_L2_5, EV_L2_DL_DATA, l2_feed_i_if_reest}, - {ST_L2_7, EV_L2_DL_DATA, l2_feed_i_pull}, - {ST_L2_8, EV_L2_DL_DATA, l2_feed_iqueue}, - {ST_L2_1, EV_L2_DL_UNIT_DATA, l2_queue_ui_assign}, - {ST_L2_2, EV_L2_DL_UNIT_DATA, l2_queue_ui}, - {ST_L2_3, EV_L2_DL_UNIT_DATA, l2_queue_ui}, - {ST_L2_4, EV_L2_DL_UNIT_DATA, l2_send_ui}, - {ST_L2_5, EV_L2_DL_UNIT_DATA, l2_send_ui}, - {ST_L2_6, EV_L2_DL_UNIT_DATA, l2_send_ui}, - {ST_L2_7, EV_L2_DL_UNIT_DATA, l2_send_ui}, - {ST_L2_8, EV_L2_DL_UNIT_DATA, l2_send_ui}, - {ST_L2_1, EV_L2_MDL_ASSIGN, l2_got_tei}, - {ST_L2_2, EV_L2_MDL_ASSIGN, l2_got_tei}, - {ST_L2_3, EV_L2_MDL_ASSIGN, l2_got_tei}, - {ST_L2_2, EV_L2_MDL_ERROR, l2_st24_tei_remove}, - {ST_L2_3, EV_L2_MDL_ERROR, l2_st3_tei_remove}, - {ST_L2_4, EV_L2_MDL_REMOVE, l2_st24_tei_remove}, - {ST_L2_5, EV_L2_MDL_REMOVE, l2_st5_tei_remove}, - {ST_L2_6, EV_L2_MDL_REMOVE, l2_st6_tei_remove}, - {ST_L2_7, EV_L2_MDL_REMOVE, l2_tei_remove}, - {ST_L2_8, EV_L2_MDL_REMOVE, l2_tei_remove}, - {ST_L2_4, EV_L2_SABME, l2_start_multi}, - {ST_L2_5, EV_L2_SABME, l2_send_UA}, - {ST_L2_6, EV_L2_SABME, l2_send_DM}, - {ST_L2_7, EV_L2_SABME, l2_restart_multi}, - {ST_L2_8, EV_L2_SABME, l2_restart_multi}, - {ST_L2_4, EV_L2_DISC, l2_send_DM}, - {ST_L2_5, EV_L2_DISC, l2_send_DM}, - {ST_L2_6, EV_L2_DISC, l2_send_UA}, - {ST_L2_7, EV_L2_DISC, l2_stop_multi}, - {ST_L2_8, EV_L2_DISC, l2_stop_multi}, - {ST_L2_4, EV_L2_UA, l2_mdl_error_ua}, - {ST_L2_5, EV_L2_UA, l2_connected}, - {ST_L2_6, EV_L2_UA, l2_released}, - {ST_L2_7, EV_L2_UA, l2_mdl_error_ua}, - {ST_L2_8, EV_L2_UA, l2_mdl_error_ua}, - {ST_L2_4, EV_L2_DM, l2_reestablish}, - {ST_L2_5, EV_L2_DM, l2_st5_dm_release}, - {ST_L2_6, EV_L2_DM, l2_st6_dm_release}, - {ST_L2_7, EV_L2_DM, l2_mdl_error_dm}, - {ST_L2_8, EV_L2_DM, l2_st8_mdl_error_dm}, - {ST_L2_1, EV_L2_UI, l2_got_ui}, - {ST_L2_2, EV_L2_UI, l2_got_ui}, - {ST_L2_3, EV_L2_UI, l2_got_ui}, - {ST_L2_4, EV_L2_UI, l2_got_ui}, - {ST_L2_5, EV_L2_UI, l2_got_ui}, - {ST_L2_6, EV_L2_UI, l2_got_ui}, - {ST_L2_7, EV_L2_UI, l2_got_ui}, - {ST_L2_8, EV_L2_UI, l2_got_ui}, - {ST_L2_7, EV_L2_FRMR, l2_got_FRMR}, - {ST_L2_8, EV_L2_FRMR, l2_got_FRMR}, - {ST_L2_7, EV_L2_SUPER, l2_st7_got_super}, - {ST_L2_8, EV_L2_SUPER, l2_st8_got_super}, - {ST_L2_7, EV_L2_I, l2_got_iframe}, - {ST_L2_8, EV_L2_I, l2_got_iframe}, - {ST_L2_5, EV_L2_T200, l2_st5_tout_200}, - {ST_L2_6, EV_L2_T200, l2_st6_tout_200}, - {ST_L2_7, EV_L2_T200, l2_st7_tout_200}, - {ST_L2_8, EV_L2_T200, l2_st8_tout_200}, - {ST_L2_7, EV_L2_T203, l2_st7_tout_203}, - {ST_L2_7, EV_L2_ACK_PULL, l2_pull_iqueue}, - {ST_L2_7, EV_L2_SET_OWN_BUSY, l2_set_own_busy}, - {ST_L2_8, EV_L2_SET_OWN_BUSY, l2_set_own_busy}, - {ST_L2_7, EV_L2_CLEAR_OWN_BUSY, l2_clear_own_busy}, - {ST_L2_8, EV_L2_CLEAR_OWN_BUSY, l2_clear_own_busy}, - {ST_L2_4, EV_L2_FRAME_ERROR, l2_frame_error}, - {ST_L2_5, EV_L2_FRAME_ERROR, l2_frame_error}, - {ST_L2_6, EV_L2_FRAME_ERROR, l2_frame_error}, - {ST_L2_7, EV_L2_FRAME_ERROR, l2_frame_error_reest}, - {ST_L2_8, EV_L2_FRAME_ERROR, l2_frame_error_reest}, - {ST_L2_1, EV_L1_DEACTIVATE, l2_st14_persistent_da}, - {ST_L2_2, EV_L1_DEACTIVATE, l2_st24_tei_remove}, - {ST_L2_3, EV_L1_DEACTIVATE, l2_st3_tei_remove}, - {ST_L2_4, EV_L1_DEACTIVATE, l2_st14_persistent_da}, - {ST_L2_5, EV_L1_DEACTIVATE, l2_st5_persistent_da}, - {ST_L2_6, EV_L1_DEACTIVATE, l2_st6_persistent_da}, - {ST_L2_7, EV_L1_DEACTIVATE, l2_persistent_da}, - {ST_L2_8, EV_L1_DEACTIVATE, l2_persistent_da}, -}; - -static void -isdnl2_l1l2(struct PStack *st, int pr, void *arg) -{ - struct sk_buff *skb = arg; - u_char *datap; - int ret = 1, len; - int c = 0; - - switch (pr) { - case (PH_DATA | INDICATION): - datap = skb->data; - len = l2addrsize(&st->l2); - if (skb->len > len) - datap += len; - else { - FsmEvent(&st->l2.l2m, EV_L2_FRAME_ERROR, (void *) 'N'); - dev_kfree_skb(skb); - return; - } - if (!(*datap & 1)) { /* I-Frame */ - if (!(c = iframe_error(st, skb))) - ret = FsmEvent(&st->l2.l2m, EV_L2_I, skb); - } else if (IsSFrame(datap, st)) { /* S-Frame */ - if (!(c = super_error(st, skb))) - ret = FsmEvent(&st->l2.l2m, EV_L2_SUPER, skb); - } else if (IsUI(datap)) { - if (!(c = UI_error(st, skb))) - ret = FsmEvent(&st->l2.l2m, EV_L2_UI, skb); - } else if (IsSABME(datap, st)) { - if (!(c = unnum_error(st, skb, CMD))) - ret = FsmEvent(&st->l2.l2m, EV_L2_SABME, skb); - } else if (IsUA(datap)) { - if (!(c = unnum_error(st, skb, RSP))) - ret = FsmEvent(&st->l2.l2m, EV_L2_UA, skb); - } else if (IsDISC(datap)) { - if (!(c = unnum_error(st, skb, CMD))) - ret = FsmEvent(&st->l2.l2m, EV_L2_DISC, skb); - } else if (IsDM(datap)) { - if (!(c = unnum_error(st, skb, RSP))) - ret = FsmEvent(&st->l2.l2m, EV_L2_DM, skb); - } else if (IsFRMR(datap)) { - if (!(c = FRMR_error(st, skb))) - ret = FsmEvent(&st->l2.l2m, EV_L2_FRMR, skb); - } else { - FsmEvent(&st->l2.l2m, EV_L2_FRAME_ERROR, (void *) 'L'); - dev_kfree_skb(skb); - ret = 0; - } - if (c) { - dev_kfree_skb(skb); - FsmEvent(&st->l2.l2m, EV_L2_FRAME_ERROR, (void *)(long)c); - ret = 0; - } - if (ret) - dev_kfree_skb(skb); - break; - case (PH_PULL | CONFIRM): - FsmEvent(&st->l2.l2m, EV_L2_ACK_PULL, arg); - break; - case (PH_PAUSE | INDICATION): - test_and_set_bit(FLG_DCHAN_BUSY, &st->l2.flag); - break; - case (PH_PAUSE | CONFIRM): - test_and_clear_bit(FLG_DCHAN_BUSY, &st->l2.flag); - break; - case (PH_ACTIVATE | CONFIRM): - case (PH_ACTIVATE | INDICATION): - test_and_set_bit(FLG_L1_ACTIV, &st->l2.flag); - if (test_and_clear_bit(FLG_ESTAB_PEND, &st->l2.flag)) - FsmEvent(&st->l2.l2m, EV_L2_DL_ESTABLISH_REQ, arg); - break; - case (PH_DEACTIVATE | INDICATION): - case (PH_DEACTIVATE | CONFIRM): - test_and_clear_bit(FLG_L1_ACTIV, &st->l2.flag); - FsmEvent(&st->l2.l2m, EV_L1_DEACTIVATE, arg); - break; - default: - l2m_debug(&st->l2.l2m, "l2 unknown pr %04x", pr); - break; - } -} - -static void -isdnl2_l3l2(struct PStack *st, int pr, void *arg) -{ - switch (pr) { - case (DL_DATA | REQUEST): - if (FsmEvent(&st->l2.l2m, EV_L2_DL_DATA, arg)) { - dev_kfree_skb((struct sk_buff *) arg); - } - break; - case (DL_UNIT_DATA | REQUEST): - if (FsmEvent(&st->l2.l2m, EV_L2_DL_UNIT_DATA, arg)) { - dev_kfree_skb((struct sk_buff *) arg); - } - break; - case (DL_ESTABLISH | REQUEST): - if (test_bit(FLG_L1_ACTIV, &st->l2.flag)) { - if (test_bit(FLG_LAPD, &st->l2.flag) || - test_bit(FLG_ORIG, &st->l2.flag)) { - FsmEvent(&st->l2.l2m, EV_L2_DL_ESTABLISH_REQ, arg); - } - } else { - if (test_bit(FLG_LAPD, &st->l2.flag) || - test_bit(FLG_ORIG, &st->l2.flag)) { - test_and_set_bit(FLG_ESTAB_PEND, &st->l2.flag); - } - st->l2.l2l1(st, PH_ACTIVATE, NULL); - } - break; - case (DL_RELEASE | REQUEST): - if (test_bit(FLG_LAPB, &st->l2.flag)) { - st->l2.l2l1(st, PH_DEACTIVATE, NULL); - } - FsmEvent(&st->l2.l2m, EV_L2_DL_RELEASE_REQ, arg); - break; - case (MDL_ASSIGN | REQUEST): - FsmEvent(&st->l2.l2m, EV_L2_MDL_ASSIGN, arg); - break; - case (MDL_REMOVE | REQUEST): - FsmEvent(&st->l2.l2m, EV_L2_MDL_REMOVE, arg); - break; - case (MDL_ERROR | RESPONSE): - FsmEvent(&st->l2.l2m, EV_L2_MDL_ERROR, arg); - break; - } -} - -void -releasestack_isdnl2(struct PStack *st) -{ - FsmDelTimer(&st->l2.t200, 21); - FsmDelTimer(&st->l2.t203, 16); - skb_queue_purge(&st->l2.i_queue); - skb_queue_purge(&st->l2.ui_queue); - ReleaseWin(&st->l2); -} - -static void -l2m_debug(struct FsmInst *fi, char *fmt, ...) -{ - va_list args; - struct PStack *st = fi->userdata; - - va_start(args, fmt); - VHiSax_putstatus(st->l1.hardware, st->l2.debug_id, fmt, args); - va_end(args); -} - -void -setstack_isdnl2(struct PStack *st, char *debug_id) -{ - spin_lock_init(&st->l2.lock); - st->l1.l1l2 = isdnl2_l1l2; - st->l3.l3l2 = isdnl2_l3l2; - - skb_queue_head_init(&st->l2.i_queue); - skb_queue_head_init(&st->l2.ui_queue); - InitWin(&st->l2); - st->l2.debug = 0; - - st->l2.l2m.fsm = &l2fsm; - if (test_bit(FLG_LAPB, &st->l2.flag)) - st->l2.l2m.state = ST_L2_4; - else - st->l2.l2m.state = ST_L2_1; - st->l2.l2m.debug = 0; - st->l2.l2m.userdata = st; - st->l2.l2m.userint = 0; - st->l2.l2m.printdebug = l2m_debug; - strcpy(st->l2.debug_id, debug_id); - - FsmInitTimer(&st->l2.l2m, &st->l2.t200); - FsmInitTimer(&st->l2.l2m, &st->l2.t203); -} - -static void -transl2_l3l2(struct PStack *st, int pr, void *arg) -{ - switch (pr) { - case (DL_DATA | REQUEST): - case (DL_UNIT_DATA | REQUEST): - st->l2.l2l1(st, PH_DATA | REQUEST, arg); - break; - case (DL_ESTABLISH | REQUEST): - st->l2.l2l1(st, PH_ACTIVATE | REQUEST, NULL); - break; - case (DL_RELEASE | REQUEST): - st->l2.l2l1(st, PH_DEACTIVATE | REQUEST, NULL); - break; - } -} - -void -setstack_transl2(struct PStack *st) -{ - st->l3.l3l2 = transl2_l3l2; -} - -void -releasestack_transl2(struct PStack *st) -{ -} - -int __init -Isdnl2New(void) -{ - l2fsm.state_count = L2_STATE_COUNT; - l2fsm.event_count = L2_EVENT_COUNT; - l2fsm.strEvent = strL2Event; - l2fsm.strState = strL2State; - return FsmNew(&l2fsm, L2FnList, ARRAY_SIZE(L2FnList)); -} - -void -Isdnl2Free(void) -{ - FsmFree(&l2fsm); -} diff --git a/drivers/isdn/hisax/isdnl2.h b/drivers/isdn/hisax/isdnl2.h deleted file mode 100644 index 7e447fb8ed1d..000000000000 --- a/drivers/isdn/hisax/isdnl2.h +++ /dev/null @@ -1,25 +0,0 @@ -/* $Id: isdnl2.h,v 1.3.6.2 2001/09/23 22:24:49 kai Exp $ - * - * Layer 2 defines - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#define RR 0x01 -#define RNR 0x05 -#define REJ 0x09 -#define SABME 0x6f -#define SABM 0x2f -#define DM 0x0f -#define UI 0x03 -#define DISC 0x43 -#define UA 0x63 -#define FRMR 0x87 -#define XID 0xaf - -#define CMD 0 -#define RSP 1 - -#define LC_FLUSH_WAIT 1 diff --git a/drivers/isdn/hisax/isdnl3.c b/drivers/isdn/hisax/isdnl3.c deleted file mode 100644 index bb3f9ec62749..000000000000 --- a/drivers/isdn/hisax/isdnl3.c +++ /dev/null @@ -1,594 +0,0 @@ -/* $Id: isdnl3.c,v 2.22.2.3 2004/01/13 14:31:25 keil Exp $ - * - * Author Karsten Keil - * based on the teles driver from Jan den Ouden - * Copyright by Karsten Keil <keil@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * For changes and modifications please read - * Documentation/isdn/HiSax.cert - * - * Thanks to Jan den Ouden - * Fritz Elfert - * - */ - -#include <linux/init.h> -#include <linux/slab.h> -#include "hisax.h" -#include "isdnl3.h" - -const char *l3_revision = "$Revision: 2.22.2.3 $"; - -static struct Fsm l3fsm; - -enum { - ST_L3_LC_REL, - ST_L3_LC_ESTAB_WAIT, - ST_L3_LC_REL_DELAY, - ST_L3_LC_REL_WAIT, - ST_L3_LC_ESTAB, -}; - -#define L3_STATE_COUNT (ST_L3_LC_ESTAB + 1) - -static char *strL3State[] = -{ - "ST_L3_LC_REL", - "ST_L3_LC_ESTAB_WAIT", - "ST_L3_LC_REL_DELAY", - "ST_L3_LC_REL_WAIT", - "ST_L3_LC_ESTAB", -}; - -enum { - EV_ESTABLISH_REQ, - EV_ESTABLISH_IND, - EV_ESTABLISH_CNF, - EV_RELEASE_REQ, - EV_RELEASE_CNF, - EV_RELEASE_IND, - EV_TIMEOUT, -}; - -#define L3_EVENT_COUNT (EV_TIMEOUT + 1) - -static char *strL3Event[] = -{ - "EV_ESTABLISH_REQ", - "EV_ESTABLISH_IND", - "EV_ESTABLISH_CNF", - "EV_RELEASE_REQ", - "EV_RELEASE_CNF", - "EV_RELEASE_IND", - "EV_TIMEOUT", -}; - -static __printf(2, 3) void - l3m_debug(struct FsmInst *fi, char *fmt, ...) -{ - va_list args; - struct PStack *st = fi->userdata; - - va_start(args, fmt); - VHiSax_putstatus(st->l1.hardware, st->l3.debug_id, fmt, args); - va_end(args); -} - -u_char * -findie(u_char *p, int size, u_char ie, int wanted_set) -{ - int l, codeset, maincodeset; - u_char *pend = p + size; - - /* skip protocol discriminator, callref and message type */ - p++; - l = (*p++) & 0xf; - p += l; - p++; - codeset = 0; - maincodeset = 0; - /* while there are bytes left... */ - while (p < pend) { - if ((*p & 0xf0) == 0x90) { - codeset = *p & 0x07; - if (!(*p & 0x08)) - maincodeset = codeset; - } - if (*p & 0x80) - p++; - else { - if (codeset == wanted_set) { - if (*p == ie) - { /* improved length check (Werner Cornelius) */ - if ((pend - p) < 2) - return (NULL); - if (*(p + 1) > (pend - (p + 2))) - return (NULL); - return (p); - } - - if (*p > ie) - return (NULL); - } - p++; - l = *p++; - p += l; - codeset = maincodeset; - } - } - return (NULL); -} - -int -getcallref(u_char *p) -{ - int l, cr = 0; - - p++; /* prot discr */ - if (*p & 0xfe) /* wrong callref BRI only 1 octet*/ - return (-2); - l = 0xf & *p++; /* callref length */ - if (!l) /* dummy CallRef */ - return (-1); - cr = *p++; - return (cr); -} - -static int OrigCallRef = 0; - -int -newcallref(void) -{ - if (OrigCallRef == 127) - OrigCallRef = 1; - else - OrigCallRef++; - return (OrigCallRef); -} - -void -newl3state(struct l3_process *pc, int state) -{ - if (pc->debug & L3_DEB_STATE) - l3_debug(pc->st, "%s cr %d %d --> %d", __func__, - pc->callref & 0x7F, - pc->state, state); - pc->state = state; -} - -static void -L3ExpireTimer(struct timer_list *timer) -{ - struct L3Timer *t = from_timer(t, timer, tl); - t->pc->st->lli.l4l3(t->pc->st, t->event, t->pc); -} - -void -L3InitTimer(struct l3_process *pc, struct L3Timer *t) -{ - t->pc = pc; - timer_setup(&t->tl, L3ExpireTimer, 0); -} - -void -L3DelTimer(struct L3Timer *t) -{ - del_timer(&t->tl); -} - -int -L3AddTimer(struct L3Timer *t, - int millisec, int event) -{ - if (timer_pending(&t->tl)) { - printk(KERN_WARNING "L3AddTimer: timer already active!\n"); - return -1; - } - t->event = event; - t->tl.expires = jiffies + (millisec * HZ) / 1000; - add_timer(&t->tl); - return 0; -} - -void -StopAllL3Timer(struct l3_process *pc) -{ - L3DelTimer(&pc->timer); -} - -struct sk_buff * -l3_alloc_skb(int len) -{ - struct sk_buff *skb; - - if (!(skb = alloc_skb(len + MAX_HEADER_LEN, GFP_ATOMIC))) { - printk(KERN_WARNING "HiSax: No skb for D-channel\n"); - return (NULL); - } - skb_reserve(skb, MAX_HEADER_LEN); - return (skb); -} - -static void -no_l3_proto(struct PStack *st, int pr, void *arg) -{ - struct sk_buff *skb = arg; - - HiSax_putstatus(st->l1.hardware, "L3", "no D protocol"); - if (skb) { - dev_kfree_skb(skb); - } -} - -static int -no_l3_proto_spec(struct PStack *st, isdn_ctrl *ic) -{ - printk(KERN_WARNING "HiSax: no specific protocol handler for proto %lu\n", ic->arg & 0xFF); - return (-1); -} - -struct l3_process -*getl3proc(struct PStack *st, int cr) -{ - struct l3_process *p = st->l3.proc; - - while (p) - if (p->callref == cr) - return (p); - else - p = p->next; - return (NULL); -} - -struct l3_process -*new_l3_process(struct PStack *st, int cr) -{ - struct l3_process *p, *np; - - if (!(p = kmalloc(sizeof(struct l3_process), GFP_ATOMIC))) { - printk(KERN_ERR "HiSax can't get memory for cr %d\n", cr); - return (NULL); - } - if (!st->l3.proc) - st->l3.proc = p; - else { - np = st->l3.proc; - while (np->next) - np = np->next; - np->next = p; - } - p->next = NULL; - p->debug = st->l3.debug; - p->callref = cr; - p->state = 0; - p->chan = NULL; - p->st = st; - p->N303 = st->l3.N303; - L3InitTimer(p, &p->timer); - return (p); -}; - -void -release_l3_process(struct l3_process *p) -{ - struct l3_process *np, *pp = NULL; - - if (!p) - return; - np = p->st->l3.proc; - while (np) { - if (np == p) { - StopAllL3Timer(p); - if (pp) - pp->next = np->next; - else if (!(p->st->l3.proc = np->next) && - !test_bit(FLG_PTP, &p->st->l2.flag)) { - if (p->debug) - l3_debug(p->st, "release_l3_process: last process"); - if (skb_queue_empty(&p->st->l3.squeue)) { - if (p->debug) - l3_debug(p->st, "release_l3_process: release link"); - if (p->st->protocol != ISDN_PTYPE_NI1) - FsmEvent(&p->st->l3.l3m, EV_RELEASE_REQ, NULL); - else - FsmEvent(&p->st->l3.l3m, EV_RELEASE_IND, NULL); - } else { - if (p->debug) - l3_debug(p->st, "release_l3_process: not release link"); - } - } - kfree(p); - return; - } - pp = np; - np = np->next; - } - printk(KERN_ERR "HiSax internal L3 error CR(%d) not in list\n", p->callref); - l3_debug(p->st, "HiSax internal L3 error CR(%d) not in list", p->callref); -}; - -static void -l3ml3p(struct PStack *st, int pr) -{ - struct l3_process *p = st->l3.proc; - struct l3_process *np; - - while (p) { - /* p might be kfreed under us, so we need to save where we want to go on */ - np = p->next; - st->l3.l3ml3(st, pr, p); - p = np; - } -} - -void -setstack_l3dc(struct PStack *st, struct Channel *chanp) -{ - char tmp[64]; - - st->l3.proc = NULL; - st->l3.global = NULL; - skb_queue_head_init(&st->l3.squeue); - st->l3.l3m.fsm = &l3fsm; - st->l3.l3m.state = ST_L3_LC_REL; - st->l3.l3m.debug = 1; - st->l3.l3m.userdata = st; - st->l3.l3m.userint = 0; - st->l3.l3m.printdebug = l3m_debug; - FsmInitTimer(&st->l3.l3m, &st->l3.l3m_timer); - strcpy(st->l3.debug_id, "L3DC "); - st->lli.l4l3_proto = no_l3_proto_spec; - -#ifdef CONFIG_HISAX_EURO - if (st->protocol == ISDN_PTYPE_EURO) { - setstack_dss1(st); - } else -#endif -#ifdef CONFIG_HISAX_NI1 - if (st->protocol == ISDN_PTYPE_NI1) { - setstack_ni1(st); - } else -#endif -#ifdef CONFIG_HISAX_1TR6 - if (st->protocol == ISDN_PTYPE_1TR6) { - setstack_1tr6(st); - } else -#endif - if (st->protocol == ISDN_PTYPE_LEASED) { - st->lli.l4l3 = no_l3_proto; - st->l2.l2l3 = no_l3_proto; - st->l3.l3ml3 = no_l3_proto; - printk(KERN_INFO "HiSax: Leased line mode\n"); - } else { - st->lli.l4l3 = no_l3_proto; - st->l2.l2l3 = no_l3_proto; - st->l3.l3ml3 = no_l3_proto; - sprintf(tmp, "protocol %s not supported", - (st->protocol == ISDN_PTYPE_1TR6) ? "1tr6" : - (st->protocol == ISDN_PTYPE_EURO) ? "euro" : - (st->protocol == ISDN_PTYPE_NI1) ? "ni1" : - "unknown"); - printk(KERN_WARNING "HiSax: %s\n", tmp); - st->protocol = -1; - } -} - -static void -isdnl3_trans(struct PStack *st, int pr, void *arg) { - st->l3.l3l2(st, pr, arg); -} - -void -releasestack_isdnl3(struct PStack *st) -{ - while (st->l3.proc) - release_l3_process(st->l3.proc); - if (st->l3.global) { - StopAllL3Timer(st->l3.global); - kfree(st->l3.global); - st->l3.global = NULL; - } - FsmDelTimer(&st->l3.l3m_timer, 54); - skb_queue_purge(&st->l3.squeue); -} - -void -setstack_l3bc(struct PStack *st, struct Channel *chanp) -{ - - st->l3.proc = NULL; - st->l3.global = NULL; - skb_queue_head_init(&st->l3.squeue); - st->l3.l3m.fsm = &l3fsm; - st->l3.l3m.state = ST_L3_LC_REL; - st->l3.l3m.debug = 1; - st->l3.l3m.userdata = st; - st->l3.l3m.userint = 0; - st->l3.l3m.printdebug = l3m_debug; - strcpy(st->l3.debug_id, "L3BC "); - st->lli.l4l3 = isdnl3_trans; -} - -#define DREL_TIMER_VALUE 40000 - -static void -lc_activate(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - FsmChangeState(fi, ST_L3_LC_ESTAB_WAIT); - st->l3.l3l2(st, DL_ESTABLISH | REQUEST, NULL); -} - -static void -lc_connect(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - struct sk_buff *skb = arg; - int dequeued = 0; - - FsmChangeState(fi, ST_L3_LC_ESTAB); - while ((skb = skb_dequeue(&st->l3.squeue))) { - st->l3.l3l2(st, DL_DATA | REQUEST, skb); - dequeued++; - } - if ((!st->l3.proc) && dequeued) { - if (st->l3.debug) - l3_debug(st, "lc_connect: release link"); - FsmEvent(&st->l3.l3m, EV_RELEASE_REQ, NULL); - } else - l3ml3p(st, DL_ESTABLISH | INDICATION); -} - -static void -lc_connected(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - struct sk_buff *skb = arg; - int dequeued = 0; - - FsmDelTimer(&st->l3.l3m_timer, 51); - FsmChangeState(fi, ST_L3_LC_ESTAB); - while ((skb = skb_dequeue(&st->l3.squeue))) { - st->l3.l3l2(st, DL_DATA | REQUEST, skb); - dequeued++; - } - if ((!st->l3.proc) && dequeued) { - if (st->l3.debug) - l3_debug(st, "lc_connected: release link"); - FsmEvent(&st->l3.l3m, EV_RELEASE_REQ, NULL); - } else - l3ml3p(st, DL_ESTABLISH | CONFIRM); -} - -static void -lc_start_delay(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - FsmChangeState(fi, ST_L3_LC_REL_DELAY); - FsmAddTimer(&st->l3.l3m_timer, DREL_TIMER_VALUE, EV_TIMEOUT, NULL, 50); -} - -static void -lc_start_delay_check(struct FsmInst *fi, int event, void *arg) -/* 20/09/00 - GE timer not user for NI-1 as layer 2 should stay up */ -{ - struct PStack *st = fi->userdata; - - FsmChangeState(fi, ST_L3_LC_REL_DELAY); - /* 19/09/00 - GE timer not user for NI-1 */ - if (st->protocol != ISDN_PTYPE_NI1) - FsmAddTimer(&st->l3.l3m_timer, DREL_TIMER_VALUE, EV_TIMEOUT, NULL, 50); -} - -static void -lc_release_req(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - if (test_bit(FLG_L2BLOCK, &st->l2.flag)) { - if (st->l3.debug) - l3_debug(st, "lc_release_req: l2 blocked"); - /* restart release timer */ - FsmAddTimer(&st->l3.l3m_timer, DREL_TIMER_VALUE, EV_TIMEOUT, NULL, 51); - } else { - FsmChangeState(fi, ST_L3_LC_REL_WAIT); - st->l3.l3l2(st, DL_RELEASE | REQUEST, NULL); - } -} - -static void -lc_release_ind(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - FsmDelTimer(&st->l3.l3m_timer, 52); - FsmChangeState(fi, ST_L3_LC_REL); - skb_queue_purge(&st->l3.squeue); - l3ml3p(st, DL_RELEASE | INDICATION); -} - -static void -lc_release_cnf(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - FsmChangeState(fi, ST_L3_LC_REL); - skb_queue_purge(&st->l3.squeue); - l3ml3p(st, DL_RELEASE | CONFIRM); -} - - -/* *INDENT-OFF* */ -static struct FsmNode L3FnList[] __initdata = -{ - {ST_L3_LC_REL, EV_ESTABLISH_REQ, lc_activate}, - {ST_L3_LC_REL, EV_ESTABLISH_IND, lc_connect}, - {ST_L3_LC_REL, EV_ESTABLISH_CNF, lc_connect}, - {ST_L3_LC_ESTAB_WAIT, EV_ESTABLISH_CNF, lc_connected}, - {ST_L3_LC_ESTAB_WAIT, EV_RELEASE_REQ, lc_start_delay}, - {ST_L3_LC_ESTAB_WAIT, EV_RELEASE_IND, lc_release_ind}, - {ST_L3_LC_ESTAB, EV_RELEASE_IND, lc_release_ind}, - {ST_L3_LC_ESTAB, EV_RELEASE_REQ, lc_start_delay_check}, - {ST_L3_LC_REL_DELAY, EV_RELEASE_IND, lc_release_ind}, - {ST_L3_LC_REL_DELAY, EV_ESTABLISH_REQ, lc_connected}, - {ST_L3_LC_REL_DELAY, EV_TIMEOUT, lc_release_req}, - {ST_L3_LC_REL_WAIT, EV_RELEASE_CNF, lc_release_cnf}, - {ST_L3_LC_REL_WAIT, EV_ESTABLISH_REQ, lc_activate}, -}; -/* *INDENT-ON* */ - -void -l3_msg(struct PStack *st, int pr, void *arg) -{ - switch (pr) { - case (DL_DATA | REQUEST): - if (st->l3.l3m.state == ST_L3_LC_ESTAB) { - st->l3.l3l2(st, pr, arg); - } else { - struct sk_buff *skb = arg; - - skb_queue_tail(&st->l3.squeue, skb); - FsmEvent(&st->l3.l3m, EV_ESTABLISH_REQ, NULL); - } - break; - case (DL_ESTABLISH | REQUEST): - FsmEvent(&st->l3.l3m, EV_ESTABLISH_REQ, NULL); - break; - case (DL_ESTABLISH | CONFIRM): - FsmEvent(&st->l3.l3m, EV_ESTABLISH_CNF, NULL); - break; - case (DL_ESTABLISH | INDICATION): - FsmEvent(&st->l3.l3m, EV_ESTABLISH_IND, NULL); - break; - case (DL_RELEASE | INDICATION): - FsmEvent(&st->l3.l3m, EV_RELEASE_IND, NULL); - break; - case (DL_RELEASE | CONFIRM): - FsmEvent(&st->l3.l3m, EV_RELEASE_CNF, NULL); - break; - case (DL_RELEASE | REQUEST): - FsmEvent(&st->l3.l3m, EV_RELEASE_REQ, NULL); - break; - } -} - -int __init -Isdnl3New(void) -{ - l3fsm.state_count = L3_STATE_COUNT; - l3fsm.event_count = L3_EVENT_COUNT; - l3fsm.strEvent = strL3Event; - l3fsm.strState = strL3State; - return FsmNew(&l3fsm, L3FnList, ARRAY_SIZE(L3FnList)); -} - -void -Isdnl3Free(void) -{ - FsmFree(&l3fsm); -} diff --git a/drivers/isdn/hisax/isdnl3.h b/drivers/isdn/hisax/isdnl3.h deleted file mode 100644 index 0edc99d40dc2..000000000000 --- a/drivers/isdn/hisax/isdnl3.h +++ /dev/null @@ -1,42 +0,0 @@ -/* $Id: isdnl3.h,v 2.6.6.2 2001/09/23 22:24:49 kai Exp $ - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#define SBIT(state) (1 << state) -#define ALL_STATES 0x03ffffff - -#define PROTO_DIS_EURO 0x08 - -#define L3_DEB_WARN 0x01 -#define L3_DEB_PROTERR 0x02 -#define L3_DEB_STATE 0x04 -#define L3_DEB_CHARGE 0x08 -#define L3_DEB_CHECK 0x10 -#define L3_DEB_SI 0x20 - -struct stateentry { - int state; - int primitive; - void (*rout) (struct l3_process *, u8, void *); -}; - -#define l3_debug(st, fmt, args...) HiSax_putstatus(st->l1.hardware, "l3 ", fmt, ## args) - -struct PStack; - -void newl3state(struct l3_process *pc, int state); -void L3InitTimer(struct l3_process *pc, struct L3Timer *t); -void L3DelTimer(struct L3Timer *t); -int L3AddTimer(struct L3Timer *t, int millisec, int event); -void StopAllL3Timer(struct l3_process *pc); -struct sk_buff *l3_alloc_skb(int len); -struct l3_process *new_l3_process(struct PStack *st, int cr); -void release_l3_process(struct l3_process *p); -struct l3_process *getl3proc(struct PStack *st, int cr); -void l3_msg(struct PStack *st, int pr, void *arg); -void setstack_dss1(struct PStack *st); -void setstack_ni1(struct PStack *st); -void setstack_1tr6(struct PStack *st); diff --git a/drivers/isdn/hisax/isurf.c b/drivers/isdn/hisax/isurf.c deleted file mode 100644 index 53e299be4304..000000000000 --- a/drivers/isdn/hisax/isurf.c +++ /dev/null @@ -1,305 +0,0 @@ -/* $Id: isurf.c,v 1.12.2.4 2004/01/13 21:46:03 keil Exp $ - * - * low level stuff for Siemens I-Surf/I-Talk cards - * - * Author Karsten Keil - * Copyright by Karsten Keil <keil@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/init.h> -#include "hisax.h" -#include "isac.h" -#include "isar.h" -#include "isdnl1.h" -#include <linux/isapnp.h> - -static const char *ISurf_revision = "$Revision: 1.12.2.4 $"; - -#define byteout(addr, val) outb(val, addr) -#define bytein(addr) inb(addr) - -#define ISURF_ISAR_RESET 1 -#define ISURF_ISAC_RESET 2 -#define ISURF_ISAR_EA 4 -#define ISURF_ARCOFI_RESET 8 -#define ISURF_RESET (ISURF_ISAR_RESET | ISURF_ISAC_RESET | ISURF_ARCOFI_RESET) - -#define ISURF_ISAR_OFFSET 0 -#define ISURF_ISAC_OFFSET 0x100 -#define ISURF_IOMEM_SIZE 0x400 -/* Interface functions */ - -static u_char -ReadISAC(struct IsdnCardState *cs, u_char offset) -{ - return (readb(cs->hw.isurf.isac + offset)); -} - -static void -WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value) -{ - writeb(value, cs->hw.isurf.isac + offset); mb(); -} - -static void -ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - register int i; - for (i = 0; i < size; i++) - data[i] = readb(cs->hw.isurf.isac); -} - -static void -WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - register int i; - for (i = 0; i < size; i++) { - writeb(data[i], cs->hw.isurf.isac); mb(); - } -} - -/* ISAR access routines - * mode = 0 access with IRQ on - * mode = 1 access with IRQ off - * mode = 2 access with IRQ off and using last offset - */ - -static u_char -ReadISAR(struct IsdnCardState *cs, int mode, u_char offset) -{ - return (readb(cs->hw.isurf.isar + offset)); -} - -static void -WriteISAR(struct IsdnCardState *cs, int mode, u_char offset, u_char value) -{ - writeb(value, cs->hw.isurf.isar + offset); mb(); -} - -static irqreturn_t -isurf_interrupt(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - u_char val; - int cnt = 5; - u_long flags; - - spin_lock_irqsave(&cs->lock, flags); - val = readb(cs->hw.isurf.isar + ISAR_IRQBIT); -Start_ISAR: - if (val & ISAR_IRQSTA) - isar_int_main(cs); - val = readb(cs->hw.isurf.isac + ISAC_ISTA); -Start_ISAC: - if (val) - isac_interrupt(cs, val); - val = readb(cs->hw.isurf.isar + ISAR_IRQBIT); - if ((val & ISAR_IRQSTA) && --cnt) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "ISAR IntStat after IntRoutine"); - goto Start_ISAR; - } - val = readb(cs->hw.isurf.isac + ISAC_ISTA); - if (val && --cnt) { - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "ISAC IntStat after IntRoutine"); - goto Start_ISAC; - } - if (!cnt) - printk(KERN_WARNING "ISurf IRQ LOOP\n"); - - writeb(0, cs->hw.isurf.isar + ISAR_IRQBIT); mb(); - writeb(0xFF, cs->hw.isurf.isac + ISAC_MASK); mb(); - writeb(0, cs->hw.isurf.isac + ISAC_MASK); mb(); - writeb(ISAR_IRQMSK, cs->hw.isurf.isar + ISAR_IRQBIT); mb(); - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -static void -release_io_isurf(struct IsdnCardState *cs) -{ - release_region(cs->hw.isurf.reset, 1); - iounmap(cs->hw.isurf.isar); - release_mem_region(cs->hw.isurf.phymem, ISURF_IOMEM_SIZE); -} - -static void -reset_isurf(struct IsdnCardState *cs, u_char chips) -{ - printk(KERN_INFO "ISurf: resetting card\n"); - - byteout(cs->hw.isurf.reset, chips); /* Reset On */ - mdelay(10); - byteout(cs->hw.isurf.reset, ISURF_ISAR_EA); /* Reset Off */ - mdelay(10); -} - -static int -ISurf_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - u_long flags; - - switch (mt) { - case CARD_RESET: - spin_lock_irqsave(&cs->lock, flags); - reset_isurf(cs, ISURF_RESET); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_RELEASE: - release_io_isurf(cs); - return (0); - case CARD_INIT: - spin_lock_irqsave(&cs->lock, flags); - reset_isurf(cs, ISURF_RESET); - clear_pending_isac_ints(cs); - writeb(0, cs->hw.isurf.isar + ISAR_IRQBIT); mb(); - initisac(cs); - initisar(cs); - /* Reenable ISAC IRQ */ - cs->writeisac(cs, ISAC_MASK, 0); - /* RESET Receiver and Transmitter */ - cs->writeisac(cs, ISAC_CMDR, 0x41); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_TEST: - return (0); - } - return (0); -} - -static int -isurf_auxcmd(struct IsdnCardState *cs, isdn_ctrl *ic) { - int ret; - u_long flags; - - if ((ic->command == ISDN_CMD_IOCTL) && (ic->arg == 9)) { - ret = isar_auxcmd(cs, ic); - spin_lock_irqsave(&cs->lock, flags); - if (!ret) { - reset_isurf(cs, ISURF_ISAR_EA | ISURF_ISAC_RESET | - ISURF_ARCOFI_RESET); - initisac(cs); - cs->writeisac(cs, ISAC_MASK, 0); - cs->writeisac(cs, ISAC_CMDR, 0x41); - } - spin_unlock_irqrestore(&cs->lock, flags); - return (ret); - } - return (isar_auxcmd(cs, ic)); -} - -#ifdef __ISAPNP__ -static struct pnp_card *pnp_c = NULL; -#endif - -int setup_isurf(struct IsdnCard *card) -{ - int ver; - struct IsdnCardState *cs = card->cs; - char tmp[64]; - - strcpy(tmp, ISurf_revision); - printk(KERN_INFO "HiSax: ISurf driver Rev. %s\n", HiSax_getrev(tmp)); - - if (cs->typ != ISDN_CTYPE_ISURF) - return (0); - if (card->para[1] && card->para[2]) { - cs->hw.isurf.reset = card->para[1]; - cs->hw.isurf.phymem = card->para[2]; - cs->irq = card->para[0]; - } else { -#ifdef __ISAPNP__ - if (isapnp_present()) { - struct pnp_dev *pnp_d = NULL; - int err; - - cs->subtyp = 0; - if ((pnp_c = pnp_find_card( - ISAPNP_VENDOR('S', 'I', 'E'), - ISAPNP_FUNCTION(0x0010), pnp_c))) { - if (!(pnp_d = pnp_find_dev(pnp_c, - ISAPNP_VENDOR('S', 'I', 'E'), - ISAPNP_FUNCTION(0x0010), pnp_d))) { - printk(KERN_ERR "ISurfPnP: PnP error card found, no device\n"); - return (0); - } - pnp_disable_dev(pnp_d); - err = pnp_activate_dev(pnp_d); - if (err < 0) { - pr_warn("%s: pnp_activate_dev ret=%d\n", - __func__, err); - return 0; - } - cs->hw.isurf.reset = pnp_port_start(pnp_d, 0); - cs->hw.isurf.phymem = pnp_mem_start(pnp_d, 1); - cs->irq = pnp_irq(pnp_d, 0); - if (cs->irq == -1 || !cs->hw.isurf.reset || !cs->hw.isurf.phymem) { - printk(KERN_ERR "ISurfPnP:some resources are missing %d/%x/%lx\n", - cs->irq, cs->hw.isurf.reset, cs->hw.isurf.phymem); - pnp_disable_dev(pnp_d); - return (0); - } - } else { - printk(KERN_INFO "ISurfPnP: no ISAPnP card found\n"); - return (0); - } - } else { - printk(KERN_INFO "ISurfPnP: no ISAPnP bus found\n"); - return (0); - } -#else - printk(KERN_WARNING "HiSax: Siemens I-Surf port/mem not set\n"); - return (0); -#endif - } - if (!request_region(cs->hw.isurf.reset, 1, "isurf isdn")) { - printk(KERN_WARNING - "HiSax: Siemens I-Surf config port %x already in use\n", - cs->hw.isurf.reset); - return (0); - } - if (!request_region(cs->hw.isurf.phymem, ISURF_IOMEM_SIZE, "isurf iomem")) { - printk(KERN_WARNING "HiSax: Siemens I-Surf memory region " - "%lx-%lx already in use\n", - cs->hw.isurf.phymem, - cs->hw.isurf.phymem + ISURF_IOMEM_SIZE); - release_region(cs->hw.isurf.reset, 1); - return (0); - } - cs->hw.isurf.isar = ioremap(cs->hw.isurf.phymem, ISURF_IOMEM_SIZE); - cs->hw.isurf.isac = cs->hw.isurf.isar + ISURF_ISAC_OFFSET; - printk(KERN_INFO - "ISurf: defined at 0x%x 0x%lx IRQ %d\n", - cs->hw.isurf.reset, - cs->hw.isurf.phymem, - cs->irq); - - setup_isac(cs); - cs->cardmsg = &ISurf_card_msg; - cs->irq_func = &isurf_interrupt; - cs->auxcmd = &isurf_auxcmd; - cs->readisac = &ReadISAC; - cs->writeisac = &WriteISAC; - cs->readisacfifo = &ReadISACfifo; - cs->writeisacfifo = &WriteISACfifo; - cs->bcs[0].hw.isar.reg = &cs->hw.isurf.isar_r; - cs->bcs[1].hw.isar.reg = &cs->hw.isurf.isar_r; - test_and_set_bit(HW_ISAR, &cs->HW_Flags); - ISACVersion(cs, "ISurf:"); - cs->BC_Read_Reg = &ReadISAR; - cs->BC_Write_Reg = &WriteISAR; - cs->BC_Send_Data = &isar_fill_fifo; - ver = ISARVersion(cs, "ISurf:"); - if (ver < 0) { - printk(KERN_WARNING - "ISurf: wrong ISAR version (ret = %d)\n", ver); - release_io_isurf(cs); - return (0); - } - return (1); -} diff --git a/drivers/isdn/hisax/ix1_micro.c b/drivers/isdn/hisax/ix1_micro.c deleted file mode 100644 index bfb79f3f0a49..000000000000 --- a/drivers/isdn/hisax/ix1_micro.c +++ /dev/null @@ -1,316 +0,0 @@ -/* $Id: ix1_micro.c,v 2.12.2.4 2004/01/13 23:48:39 keil Exp $ - * - * low level stuff for ITK ix1-micro Rev.2 isdn cards - * derived from the original file teles3.c from Karsten Keil - * - * Author Klaus-Peter Nischke - * Copyright by Klaus-Peter Nischke, ITK AG - * <klaus@nischke.do.eunet.de> - * by Karsten Keil <keil@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * Klaus-Peter Nischke - * Deusener Str. 287 - * 44369 Dortmund - * Germany - */ - -#include <linux/init.h> -#include <linux/isapnp.h> -#include "hisax.h" -#include "isac.h" -#include "hscx.h" -#include "isdnl1.h" - -static const char *ix1_revision = "$Revision: 2.12.2.4 $"; - -#define byteout(addr, val) outb(val, addr) -#define bytein(addr) inb(addr) - -#define SPECIAL_PORT_OFFSET 3 - -#define ISAC_COMMAND_OFFSET 2 -#define ISAC_DATA_OFFSET 0 -#define HSCX_COMMAND_OFFSET 2 -#define HSCX_DATA_OFFSET 1 - -#define TIMEOUT 50 - -static inline u_char -readreg(unsigned int ale, unsigned int adr, u_char off) -{ - register u_char ret; - - byteout(ale, off); - ret = bytein(adr); - return (ret); -} - -static inline void -readfifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size) -{ - byteout(ale, off); - insb(adr, data, size); -} - - -static inline void -writereg(unsigned int ale, unsigned int adr, u_char off, u_char data) -{ - byteout(ale, off); - byteout(adr, data); -} - -static inline void -writefifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size) -{ - byteout(ale, off); - outsb(adr, data, size); -} - -/* Interface functions */ - -static u_char -ReadISAC(struct IsdnCardState *cs, u_char offset) -{ - return (readreg(cs->hw.ix1.isac_ale, cs->hw.ix1.isac, offset)); -} - -static void -WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value) -{ - writereg(cs->hw.ix1.isac_ale, cs->hw.ix1.isac, offset, value); -} - -static void -ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - readfifo(cs->hw.ix1.isac_ale, cs->hw.ix1.isac, 0, data, size); -} - -static void -WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - writefifo(cs->hw.ix1.isac_ale, cs->hw.ix1.isac, 0, data, size); -} - -static u_char -ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset) -{ - return (readreg(cs->hw.ix1.hscx_ale, - cs->hw.ix1.hscx, offset + (hscx ? 0x40 : 0))); -} - -static void -WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) -{ - writereg(cs->hw.ix1.hscx_ale, - cs->hw.ix1.hscx, offset + (hscx ? 0x40 : 0), value); -} - -#define READHSCX(cs, nr, reg) readreg(cs->hw.ix1.hscx_ale, \ - cs->hw.ix1.hscx, reg + (nr ? 0x40 : 0)) -#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.ix1.hscx_ale, \ - cs->hw.ix1.hscx, reg + (nr ? 0x40 : 0), data) - -#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.ix1.hscx_ale, \ - cs->hw.ix1.hscx, (nr ? 0x40 : 0), ptr, cnt) - -#define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.ix1.hscx_ale, \ - cs->hw.ix1.hscx, (nr ? 0x40 : 0), ptr, cnt) - -#include "hscx_irq.c" - -static irqreturn_t -ix1micro_interrupt(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - u_char val; - u_long flags; - - spin_lock_irqsave(&cs->lock, flags); - val = readreg(cs->hw.ix1.hscx_ale, cs->hw.ix1.hscx, HSCX_ISTA + 0x40); -Start_HSCX: - if (val) - hscx_int_main(cs, val); - val = readreg(cs->hw.ix1.isac_ale, cs->hw.ix1.isac, ISAC_ISTA); -Start_ISAC: - if (val) - isac_interrupt(cs, val); - val = readreg(cs->hw.ix1.hscx_ale, cs->hw.ix1.hscx, HSCX_ISTA + 0x40); - if (val) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "HSCX IntStat after IntRoutine"); - goto Start_HSCX; - } - val = readreg(cs->hw.ix1.isac_ale, cs->hw.ix1.isac, ISAC_ISTA); - if (val) { - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "ISAC IntStat after IntRoutine"); - goto Start_ISAC; - } - writereg(cs->hw.ix1.hscx_ale, cs->hw.ix1.hscx, HSCX_MASK, 0xFF); - writereg(cs->hw.ix1.hscx_ale, cs->hw.ix1.hscx, HSCX_MASK + 0x40, 0xFF); - writereg(cs->hw.ix1.isac_ale, cs->hw.ix1.isac, ISAC_MASK, 0xFF); - writereg(cs->hw.ix1.isac_ale, cs->hw.ix1.isac, ISAC_MASK, 0); - writereg(cs->hw.ix1.hscx_ale, cs->hw.ix1.hscx, HSCX_MASK, 0); - writereg(cs->hw.ix1.hscx_ale, cs->hw.ix1.hscx, HSCX_MASK + 0x40, 0); - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -static void -release_io_ix1micro(struct IsdnCardState *cs) -{ - if (cs->hw.ix1.cfg_reg) - release_region(cs->hw.ix1.cfg_reg, 4); -} - -static void -ix1_reset(struct IsdnCardState *cs) -{ - int cnt; - - /* reset isac */ - cnt = 3 * (HZ / 10) + 1; - while (cnt--) { - byteout(cs->hw.ix1.cfg_reg + SPECIAL_PORT_OFFSET, 1); - HZDELAY(1); /* wait >=10 ms */ - } - byteout(cs->hw.ix1.cfg_reg + SPECIAL_PORT_OFFSET, 0); -} - -static int -ix1_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - u_long flags; - - switch (mt) { - case CARD_RESET: - spin_lock_irqsave(&cs->lock, flags); - ix1_reset(cs); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_RELEASE: - release_io_ix1micro(cs); - return (0); - case CARD_INIT: - spin_lock_irqsave(&cs->lock, flags); - ix1_reset(cs); - inithscxisac(cs, 3); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_TEST: - return (0); - } - return (0); -} - -#ifdef __ISAPNP__ -static struct isapnp_device_id itk_ids[] = { - { ISAPNP_VENDOR('I', 'T', 'K'), ISAPNP_FUNCTION(0x25), - ISAPNP_VENDOR('I', 'T', 'K'), ISAPNP_FUNCTION(0x25), - (unsigned long) "ITK micro 2" }, - { ISAPNP_VENDOR('I', 'T', 'K'), ISAPNP_FUNCTION(0x29), - ISAPNP_VENDOR('I', 'T', 'K'), ISAPNP_FUNCTION(0x29), - (unsigned long) "ITK micro 2." }, - { 0, } -}; - -static struct isapnp_device_id *ipid = &itk_ids[0]; -static struct pnp_card *pnp_c = NULL; -#endif - - -int setup_ix1micro(struct IsdnCard *card) -{ - struct IsdnCardState *cs = card->cs; - char tmp[64]; - - strcpy(tmp, ix1_revision); - printk(KERN_INFO "HiSax: ITK IX1 driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_IX1MICROR2) - return (0); - -#ifdef __ISAPNP__ - if (!card->para[1] && isapnp_present()) { - struct pnp_dev *pnp_d; - while (ipid->card_vendor) { - if ((pnp_c = pnp_find_card(ipid->card_vendor, - ipid->card_device, pnp_c))) { - pnp_d = NULL; - if ((pnp_d = pnp_find_dev(pnp_c, - ipid->vendor, ipid->function, pnp_d))) { - int err; - - printk(KERN_INFO "HiSax: %s detected\n", - (char *)ipid->driver_data); - pnp_disable_dev(pnp_d); - err = pnp_activate_dev(pnp_d); - if (err < 0) { - printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n", - __func__, err); - return (0); - } - card->para[1] = pnp_port_start(pnp_d, 0); - card->para[0] = pnp_irq(pnp_d, 0); - if (card->para[0] == -1 || !card->para[1]) { - printk(KERN_ERR "ITK PnP:some resources are missing %ld/%lx\n", - card->para[0], card->para[1]); - pnp_disable_dev(pnp_d); - return (0); - } - break; - } else { - printk(KERN_ERR "ITK PnP: PnP error card found, no device\n"); - } - } - ipid++; - pnp_c = NULL; - } - if (!ipid->card_vendor) { - printk(KERN_INFO "ITK PnP: no ISAPnP card found\n"); - return (0); - } - } -#endif - /* IO-Ports */ - cs->hw.ix1.isac_ale = card->para[1] + ISAC_COMMAND_OFFSET; - cs->hw.ix1.hscx_ale = card->para[1] + HSCX_COMMAND_OFFSET; - cs->hw.ix1.isac = card->para[1] + ISAC_DATA_OFFSET; - cs->hw.ix1.hscx = card->para[1] + HSCX_DATA_OFFSET; - cs->hw.ix1.cfg_reg = card->para[1]; - cs->irq = card->para[0]; - if (cs->hw.ix1.cfg_reg) { - if (!request_region(cs->hw.ix1.cfg_reg, 4, "ix1micro cfg")) { - printk(KERN_WARNING - "HiSax: ITK ix1-micro Rev.2 config port " - "%x-%x already in use\n", - cs->hw.ix1.cfg_reg, - cs->hw.ix1.cfg_reg + 4); - return (0); - } - } - printk(KERN_INFO "HiSax: ITK ix1-micro Rev.2 config irq:%d io:0x%X\n", - cs->irq, cs->hw.ix1.cfg_reg); - setup_isac(cs); - cs->readisac = &ReadISAC; - cs->writeisac = &WriteISAC; - cs->readisacfifo = &ReadISACfifo; - cs->writeisacfifo = &WriteISACfifo; - cs->BC_Read_Reg = &ReadHSCX; - cs->BC_Write_Reg = &WriteHSCX; - cs->BC_Send_Data = &hscx_fill_fifo; - cs->cardmsg = &ix1_card_msg; - cs->irq_func = &ix1micro_interrupt; - ISACVersion(cs, "ix1-Micro:"); - if (HscxVersion(cs, "ix1-Micro:")) { - printk(KERN_WARNING - "ix1-Micro: wrong HSCX versions check IO address\n"); - release_io_ix1micro(cs); - return (0); - } - return (1); -} diff --git a/drivers/isdn/hisax/jade.c b/drivers/isdn/hisax/jade.c deleted file mode 100644 index e2ae7871a209..000000000000 --- a/drivers/isdn/hisax/jade.c +++ /dev/null @@ -1,305 +0,0 @@ -/* $Id: jade.c,v 1.9.2.4 2004/01/14 16:04:48 keil Exp $ - * - * JADE stuff (derived from original hscx.c) - * - * Author Roland Klabunde - * Copyright by Roland Klabunde <R.Klabunde@Berkom.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - - -#include <linux/init.h> -#include "hisax.h" -#include "hscx.h" -#include "jade.h" -#include "isdnl1.h" -#include <linux/interrupt.h> -#include <linux/slab.h> - - -int -JadeVersion(struct IsdnCardState *cs, char *s) -{ - int ver; - int to = 50; - cs->BC_Write_Reg(cs, -1, 0x50, 0x19); - while (to) { - udelay(1); - ver = cs->BC_Read_Reg(cs, -1, 0x60); - to--; - if (ver) - break; - if (!to) { - printk(KERN_INFO "%s JADE version not obtainable\n", s); - return (0); - } - } - /* Wait for the JADE */ - udelay(10); - /* Read version */ - ver = cs->BC_Read_Reg(cs, -1, 0x60); - printk(KERN_INFO "%s JADE version: %d\n", s, ver); - return (1); -} - -/* Write to indirect accessible jade register set */ -static void -jade_write_indirect(struct IsdnCardState *cs, u_char reg, u_char value) -{ - int to = 50; - u_char ret; - - /* Write the data */ - cs->BC_Write_Reg(cs, -1, COMM_JADE + 1, value); - /* Say JADE we wanna write indirect reg 'reg' */ - cs->BC_Write_Reg(cs, -1, COMM_JADE, reg); - to = 50; - /* Wait for RDY goes high */ - while (to) { - udelay(1); - ret = cs->BC_Read_Reg(cs, -1, COMM_JADE); - to--; - if (ret & 1) - /* Got acknowledge */ - break; - if (!to) { - printk(KERN_INFO "Can not see ready bit from JADE DSP (reg=0x%X, value=0x%X)\n", reg, value); - return; - } - } -} - - - -static void -modejade(struct BCState *bcs, int mode, int bc) -{ - struct IsdnCardState *cs = bcs->cs; - int jade = bcs->hw.hscx.hscx; - - if (cs->debug & L1_DEB_HSCX) { - debugl1(cs, "jade %c mode %d ichan %d", 'A' + jade, mode, bc); - } - bcs->mode = mode; - bcs->channel = bc; - - cs->BC_Write_Reg(cs, jade, jade_HDLC_MODE, (mode == L1_MODE_TRANS ? jadeMODE_TMO : 0x00)); - cs->BC_Write_Reg(cs, jade, jade_HDLC_CCR0, (jadeCCR0_PU | jadeCCR0_ITF)); - cs->BC_Write_Reg(cs, jade, jade_HDLC_CCR1, 0x00); - - jade_write_indirect(cs, jade_HDLC1SERRXPATH, 0x08); - jade_write_indirect(cs, jade_HDLC2SERRXPATH, 0x08); - jade_write_indirect(cs, jade_HDLC1SERTXPATH, 0x00); - jade_write_indirect(cs, jade_HDLC2SERTXPATH, 0x00); - - cs->BC_Write_Reg(cs, jade, jade_HDLC_XCCR, 0x07); - cs->BC_Write_Reg(cs, jade, jade_HDLC_RCCR, 0x07); - - if (bc == 0) { - cs->BC_Write_Reg(cs, jade, jade_HDLC_TSAX, 0x00); - cs->BC_Write_Reg(cs, jade, jade_HDLC_TSAR, 0x00); - } else { - cs->BC_Write_Reg(cs, jade, jade_HDLC_TSAX, 0x04); - cs->BC_Write_Reg(cs, jade, jade_HDLC_TSAR, 0x04); - } - switch (mode) { - case (L1_MODE_NULL): - cs->BC_Write_Reg(cs, jade, jade_HDLC_MODE, jadeMODE_TMO); - break; - case (L1_MODE_TRANS): - cs->BC_Write_Reg(cs, jade, jade_HDLC_MODE, (jadeMODE_TMO | jadeMODE_RAC | jadeMODE_XAC)); - break; - case (L1_MODE_HDLC): - cs->BC_Write_Reg(cs, jade, jade_HDLC_MODE, (jadeMODE_RAC | jadeMODE_XAC)); - break; - } - if (mode) { - cs->BC_Write_Reg(cs, jade, jade_HDLC_RCMD, (jadeRCMD_RRES | jadeRCMD_RMC)); - cs->BC_Write_Reg(cs, jade, jade_HDLC_XCMD, jadeXCMD_XRES); - /* Unmask ints */ - cs->BC_Write_Reg(cs, jade, jade_HDLC_IMR, 0xF8); - } - else - /* Mask ints */ - cs->BC_Write_Reg(cs, jade, jade_HDLC_IMR, 0x00); -} - -static void -jade_l2l1(struct PStack *st, int pr, void *arg) -{ - struct BCState *bcs = st->l1.bcs; - struct sk_buff *skb = arg; - u_long flags; - - switch (pr) { - case (PH_DATA | REQUEST): - spin_lock_irqsave(&bcs->cs->lock, flags); - if (bcs->tx_skb) { - skb_queue_tail(&bcs->squeue, skb); - } else { - bcs->tx_skb = skb; - test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); - bcs->hw.hscx.count = 0; - bcs->cs->BC_Send_Data(bcs); - } - spin_unlock_irqrestore(&bcs->cs->lock, flags); - break; - case (PH_PULL | INDICATION): - spin_lock_irqsave(&bcs->cs->lock, flags); - if (bcs->tx_skb) { - printk(KERN_WARNING "jade_l2l1: this shouldn't happen\n"); - } else { - test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); - bcs->tx_skb = skb; - bcs->hw.hscx.count = 0; - bcs->cs->BC_Send_Data(bcs); - } - spin_unlock_irqrestore(&bcs->cs->lock, flags); - break; - case (PH_PULL | REQUEST): - if (!bcs->tx_skb) { - test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); - } else - test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - break; - case (PH_ACTIVATE | REQUEST): - spin_lock_irqsave(&bcs->cs->lock, flags); - test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag); - modejade(bcs, st->l1.mode, st->l1.bc); - spin_unlock_irqrestore(&bcs->cs->lock, flags); - l1_msg_b(st, pr, arg); - break; - case (PH_DEACTIVATE | REQUEST): - l1_msg_b(st, pr, arg); - break; - case (PH_DEACTIVATE | CONFIRM): - spin_lock_irqsave(&bcs->cs->lock, flags); - test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag); - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - modejade(bcs, 0, st->l1.bc); - spin_unlock_irqrestore(&bcs->cs->lock, flags); - st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL); - break; - } -} - -static void -close_jadestate(struct BCState *bcs) -{ - modejade(bcs, 0, bcs->channel); - if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) { - kfree(bcs->hw.hscx.rcvbuf); - bcs->hw.hscx.rcvbuf = NULL; - kfree(bcs->blog); - bcs->blog = NULL; - skb_queue_purge(&bcs->rqueue); - skb_queue_purge(&bcs->squeue); - if (bcs->tx_skb) { - dev_kfree_skb_any(bcs->tx_skb); - bcs->tx_skb = NULL; - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - } - } -} - -static int -open_jadestate(struct IsdnCardState *cs, struct BCState *bcs) -{ - if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { - if (!(bcs->hw.hscx.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) { - printk(KERN_WARNING - "HiSax: No memory for hscx.rcvbuf\n"); - test_and_clear_bit(BC_FLG_INIT, &bcs->Flag); - return (1); - } - if (!(bcs->blog = kmalloc(MAX_BLOG_SPACE, GFP_ATOMIC))) { - printk(KERN_WARNING - "HiSax: No memory for bcs->blog\n"); - test_and_clear_bit(BC_FLG_INIT, &bcs->Flag); - kfree(bcs->hw.hscx.rcvbuf); - bcs->hw.hscx.rcvbuf = NULL; - return (2); - } - skb_queue_head_init(&bcs->rqueue); - skb_queue_head_init(&bcs->squeue); - } - bcs->tx_skb = NULL; - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - bcs->event = 0; - bcs->hw.hscx.rcvidx = 0; - bcs->tx_cnt = 0; - return (0); -} - - -static int -setstack_jade(struct PStack *st, struct BCState *bcs) -{ - bcs->channel = st->l1.bc; - if (open_jadestate(st->l1.hardware, bcs)) - return (-1); - st->l1.bcs = bcs; - st->l2.l2l1 = jade_l2l1; - setstack_manager(st); - bcs->st = st; - setstack_l1_B(st); - return (0); -} - -void -clear_pending_jade_ints(struct IsdnCardState *cs) -{ - int val; - - cs->BC_Write_Reg(cs, 0, jade_HDLC_IMR, 0x00); - cs->BC_Write_Reg(cs, 1, jade_HDLC_IMR, 0x00); - - val = cs->BC_Read_Reg(cs, 1, jade_HDLC_ISR); - debugl1(cs, "jade B ISTA %x", val); - val = cs->BC_Read_Reg(cs, 0, jade_HDLC_ISR); - debugl1(cs, "jade A ISTA %x", val); - val = cs->BC_Read_Reg(cs, 1, jade_HDLC_STAR); - debugl1(cs, "jade B STAR %x", val); - val = cs->BC_Read_Reg(cs, 0, jade_HDLC_STAR); - debugl1(cs, "jade A STAR %x", val); - /* Unmask ints */ - cs->BC_Write_Reg(cs, 0, jade_HDLC_IMR, 0xF8); - cs->BC_Write_Reg(cs, 1, jade_HDLC_IMR, 0xF8); -} - -void -initjade(struct IsdnCardState *cs) -{ - cs->bcs[0].BC_SetStack = setstack_jade; - cs->bcs[1].BC_SetStack = setstack_jade; - cs->bcs[0].BC_Close = close_jadestate; - cs->bcs[1].BC_Close = close_jadestate; - cs->bcs[0].hw.hscx.hscx = 0; - cs->bcs[1].hw.hscx.hscx = 1; - - /* Stop DSP audio tx/rx */ - jade_write_indirect(cs, 0x11, 0x0f); - jade_write_indirect(cs, 0x17, 0x2f); - - /* Transparent Mode, RxTx inactive, No Test, No RFS/TFS */ - cs->BC_Write_Reg(cs, 0, jade_HDLC_MODE, jadeMODE_TMO); - cs->BC_Write_Reg(cs, 1, jade_HDLC_MODE, jadeMODE_TMO); - /* Power down, 1-Idle, RxTx least significant bit first */ - cs->BC_Write_Reg(cs, 0, jade_HDLC_CCR0, 0x00); - cs->BC_Write_Reg(cs, 1, jade_HDLC_CCR0, 0x00); - /* Mask all interrupts */ - cs->BC_Write_Reg(cs, 0, jade_HDLC_IMR, 0x00); - cs->BC_Write_Reg(cs, 1, jade_HDLC_IMR, 0x00); - /* Setup host access to hdlc controller */ - jade_write_indirect(cs, jade_HDLCCNTRACCESS, (jadeINDIRECT_HAH1 | jadeINDIRECT_HAH2)); - /* Unmask HDLC int (don't forget DSP int later on)*/ - cs->BC_Write_Reg(cs, -1, jade_INT, (jadeINT_HDLC1 | jadeINT_HDLC2)); - - /* once again TRANSPARENT */ - modejade(cs->bcs, 0, 0); - modejade(cs->bcs + 1, 0, 0); -} diff --git a/drivers/isdn/hisax/jade.h b/drivers/isdn/hisax/jade.h deleted file mode 100644 index 4b98096a5858..000000000000 --- a/drivers/isdn/hisax/jade.h +++ /dev/null @@ -1,134 +0,0 @@ -/* $Id: jade.h,v 1.5.2.3 2004/01/14 16:04:48 keil Exp $ - * - * JADE specific defines - * - * Author Roland Klabunde - * Copyright by Roland Klabunde <R.Klabunde@Berkom.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -/* All Registers original Siemens Spec */ -#ifndef __JADE_H__ -#define __JADE_H__ - -/* Special registers for access to indirect accessible JADE regs */ -#define DIRECT_IO_JADE 0x0000 /* Jade direct io access area */ -#define COMM_JADE 0x0040 /* Jade communication area */ - -/********************************************************************/ -/* JADE-HDLC registers */ -/********************************************************************/ -#define jade_HDLC_RFIFO 0x00 /* R */ -#define jade_HDLC_XFIFO 0x00 /* W */ - -#define jade_HDLC_STAR 0x20 /* R */ -#define jadeSTAR_XDOV 0x80 -#define jadeSTAR_XFW 0x40 /* Does not work*/ -#define jadeSTAR_XCEC 0x20 -#define jadeSTAR_RCEC 0x10 -#define jadeSTAR_BSY 0x08 -#define jadeSTAR_RNA 0x04 -#define jadeSTAR_STR 0x02 -#define jadeSTAR_STX 0x01 - -#define jade_HDLC_XCMD 0x20 /* W */ -#define jadeXCMD_XF 0x80 -#define jadeXCMD_XME 0x40 -#define jadeXCMD_XRES 0x20 -#define jadeXCMD_STX 0x01 - -#define jade_HDLC_RSTA 0x21 /* R */ -#define jadeRSTA_VFR 0x80 -#define jadeRSTA_RDO 0x40 -#define jadeRSTA_CRC 0x20 -#define jadeRSTA_RAB 0x10 -#define jadeRSTA_MASK 0xF0 - -#define jade_HDLC_MODE 0x22 /* RW*/ -#define jadeMODE_TMO 0x80 -#define jadeMODE_RAC 0x40 -#define jadeMODE_XAC 0x20 -#define jadeMODE_TLP 0x10 -#define jadeMODE_ERFS 0x02 -#define jadeMODE_ETFS 0x01 - -#define jade_HDLC_RBCH 0x24 /* R */ - -#define jade_HDLC_RBCL 0x25 /* R */ -#define jade_HDLC_RCMD 0x25 /* W */ -#define jadeRCMD_RMC 0x80 -#define jadeRCMD_RRES 0x40 -#define jadeRCMD_RMD 0x20 -#define jadeRCMD_STR 0x02 - -#define jade_HDLC_CCR0 0x26 /* RW*/ -#define jadeCCR0_PU 0x80 -#define jadeCCR0_ITF 0x40 -#define jadeCCR0_C32 0x20 -#define jadeCCR0_CRL 0x10 -#define jadeCCR0_RCRC 0x08 -#define jadeCCR0_XCRC 0x04 -#define jadeCCR0_RMSB 0x02 -#define jadeCCR0_XMSB 0x01 - -#define jade_HDLC_CCR1 0x27 /* RW*/ -#define jadeCCR1_RCS0 0x80 -#define jadeCCR1_RCONT 0x40 -#define jadeCCR1_RFDIS 0x20 -#define jadeCCR1_XCS0 0x10 -#define jadeCCR1_XCONT 0x08 -#define jadeCCR1_XFDIS 0x04 - -#define jade_HDLC_TSAR 0x28 /* RW*/ -#define jade_HDLC_TSAX 0x29 /* RW*/ -#define jade_HDLC_RCCR 0x2A /* RW*/ -#define jade_HDLC_XCCR 0x2B /* RW*/ - -#define jade_HDLC_ISR 0x2C /* R */ -#define jade_HDLC_IMR 0x2C /* W */ -#define jadeISR_RME 0x80 -#define jadeISR_RPF 0x40 -#define jadeISR_RFO 0x20 -#define jadeISR_XPR 0x10 -#define jadeISR_XDU 0x08 -#define jadeISR_ALLS 0x04 - -#define jade_INT 0x75 -#define jadeINT_HDLC1 0x02 -#define jadeINT_HDLC2 0x01 -#define jadeINT_DSP 0x04 -#define jade_INTR 0x70 - -/********************************************************************/ -/* Indirect accessible JADE registers of common interest */ -/********************************************************************/ -#define jade_CHIPVERSIONNR 0x00 /* Does not work*/ - -#define jade_HDLCCNTRACCESS 0x10 -#define jadeINDIRECT_HAH1 0x02 -#define jadeINDIRECT_HAH2 0x01 - -#define jade_HDLC1SERRXPATH 0x1D -#define jade_HDLC1SERTXPATH 0x1E -#define jade_HDLC2SERRXPATH 0x1F -#define jade_HDLC2SERTXPATH 0x20 -#define jadeINDIRECT_SLIN1 0x10 -#define jadeINDIRECT_SLIN0 0x08 -#define jadeINDIRECT_LMOD1 0x04 -#define jadeINDIRECT_LMOD0 0x02 -#define jadeINDIRECT_HHR 0x01 -#define jadeINDIRECT_HHX 0x01 - -#define jade_RXAUDIOCH1CFG 0x11 -#define jade_RXAUDIOCH2CFG 0x14 -#define jade_TXAUDIOCH1CFG 0x17 -#define jade_TXAUDIOCH2CFG 0x1A - -extern int JadeVersion(struct IsdnCardState *cs, char *s); -extern void clear_pending_jade_ints(struct IsdnCardState *cs); -extern void initjade(struct IsdnCardState *cs); - -#endif /* __JADE_H__ */ diff --git a/drivers/isdn/hisax/jade_irq.c b/drivers/isdn/hisax/jade_irq.c deleted file mode 100644 index a89e2df911c5..000000000000 --- a/drivers/isdn/hisax/jade_irq.c +++ /dev/null @@ -1,238 +0,0 @@ -/* $Id: jade_irq.c,v 1.7.2.4 2004/02/11 13:21:34 keil Exp $ - * - * Low level JADE IRQ stuff (derived from original hscx_irq.c) - * - * Author Roland Klabunde - * Copyright by Roland Klabunde <R.Klabunde@Berkom.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -static inline void -waitforCEC(struct IsdnCardState *cs, int jade, int reg) -{ - int to = 50; - int mask = (reg == jade_HDLC_XCMD ? jadeSTAR_XCEC : jadeSTAR_RCEC); - while ((READJADE(cs, jade, jade_HDLC_STAR) & mask) && to) { - udelay(1); - to--; - } - if (!to) - printk(KERN_WARNING "HiSax: waitforCEC (jade) timeout\n"); -} - - -static inline void -waitforXFW(struct IsdnCardState *cs, int jade) -{ - /* Does not work on older jade versions, don't care */ -} - -static inline void -WriteJADECMDR(struct IsdnCardState *cs, int jade, int reg, u_char data) -{ - waitforCEC(cs, jade, reg); - WRITEJADE(cs, jade, reg, data); -} - - - -static void -jade_empty_fifo(struct BCState *bcs, int count) -{ - u_char *ptr; - struct IsdnCardState *cs = bcs->cs; - - if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) - debugl1(cs, "jade_empty_fifo"); - - if (bcs->hw.hscx.rcvidx + count > HSCX_BUFMAX) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "jade_empty_fifo: incoming packet too large"); - WriteJADECMDR(cs, bcs->hw.hscx.hscx, jade_HDLC_RCMD, jadeRCMD_RMC); - bcs->hw.hscx.rcvidx = 0; - return; - } - ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx; - bcs->hw.hscx.rcvidx += count; - READJADEFIFO(cs, bcs->hw.hscx.hscx, ptr, count); - WriteJADECMDR(cs, bcs->hw.hscx.hscx, jade_HDLC_RCMD, jadeRCMD_RMC); - if (cs->debug & L1_DEB_HSCX_FIFO) { - char *t = bcs->blog; - - t += sprintf(t, "jade_empty_fifo %c cnt %d", - bcs->hw.hscx.hscx ? 'B' : 'A', count); - QuickHex(t, ptr, count); - debugl1(cs, "%s", bcs->blog); - } -} - -static void -jade_fill_fifo(struct BCState *bcs) -{ - struct IsdnCardState *cs = bcs->cs; - int more, count; - int fifo_size = 32; - u_char *ptr; - - if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) - debugl1(cs, "jade_fill_fifo"); - - if (!bcs->tx_skb) - return; - if (bcs->tx_skb->len <= 0) - return; - - more = (bcs->mode == L1_MODE_TRANS) ? 1 : 0; - if (bcs->tx_skb->len > fifo_size) { - more = !0; - count = fifo_size; - } else - count = bcs->tx_skb->len; - - waitforXFW(cs, bcs->hw.hscx.hscx); - ptr = bcs->tx_skb->data; - skb_pull(bcs->tx_skb, count); - bcs->tx_cnt -= count; - bcs->hw.hscx.count += count; - WRITEJADEFIFO(cs, bcs->hw.hscx.hscx, ptr, count); - WriteJADECMDR(cs, bcs->hw.hscx.hscx, jade_HDLC_XCMD, more ? jadeXCMD_XF : (jadeXCMD_XF | jadeXCMD_XME)); - if (cs->debug & L1_DEB_HSCX_FIFO) { - char *t = bcs->blog; - - t += sprintf(t, "jade_fill_fifo %c cnt %d", - bcs->hw.hscx.hscx ? 'B' : 'A', count); - QuickHex(t, ptr, count); - debugl1(cs, "%s", bcs->blog); - } -} - - -static void -jade_interrupt(struct IsdnCardState *cs, u_char val, u_char jade) -{ - u_char r; - struct BCState *bcs = cs->bcs + jade; - struct sk_buff *skb; - int fifo_size = 32; - int count; - int i_jade = (int) jade; /* To satisfy the compiler */ - - if (!test_bit(BC_FLG_INIT, &bcs->Flag)) - return; - - if (val & 0x80) { /* RME */ - r = READJADE(cs, i_jade, jade_HDLC_RSTA); - if ((r & 0xf0) != 0xa0) { - if (!(r & 0x80)) - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "JADE %s invalid frame", (jade ? "B" : "A")); - if ((r & 0x40) && bcs->mode) - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "JADE %c RDO mode=%d", 'A' + jade, bcs->mode); - if (!(r & 0x20)) - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "JADE %c CRC error", 'A' + jade); - WriteJADECMDR(cs, jade, jade_HDLC_RCMD, jadeRCMD_RMC); - } else { - count = READJADE(cs, i_jade, jade_HDLC_RBCL) & 0x1F; - if (count == 0) - count = fifo_size; - jade_empty_fifo(bcs, count); - if ((count = bcs->hw.hscx.rcvidx - 1) > 0) { - if (cs->debug & L1_DEB_HSCX_FIFO) - debugl1(cs, "HX Frame %d", count); - if (!(skb = dev_alloc_skb(count))) - printk(KERN_WARNING "JADE %s receive out of memory\n", (jade ? "B" : "A")); - else { - skb_put_data(skb, bcs->hw.hscx.rcvbuf, - count); - skb_queue_tail(&bcs->rqueue, skb); - } - } - } - bcs->hw.hscx.rcvidx = 0; - schedule_event(bcs, B_RCVBUFREADY); - } - if (val & 0x40) { /* RPF */ - jade_empty_fifo(bcs, fifo_size); - if (bcs->mode == L1_MODE_TRANS) { - /* receive audio data */ - if (!(skb = dev_alloc_skb(fifo_size))) - printk(KERN_WARNING "HiSax: receive out of memory\n"); - else { - skb_put_data(skb, bcs->hw.hscx.rcvbuf, - fifo_size); - skb_queue_tail(&bcs->rqueue, skb); - } - bcs->hw.hscx.rcvidx = 0; - schedule_event(bcs, B_RCVBUFREADY); - } - } - if (val & 0x10) { /* XPR */ - if (bcs->tx_skb) { - if (bcs->tx_skb->len) { - jade_fill_fifo(bcs); - return; - } else { - if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) && - (PACKET_NOACK != bcs->tx_skb->pkt_type)) { - u_long flags; - spin_lock_irqsave(&bcs->aclock, flags); - bcs->ackcnt += bcs->hw.hscx.count; - spin_unlock_irqrestore(&bcs->aclock, flags); - schedule_event(bcs, B_ACKPENDING); - } - dev_kfree_skb_irq(bcs->tx_skb); - bcs->hw.hscx.count = 0; - bcs->tx_skb = NULL; - } - } - if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) { - bcs->hw.hscx.count = 0; - test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); - jade_fill_fifo(bcs); - } else { - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - schedule_event(bcs, B_XMTBUFREADY); - } - } -} - -static inline void -jade_int_main(struct IsdnCardState *cs, u_char val, int jade) -{ - struct BCState *bcs; - bcs = cs->bcs + jade; - - if (val & jadeISR_RFO) { - /* handled with RDO */ - val &= ~jadeISR_RFO; - } - if (val & jadeISR_XDU) { - /* relevant in HDLC mode only */ - /* don't reset XPR here */ - if (bcs->mode == 1) - jade_fill_fifo(bcs); - else { - /* Here we lost an TX interrupt, so - * restart transmitting the whole frame. - */ - if (bcs->tx_skb) { - skb_push(bcs->tx_skb, bcs->hw.hscx.count); - bcs->tx_cnt += bcs->hw.hscx.count; - bcs->hw.hscx.count = 0; - } - WriteJADECMDR(cs, bcs->hw.hscx.hscx, jade_HDLC_XCMD, jadeXCMD_XRES); - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "JADE %c EXIR %x Lost TX", 'A' + jade, val); - } - } - if (val & (jadeISR_RME | jadeISR_RPF | jadeISR_XPR)) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "JADE %c interrupt %x", 'A' + jade, val); - jade_interrupt(cs, val, jade); - } -} diff --git a/drivers/isdn/hisax/l3_1tr6.c b/drivers/isdn/hisax/l3_1tr6.c deleted file mode 100644 index 98f60d1523f4..000000000000 --- a/drivers/isdn/hisax/l3_1tr6.c +++ /dev/null @@ -1,932 +0,0 @@ -/* $Id: l3_1tr6.c,v 2.15.2.3 2004/01/13 14:31:25 keil Exp $ - * - * German 1TR6 D-channel protocol - * - * Author Karsten Keil - * Copyright by Karsten Keil <keil@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * For changes and modifications please read - * Documentation/isdn/HiSax.cert - * - */ - -#include "hisax.h" -#include "l3_1tr6.h" -#include "isdnl3.h" -#include <linux/ctype.h> - -extern char *HiSax_getrev(const char *revision); -static const char *l3_1tr6_revision = "$Revision: 2.15.2.3 $"; - -#define MsgHead(ptr, cref, mty, dis) \ - *ptr++ = dis; \ - *ptr++ = 0x1; \ - *ptr++ = cref ^ 0x80; \ - *ptr++ = mty - -static void -l3_1TR6_message(struct l3_process *pc, u_char mt, u_char pd) -{ - struct sk_buff *skb; - u_char *p; - - if (!(skb = l3_alloc_skb(4))) - return; - p = skb_put(skb, 4); - MsgHead(p, pc->callref, mt, pd); - l3_msg(pc->st, DL_DATA | REQUEST, skb); -} - -static void -l3_1tr6_release_req(struct l3_process *pc, u_char pr, void *arg) -{ - StopAllL3Timer(pc); - newl3state(pc, 19); - l3_1TR6_message(pc, MT_N1_REL, PROTO_DIS_N1); - L3AddTimer(&pc->timer, T308, CC_T308_1); -} - -static void -l3_1tr6_invalid(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - - dev_kfree_skb(skb); - l3_1tr6_release_req(pc, 0, NULL); -} - -static void -l3_1tr6_error(struct l3_process *pc, u_char *msg, struct sk_buff *skb) -{ - dev_kfree_skb(skb); - if (pc->st->l3.debug & L3_DEB_WARN) - l3_debug(pc->st, "%s", msg); - l3_1tr6_release_req(pc, 0, NULL); -} - -static void -l3_1tr6_setup_req(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb; - u_char tmp[128]; - u_char *p = tmp; - u_char *teln; - u_char *eaz; - u_char channel = 0; - int l; - - MsgHead(p, pc->callref, MT_N1_SETUP, PROTO_DIS_N1); - teln = pc->para.setup.phone; - pc->para.spv = 0; - if (!isdigit(*teln)) { - switch (0x5f & *teln) { - case 'S': - pc->para.spv = 1; - break; - case 'C': - channel = 0x08; - /* fall through */ - case 'P': - channel |= 0x80; - teln++; - if (*teln == '1') - channel |= 0x01; - else - channel |= 0x02; - break; - default: - if (pc->st->l3.debug & L3_DEB_WARN) - l3_debug(pc->st, "Wrong MSN Code"); - break; - } - teln++; - } - if (channel) { - *p++ = 0x18; /* channel indicator */ - *p++ = 1; - *p++ = channel; - } - if (pc->para.spv) { /* SPV ? */ - /* NSF SPV */ - *p++ = WE0_netSpecFac; - *p++ = 4; /* Laenge */ - *p++ = 0; - *p++ = FAC_SPV; /* SPV */ - *p++ = pc->para.setup.si1; /* 0 for all Services */ - *p++ = pc->para.setup.si2; /* 0 for all Services */ - *p++ = WE0_netSpecFac; - *p++ = 4; /* Laenge */ - *p++ = 0; - *p++ = FAC_Activate; /* aktiviere SPV (default) */ - *p++ = pc->para.setup.si1; /* 0 for all Services */ - *p++ = pc->para.setup.si2; /* 0 for all Services */ - } - eaz = pc->para.setup.eazmsn; - if (*eaz) { - *p++ = WE0_origAddr; - *p++ = strlen(eaz) + 1; - /* Classify as AnyPref. */ - *p++ = 0x81; /* Ext = '1'B, Type = '000'B, Plan = '0001'B. */ - while (*eaz) - *p++ = *eaz++ & 0x7f; - } - *p++ = WE0_destAddr; - *p++ = strlen(teln) + 1; - /* Classify as AnyPref. */ - *p++ = 0x81; /* Ext = '1'B, Type = '000'B, Plan = '0001'B. */ - while (*teln) - *p++ = *teln++ & 0x7f; - - *p++ = WE_Shift_F6; - /* Codesatz 6 fuer Service */ - *p++ = WE6_serviceInd; - *p++ = 2; /* len=2 info,info2 */ - *p++ = pc->para.setup.si1; - *p++ = pc->para.setup.si2; - - l = p - tmp; - if (!(skb = l3_alloc_skb(l))) - return; - skb_put_data(skb, tmp, l); - L3DelTimer(&pc->timer); - L3AddTimer(&pc->timer, T303, CC_T303); - newl3state(pc, 1); - l3_msg(pc->st, DL_DATA | REQUEST, skb); -} - -static void -l3_1tr6_setup(struct l3_process *pc, u_char pr, void *arg) -{ - u_char *p; - int bcfound = 0; - struct sk_buff *skb = arg; - - /* Channel Identification */ - p = findie(skb->data, skb->len, WE0_chanID, 0); - if (p) { - if (p[1] != 1) { - l3_1tr6_error(pc, "setup wrong chanID len", skb); - return; - } - if ((p[2] & 0xf4) != 0x80) { - l3_1tr6_error(pc, "setup wrong WE0_chanID", skb); - return; - } - if ((pc->para.bchannel = p[2] & 0x3)) - bcfound++; - } else { - l3_1tr6_error(pc, "missing setup chanID", skb); - return; - } - - p = skb->data; - if ((p = findie(p, skb->len, WE6_serviceInd, 6))) { - pc->para.setup.si1 = p[2]; - pc->para.setup.si2 = p[3]; - } else { - l3_1tr6_error(pc, "missing setup SI", skb); - return; - } - - p = skb->data; - if ((p = findie(p, skb->len, WE0_destAddr, 0))) - iecpy(pc->para.setup.eazmsn, p, 1); - else - pc->para.setup.eazmsn[0] = 0; - - p = skb->data; - if ((p = findie(p, skb->len, WE0_origAddr, 0))) { - iecpy(pc->para.setup.phone, p, 1); - } else - pc->para.setup.phone[0] = 0; - - p = skb->data; - pc->para.spv = 0; - if ((p = findie(p, skb->len, WE0_netSpecFac, 0))) { - if ((FAC_SPV == p[3]) || (FAC_Activate == p[3])) - pc->para.spv = 1; - } - dev_kfree_skb(skb); - - /* Signal all services, linklevel takes care of Service-Indicator */ - if (bcfound) { - if ((pc->para.setup.si1 != 7) && (pc->st->l3.debug & L3_DEB_WARN)) { - l3_debug(pc->st, "non-digital call: %s -> %s", - pc->para.setup.phone, - pc->para.setup.eazmsn); - } - newl3state(pc, 6); - pc->st->l3.l3l4(pc->st, CC_SETUP | INDICATION, pc); - } else - release_l3_process(pc); -} - -static void -l3_1tr6_setup_ack(struct l3_process *pc, u_char pr, void *arg) -{ - u_char *p; - struct sk_buff *skb = arg; - - L3DelTimer(&pc->timer); - p = skb->data; - newl3state(pc, 2); - if ((p = findie(p, skb->len, WE0_chanID, 0))) { - if (p[1] != 1) { - l3_1tr6_error(pc, "setup_ack wrong chanID len", skb); - return; - } - if ((p[2] & 0xf4) != 0x80) { - l3_1tr6_error(pc, "setup_ack wrong WE0_chanID", skb); - return; - } - pc->para.bchannel = p[2] & 0x3; - } else { - l3_1tr6_error(pc, "missing setup_ack WE0_chanID", skb); - return; - } - dev_kfree_skb(skb); - L3AddTimer(&pc->timer, T304, CC_T304); - pc->st->l3.l3l4(pc->st, CC_MORE_INFO | INDICATION, pc); -} - -static void -l3_1tr6_call_sent(struct l3_process *pc, u_char pr, void *arg) -{ - u_char *p; - struct sk_buff *skb = arg; - - L3DelTimer(&pc->timer); - p = skb->data; - if ((p = findie(p, skb->len, WE0_chanID, 0))) { - if (p[1] != 1) { - l3_1tr6_error(pc, "call sent wrong chanID len", skb); - return; - } - if ((p[2] & 0xf4) != 0x80) { - l3_1tr6_error(pc, "call sent wrong WE0_chanID", skb); - return; - } - if ((pc->state == 2) && (pc->para.bchannel != (p[2] & 0x3))) { - l3_1tr6_error(pc, "call sent wrong chanID value", skb); - return; - } - pc->para.bchannel = p[2] & 0x3; - } else { - l3_1tr6_error(pc, "missing call sent WE0_chanID", skb); - return; - } - dev_kfree_skb(skb); - L3AddTimer(&pc->timer, T310, CC_T310); - newl3state(pc, 3); - pc->st->l3.l3l4(pc->st, CC_PROCEEDING | INDICATION, pc); -} - -static void -l3_1tr6_alert(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - - dev_kfree_skb(skb); - L3DelTimer(&pc->timer); /* T304 */ - newl3state(pc, 4); - pc->st->l3.l3l4(pc->st, CC_ALERTING | INDICATION, pc); -} - -static void -l3_1tr6_info(struct l3_process *pc, u_char pr, void *arg) -{ - u_char *p; - int i, tmpcharge = 0; - char a_charge[8]; - struct sk_buff *skb = arg; - - p = skb->data; - if ((p = findie(p, skb->len, WE6_chargingInfo, 6))) { - iecpy(a_charge, p, 1); - for (i = 0; i < strlen(a_charge); i++) { - tmpcharge *= 10; - tmpcharge += a_charge[i] & 0xf; - } - if (tmpcharge > pc->para.chargeinfo) { - pc->para.chargeinfo = tmpcharge; - pc->st->l3.l3l4(pc->st, CC_CHARGE | INDICATION, pc); - } - if (pc->st->l3.debug & L3_DEB_CHARGE) { - l3_debug(pc->st, "charging info %d", - pc->para.chargeinfo); - } - } else if (pc->st->l3.debug & L3_DEB_CHARGE) - l3_debug(pc->st, "charging info not found"); - dev_kfree_skb(skb); - -} - -static void -l3_1tr6_info_s2(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - - dev_kfree_skb(skb); -} - -static void -l3_1tr6_connect(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - - L3DelTimer(&pc->timer); /* T310 */ - if (!findie(skb->data, skb->len, WE6_date, 6)) { - l3_1tr6_error(pc, "missing connect date", skb); - return; - } - newl3state(pc, 10); - dev_kfree_skb(skb); - pc->para.chargeinfo = 0; - pc->st->l3.l3l4(pc->st, CC_SETUP | CONFIRM, pc); -} - -static void -l3_1tr6_rel(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - u_char *p; - - p = skb->data; - if ((p = findie(p, skb->len, WE0_cause, 0))) { - if (p[1] > 0) { - pc->para.cause = p[2]; - if (p[1] > 1) - pc->para.loc = p[3]; - else - pc->para.loc = 0; - } else { - pc->para.cause = 0; - pc->para.loc = 0; - } - } else { - pc->para.cause = NO_CAUSE; - l3_1tr6_error(pc, "missing REL cause", skb); - return; - } - dev_kfree_skb(skb); - StopAllL3Timer(pc); - newl3state(pc, 0); - l3_1TR6_message(pc, MT_N1_REL_ACK, PROTO_DIS_N1); - pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc); - release_l3_process(pc); -} - -static void -l3_1tr6_rel_ack(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - - dev_kfree_skb(skb); - StopAllL3Timer(pc); - newl3state(pc, 0); - pc->para.cause = NO_CAUSE; - pc->st->l3.l3l4(pc->st, CC_RELEASE | CONFIRM, pc); - release_l3_process(pc); -} - -static void -l3_1tr6_disc(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - u_char *p; - int i, tmpcharge = 0; - char a_charge[8]; - - StopAllL3Timer(pc); - p = skb->data; - if ((p = findie(p, skb->len, WE6_chargingInfo, 6))) { - iecpy(a_charge, p, 1); - for (i = 0; i < strlen(a_charge); i++) { - tmpcharge *= 10; - tmpcharge += a_charge[i] & 0xf; - } - if (tmpcharge > pc->para.chargeinfo) { - pc->para.chargeinfo = tmpcharge; - pc->st->l3.l3l4(pc->st, CC_CHARGE | INDICATION, pc); - } - if (pc->st->l3.debug & L3_DEB_CHARGE) { - l3_debug(pc->st, "charging info %d", - pc->para.chargeinfo); - } - } else if (pc->st->l3.debug & L3_DEB_CHARGE) - l3_debug(pc->st, "charging info not found"); - - - p = skb->data; - if ((p = findie(p, skb->len, WE0_cause, 0))) { - if (p[1] > 0) { - pc->para.cause = p[2]; - if (p[1] > 1) - pc->para.loc = p[3]; - else - pc->para.loc = 0; - } else { - pc->para.cause = 0; - pc->para.loc = 0; - } - } else { - if (pc->st->l3.debug & L3_DEB_WARN) - l3_debug(pc->st, "cause not found"); - pc->para.cause = NO_CAUSE; - } - if (!findie(skb->data, skb->len, WE6_date, 6)) { - l3_1tr6_error(pc, "missing connack date", skb); - return; - } - dev_kfree_skb(skb); - newl3state(pc, 12); - pc->st->l3.l3l4(pc->st, CC_DISCONNECT | INDICATION, pc); -} - - -static void -l3_1tr6_connect_ack(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - - if (!findie(skb->data, skb->len, WE6_date, 6)) { - l3_1tr6_error(pc, "missing connack date", skb); - return; - } - dev_kfree_skb(skb); - newl3state(pc, 10); - pc->para.chargeinfo = 0; - L3DelTimer(&pc->timer); - pc->st->l3.l3l4(pc->st, CC_SETUP_COMPL | INDICATION, pc); -} - -static void -l3_1tr6_alert_req(struct l3_process *pc, u_char pr, void *arg) -{ - newl3state(pc, 7); - l3_1TR6_message(pc, MT_N1_ALERT, PROTO_DIS_N1); -} - -static void -l3_1tr6_setup_rsp(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb; - u_char tmp[24]; - u_char *p = tmp; - int l; - - MsgHead(p, pc->callref, MT_N1_CONN, PROTO_DIS_N1); - if (pc->para.spv) { /* SPV ? */ - /* NSF SPV */ - *p++ = WE0_netSpecFac; - *p++ = 4; /* Laenge */ - *p++ = 0; - *p++ = FAC_SPV; /* SPV */ - *p++ = pc->para.setup.si1; - *p++ = pc->para.setup.si2; - *p++ = WE0_netSpecFac; - *p++ = 4; /* Laenge */ - *p++ = 0; - *p++ = FAC_Activate; /* aktiviere SPV */ - *p++ = pc->para.setup.si1; - *p++ = pc->para.setup.si2; - } - newl3state(pc, 8); - l = p - tmp; - if (!(skb = l3_alloc_skb(l))) - return; - skb_put_data(skb, tmp, l); - l3_msg(pc->st, DL_DATA | REQUEST, skb); - L3DelTimer(&pc->timer); - L3AddTimer(&pc->timer, T313, CC_T313); -} - -static void -l3_1tr6_reset(struct l3_process *pc, u_char pr, void *arg) -{ - release_l3_process(pc); -} - -static void -l3_1tr6_disconnect_req(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb; - u_char tmp[16]; - u_char *p = tmp; - int l; - u_char cause = 0x10; - u_char clen = 1; - - if (pc->para.cause > 0) - cause = pc->para.cause; - /* Map DSS1 causes */ - switch (cause & 0x7f) { - case 0x10: - clen = 0; - break; - case 0x11: - cause = CAUSE_UserBusy; - break; - case 0x15: - cause = CAUSE_CallRejected; - break; - } - StopAllL3Timer(pc); - MsgHead(p, pc->callref, MT_N1_DISC, PROTO_DIS_N1); - *p++ = WE0_cause; - *p++ = clen; /* Laenge */ - if (clen) - *p++ = cause | 0x80; - newl3state(pc, 11); - l = p - tmp; - if (!(skb = l3_alloc_skb(l))) - return; - skb_put_data(skb, tmp, l); - l3_msg(pc->st, DL_DATA | REQUEST, skb); - L3AddTimer(&pc->timer, T305, CC_T305); -} - -static void -l3_1tr6_t303(struct l3_process *pc, u_char pr, void *arg) -{ - if (pc->N303 > 0) { - pc->N303--; - L3DelTimer(&pc->timer); - l3_1tr6_setup_req(pc, pr, arg); - } else { - L3DelTimer(&pc->timer); - pc->para.cause = 0; - l3_1tr6_disconnect_req(pc, 0, NULL); - } -} - -static void -l3_1tr6_t304(struct l3_process *pc, u_char pr, void *arg) -{ - L3DelTimer(&pc->timer); - pc->para.cause = 0xE6; - l3_1tr6_disconnect_req(pc, pr, NULL); - pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc); -} - -static void -l3_1tr6_t305(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb; - u_char tmp[16]; - u_char *p = tmp; - int l; - u_char cause = 0x90; - u_char clen = 1; - - L3DelTimer(&pc->timer); - if (pc->para.cause != NO_CAUSE) - cause = pc->para.cause; - /* Map DSS1 causes */ - switch (cause & 0x7f) { - case 0x10: - clen = 0; - break; - case 0x15: - cause = CAUSE_CallRejected; - break; - } - MsgHead(p, pc->callref, MT_N1_REL, PROTO_DIS_N1); - *p++ = WE0_cause; - *p++ = clen; /* Laenge */ - if (clen) - *p++ = cause; - newl3state(pc, 19); - l = p - tmp; - if (!(skb = l3_alloc_skb(l))) - return; - skb_put_data(skb, tmp, l); - l3_msg(pc->st, DL_DATA | REQUEST, skb); - L3AddTimer(&pc->timer, T308, CC_T308_1); -} - -static void -l3_1tr6_t310(struct l3_process *pc, u_char pr, void *arg) -{ - L3DelTimer(&pc->timer); - pc->para.cause = 0xE6; - l3_1tr6_disconnect_req(pc, pr, NULL); - pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc); -} - -static void -l3_1tr6_t313(struct l3_process *pc, u_char pr, void *arg) -{ - L3DelTimer(&pc->timer); - pc->para.cause = 0xE6; - l3_1tr6_disconnect_req(pc, pr, NULL); - pc->st->l3.l3l4(pc->st, CC_CONNECT_ERR, pc); -} - -static void -l3_1tr6_t308_1(struct l3_process *pc, u_char pr, void *arg) -{ - L3DelTimer(&pc->timer); - l3_1TR6_message(pc, MT_N1_REL, PROTO_DIS_N1); - L3AddTimer(&pc->timer, T308, CC_T308_2); - newl3state(pc, 19); -} - -static void -l3_1tr6_t308_2(struct l3_process *pc, u_char pr, void *arg) -{ - L3DelTimer(&pc->timer); - pc->st->l3.l3l4(pc->st, CC_RELEASE_ERR, pc); - release_l3_process(pc); -} - -static void -l3_1tr6_dl_reset(struct l3_process *pc, u_char pr, void *arg) -{ - pc->para.cause = CAUSE_LocalProcErr; - l3_1tr6_disconnect_req(pc, pr, NULL); - pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc); -} - -static void -l3_1tr6_dl_release(struct l3_process *pc, u_char pr, void *arg) -{ - newl3state(pc, 0); - pc->para.cause = 0x1b; /* Destination out of order */ - pc->para.loc = 0; - pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc); - release_l3_process(pc); -} - -/* *INDENT-OFF* */ -static struct stateentry downstl[] = -{ - {SBIT(0), - CC_SETUP | REQUEST, l3_1tr6_setup_req}, - {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(6) | SBIT(7) | SBIT(8) | - SBIT(10), - CC_DISCONNECT | REQUEST, l3_1tr6_disconnect_req}, - {SBIT(12), - CC_RELEASE | REQUEST, l3_1tr6_release_req}, - {SBIT(6), - CC_IGNORE | REQUEST, l3_1tr6_reset}, - {SBIT(6), - CC_REJECT | REQUEST, l3_1tr6_disconnect_req}, - {SBIT(6), - CC_ALERTING | REQUEST, l3_1tr6_alert_req}, - {SBIT(6) | SBIT(7), - CC_SETUP | RESPONSE, l3_1tr6_setup_rsp}, - {SBIT(1), - CC_T303, l3_1tr6_t303}, - {SBIT(2), - CC_T304, l3_1tr6_t304}, - {SBIT(3), - CC_T310, l3_1tr6_t310}, - {SBIT(8), - CC_T313, l3_1tr6_t313}, - {SBIT(11), - CC_T305, l3_1tr6_t305}, - {SBIT(19), - CC_T308_1, l3_1tr6_t308_1}, - {SBIT(19), - CC_T308_2, l3_1tr6_t308_2}, -}; - -static struct stateentry datastln1[] = -{ - {SBIT(0), - MT_N1_INVALID, l3_1tr6_invalid}, - {SBIT(0), - MT_N1_SETUP, l3_1tr6_setup}, - {SBIT(1), - MT_N1_SETUP_ACK, l3_1tr6_setup_ack}, - {SBIT(1) | SBIT(2), - MT_N1_CALL_SENT, l3_1tr6_call_sent}, - {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(10), - MT_N1_DISC, l3_1tr6_disc}, - {SBIT(2) | SBIT(3) | SBIT(4), - MT_N1_ALERT, l3_1tr6_alert}, - {SBIT(2) | SBIT(3) | SBIT(4), - MT_N1_CONN, l3_1tr6_connect}, - {SBIT(2), - MT_N1_INFO, l3_1tr6_info_s2}, - {SBIT(8), - MT_N1_CONN_ACK, l3_1tr6_connect_ack}, - {SBIT(10), - MT_N1_INFO, l3_1tr6_info}, - {SBIT(0) | SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | - SBIT(10) | SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17), - MT_N1_REL, l3_1tr6_rel}, - {SBIT(19), - MT_N1_REL, l3_1tr6_rel_ack}, - {SBIT(0) | SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | - SBIT(10) | SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17), - MT_N1_REL_ACK, l3_1tr6_invalid}, - {SBIT(19), - MT_N1_REL_ACK, l3_1tr6_rel_ack} -}; - -static struct stateentry manstatelist[] = -{ - {SBIT(2), - DL_ESTABLISH | INDICATION, l3_1tr6_dl_reset}, - {ALL_STATES, - DL_RELEASE | INDICATION, l3_1tr6_dl_release}, -}; - -/* *INDENT-ON* */ - -static void -up1tr6(struct PStack *st, int pr, void *arg) -{ - int i, mt, cr; - struct l3_process *proc; - struct sk_buff *skb = arg; - - switch (pr) { - case (DL_DATA | INDICATION): - case (DL_UNIT_DATA | INDICATION): - break; - case (DL_ESTABLISH | CONFIRM): - case (DL_ESTABLISH | INDICATION): - case (DL_RELEASE | INDICATION): - case (DL_RELEASE | CONFIRM): - l3_msg(st, pr, arg); - return; - break; - } - if (skb->len < 4) { - if (st->l3.debug & L3_DEB_PROTERR) { - l3_debug(st, "up1tr6 len only %d", skb->len); - } - dev_kfree_skb(skb); - return; - } - if ((skb->data[0] & 0xfe) != PROTO_DIS_N0) { - if (st->l3.debug & L3_DEB_PROTERR) { - l3_debug(st, "up1tr6%sunexpected discriminator %x message len %d", - (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ", - skb->data[0], skb->len); - } - dev_kfree_skb(skb); - return; - } - if (skb->data[1] != 1) { - if (st->l3.debug & L3_DEB_PROTERR) { - l3_debug(st, "up1tr6 CR len not 1"); - } - dev_kfree_skb(skb); - return; - } - cr = skb->data[2]; - mt = skb->data[3]; - if (skb->data[0] == PROTO_DIS_N0) { - dev_kfree_skb(skb); - if (st->l3.debug & L3_DEB_STATE) { - l3_debug(st, "up1tr6%s N0 mt %x unhandled", - (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ", mt); - } - } else if (skb->data[0] == PROTO_DIS_N1) { - if (!(proc = getl3proc(st, cr))) { - if (mt == MT_N1_SETUP) { - if (cr < 128) { - if (!(proc = new_l3_process(st, cr))) { - if (st->l3.debug & L3_DEB_PROTERR) { - l3_debug(st, "up1tr6 no roc mem"); - } - dev_kfree_skb(skb); - return; - } - } else { - dev_kfree_skb(skb); - return; - } - } else if ((mt == MT_N1_REL) || (mt == MT_N1_REL_ACK) || - (mt == MT_N1_CANC_ACK) || (mt == MT_N1_CANC_REJ) || - (mt == MT_N1_REG_ACK) || (mt == MT_N1_REG_REJ) || - (mt == MT_N1_SUSP_ACK) || (mt == MT_N1_RES_REJ) || - (mt == MT_N1_INFO)) { - dev_kfree_skb(skb); - return; - } else { - if (!(proc = new_l3_process(st, cr))) { - if (st->l3.debug & L3_DEB_PROTERR) { - l3_debug(st, "up1tr6 no roc mem"); - } - dev_kfree_skb(skb); - return; - } - mt = MT_N1_INVALID; - } - } - for (i = 0; i < ARRAY_SIZE(datastln1); i++) - if ((mt == datastln1[i].primitive) && - ((1 << proc->state) & datastln1[i].state)) - break; - if (i == ARRAY_SIZE(datastln1)) { - dev_kfree_skb(skb); - if (st->l3.debug & L3_DEB_STATE) { - l3_debug(st, "up1tr6%sstate %d mt %x unhandled", - (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ", - proc->state, mt); - } - return; - } else { - if (st->l3.debug & L3_DEB_STATE) { - l3_debug(st, "up1tr6%sstate %d mt %x", - (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ", - proc->state, mt); - } - datastln1[i].rout(proc, pr, skb); - } - } -} - -static void -down1tr6(struct PStack *st, int pr, void *arg) -{ - int i, cr; - struct l3_process *proc; - struct Channel *chan; - - if ((DL_ESTABLISH | REQUEST) == pr) { - l3_msg(st, pr, NULL); - return; - } else if ((CC_SETUP | REQUEST) == pr) { - chan = arg; - cr = newcallref(); - cr |= 0x80; - if (!(proc = new_l3_process(st, cr))) { - return; - } else { - proc->chan = chan; - chan->proc = proc; - memcpy(&proc->para.setup, &chan->setup, sizeof(setup_parm)); - proc->callref = cr; - } - } else { - proc = arg; - } - - for (i = 0; i < ARRAY_SIZE(downstl); i++) - if ((pr == downstl[i].primitive) && - ((1 << proc->state) & downstl[i].state)) - break; - if (i == ARRAY_SIZE(downstl)) { - if (st->l3.debug & L3_DEB_STATE) { - l3_debug(st, "down1tr6 state %d prim %d unhandled", - proc->state, pr); - } - } else { - if (st->l3.debug & L3_DEB_STATE) { - l3_debug(st, "down1tr6 state %d prim %d", - proc->state, pr); - } - downstl[i].rout(proc, pr, arg); - } -} - -static void -man1tr6(struct PStack *st, int pr, void *arg) -{ - int i; - struct l3_process *proc = arg; - - if (!proc) { - printk(KERN_ERR "HiSax man1tr6 without proc pr=%04x\n", pr); - return; - } - for (i = 0; i < ARRAY_SIZE(manstatelist); i++) - if ((pr == manstatelist[i].primitive) && - ((1 << proc->state) & manstatelist[i].state)) - break; - if (i == ARRAY_SIZE(manstatelist)) { - if (st->l3.debug & L3_DEB_STATE) { - l3_debug(st, "cr %d man1tr6 state %d prim %d unhandled", - proc->callref & 0x7f, proc->state, pr); - } - } else { - if (st->l3.debug & L3_DEB_STATE) { - l3_debug(st, "cr %d man1tr6 state %d prim %d", - proc->callref & 0x7f, proc->state, pr); - } - manstatelist[i].rout(proc, pr, arg); - } -} - -void -setstack_1tr6(struct PStack *st) -{ - char tmp[64]; - - st->lli.l4l3 = down1tr6; - st->l2.l2l3 = up1tr6; - st->l3.l3ml3 = man1tr6; - st->l3.N303 = 0; - - strcpy(tmp, l3_1tr6_revision); - printk(KERN_INFO "HiSax: 1TR6 Rev. %s\n", HiSax_getrev(tmp)); -} diff --git a/drivers/isdn/hisax/l3_1tr6.h b/drivers/isdn/hisax/l3_1tr6.h deleted file mode 100644 index 43215c00cada..000000000000 --- a/drivers/isdn/hisax/l3_1tr6.h +++ /dev/null @@ -1,164 +0,0 @@ -/* $Id: l3_1tr6.h,v 2.2.6.2 2001/09/23 22:24:49 kai Exp $ - * - * German 1TR6 D-channel protocol defines - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#ifndef l3_1tr6 -#define l3_1tr6 - -#define PROTO_DIS_N0 0x40 -#define PROTO_DIS_N1 0x41 - -/* - * MsgType N0 - */ -#define MT_N0_REG_IND 0x61 -#define MT_N0_CANC_IND 0x62 -#define MT_N0_FAC_STA 0x63 -#define MT_N0_STA_ACK 0x64 -#define MT_N0_STA_REJ 0x65 -#define MT_N0_FAC_INF 0x66 -#define MT_N0_INF_ACK 0x67 -#define MT_N0_INF_REJ 0x68 -#define MT_N0_CLOSE 0x75 -#define MT_N0_CLO_ACK 0x77 - -/* - * MsgType N1 - */ - -#define MT_N1_ESC 0x00 -#define MT_N1_ALERT 0x01 -#define MT_N1_CALL_SENT 0x02 -#define MT_N1_CONN 0x07 -#define MT_N1_CONN_ACK 0x0F -#define MT_N1_SETUP 0x05 -#define MT_N1_SETUP_ACK 0x0D -#define MT_N1_RES 0x26 -#define MT_N1_RES_ACK 0x2E -#define MT_N1_RES_REJ 0x22 -#define MT_N1_SUSP 0x25 -#define MT_N1_SUSP_ACK 0x2D -#define MT_N1_SUSP_REJ 0x21 -#define MT_N1_USER_INFO 0x20 -#define MT_N1_DET 0x40 -#define MT_N1_DISC 0x45 -#define MT_N1_REL 0x4D -#define MT_N1_REL_ACK 0x5A -#define MT_N1_CANC_ACK 0x6E -#define MT_N1_CANC_REJ 0x67 -#define MT_N1_CON_CON 0x69 -#define MT_N1_FAC 0x60 -#define MT_N1_FAC_ACK 0x68 -#define MT_N1_FAC_CAN 0x66 -#define MT_N1_FAC_REG 0x64 -#define MT_N1_FAC_REJ 0x65 -#define MT_N1_INFO 0x6D -#define MT_N1_REG_ACK 0x6C -#define MT_N1_REG_REJ 0x6F -#define MT_N1_STAT 0x63 -#define MT_N1_INVALID 0 - -/* - * W Elemente - */ - -#define WE_Shift_F0 0x90 -#define WE_Shift_F6 0x96 -#define WE_Shift_OF0 0x98 -#define WE_Shift_OF6 0x9E - -#define WE0_cause 0x08 -#define WE0_connAddr 0x0C -#define WE0_callID 0x10 -#define WE0_chanID 0x18 -#define WE0_netSpecFac 0x20 -#define WE0_display 0x28 -#define WE0_keypad 0x2C -#define WE0_origAddr 0x6C -#define WE0_destAddr 0x70 -#define WE0_userInfo 0x7E - -#define WE0_moreData 0xA0 -#define WE0_congestLevel 0xB0 - -#define WE6_serviceInd 0x01 -#define WE6_chargingInfo 0x02 -#define WE6_date 0x03 -#define WE6_facSelect 0x05 -#define WE6_facStatus 0x06 -#define WE6_statusCalled 0x07 -#define WE6_addTransAttr 0x08 - -/* - * FacCodes - */ -#define FAC_Sperre 0x01 -#define FAC_Sperre_All 0x02 -#define FAC_Sperre_Fern 0x03 -#define FAC_Sperre_Intl 0x04 -#define FAC_Sperre_Interk 0x05 - -#define FAC_Forward1 0x02 -#define FAC_Forward2 0x03 -#define FAC_Konferenz 0x06 -#define FAC_GrabBchan 0x0F -#define FAC_Reactivate 0x10 -#define FAC_Konferenz3 0x11 -#define FAC_Dienstwechsel1 0x12 -#define FAC_Dienstwechsel2 0x13 -#define FAC_NummernIdent 0x14 -#define FAC_GBG 0x15 -#define FAC_DisplayUebergeben 0x17 -#define FAC_DisplayUmgeleitet 0x1A -#define FAC_Unterdruecke 0x1B -#define FAC_Deactivate 0x1E -#define FAC_Activate 0x1D -#define FAC_SPV 0x1F -#define FAC_Rueckwechsel 0x23 -#define FAC_Umleitung 0x24 - -/* - * Cause codes - */ -#define CAUSE_InvCRef 0x01 -#define CAUSE_BearerNotImpl 0x03 -#define CAUSE_CIDunknown 0x07 -#define CAUSE_CIDinUse 0x08 -#define CAUSE_NoChans 0x0A -#define CAUSE_FacNotImpl 0x10 -#define CAUSE_FacNotSubscr 0x11 -#define CAUSE_OutgoingBarred 0x20 -#define CAUSE_UserAccessBusy 0x21 -#define CAUSE_NegativeGBG 0x22 -#define CAUSE_UnknownGBG 0x23 -#define CAUSE_NoSPVknown 0x25 -#define CAUSE_DestNotObtain 0x35 -#define CAUSE_NumberChanged 0x38 -#define CAUSE_OutOfOrder 0x39 -#define CAUSE_NoUserResponse 0x3A -#define CAUSE_UserBusy 0x3B -#define CAUSE_IncomingBarred 0x3D -#define CAUSE_CallRejected 0x3E -#define CAUSE_NetworkCongestion 0x59 -#define CAUSE_RemoteUser 0x5A -#define CAUSE_LocalProcErr 0x70 -#define CAUSE_RemoteProcErr 0x71 -#define CAUSE_RemoteUserSuspend 0x72 -#define CAUSE_RemoteUserResumed 0x73 -#define CAUSE_UserInfoDiscarded 0x7F - -#define T303 4000 -#define T304 20000 -#define T305 4000 -#define T308 4000 -#define T310 120000 -#define T313 4000 -#define T318 4000 -#define T319 4000 - -#endif diff --git a/drivers/isdn/hisax/l3dss1.c b/drivers/isdn/hisax/l3dss1.c deleted file mode 100644 index 368d152a8f1d..000000000000 --- a/drivers/isdn/hisax/l3dss1.c +++ /dev/null @@ -1,3227 +0,0 @@ -/* $Id: l3dss1.c,v 2.32.2.3 2004/01/13 14:31:25 keil Exp $ - * - * EURO/DSS1 D-channel protocol - * - * German 1TR6 D-channel protocol - * - * Author Karsten Keil - * based on the teles driver from Jan den Ouden - * Copyright by Karsten Keil <keil@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * For changes and modifications please read - * Documentation/isdn/HiSax.cert - * - * Thanks to Jan den Ouden - * Fritz Elfert - * - */ - -#include "hisax.h" -#include "isdnl3.h" -#include "l3dss1.h" -#include <linux/ctype.h> -#include <linux/slab.h> - -extern char *HiSax_getrev(const char *revision); -static const char *dss1_revision = "$Revision: 2.32.2.3 $"; - -#define EXT_BEARER_CAPS 1 - -#define MsgHead(ptr, cref, mty) \ - *ptr++ = 0x8; \ - if (cref == -1) { \ - *ptr++ = 0x0; \ - } else { \ - *ptr++ = 0x1; \ - *ptr++ = cref^0x80; \ - } \ - *ptr++ = mty - - -/**********************************************/ -/* get a new invoke id for remote operations. */ -/* Only a return value != 0 is valid */ -/**********************************************/ -static unsigned char new_invoke_id(struct PStack *p) -{ - unsigned char retval; - int i; - - i = 32; /* maximum search depth */ - - retval = p->prot.dss1.last_invoke_id + 1; /* try new id */ - while ((i) && (p->prot.dss1.invoke_used[retval >> 3] == 0xFF)) { - p->prot.dss1.last_invoke_id = (retval & 0xF8) + 8; - i--; - } - if (i) { - while (p->prot.dss1.invoke_used[retval >> 3] & (1 << (retval & 7))) - retval++; - } else - retval = 0; - p->prot.dss1.last_invoke_id = retval; - p->prot.dss1.invoke_used[retval >> 3] |= (1 << (retval & 7)); - return (retval); -} /* new_invoke_id */ - -/*************************/ -/* free a used invoke id */ -/*************************/ -static void free_invoke_id(struct PStack *p, unsigned char id) -{ - - if (!id) return; /* 0 = invalid value */ - - p->prot.dss1.invoke_used[id >> 3] &= ~(1 << (id & 7)); -} /* free_invoke_id */ - - -/**********************************************************/ -/* create a new l3 process and fill in dss1 specific data */ -/**********************************************************/ -static struct l3_process -*dss1_new_l3_process(struct PStack *st, int cr) -{ struct l3_process *proc; - - if (!(proc = new_l3_process(st, cr))) - return (NULL); - - proc->prot.dss1.invoke_id = 0; - proc->prot.dss1.remote_operation = 0; - proc->prot.dss1.uus1_data[0] = '\0'; - - return (proc); -} /* dss1_new_l3_process */ - -/************************************************/ -/* free a l3 process and all dss1 specific data */ -/************************************************/ -static void -dss1_release_l3_process(struct l3_process *p) -{ - free_invoke_id(p->st, p->prot.dss1.invoke_id); - release_l3_process(p); -} /* dss1_release_l3_process */ - -/********************************************************/ -/* search a process with invoke id id and dummy callref */ -/********************************************************/ -static struct l3_process * -l3dss1_search_dummy_proc(struct PStack *st, int id) -{ struct l3_process *pc = st->l3.proc; /* start of processes */ - - if (!id) return (NULL); - - while (pc) - { if ((pc->callref == -1) && (pc->prot.dss1.invoke_id == id)) - return (pc); - pc = pc->next; - } - return (NULL); -} /* l3dss1_search_dummy_proc */ - -/*******************************************************************/ -/* called when a facility message with a dummy callref is received */ -/* and a return result is delivered. id specifies the invoke id. */ -/*******************************************************************/ -static void -l3dss1_dummy_return_result(struct PStack *st, int id, u_char *p, u_char nlen) -{ isdn_ctrl ic; - struct IsdnCardState *cs; - struct l3_process *pc = NULL; - - if ((pc = l3dss1_search_dummy_proc(st, id))) - { L3DelTimer(&pc->timer); /* remove timer */ - - cs = pc->st->l1.hardware; - ic.driver = cs->myid; - ic.command = ISDN_STAT_PROT; - ic.arg = DSS1_STAT_INVOKE_RES; - ic.parm.dss1_io.hl_id = pc->prot.dss1.invoke_id; - ic.parm.dss1_io.ll_id = pc->prot.dss1.ll_id; - ic.parm.dss1_io.proc = pc->prot.dss1.proc; - ic.parm.dss1_io.timeout = 0; - ic.parm.dss1_io.datalen = nlen; - ic.parm.dss1_io.data = p; - free_invoke_id(pc->st, pc->prot.dss1.invoke_id); - pc->prot.dss1.invoke_id = 0; /* reset id */ - - cs->iif.statcallb(&ic); - dss1_release_l3_process(pc); - } - else - l3_debug(st, "dummy return result id=0x%x result len=%d", id, nlen); -} /* l3dss1_dummy_return_result */ - -/*******************************************************************/ -/* called when a facility message with a dummy callref is received */ -/* and a return error is delivered. id specifies the invoke id. */ -/*******************************************************************/ -static void -l3dss1_dummy_error_return(struct PStack *st, int id, ulong error) -{ isdn_ctrl ic; - struct IsdnCardState *cs; - struct l3_process *pc = NULL; - - if ((pc = l3dss1_search_dummy_proc(st, id))) - { L3DelTimer(&pc->timer); /* remove timer */ - - cs = pc->st->l1.hardware; - ic.driver = cs->myid; - ic.command = ISDN_STAT_PROT; - ic.arg = DSS1_STAT_INVOKE_ERR; - ic.parm.dss1_io.hl_id = pc->prot.dss1.invoke_id; - ic.parm.dss1_io.ll_id = pc->prot.dss1.ll_id; - ic.parm.dss1_io.proc = pc->prot.dss1.proc; - ic.parm.dss1_io.timeout = error; - ic.parm.dss1_io.datalen = 0; - ic.parm.dss1_io.data = NULL; - free_invoke_id(pc->st, pc->prot.dss1.invoke_id); - pc->prot.dss1.invoke_id = 0; /* reset id */ - - cs->iif.statcallb(&ic); - dss1_release_l3_process(pc); - } - else - l3_debug(st, "dummy return error id=0x%x error=0x%lx", id, error); -} /* l3dss1_error_return */ - -/*******************************************************************/ -/* called when a facility message with a dummy callref is received */ -/* and a invoke is delivered. id specifies the invoke id. */ -/*******************************************************************/ -static void -l3dss1_dummy_invoke(struct PStack *st, int cr, int id, - int ident, u_char *p, u_char nlen) -{ isdn_ctrl ic; - struct IsdnCardState *cs; - - l3_debug(st, "dummy invoke %s id=0x%x ident=0x%x datalen=%d", - (cr == -1) ? "local" : "broadcast", id, ident, nlen); - if (cr >= -1) return; /* ignore local data */ - - cs = st->l1.hardware; - ic.driver = cs->myid; - ic.command = ISDN_STAT_PROT; - ic.arg = DSS1_STAT_INVOKE_BRD; - ic.parm.dss1_io.hl_id = id; - ic.parm.dss1_io.ll_id = 0; - ic.parm.dss1_io.proc = ident; - ic.parm.dss1_io.timeout = 0; - ic.parm.dss1_io.datalen = nlen; - ic.parm.dss1_io.data = p; - - cs->iif.statcallb(&ic); -} /* l3dss1_dummy_invoke */ - -static void -l3dss1_parse_facility(struct PStack *st, struct l3_process *pc, - int cr, u_char *p) -{ - int qd_len = 0; - unsigned char nlen = 0, ilen, cp_tag; - int ident, id; - ulong err_ret; - - if (pc) - st = pc->st; /* valid Stack */ - else - if ((!st) || (cr >= 0)) return; /* neither pc nor st specified */ - - p++; - qd_len = *p++; - if (qd_len == 0) { - l3_debug(st, "qd_len == 0"); - return; - } - if ((*p & 0x1F) != 0x11) { /* Service discriminator, supplementary service */ - l3_debug(st, "supplementary service != 0x11"); - return; - } - while (qd_len > 0 && !(*p & 0x80)) { /* extension ? */ - p++; - qd_len--; - } - if (qd_len < 2) { - l3_debug(st, "qd_len < 2"); - return; - } - p++; - qd_len--; - if ((*p & 0xE0) != 0xA0) { /* class and form */ - l3_debug(st, "class and form != 0xA0"); - return; - } - - cp_tag = *p & 0x1F; /* remember tag value */ - - p++; - qd_len--; - if (qd_len < 1) - { l3_debug(st, "qd_len < 1"); - return; - } - if (*p & 0x80) - { /* length format indefinite or limited */ - nlen = *p++ & 0x7F; /* number of len bytes or indefinite */ - if ((qd_len-- < ((!nlen) ? 3 : (1 + nlen))) || - (nlen > 1)) - { l3_debug(st, "length format error or not implemented"); - return; - } - if (nlen == 1) - { nlen = *p++; /* complete length */ - qd_len--; - } - else - { qd_len -= 2; /* trailing null bytes */ - if ((*(p + qd_len)) || (*(p + qd_len + 1))) - { l3_debug(st, "length format indefinite error"); - return; - } - nlen = qd_len; - } - } - else - { nlen = *p++; - qd_len--; - } - if (qd_len < nlen) - { l3_debug(st, "qd_len < nlen"); - return; - } - qd_len -= nlen; - - if (nlen < 2) - { l3_debug(st, "nlen < 2"); - return; - } - if (*p != 0x02) - { /* invoke identifier tag */ - l3_debug(st, "invoke identifier tag !=0x02"); - return; - } - p++; - nlen--; - if (*p & 0x80) - { /* length format */ - l3_debug(st, "invoke id length format 2"); - return; - } - ilen = *p++; - nlen--; - if (ilen > nlen || ilen == 0) - { l3_debug(st, "ilen > nlen || ilen == 0"); - return; - } - nlen -= ilen; - id = 0; - while (ilen > 0) - { id = (id << 8) | (*p++ & 0xFF); /* invoke identifier */ - ilen--; - } - - switch (cp_tag) { /* component tag */ - case 1: /* invoke */ - if (nlen < 2) { - l3_debug(st, "nlen < 2 22"); - return; - } - if (*p != 0x02) { /* operation value */ - l3_debug(st, "operation value !=0x02"); - return; - } - p++; - nlen--; - ilen = *p++; - nlen--; - if (ilen > nlen || ilen == 0) { - l3_debug(st, "ilen > nlen || ilen == 0 22"); - return; - } - nlen -= ilen; - ident = 0; - while (ilen > 0) { - ident = (ident << 8) | (*p++ & 0xFF); - ilen--; - } - - if (!pc) - { l3dss1_dummy_invoke(st, cr, id, ident, p, nlen); - return; - } -#ifdef CONFIG_DE_AOC - { - -#define FOO1(s, a, b) \ - while (nlen > 1) { \ - int ilen = p[1]; \ - if (nlen < ilen + 2) { \ - l3_debug(st, "FOO1 nlen < ilen+2"); \ - return; \ - } \ - nlen -= ilen + 2; \ - if ((*p & 0xFF) == (a)) { \ - int nlen = ilen; \ - p += 2; \ - b; \ - } else { \ - p += ilen + 2; \ - } \ - } - - switch (ident) { - case 0x22: /* during */ - FOO1("1A", 0x30, FOO1("1C", 0xA1, FOO1("1D", 0x30, FOO1("1E", 0x02, ( { - ident = 0; - nlen = (nlen) ? nlen : 0; /* Make gcc happy */ - while (ilen > 0) { - ident = (ident << 8) | *p++; - ilen--; - } - if (ident > pc->para.chargeinfo) { - pc->para.chargeinfo = ident; - st->l3.l3l4(st, CC_CHARGE | INDICATION, pc); - } - if (st->l3.debug & L3_DEB_CHARGE) { - if (*(p + 2) == 0) { - l3_debug(st, "charging info during %d", pc->para.chargeinfo); - } - else { - l3_debug(st, "charging info final %d", pc->para.chargeinfo); - } - } - } - ))))) - break; - case 0x24: /* final */ - FOO1("2A", 0x30, FOO1("2B", 0x30, FOO1("2C", 0xA1, FOO1("2D", 0x30, FOO1("2E", 0x02, ( { - ident = 0; - nlen = (nlen) ? nlen : 0; /* Make gcc happy */ - while (ilen > 0) { - ident = (ident << 8) | *p++; - ilen--; - } - if (ident > pc->para.chargeinfo) { - pc->para.chargeinfo = ident; - st->l3.l3l4(st, CC_CHARGE | INDICATION, pc); - } - if (st->l3.debug & L3_DEB_CHARGE) { - l3_debug(st, "charging info final %d", pc->para.chargeinfo); - } - } - )))))) - break; - default: - l3_debug(st, "invoke break invalid ident %02x", ident); - break; - } -#undef FOO1 - - } -#else /* not CONFIG_DE_AOC */ - l3_debug(st, "invoke break"); -#endif /* not CONFIG_DE_AOC */ - break; - case 2: /* return result */ - /* if no process available handle separately */ - if (!pc) - { if (cr == -1) - l3dss1_dummy_return_result(st, id, p, nlen); - return; - } - if ((pc->prot.dss1.invoke_id) && (pc->prot.dss1.invoke_id == id)) - { /* Diversion successful */ - free_invoke_id(st, pc->prot.dss1.invoke_id); - pc->prot.dss1.remote_result = 0; /* success */ - pc->prot.dss1.invoke_id = 0; - pc->redir_result = pc->prot.dss1.remote_result; - st->l3.l3l4(st, CC_REDIR | INDICATION, pc); } /* Diversion successful */ - else - l3_debug(st, "return error unknown identifier"); - break; - case 3: /* return error */ - err_ret = 0; - if (nlen < 2) - { l3_debug(st, "return error nlen < 2"); - return; - } - if (*p != 0x02) - { /* result tag */ - l3_debug(st, "invoke error tag !=0x02"); - return; - } - p++; - nlen--; - if (*p > 4) - { /* length format */ - l3_debug(st, "invoke return errlen > 4 "); - return; - } - ilen = *p++; - nlen--; - if (ilen > nlen || ilen == 0) - { l3_debug(st, "error return ilen > nlen || ilen == 0"); - return; - } - nlen -= ilen; - while (ilen > 0) - { err_ret = (err_ret << 8) | (*p++ & 0xFF); /* error value */ - ilen--; - } - /* if no process available handle separately */ - if (!pc) - { if (cr == -1) - l3dss1_dummy_error_return(st, id, err_ret); - return; - } - if ((pc->prot.dss1.invoke_id) && (pc->prot.dss1.invoke_id == id)) - { /* Deflection error */ - free_invoke_id(st, pc->prot.dss1.invoke_id); - pc->prot.dss1.remote_result = err_ret; /* result */ - pc->prot.dss1.invoke_id = 0; - pc->redir_result = pc->prot.dss1.remote_result; - st->l3.l3l4(st, CC_REDIR | INDICATION, pc); - } /* Deflection error */ - else - l3_debug(st, "return result unknown identifier"); - break; - default: - l3_debug(st, "facility default break tag=0x%02x", cp_tag); - break; - } -} - -static void -l3dss1_message(struct l3_process *pc, u_char mt) -{ - struct sk_buff *skb; - u_char *p; - - if (!(skb = l3_alloc_skb(4))) - return; - p = skb_put(skb, 4); - MsgHead(p, pc->callref, mt); - l3_msg(pc->st, DL_DATA | REQUEST, skb); -} - -static void -l3dss1_message_cause(struct l3_process *pc, u_char mt, u_char cause) -{ - struct sk_buff *skb; - u_char tmp[16]; - u_char *p = tmp; - int l; - - MsgHead(p, pc->callref, mt); - *p++ = IE_CAUSE; - *p++ = 0x2; - *p++ = 0x80; - *p++ = cause | 0x80; - - l = p - tmp; - if (!(skb = l3_alloc_skb(l))) - return; - skb_put_data(skb, tmp, l); - l3_msg(pc->st, DL_DATA | REQUEST, skb); -} - -static void -l3dss1_status_send(struct l3_process *pc, u_char pr, void *arg) -{ - u_char tmp[16]; - u_char *p = tmp; - int l; - struct sk_buff *skb; - - MsgHead(p, pc->callref, MT_STATUS); - - *p++ = IE_CAUSE; - *p++ = 0x2; - *p++ = 0x80; - *p++ = pc->para.cause | 0x80; - - *p++ = IE_CALL_STATE; - *p++ = 0x1; - *p++ = pc->state & 0x3f; - - l = p - tmp; - if (!(skb = l3_alloc_skb(l))) - return; - skb_put_data(skb, tmp, l); - l3_msg(pc->st, DL_DATA | REQUEST, skb); -} - -static void -l3dss1_msg_without_setup(struct l3_process *pc, u_char pr, void *arg) -{ - /* This routine is called if here was no SETUP made (checks in dss1up and in - * l3dss1_setup) and a RELEASE_COMPLETE have to be sent with an error code - * MT_STATUS_ENQUIRE in the NULL state is handled too - */ - u_char tmp[16]; - u_char *p = tmp; - int l; - struct sk_buff *skb; - - switch (pc->para.cause) { - case 81: /* invalid callreference */ - case 88: /* incomp destination */ - case 96: /* mandory IE missing */ - case 100: /* invalid IE contents */ - case 101: /* incompatible Callstate */ - MsgHead(p, pc->callref, MT_RELEASE_COMPLETE); - *p++ = IE_CAUSE; - *p++ = 0x2; - *p++ = 0x80; - *p++ = pc->para.cause | 0x80; - break; - default: - printk(KERN_ERR "HiSax l3dss1_msg_without_setup wrong cause %d\n", - pc->para.cause); - return; - } - l = p - tmp; - if (!(skb = l3_alloc_skb(l))) - return; - skb_put_data(skb, tmp, l); - l3_msg(pc->st, DL_DATA | REQUEST, skb); - dss1_release_l3_process(pc); -} - -static int ie_ALERTING[] = {IE_BEARER, IE_CHANNEL_ID | IE_MANDATORY_1, - IE_FACILITY, IE_PROGRESS, IE_DISPLAY, IE_SIGNAL, IE_HLC, - IE_USER_USER, -1}; -static int ie_CALL_PROCEEDING[] = {IE_BEARER, IE_CHANNEL_ID | IE_MANDATORY_1, - IE_FACILITY, IE_PROGRESS, IE_DISPLAY, IE_HLC, -1}; -static int ie_CONNECT[] = {IE_BEARER, IE_CHANNEL_ID | IE_MANDATORY_1, - IE_FACILITY, IE_PROGRESS, IE_DISPLAY, IE_DATE, IE_SIGNAL, - IE_CONNECT_PN, IE_CONNECT_SUB, IE_LLC, IE_HLC, IE_USER_USER, -1}; -static int ie_CONNECT_ACKNOWLEDGE[] = {IE_CHANNEL_ID, IE_DISPLAY, IE_SIGNAL, -1}; -static int ie_DISCONNECT[] = {IE_CAUSE | IE_MANDATORY, IE_FACILITY, - IE_PROGRESS, IE_DISPLAY, IE_SIGNAL, IE_USER_USER, -1}; -static int ie_INFORMATION[] = {IE_COMPLETE, IE_DISPLAY, IE_KEYPAD, IE_SIGNAL, - IE_CALLED_PN, -1}; -static int ie_NOTIFY[] = {IE_BEARER, IE_NOTIFY | IE_MANDATORY, IE_DISPLAY, -1}; -static int ie_PROGRESS[] = {IE_BEARER, IE_CAUSE, IE_FACILITY, IE_PROGRESS | - IE_MANDATORY, IE_DISPLAY, IE_HLC, IE_USER_USER, -1}; -static int ie_RELEASE[] = {IE_CAUSE | IE_MANDATORY_1, IE_FACILITY, IE_DISPLAY, - IE_SIGNAL, IE_USER_USER, -1}; -/* a RELEASE_COMPLETE with errors don't require special actions - static int ie_RELEASE_COMPLETE[] = {IE_CAUSE | IE_MANDATORY_1, IE_DISPLAY, IE_SIGNAL, IE_USER_USER, -1}; -*/ -static int ie_RESUME_ACKNOWLEDGE[] = {IE_CHANNEL_ID | IE_MANDATORY, IE_FACILITY, - IE_DISPLAY, -1}; -static int ie_RESUME_REJECT[] = {IE_CAUSE | IE_MANDATORY, IE_DISPLAY, -1}; -static int ie_SETUP[] = {IE_COMPLETE, IE_BEARER | IE_MANDATORY, - IE_CHANNEL_ID | IE_MANDATORY, IE_FACILITY, IE_PROGRESS, - IE_NET_FAC, IE_DISPLAY, IE_KEYPAD, IE_SIGNAL, IE_CALLING_PN, - IE_CALLING_SUB, IE_CALLED_PN, IE_CALLED_SUB, IE_REDIR_NR, - IE_LLC, IE_HLC, IE_USER_USER, -1}; -static int ie_SETUP_ACKNOWLEDGE[] = {IE_CHANNEL_ID | IE_MANDATORY, IE_FACILITY, - IE_PROGRESS, IE_DISPLAY, IE_SIGNAL, -1}; -static int ie_STATUS[] = {IE_CAUSE | IE_MANDATORY, IE_CALL_STATE | - IE_MANDATORY, IE_DISPLAY, -1}; -static int ie_STATUS_ENQUIRY[] = {IE_DISPLAY, -1}; -static int ie_SUSPEND_ACKNOWLEDGE[] = {IE_DISPLAY, IE_FACILITY, -1}; -static int ie_SUSPEND_REJECT[] = {IE_CAUSE | IE_MANDATORY, IE_DISPLAY, -1}; -/* not used - * static int ie_CONGESTION_CONTROL[] = {IE_CONGESTION | IE_MANDATORY, - * IE_CAUSE | IE_MANDATORY, IE_DISPLAY, -1}; - * static int ie_USER_INFORMATION[] = {IE_MORE_DATA, IE_USER_USER | IE_MANDATORY, -1}; - * static int ie_RESTART[] = {IE_CHANNEL_ID, IE_DISPLAY, IE_RESTART_IND | - * IE_MANDATORY, -1}; - */ -static int ie_FACILITY[] = {IE_FACILITY | IE_MANDATORY, IE_DISPLAY, -1}; -static int comp_required[] = {1, 2, 3, 5, 6, 7, 9, 10, 11, 14, 15, -1}; -static int l3_valid_states[] = {0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 15, 17, 19, 25, -1}; - -struct ie_len { - int ie; - int len; -}; - -static -struct ie_len max_ie_len[] = { - {IE_SEGMENT, 4}, - {IE_BEARER, 12}, - {IE_CAUSE, 32}, - {IE_CALL_ID, 10}, - {IE_CALL_STATE, 3}, - {IE_CHANNEL_ID, 34}, - {IE_FACILITY, 255}, - {IE_PROGRESS, 4}, - {IE_NET_FAC, 255}, - {IE_NOTIFY, 3}, - {IE_DISPLAY, 82}, - {IE_DATE, 8}, - {IE_KEYPAD, 34}, - {IE_SIGNAL, 3}, - {IE_INFORATE, 6}, - {IE_E2E_TDELAY, 11}, - {IE_TDELAY_SEL, 5}, - {IE_PACK_BINPARA, 3}, - {IE_PACK_WINSIZE, 4}, - {IE_PACK_SIZE, 4}, - {IE_CUG, 7}, - {IE_REV_CHARGE, 3}, - {IE_CALLING_PN, 24}, - {IE_CALLING_SUB, 23}, - {IE_CALLED_PN, 24}, - {IE_CALLED_SUB, 23}, - {IE_REDIR_NR, 255}, - {IE_TRANS_SEL, 255}, - {IE_RESTART_IND, 3}, - {IE_LLC, 18}, - {IE_HLC, 5}, - {IE_USER_USER, 131}, - {-1, 0}, -}; - -static int -getmax_ie_len(u_char ie) { - int i = 0; - while (max_ie_len[i].ie != -1) { - if (max_ie_len[i].ie == ie) - return (max_ie_len[i].len); - i++; - } - return (255); -} - -static int -ie_in_set(struct l3_process *pc, u_char ie, int *checklist) { - int ret = 1; - - while (*checklist != -1) { - if ((*checklist & 0xff) == ie) { - if (ie & 0x80) - return (-ret); - else - return (ret); - } - ret++; - checklist++; - } - return (0); -} - -static int -check_infoelements(struct l3_process *pc, struct sk_buff *skb, int *checklist) -{ - int *cl = checklist; - u_char mt; - u_char *p, ie; - int l, newpos, oldpos; - int err_seq = 0, err_len = 0, err_compr = 0, err_ureg = 0; - u_char codeset = 0; - u_char old_codeset = 0; - u_char codelock = 1; - - p = skb->data; - /* skip cr */ - p++; - l = (*p++) & 0xf; - p += l; - mt = *p++; - oldpos = 0; - while ((p - skb->data) < skb->len) { - if ((*p & 0xf0) == 0x90) { /* shift codeset */ - old_codeset = codeset; - codeset = *p & 7; - if (*p & 0x08) - codelock = 0; - else - codelock = 1; - if (pc->debug & L3_DEB_CHECK) - l3_debug(pc->st, "check IE shift%scodeset %d->%d", - codelock ? " locking " : " ", old_codeset, codeset); - p++; - continue; - } - if (!codeset) { /* only codeset 0 */ - if ((newpos = ie_in_set(pc, *p, cl))) { - if (newpos > 0) { - if (newpos < oldpos) - err_seq++; - else - oldpos = newpos; - } - } else { - if (ie_in_set(pc, *p, comp_required)) - err_compr++; - else - err_ureg++; - } - } - ie = *p++; - if (ie & 0x80) { - l = 1; - } else { - l = *p++; - p += l; - l += 2; - } - if (!codeset && (l > getmax_ie_len(ie))) - err_len++; - if (!codelock) { - if (pc->debug & L3_DEB_CHECK) - l3_debug(pc->st, "check IE shift back codeset %d->%d", - codeset, old_codeset); - codeset = old_codeset; - codelock = 1; - } - } - if (err_compr | err_ureg | err_len | err_seq) { - if (pc->debug & L3_DEB_CHECK) - l3_debug(pc->st, "check IE MT(%x) %d/%d/%d/%d", - mt, err_compr, err_ureg, err_len, err_seq); - if (err_compr) - return (ERR_IE_COMPREHENSION); - if (err_ureg) - return (ERR_IE_UNRECOGNIZED); - if (err_len) - return (ERR_IE_LENGTH); - if (err_seq) - return (ERR_IE_SEQUENCE); - } - return (0); -} - -/* verify if a message type exists and contain no IE error */ -static int -l3dss1_check_messagetype_validity(struct l3_process *pc, int mt, void *arg) -{ - switch (mt) { - case MT_ALERTING: - case MT_CALL_PROCEEDING: - case MT_CONNECT: - case MT_CONNECT_ACKNOWLEDGE: - case MT_DISCONNECT: - case MT_INFORMATION: - case MT_FACILITY: - case MT_NOTIFY: - case MT_PROGRESS: - case MT_RELEASE: - case MT_RELEASE_COMPLETE: - case MT_SETUP: - case MT_SETUP_ACKNOWLEDGE: - case MT_RESUME_ACKNOWLEDGE: - case MT_RESUME_REJECT: - case MT_SUSPEND_ACKNOWLEDGE: - case MT_SUSPEND_REJECT: - case MT_USER_INFORMATION: - case MT_RESTART: - case MT_RESTART_ACKNOWLEDGE: - case MT_CONGESTION_CONTROL: - case MT_STATUS: - case MT_STATUS_ENQUIRY: - if (pc->debug & L3_DEB_CHECK) - l3_debug(pc->st, "l3dss1_check_messagetype_validity mt(%x) OK", mt); - break; - case MT_RESUME: /* RESUME only in user->net */ - case MT_SUSPEND: /* SUSPEND only in user->net */ - default: - if (pc->debug & (L3_DEB_CHECK | L3_DEB_WARN)) - l3_debug(pc->st, "l3dss1_check_messagetype_validity mt(%x) fail", mt); - pc->para.cause = 97; - l3dss1_status_send(pc, 0, NULL); - return (1); - } - return (0); -} - -static void -l3dss1_std_ie_err(struct l3_process *pc, int ret) { - - if (pc->debug & L3_DEB_CHECK) - l3_debug(pc->st, "check_infoelements ret %d", ret); - switch (ret) { - case 0: - break; - case ERR_IE_COMPREHENSION: - pc->para.cause = 96; - l3dss1_status_send(pc, 0, NULL); - break; - case ERR_IE_UNRECOGNIZED: - pc->para.cause = 99; - l3dss1_status_send(pc, 0, NULL); - break; - case ERR_IE_LENGTH: - pc->para.cause = 100; - l3dss1_status_send(pc, 0, NULL); - break; - case ERR_IE_SEQUENCE: - default: - break; - } -} - -static int -l3dss1_get_channel_id(struct l3_process *pc, struct sk_buff *skb) { - u_char *p; - - p = skb->data; - if ((p = findie(p, skb->len, IE_CHANNEL_ID, 0))) { - p++; - if (*p != 1) { /* len for BRI = 1 */ - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "wrong chid len %d", *p); - return (-2); - } - p++; - if (*p & 0x60) { /* only base rate interface */ - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "wrong chid %x", *p); - return (-3); - } - return (*p & 0x3); - } else - return (-1); -} - -static int -l3dss1_get_cause(struct l3_process *pc, struct sk_buff *skb) { - u_char l, i = 0; - u_char *p; - - p = skb->data; - pc->para.cause = 31; - pc->para.loc = 0; - if ((p = findie(p, skb->len, IE_CAUSE, 0))) { - p++; - l = *p++; - if (l > 30) - return (1); - if (l) { - pc->para.loc = *p++; - l--; - } else { - return (2); - } - if (l && !(pc->para.loc & 0x80)) { - l--; - p++; /* skip recommendation */ - } - if (l) { - pc->para.cause = *p++; - l--; - if (!(pc->para.cause & 0x80)) - return (3); - } else - return (4); - while (l && (i < 6)) { - pc->para.diag[i++] = *p++; - l--; - } - } else - return (-1); - return (0); -} - -static void -l3dss1_msg_with_uus(struct l3_process *pc, u_char cmd) -{ - struct sk_buff *skb; - u_char tmp[16 + 40]; - u_char *p = tmp; - int l; - - MsgHead(p, pc->callref, cmd); - - if (pc->prot.dss1.uus1_data[0]) - { *p++ = IE_USER_USER; /* UUS info element */ - *p++ = strlen(pc->prot.dss1.uus1_data) + 1; - *p++ = 0x04; /* IA5 chars */ - strcpy(p, pc->prot.dss1.uus1_data); - p += strlen(pc->prot.dss1.uus1_data); - pc->prot.dss1.uus1_data[0] = '\0'; - } - - l = p - tmp; - if (!(skb = l3_alloc_skb(l))) - return; - skb_put_data(skb, tmp, l); - l3_msg(pc->st, DL_DATA | REQUEST, skb); -} /* l3dss1_msg_with_uus */ - -static void -l3dss1_release_req(struct l3_process *pc, u_char pr, void *arg) -{ - StopAllL3Timer(pc); - newl3state(pc, 19); - if (!pc->prot.dss1.uus1_data[0]) - l3dss1_message(pc, MT_RELEASE); - else - l3dss1_msg_with_uus(pc, MT_RELEASE); - L3AddTimer(&pc->timer, T308, CC_T308_1); -} - -static void -l3dss1_release_cmpl(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - int ret; - - if ((ret = l3dss1_get_cause(pc, skb)) > 0) { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "RELCMPL get_cause ret(%d)", ret); - } else if (ret < 0) - pc->para.cause = NO_CAUSE; - StopAllL3Timer(pc); - newl3state(pc, 0); - pc->st->l3.l3l4(pc->st, CC_RELEASE | CONFIRM, pc); - dss1_release_l3_process(pc); -} - -#ifdef EXT_BEARER_CAPS - -static u_char * -EncodeASyncParams(u_char *p, u_char si2) -{ // 7c 06 88 90 21 42 00 bb - - p[0] = 0; - p[1] = 0x40; // Intermediate rate: 16 kbit/s jj 2000.02.19 - p[2] = 0x80; - if (si2 & 32) // 7 data bits - - p[2] += 16; - else // 8 data bits - - p[2] += 24; - - if (si2 & 16) // 2 stop bits - - p[2] += 96; - else // 1 stop bit - - p[2] += 32; - - if (si2 & 8) // even parity - - p[2] += 2; - else // no parity - - p[2] += 3; - - switch (si2 & 0x07) { - case 0: - p[0] = 66; // 1200 bit/s - - break; - case 1: - p[0] = 88; // 1200/75 bit/s - - break; - case 2: - p[0] = 87; // 75/1200 bit/s - - break; - case 3: - p[0] = 67; // 2400 bit/s - - break; - case 4: - p[0] = 69; // 4800 bit/s - - break; - case 5: - p[0] = 72; // 9600 bit/s - - break; - case 6: - p[0] = 73; // 14400 bit/s - - break; - case 7: - p[0] = 75; // 19200 bit/s - - break; - } - return p + 3; -} - -static u_char -EncodeSyncParams(u_char si2, u_char ai) -{ - - switch (si2) { - case 0: - return ai + 2; // 1200 bit/s - - case 1: - return ai + 24; // 1200/75 bit/s - - case 2: - return ai + 23; // 75/1200 bit/s - - case 3: - return ai + 3; // 2400 bit/s - - case 4: - return ai + 5; // 4800 bit/s - - case 5: - return ai + 8; // 9600 bit/s - - case 6: - return ai + 9; // 14400 bit/s - - case 7: - return ai + 11; // 19200 bit/s - - case 8: - return ai + 14; // 48000 bit/s - - case 9: - return ai + 15; // 56000 bit/s - - case 15: - return ai + 40; // negotiate bit/s - - default: - break; - } - return ai; -} - - -static u_char -DecodeASyncParams(u_char si2, u_char *p) -{ - u_char info; - - switch (p[5]) { - case 66: // 1200 bit/s - - break; // si2 don't change - - case 88: // 1200/75 bit/s - - si2 += 1; - break; - case 87: // 75/1200 bit/s - - si2 += 2; - break; - case 67: // 2400 bit/s - - si2 += 3; - break; - case 69: // 4800 bit/s - - si2 += 4; - break; - case 72: // 9600 bit/s - - si2 += 5; - break; - case 73: // 14400 bit/s - - si2 += 6; - break; - case 75: // 19200 bit/s - - si2 += 7; - break; - } - - info = p[7] & 0x7f; - if ((info & 16) && (!(info & 8))) // 7 data bits - - si2 += 32; // else 8 data bits - - if ((info & 96) == 96) // 2 stop bits - - si2 += 16; // else 1 stop bit - - if ((info & 2) && (!(info & 1))) // even parity - - si2 += 8; // else no parity - - return si2; -} - - -static u_char -DecodeSyncParams(u_char si2, u_char info) -{ - info &= 0x7f; - switch (info) { - case 40: // bit/s negotiation failed ai := 165 not 175! - - return si2 + 15; - case 15: // 56000 bit/s failed, ai := 0 not 169 ! - - return si2 + 9; - case 14: // 48000 bit/s - - return si2 + 8; - case 11: // 19200 bit/s - - return si2 + 7; - case 9: // 14400 bit/s - - return si2 + 6; - case 8: // 9600 bit/s - - return si2 + 5; - case 5: // 4800 bit/s - - return si2 + 4; - case 3: // 2400 bit/s - - return si2 + 3; - case 23: // 75/1200 bit/s - - return si2 + 2; - case 24: // 1200/75 bit/s - - return si2 + 1; - default: // 1200 bit/s - - return si2; - } -} - -static u_char -DecodeSI2(struct sk_buff *skb) -{ - u_char *p; //, *pend=skb->data + skb->len; - - if ((p = findie(skb->data, skb->len, 0x7c, 0))) { - switch (p[4] & 0x0f) { - case 0x01: - if (p[1] == 0x04) // sync. Bitratenadaption - - return DecodeSyncParams(160, p[5]); // V.110/X.30 - - else if (p[1] == 0x06) // async. Bitratenadaption - - return DecodeASyncParams(192, p); // V.110/X.30 - - break; - case 0x08: // if (p[5] == 0x02) // sync. Bitratenadaption - if (p[1] > 3) - return DecodeSyncParams(176, p[5]); // V.120 - break; - } - } - return 0; -} - -#endif - - -static void -l3dss1_setup_req(struct l3_process *pc, u_char pr, - void *arg) -{ - struct sk_buff *skb; - u_char tmp[128]; - u_char *p = tmp; - u_char channel = 0; - - u_char send_keypad; - u_char screen = 0x80; - u_char *teln; - u_char *msn; - u_char *sub; - u_char *sp; - int l; - - MsgHead(p, pc->callref, MT_SETUP); - - teln = pc->para.setup.phone; -#ifndef CONFIG_HISAX_NO_KEYPAD - send_keypad = (strchr(teln, '*') || strchr(teln, '#')) ? 1 : 0; -#else - send_keypad = 0; -#endif -#ifndef CONFIG_HISAX_NO_SENDCOMPLETE - if (!send_keypad) - *p++ = 0xa1; /* complete indicator */ -#endif - /* - * Set Bearer Capability, Map info from 1TR6-convention to EDSS1 - */ - switch (pc->para.setup.si1) { - case 1: /* Telephony */ - *p++ = IE_BEARER; - *p++ = 0x3; /* Length */ - *p++ = 0x90; /* Coding Std. CCITT, 3.1 kHz audio */ - *p++ = 0x90; /* Circuit-Mode 64kbps */ - *p++ = 0xa3; /* A-Law Audio */ - break; - case 5: /* Datatransmission 64k, BTX */ - case 7: /* Datatransmission 64k */ - default: - *p++ = IE_BEARER; - *p++ = 0x2; /* Length */ - *p++ = 0x88; /* Coding Std. CCITT, unrestr. dig. Inform. */ - *p++ = 0x90; /* Circuit-Mode 64kbps */ - break; - } - - if (send_keypad) { - *p++ = IE_KEYPAD; - *p++ = strlen(teln); - while (*teln) - *p++ = (*teln++) & 0x7F; - } - - /* - * What about info2? Mapping to High-Layer-Compatibility? - */ - if ((*teln) && (!send_keypad)) { - /* parse number for special things */ - if (!isdigit(*teln)) { - switch (0x5f & *teln) { - case 'C': - channel = 0x08; - /* fall through */ - case 'P': - channel |= 0x80; - teln++; - if (*teln == '1') - channel |= 0x01; - else - channel |= 0x02; - break; - case 'R': - screen = 0xA0; - break; - case 'D': - screen = 0x80; - break; - - default: - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "Wrong MSN Code"); - break; - } - teln++; - } - } - if (channel) { - *p++ = IE_CHANNEL_ID; - *p++ = 1; - *p++ = channel; - } - msn = pc->para.setup.eazmsn; - sub = NULL; - sp = msn; - while (*sp) { - if ('.' == *sp) { - sub = sp; - *sp = 0; - } else - sp++; - } - if (*msn) { - *p++ = IE_CALLING_PN; - *p++ = strlen(msn) + (screen ? 2 : 1); - /* Classify as AnyPref. */ - if (screen) { - *p++ = 0x01; /* Ext = '0'B, Type = '000'B, Plan = '0001'B. */ - *p++ = screen; - } else - *p++ = 0x81; /* Ext = '1'B, Type = '000'B, Plan = '0001'B. */ - while (*msn) - *p++ = *msn++ & 0x7f; - } - if (sub) { - *sub++ = '.'; - *p++ = IE_CALLING_SUB; - *p++ = strlen(sub) + 2; - *p++ = 0x80; /* NSAP coded */ - *p++ = 0x50; /* local IDI format */ - while (*sub) - *p++ = *sub++ & 0x7f; - } - sub = NULL; - sp = teln; - while (*sp) { - if ('.' == *sp) { - sub = sp; - *sp = 0; - } else - sp++; - } - - if (!send_keypad) { - *p++ = IE_CALLED_PN; - *p++ = strlen(teln) + 1; - /* Classify as AnyPref. */ - *p++ = 0x81; /* Ext = '1'B, Type = '000'B, Plan = '0001'B. */ - while (*teln) - *p++ = *teln++ & 0x7f; - - if (sub) { - *sub++ = '.'; - *p++ = IE_CALLED_SUB; - *p++ = strlen(sub) + 2; - *p++ = 0x80; /* NSAP coded */ - *p++ = 0x50; /* local IDI format */ - while (*sub) - *p++ = *sub++ & 0x7f; - } - } -#ifdef EXT_BEARER_CAPS - if ((pc->para.setup.si2 >= 160) && (pc->para.setup.si2 <= 175)) { // sync. Bitratenadaption, V.110/X.30 - - *p++ = IE_LLC; - *p++ = 0x04; - *p++ = 0x88; - *p++ = 0x90; - *p++ = 0x21; - *p++ = EncodeSyncParams(pc->para.setup.si2 - 160, 0x80); - } else if ((pc->para.setup.si2 >= 176) && (pc->para.setup.si2 <= 191)) { // sync. Bitratenadaption, V.120 - - *p++ = IE_LLC; - *p++ = 0x05; - *p++ = 0x88; - *p++ = 0x90; - *p++ = 0x28; - *p++ = EncodeSyncParams(pc->para.setup.si2 - 176, 0); - *p++ = 0x82; - } else if (pc->para.setup.si2 >= 192) { // async. Bitratenadaption, V.110/X.30 - - *p++ = IE_LLC; - *p++ = 0x06; - *p++ = 0x88; - *p++ = 0x90; - *p++ = 0x21; - p = EncodeASyncParams(p, pc->para.setup.si2 - 192); -#ifndef CONFIG_HISAX_NO_LLC - } else { - switch (pc->para.setup.si1) { - case 1: /* Telephony */ - *p++ = IE_LLC; - *p++ = 0x3; /* Length */ - *p++ = 0x90; /* Coding Std. CCITT, 3.1 kHz audio */ - *p++ = 0x90; /* Circuit-Mode 64kbps */ - *p++ = 0xa3; /* A-Law Audio */ - break; - case 5: /* Datatransmission 64k, BTX */ - case 7: /* Datatransmission 64k */ - default: - *p++ = IE_LLC; - *p++ = 0x2; /* Length */ - *p++ = 0x88; /* Coding Std. CCITT, unrestr. dig. Inform. */ - *p++ = 0x90; /* Circuit-Mode 64kbps */ - break; - } -#endif - } -#endif - l = p - tmp; - if (!(skb = l3_alloc_skb(l))) - return; - skb_put_data(skb, tmp, l); - L3DelTimer(&pc->timer); - L3AddTimer(&pc->timer, T303, CC_T303); - newl3state(pc, 1); - l3_msg(pc->st, DL_DATA | REQUEST, skb); -} - -static void -l3dss1_call_proc(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - int id, ret; - - if ((id = l3dss1_get_channel_id(pc, skb)) >= 0) { - if ((0 == id) || ((3 == id) && (0x10 == pc->para.moderate))) { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "setup answer with wrong chid %x", id); - pc->para.cause = 100; - l3dss1_status_send(pc, pr, NULL); - return; - } - pc->para.bchannel = id; - } else if (1 == pc->state) { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "setup answer wrong chid (ret %d)", id); - if (id == -1) - pc->para.cause = 96; - else - pc->para.cause = 100; - l3dss1_status_send(pc, pr, NULL); - return; - } - /* Now we are on none mandatory IEs */ - ret = check_infoelements(pc, skb, ie_CALL_PROCEEDING); - if (ERR_IE_COMPREHENSION == ret) { - l3dss1_std_ie_err(pc, ret); - return; - } - L3DelTimer(&pc->timer); - newl3state(pc, 3); - L3AddTimer(&pc->timer, T310, CC_T310); - if (ret) /* STATUS for none mandatory IE errors after actions are taken */ - l3dss1_std_ie_err(pc, ret); - pc->st->l3.l3l4(pc->st, CC_PROCEEDING | INDICATION, pc); -} - -static void -l3dss1_setup_ack(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - int id, ret; - - if ((id = l3dss1_get_channel_id(pc, skb)) >= 0) { - if ((0 == id) || ((3 == id) && (0x10 == pc->para.moderate))) { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "setup answer with wrong chid %x", id); - pc->para.cause = 100; - l3dss1_status_send(pc, pr, NULL); - return; - } - pc->para.bchannel = id; - } else { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "setup answer wrong chid (ret %d)", id); - if (id == -1) - pc->para.cause = 96; - else - pc->para.cause = 100; - l3dss1_status_send(pc, pr, NULL); - return; - } - /* Now we are on none mandatory IEs */ - ret = check_infoelements(pc, skb, ie_SETUP_ACKNOWLEDGE); - if (ERR_IE_COMPREHENSION == ret) { - l3dss1_std_ie_err(pc, ret); - return; - } - L3DelTimer(&pc->timer); - newl3state(pc, 2); - L3AddTimer(&pc->timer, T304, CC_T304); - if (ret) /* STATUS for none mandatory IE errors after actions are taken */ - l3dss1_std_ie_err(pc, ret); - pc->st->l3.l3l4(pc->st, CC_MORE_INFO | INDICATION, pc); -} - -static void -l3dss1_disconnect(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - u_char *p; - int ret; - u_char cause = 0; - - StopAllL3Timer(pc); - if ((ret = l3dss1_get_cause(pc, skb))) { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "DISC get_cause ret(%d)", ret); - if (ret < 0) - cause = 96; - else if (ret > 0) - cause = 100; - } - if ((p = findie(skb->data, skb->len, IE_FACILITY, 0))) - l3dss1_parse_facility(pc->st, pc, pc->callref, p); - ret = check_infoelements(pc, skb, ie_DISCONNECT); - if (ERR_IE_COMPREHENSION == ret) - cause = 96; - else if ((!cause) && (ERR_IE_UNRECOGNIZED == ret)) - cause = 99; - ret = pc->state; - newl3state(pc, 12); - if (cause) - newl3state(pc, 19); - if (11 != ret) - pc->st->l3.l3l4(pc->st, CC_DISCONNECT | INDICATION, pc); - else if (!cause) - l3dss1_release_req(pc, pr, NULL); - if (cause) { - l3dss1_message_cause(pc, MT_RELEASE, cause); - L3AddTimer(&pc->timer, T308, CC_T308_1); - } -} - -static void -l3dss1_connect(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - int ret; - - ret = check_infoelements(pc, skb, ie_CONNECT); - if (ERR_IE_COMPREHENSION == ret) { - l3dss1_std_ie_err(pc, ret); - return; - } - L3DelTimer(&pc->timer); /* T310 */ - newl3state(pc, 10); - pc->para.chargeinfo = 0; - /* here should inserted COLP handling KKe */ - if (ret) - l3dss1_std_ie_err(pc, ret); - pc->st->l3.l3l4(pc->st, CC_SETUP | CONFIRM, pc); -} - -static void -l3dss1_alerting(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - int ret; - - ret = check_infoelements(pc, skb, ie_ALERTING); - if (ERR_IE_COMPREHENSION == ret) { - l3dss1_std_ie_err(pc, ret); - return; - } - L3DelTimer(&pc->timer); /* T304 */ - newl3state(pc, 4); - if (ret) - l3dss1_std_ie_err(pc, ret); - pc->st->l3.l3l4(pc->st, CC_ALERTING | INDICATION, pc); -} - -static void -l3dss1_setup(struct l3_process *pc, u_char pr, void *arg) -{ - u_char *p; - int bcfound = 0; - char tmp[80]; - struct sk_buff *skb = arg; - int id; - int err = 0; - - /* - * Bearer Capabilities - */ - p = skb->data; - /* only the first occurrence 'll be detected ! */ - if ((p = findie(p, skb->len, 0x04, 0))) { - if ((p[1] < 2) || (p[1] > 11)) - err = 1; - else { - pc->para.setup.si2 = 0; - switch (p[2] & 0x7f) { - case 0x00: /* Speech */ - case 0x10: /* 3.1 Khz audio */ - pc->para.setup.si1 = 1; - break; - case 0x08: /* Unrestricted digital information */ - pc->para.setup.si1 = 7; -/* JIM, 05.11.97 I wanna set service indicator 2 */ -#ifdef EXT_BEARER_CAPS - pc->para.setup.si2 = DecodeSI2(skb); -#endif - break; - case 0x09: /* Restricted digital information */ - pc->para.setup.si1 = 2; - break; - case 0x11: - /* Unrestr. digital information with - * tones/announcements ( or 7 kHz audio - */ - pc->para.setup.si1 = 3; - break; - case 0x18: /* Video */ - pc->para.setup.si1 = 4; - break; - default: - err = 2; - break; - } - switch (p[3] & 0x7f) { - case 0x40: /* packed mode */ - pc->para.setup.si1 = 8; - break; - case 0x10: /* 64 kbit */ - case 0x11: /* 2*64 kbit */ - case 0x13: /* 384 kbit */ - case 0x15: /* 1536 kbit */ - case 0x17: /* 1920 kbit */ - pc->para.moderate = p[3] & 0x7f; - break; - default: - err = 3; - break; - } - } - if (pc->debug & L3_DEB_SI) - l3_debug(pc->st, "SI=%d, AI=%d", - pc->para.setup.si1, pc->para.setup.si2); - if (err) { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "setup with wrong bearer(l=%d:%x,%x)", - p[1], p[2], p[3]); - pc->para.cause = 100; - l3dss1_msg_without_setup(pc, pr, NULL); - return; - } - } else { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "setup without bearer capabilities"); - /* ETS 300-104 1.3.3 */ - pc->para.cause = 96; - l3dss1_msg_without_setup(pc, pr, NULL); - return; - } - /* - * Channel Identification - */ - if ((id = l3dss1_get_channel_id(pc, skb)) >= 0) { - if ((pc->para.bchannel = id)) { - if ((3 == id) && (0x10 == pc->para.moderate)) { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "setup with wrong chid %x", - id); - pc->para.cause = 100; - l3dss1_msg_without_setup(pc, pr, NULL); - return; - } - bcfound++; - } else - { if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "setup without bchannel, call waiting"); - bcfound++; - } - } else { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "setup with wrong chid ret %d", id); - if (id == -1) - pc->para.cause = 96; - else - pc->para.cause = 100; - l3dss1_msg_without_setup(pc, pr, NULL); - return; - } - /* Now we are on none mandatory IEs */ - err = check_infoelements(pc, skb, ie_SETUP); - if (ERR_IE_COMPREHENSION == err) { - pc->para.cause = 96; - l3dss1_msg_without_setup(pc, pr, NULL); - return; - } - p = skb->data; - if ((p = findie(p, skb->len, 0x70, 0))) - iecpy(pc->para.setup.eazmsn, p, 1); - else - pc->para.setup.eazmsn[0] = 0; - - p = skb->data; - if ((p = findie(p, skb->len, 0x71, 0))) { - /* Called party subaddress */ - if ((p[1] >= 2) && (p[2] == 0x80) && (p[3] == 0x50)) { - tmp[0] = '.'; - iecpy(&tmp[1], p, 2); - strcat(pc->para.setup.eazmsn, tmp); - } else if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "wrong called subaddress"); - } - p = skb->data; - if ((p = findie(p, skb->len, 0x6c, 0))) { - pc->para.setup.plan = p[2]; - if (p[2] & 0x80) { - iecpy(pc->para.setup.phone, p, 1); - pc->para.setup.screen = 0; - } else { - iecpy(pc->para.setup.phone, p, 2); - pc->para.setup.screen = p[3]; - } - } else { - pc->para.setup.phone[0] = 0; - pc->para.setup.plan = 0; - pc->para.setup.screen = 0; - } - p = skb->data; - if ((p = findie(p, skb->len, 0x6d, 0))) { - /* Calling party subaddress */ - if ((p[1] >= 2) && (p[2] == 0x80) && (p[3] == 0x50)) { - tmp[0] = '.'; - iecpy(&tmp[1], p, 2); - strcat(pc->para.setup.phone, tmp); - } else if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "wrong calling subaddress"); - } - newl3state(pc, 6); - if (err) /* STATUS for none mandatory IE errors after actions are taken */ - l3dss1_std_ie_err(pc, err); - pc->st->l3.l3l4(pc->st, CC_SETUP | INDICATION, pc); -} - -static void -l3dss1_reset(struct l3_process *pc, u_char pr, void *arg) -{ - dss1_release_l3_process(pc); -} - -static void -l3dss1_disconnect_req(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb; - u_char tmp[16 + 40]; - u_char *p = tmp; - int l; - u_char cause = 16; - - if (pc->para.cause != NO_CAUSE) - cause = pc->para.cause; - - StopAllL3Timer(pc); - - MsgHead(p, pc->callref, MT_DISCONNECT); - - *p++ = IE_CAUSE; - *p++ = 0x2; - *p++ = 0x80; - *p++ = cause | 0x80; - - if (pc->prot.dss1.uus1_data[0]) - { *p++ = IE_USER_USER; /* UUS info element */ - *p++ = strlen(pc->prot.dss1.uus1_data) + 1; - *p++ = 0x04; /* IA5 chars */ - strcpy(p, pc->prot.dss1.uus1_data); - p += strlen(pc->prot.dss1.uus1_data); - pc->prot.dss1.uus1_data[0] = '\0'; - } - - l = p - tmp; - if (!(skb = l3_alloc_skb(l))) - return; - skb_put_data(skb, tmp, l); - newl3state(pc, 11); - l3_msg(pc->st, DL_DATA | REQUEST, skb); - L3AddTimer(&pc->timer, T305, CC_T305); -} - -static void -l3dss1_setup_rsp(struct l3_process *pc, u_char pr, - void *arg) -{ - if (!pc->para.bchannel) - { if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "D-chan connect for waiting call"); - l3dss1_disconnect_req(pc, pr, arg); - return; - } - newl3state(pc, 8); - l3dss1_message(pc, MT_CONNECT); - L3DelTimer(&pc->timer); - L3AddTimer(&pc->timer, T313, CC_T313); -} - -static void -l3dss1_connect_ack(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - int ret; - - ret = check_infoelements(pc, skb, ie_CONNECT_ACKNOWLEDGE); - if (ERR_IE_COMPREHENSION == ret) { - l3dss1_std_ie_err(pc, ret); - return; - } - newl3state(pc, 10); - L3DelTimer(&pc->timer); - if (ret) - l3dss1_std_ie_err(pc, ret); - pc->st->l3.l3l4(pc->st, CC_SETUP_COMPL | INDICATION, pc); -} - -static void -l3dss1_reject_req(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb; - u_char tmp[16]; - u_char *p = tmp; - int l; - u_char cause = 21; - - if (pc->para.cause != NO_CAUSE) - cause = pc->para.cause; - - MsgHead(p, pc->callref, MT_RELEASE_COMPLETE); - - *p++ = IE_CAUSE; - *p++ = 0x2; - *p++ = 0x80; - *p++ = cause | 0x80; - - l = p - tmp; - if (!(skb = l3_alloc_skb(l))) - return; - skb_put_data(skb, tmp, l); - l3_msg(pc->st, DL_DATA | REQUEST, skb); - pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc); - newl3state(pc, 0); - dss1_release_l3_process(pc); -} - -static void -l3dss1_release(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - u_char *p; - int ret, cause = 0; - - StopAllL3Timer(pc); - if ((ret = l3dss1_get_cause(pc, skb)) > 0) { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "REL get_cause ret(%d)", ret); - } else if (ret < 0) - pc->para.cause = NO_CAUSE; - if ((p = findie(skb->data, skb->len, IE_FACILITY, 0))) { - l3dss1_parse_facility(pc->st, pc, pc->callref, p); - } - if ((ret < 0) && (pc->state != 11)) - cause = 96; - else if (ret > 0) - cause = 100; - ret = check_infoelements(pc, skb, ie_RELEASE); - if (ERR_IE_COMPREHENSION == ret) - cause = 96; - else if ((ERR_IE_UNRECOGNIZED == ret) && (!cause)) - cause = 99; - if (cause) - l3dss1_message_cause(pc, MT_RELEASE_COMPLETE, cause); - else - l3dss1_message(pc, MT_RELEASE_COMPLETE); - pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc); - newl3state(pc, 0); - dss1_release_l3_process(pc); -} - -static void -l3dss1_alert_req(struct l3_process *pc, u_char pr, - void *arg) -{ - newl3state(pc, 7); - if (!pc->prot.dss1.uus1_data[0]) - l3dss1_message(pc, MT_ALERTING); - else - l3dss1_msg_with_uus(pc, MT_ALERTING); -} - -static void -l3dss1_proceed_req(struct l3_process *pc, u_char pr, - void *arg) -{ - newl3state(pc, 9); - l3dss1_message(pc, MT_CALL_PROCEEDING); - pc->st->l3.l3l4(pc->st, CC_PROCEED_SEND | INDICATION, pc); -} - -static void -l3dss1_setup_ack_req(struct l3_process *pc, u_char pr, - void *arg) -{ - newl3state(pc, 25); - L3DelTimer(&pc->timer); - L3AddTimer(&pc->timer, T302, CC_T302); - l3dss1_message(pc, MT_SETUP_ACKNOWLEDGE); -} - -/********************************************/ -/* deliver a incoming display message to HL */ -/********************************************/ -static void -l3dss1_deliver_display(struct l3_process *pc, int pr, u_char *infp) -{ u_char len; - isdn_ctrl ic; - struct IsdnCardState *cs; - char *p; - - if (*infp++ != IE_DISPLAY) return; - if ((len = *infp++) > 80) return; /* total length <= 82 */ - if (!pc->chan) return; - - p = ic.parm.display; - while (len--) - *p++ = *infp++; - *p = '\0'; - ic.command = ISDN_STAT_DISPLAY; - cs = pc->st->l1.hardware; - ic.driver = cs->myid; - ic.arg = pc->chan->chan; - cs->iif.statcallb(&ic); -} /* l3dss1_deliver_display */ - - -static void -l3dss1_progress(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - int err = 0; - u_char *p; - - if ((p = findie(skb->data, skb->len, IE_PROGRESS, 0))) { - if (p[1] != 2) { - err = 1; - pc->para.cause = 100; - } else if (!(p[2] & 0x70)) { - switch (p[2]) { - case 0x80: - case 0x81: - case 0x82: - case 0x84: - case 0x85: - case 0x87: - case 0x8a: - switch (p[3]) { - case 0x81: - case 0x82: - case 0x83: - case 0x84: - case 0x88: - break; - default: - err = 2; - pc->para.cause = 100; - break; - } - break; - default: - err = 3; - pc->para.cause = 100; - break; - } - } - } else { - pc->para.cause = 96; - err = 4; - } - if (err) { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "progress error %d", err); - l3dss1_status_send(pc, pr, NULL); - return; - } - /* Now we are on none mandatory IEs */ - err = check_infoelements(pc, skb, ie_PROGRESS); - if (err) - l3dss1_std_ie_err(pc, err); - if (ERR_IE_COMPREHENSION != err) - pc->st->l3.l3l4(pc->st, CC_PROGRESS | INDICATION, pc); -} - -static void -l3dss1_notify(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - int err = 0; - u_char *p; - - if ((p = findie(skb->data, skb->len, IE_NOTIFY, 0))) { - if (p[1] != 1) { - err = 1; - pc->para.cause = 100; - } else { - switch (p[2]) { - case 0x80: - case 0x81: - case 0x82: - break; - default: - pc->para.cause = 100; - err = 2; - break; - } - } - } else { - pc->para.cause = 96; - err = 3; - } - if (err) { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "notify error %d", err); - l3dss1_status_send(pc, pr, NULL); - return; - } - /* Now we are on none mandatory IEs */ - err = check_infoelements(pc, skb, ie_NOTIFY); - if (err) - l3dss1_std_ie_err(pc, err); - if (ERR_IE_COMPREHENSION != err) - pc->st->l3.l3l4(pc->st, CC_NOTIFY | INDICATION, pc); -} - -static void -l3dss1_status_enq(struct l3_process *pc, u_char pr, void *arg) -{ - int ret; - struct sk_buff *skb = arg; - - ret = check_infoelements(pc, skb, ie_STATUS_ENQUIRY); - l3dss1_std_ie_err(pc, ret); - pc->para.cause = 30; /* response to STATUS_ENQUIRY */ - l3dss1_status_send(pc, pr, NULL); -} - -static void -l3dss1_information(struct l3_process *pc, u_char pr, void *arg) -{ - int ret; - struct sk_buff *skb = arg; - u_char *p; - char tmp[32]; - - ret = check_infoelements(pc, skb, ie_INFORMATION); - if (ret) - l3dss1_std_ie_err(pc, ret); - if (pc->state == 25) { /* overlap receiving */ - L3DelTimer(&pc->timer); - p = skb->data; - if ((p = findie(p, skb->len, 0x70, 0))) { - iecpy(tmp, p, 1); - strcat(pc->para.setup.eazmsn, tmp); - pc->st->l3.l3l4(pc->st, CC_MORE_INFO | INDICATION, pc); - } - L3AddTimer(&pc->timer, T302, CC_T302); - } -} - -/******************************/ -/* handle deflection requests */ -/******************************/ -static void l3dss1_redir_req(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb; - u_char tmp[128]; - u_char *p = tmp; - u_char *subp; - u_char len_phone = 0; - u_char len_sub = 0; - int l; - - - strcpy(pc->prot.dss1.uus1_data, pc->chan->setup.eazmsn); /* copy uus element if available */ - if (!pc->chan->setup.phone[0]) - { pc->para.cause = -1; - l3dss1_disconnect_req(pc, pr, arg); /* disconnect immediately */ - return; - } /* only uus */ - - if (pc->prot.dss1.invoke_id) - free_invoke_id(pc->st, pc->prot.dss1.invoke_id); - - if (!(pc->prot.dss1.invoke_id = new_invoke_id(pc->st))) - return; - - MsgHead(p, pc->callref, MT_FACILITY); - - for (subp = pc->chan->setup.phone; (*subp) && (*subp != '.'); subp++) len_phone++; /* len of phone number */ - if (*subp++ == '.') len_sub = strlen(subp) + 2; /* length including info subaddress element */ - - *p++ = 0x1c; /* Facility info element */ - *p++ = len_phone + len_sub + 2 + 2 + 8 + 3 + 3; /* length of element */ - *p++ = 0x91; /* remote operations protocol */ - *p++ = 0xa1; /* invoke component */ - - *p++ = len_phone + len_sub + 2 + 2 + 8 + 3; /* length of data */ - *p++ = 0x02; /* invoke id tag, integer */ - *p++ = 0x01; /* length */ - *p++ = pc->prot.dss1.invoke_id; /* invoke id */ - *p++ = 0x02; /* operation value tag, integer */ - *p++ = 0x01; /* length */ - *p++ = 0x0D; /* Call Deflect */ - - *p++ = 0x30; /* sequence phone number */ - *p++ = len_phone + 2 + 2 + 3 + len_sub; /* length */ - - *p++ = 0x30; /* Deflected to UserNumber */ - *p++ = len_phone + 2 + len_sub; /* length */ - *p++ = 0x80; /* NumberDigits */ - *p++ = len_phone; /* length */ - for (l = 0; l < len_phone; l++) - *p++ = pc->chan->setup.phone[l]; - - if (len_sub) - { *p++ = 0x04; /* called party subaddress */ - *p++ = len_sub - 2; - while (*subp) *p++ = *subp++; - } - - *p++ = 0x01; /* screening identifier */ - *p++ = 0x01; - *p++ = pc->chan->setup.screen; - - l = p - tmp; - if (!(skb = l3_alloc_skb(l))) return; - skb_put_data(skb, tmp, l); - - l3_msg(pc->st, DL_DATA | REQUEST, skb); -} /* l3dss1_redir_req */ - -/********************************************/ -/* handle deflection request in early state */ -/********************************************/ -static void l3dss1_redir_req_early(struct l3_process *pc, u_char pr, void *arg) -{ - l3dss1_proceed_req(pc, pr, arg); - l3dss1_redir_req(pc, pr, arg); -} /* l3dss1_redir_req_early */ - -/***********************************************/ -/* handle special commands for this protocol. */ -/* Examples are call independent services like */ -/* remote operations with dummy callref. */ -/***********************************************/ -static int l3dss1_cmd_global(struct PStack *st, isdn_ctrl *ic) -{ u_char id; - u_char temp[265]; - u_char *p = temp; - int i, l, proc_len; - struct sk_buff *skb; - struct l3_process *pc = NULL; - - switch (ic->arg) - { case DSS1_CMD_INVOKE: - if (ic->parm.dss1_io.datalen < 0) return (-2); /* invalid parameter */ - - for (proc_len = 1, i = ic->parm.dss1_io.proc >> 8; i; i++) - i = i >> 8; /* add one byte */ - l = ic->parm.dss1_io.datalen + proc_len + 8; /* length excluding ie header */ - if (l > 255) - return (-2); /* too long */ - - if (!(id = new_invoke_id(st))) - return (0); /* first get a invoke id -> return if no available */ - - i = -1; - MsgHead(p, i, MT_FACILITY); /* build message head */ - *p++ = 0x1C; /* Facility IE */ - *p++ = l; /* length of ie */ - *p++ = 0x91; /* remote operations */ - *p++ = 0xA1; /* invoke */ - *p++ = l - 3; /* length of invoke */ - *p++ = 0x02; /* invoke id tag */ - *p++ = 0x01; /* length is 1 */ - *p++ = id; /* invoke id */ - *p++ = 0x02; /* operation */ - *p++ = proc_len; /* length of operation */ - - for (i = proc_len; i; i--) - *p++ = (ic->parm.dss1_io.proc >> (i - 1)) & 0xFF; - memcpy(p, ic->parm.dss1_io.data, ic->parm.dss1_io.datalen); /* copy data */ - l = (p - temp) + ic->parm.dss1_io.datalen; /* total length */ - - if (ic->parm.dss1_io.timeout > 0) - if (!(pc = dss1_new_l3_process(st, -1))) - { free_invoke_id(st, id); - return (-2); - } - pc->prot.dss1.ll_id = ic->parm.dss1_io.ll_id; /* remember id */ - pc->prot.dss1.proc = ic->parm.dss1_io.proc; /* and procedure */ - - if (!(skb = l3_alloc_skb(l))) - { free_invoke_id(st, id); - if (pc) dss1_release_l3_process(pc); - return (-2); - } - skb_put_data(skb, temp, l); - - if (pc) - { pc->prot.dss1.invoke_id = id; /* remember id */ - L3AddTimer(&pc->timer, ic->parm.dss1_io.timeout, CC_TDSS1_IO | REQUEST); - } - - l3_msg(st, DL_DATA | REQUEST, skb); - ic->parm.dss1_io.hl_id = id; /* return id */ - return (0); - - case DSS1_CMD_INVOKE_ABORT: - if ((pc = l3dss1_search_dummy_proc(st, ic->parm.dss1_io.hl_id))) - { L3DelTimer(&pc->timer); /* remove timer */ - dss1_release_l3_process(pc); - return (0); - } - else - { l3_debug(st, "l3dss1_cmd_global abort unknown id"); - return (-2); - } - break; - - default: - l3_debug(st, "l3dss1_cmd_global unknown cmd 0x%lx", ic->arg); - return (-1); - } /* switch ic-> arg */ - return (-1); -} /* l3dss1_cmd_global */ - -static void -l3dss1_io_timer(struct l3_process *pc) -{ isdn_ctrl ic; - struct IsdnCardState *cs = pc->st->l1.hardware; - - L3DelTimer(&pc->timer); /* remove timer */ - - ic.driver = cs->myid; - ic.command = ISDN_STAT_PROT; - ic.arg = DSS1_STAT_INVOKE_ERR; - ic.parm.dss1_io.hl_id = pc->prot.dss1.invoke_id; - ic.parm.dss1_io.ll_id = pc->prot.dss1.ll_id; - ic.parm.dss1_io.proc = pc->prot.dss1.proc; - ic.parm.dss1_io.timeout = -1; - ic.parm.dss1_io.datalen = 0; - ic.parm.dss1_io.data = NULL; - free_invoke_id(pc->st, pc->prot.dss1.invoke_id); - pc->prot.dss1.invoke_id = 0; /* reset id */ - - cs->iif.statcallb(&ic); - - dss1_release_l3_process(pc); -} /* l3dss1_io_timer */ - -static void -l3dss1_release_ind(struct l3_process *pc, u_char pr, void *arg) -{ - u_char *p; - struct sk_buff *skb = arg; - int callState = 0; - p = skb->data; - - if ((p = findie(p, skb->len, IE_CALL_STATE, 0))) { - p++; - if (1 == *p++) - callState = *p; - } - if (callState == 0) { - /* ETS 300-104 7.6.1, 8.6.1, 10.6.1... and 16.1 - * set down layer 3 without sending any message - */ - pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc); - newl3state(pc, 0); - dss1_release_l3_process(pc); - } else { - pc->st->l3.l3l4(pc->st, CC_IGNORE | INDICATION, pc); - } -} - -static void -l3dss1_dummy(struct l3_process *pc, u_char pr, void *arg) -{ -} - -static void -l3dss1_t302(struct l3_process *pc, u_char pr, void *arg) -{ - L3DelTimer(&pc->timer); - pc->para.loc = 0; - pc->para.cause = 28; /* invalid number */ - l3dss1_disconnect_req(pc, pr, NULL); - pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc); -} - -static void -l3dss1_t303(struct l3_process *pc, u_char pr, void *arg) -{ - if (pc->N303 > 0) { - pc->N303--; - L3DelTimer(&pc->timer); - l3dss1_setup_req(pc, pr, arg); - } else { - L3DelTimer(&pc->timer); - l3dss1_message_cause(pc, MT_RELEASE_COMPLETE, 102); - pc->st->l3.l3l4(pc->st, CC_NOSETUP_RSP, pc); - dss1_release_l3_process(pc); - } -} - -static void -l3dss1_t304(struct l3_process *pc, u_char pr, void *arg) -{ - L3DelTimer(&pc->timer); - pc->para.loc = 0; - pc->para.cause = 102; - l3dss1_disconnect_req(pc, pr, NULL); - pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc); - -} - -static void -l3dss1_t305(struct l3_process *pc, u_char pr, void *arg) -{ - u_char tmp[16]; - u_char *p = tmp; - int l; - struct sk_buff *skb; - u_char cause = 16; - - L3DelTimer(&pc->timer); - if (pc->para.cause != NO_CAUSE) - cause = pc->para.cause; - - MsgHead(p, pc->callref, MT_RELEASE); - - *p++ = IE_CAUSE; - *p++ = 0x2; - *p++ = 0x80; - *p++ = cause | 0x80; - - l = p - tmp; - if (!(skb = l3_alloc_skb(l))) - return; - skb_put_data(skb, tmp, l); - newl3state(pc, 19); - l3_msg(pc->st, DL_DATA | REQUEST, skb); - L3AddTimer(&pc->timer, T308, CC_T308_1); -} - -static void -l3dss1_t310(struct l3_process *pc, u_char pr, void *arg) -{ - L3DelTimer(&pc->timer); - pc->para.loc = 0; - pc->para.cause = 102; - l3dss1_disconnect_req(pc, pr, NULL); - pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc); -} - -static void -l3dss1_t313(struct l3_process *pc, u_char pr, void *arg) -{ - L3DelTimer(&pc->timer); - pc->para.loc = 0; - pc->para.cause = 102; - l3dss1_disconnect_req(pc, pr, NULL); - pc->st->l3.l3l4(pc->st, CC_CONNECT_ERR, pc); -} - -static void -l3dss1_t308_1(struct l3_process *pc, u_char pr, void *arg) -{ - newl3state(pc, 19); - L3DelTimer(&pc->timer); - l3dss1_message(pc, MT_RELEASE); - L3AddTimer(&pc->timer, T308, CC_T308_2); -} - -static void -l3dss1_t308_2(struct l3_process *pc, u_char pr, void *arg) -{ - L3DelTimer(&pc->timer); - pc->st->l3.l3l4(pc->st, CC_RELEASE_ERR, pc); - dss1_release_l3_process(pc); -} - -static void -l3dss1_t318(struct l3_process *pc, u_char pr, void *arg) -{ - L3DelTimer(&pc->timer); - pc->para.cause = 102; /* Timer expiry */ - pc->para.loc = 0; /* local */ - pc->st->l3.l3l4(pc->st, CC_RESUME_ERR, pc); - newl3state(pc, 19); - l3dss1_message(pc, MT_RELEASE); - L3AddTimer(&pc->timer, T308, CC_T308_1); -} - -static void -l3dss1_t319(struct l3_process *pc, u_char pr, void *arg) -{ - L3DelTimer(&pc->timer); - pc->para.cause = 102; /* Timer expiry */ - pc->para.loc = 0; /* local */ - pc->st->l3.l3l4(pc->st, CC_SUSPEND_ERR, pc); - newl3state(pc, 10); -} - -static void -l3dss1_restart(struct l3_process *pc, u_char pr, void *arg) -{ - L3DelTimer(&pc->timer); - pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc); - dss1_release_l3_process(pc); -} - -static void -l3dss1_status(struct l3_process *pc, u_char pr, void *arg) -{ - u_char *p; - struct sk_buff *skb = arg; - int ret; - u_char cause = 0, callState = 0; - - if ((ret = l3dss1_get_cause(pc, skb))) { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "STATUS get_cause ret(%d)", ret); - if (ret < 0) - cause = 96; - else if (ret > 0) - cause = 100; - } - if ((p = findie(skb->data, skb->len, IE_CALL_STATE, 0))) { - p++; - if (1 == *p++) { - callState = *p; - if (!ie_in_set(pc, *p, l3_valid_states)) - cause = 100; - } else - cause = 100; - } else - cause = 96; - if (!cause) { /* no error before */ - ret = check_infoelements(pc, skb, ie_STATUS); - if (ERR_IE_COMPREHENSION == ret) - cause = 96; - else if (ERR_IE_UNRECOGNIZED == ret) - cause = 99; - } - if (cause) { - u_char tmp; - - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "STATUS error(%d/%d)", ret, cause); - tmp = pc->para.cause; - pc->para.cause = cause; - l3dss1_status_send(pc, 0, NULL); - if (cause == 99) - pc->para.cause = tmp; - else - return; - } - cause = pc->para.cause; - if (((cause & 0x7f) == 111) && (callState == 0)) { - /* ETS 300-104 7.6.1, 8.6.1, 10.6.1... - * if received MT_STATUS with cause == 111 and call - * state == 0, then we must set down layer 3 - */ - pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc); - newl3state(pc, 0); - dss1_release_l3_process(pc); - } -} - -static void -l3dss1_facility(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - int ret; - - ret = check_infoelements(pc, skb, ie_FACILITY); - l3dss1_std_ie_err(pc, ret); - { - u_char *p; - if ((p = findie(skb->data, skb->len, IE_FACILITY, 0))) - l3dss1_parse_facility(pc->st, pc, pc->callref, p); - } -} - -static void -l3dss1_suspend_req(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb; - u_char tmp[32]; - u_char *p = tmp; - u_char i, l; - u_char *msg = pc->chan->setup.phone; - - MsgHead(p, pc->callref, MT_SUSPEND); - l = *msg++; - if (l && (l <= 10)) { /* Max length 10 octets */ - *p++ = IE_CALL_ID; - *p++ = l; - for (i = 0; i < l; i++) - *p++ = *msg++; - } else if (l) { - l3_debug(pc->st, "SUS wrong CALL_ID len %d", l); - return; - } - l = p - tmp; - if (!(skb = l3_alloc_skb(l))) - return; - skb_put_data(skb, tmp, l); - l3_msg(pc->st, DL_DATA | REQUEST, skb); - newl3state(pc, 15); - L3AddTimer(&pc->timer, T319, CC_T319); -} - -static void -l3dss1_suspend_ack(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - int ret; - - L3DelTimer(&pc->timer); - newl3state(pc, 0); - pc->para.cause = NO_CAUSE; - pc->st->l3.l3l4(pc->st, CC_SUSPEND | CONFIRM, pc); - /* We don't handle suspend_ack for IE errors now */ - if ((ret = check_infoelements(pc, skb, ie_SUSPEND_ACKNOWLEDGE))) - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "SUSPACK check ie(%d)", ret); - dss1_release_l3_process(pc); -} - -static void -l3dss1_suspend_rej(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - int ret; - - if ((ret = l3dss1_get_cause(pc, skb))) { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "SUSP_REJ get_cause ret(%d)", ret); - if (ret < 0) - pc->para.cause = 96; - else - pc->para.cause = 100; - l3dss1_status_send(pc, pr, NULL); - return; - } - ret = check_infoelements(pc, skb, ie_SUSPEND_REJECT); - if (ERR_IE_COMPREHENSION == ret) { - l3dss1_std_ie_err(pc, ret); - return; - } - L3DelTimer(&pc->timer); - pc->st->l3.l3l4(pc->st, CC_SUSPEND_ERR, pc); - newl3state(pc, 10); - if (ret) /* STATUS for none mandatory IE errors after actions are taken */ - l3dss1_std_ie_err(pc, ret); -} - -static void -l3dss1_resume_req(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb; - u_char tmp[32]; - u_char *p = tmp; - u_char i, l; - u_char *msg = pc->para.setup.phone; - - MsgHead(p, pc->callref, MT_RESUME); - - l = *msg++; - if (l && (l <= 10)) { /* Max length 10 octets */ - *p++ = IE_CALL_ID; - *p++ = l; - for (i = 0; i < l; i++) - *p++ = *msg++; - } else if (l) { - l3_debug(pc->st, "RES wrong CALL_ID len %d", l); - return; - } - l = p - tmp; - if (!(skb = l3_alloc_skb(l))) - return; - skb_put_data(skb, tmp, l); - l3_msg(pc->st, DL_DATA | REQUEST, skb); - newl3state(pc, 17); - L3AddTimer(&pc->timer, T318, CC_T318); -} - -static void -l3dss1_resume_ack(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - int id, ret; - - if ((id = l3dss1_get_channel_id(pc, skb)) > 0) { - if ((0 == id) || ((3 == id) && (0x10 == pc->para.moderate))) { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "resume ack with wrong chid %x", id); - pc->para.cause = 100; - l3dss1_status_send(pc, pr, NULL); - return; - } - pc->para.bchannel = id; - } else if (1 == pc->state) { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "resume ack without chid (ret %d)", id); - pc->para.cause = 96; - l3dss1_status_send(pc, pr, NULL); - return; - } - ret = check_infoelements(pc, skb, ie_RESUME_ACKNOWLEDGE); - if (ERR_IE_COMPREHENSION == ret) { - l3dss1_std_ie_err(pc, ret); - return; - } - L3DelTimer(&pc->timer); - pc->st->l3.l3l4(pc->st, CC_RESUME | CONFIRM, pc); - newl3state(pc, 10); - if (ret) /* STATUS for none mandatory IE errors after actions are taken */ - l3dss1_std_ie_err(pc, ret); -} - -static void -l3dss1_resume_rej(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - int ret; - - if ((ret = l3dss1_get_cause(pc, skb))) { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "RES_REJ get_cause ret(%d)", ret); - if (ret < 0) - pc->para.cause = 96; - else - pc->para.cause = 100; - l3dss1_status_send(pc, pr, NULL); - return; - } - ret = check_infoelements(pc, skb, ie_RESUME_REJECT); - if (ERR_IE_COMPREHENSION == ret) { - l3dss1_std_ie_err(pc, ret); - return; - } - L3DelTimer(&pc->timer); - pc->st->l3.l3l4(pc->st, CC_RESUME_ERR, pc); - newl3state(pc, 0); - if (ret) /* STATUS for none mandatory IE errors after actions are taken */ - l3dss1_std_ie_err(pc, ret); - dss1_release_l3_process(pc); -} - -static void -l3dss1_global_restart(struct l3_process *pc, u_char pr, void *arg) -{ - u_char tmp[32]; - u_char *p; - u_char ri, ch = 0, chan = 0; - int l; - struct sk_buff *skb = arg; - struct l3_process *up; - - newl3state(pc, 2); - L3DelTimer(&pc->timer); - p = skb->data; - if ((p = findie(p, skb->len, IE_RESTART_IND, 0))) { - ri = p[2]; - l3_debug(pc->st, "Restart %x", ri); - } else { - l3_debug(pc->st, "Restart without restart IE"); - ri = 0x86; - } - p = skb->data; - if ((p = findie(p, skb->len, IE_CHANNEL_ID, 0))) { - chan = p[2] & 3; - ch = p[2]; - if (pc->st->l3.debug) - l3_debug(pc->st, "Restart for channel %d", chan); - } - newl3state(pc, 2); - up = pc->st->l3.proc; - while (up) { - if ((ri & 7) == 7) - up->st->lli.l4l3(up->st, CC_RESTART | REQUEST, up); - else if (up->para.bchannel == chan) - up->st->lli.l4l3(up->st, CC_RESTART | REQUEST, up); - up = up->next; - } - p = tmp; - MsgHead(p, pc->callref, MT_RESTART_ACKNOWLEDGE); - if (chan) { - *p++ = IE_CHANNEL_ID; - *p++ = 1; - *p++ = ch | 0x80; - } - *p++ = 0x79; /* RESTART Ind */ - *p++ = 1; - *p++ = ri; - l = p - tmp; - if (!(skb = l3_alloc_skb(l))) - return; - skb_put_data(skb, tmp, l); - newl3state(pc, 0); - l3_msg(pc->st, DL_DATA | REQUEST, skb); -} - -static void -l3dss1_dl_reset(struct l3_process *pc, u_char pr, void *arg) -{ - pc->para.cause = 0x29; /* Temporary failure */ - pc->para.loc = 0; - l3dss1_disconnect_req(pc, pr, NULL); - pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc); -} - -static void -l3dss1_dl_release(struct l3_process *pc, u_char pr, void *arg) -{ - newl3state(pc, 0); - pc->para.cause = 0x1b; /* Destination out of order */ - pc->para.loc = 0; - pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc); - release_l3_process(pc); -} - -static void -l3dss1_dl_reestablish(struct l3_process *pc, u_char pr, void *arg) -{ - L3DelTimer(&pc->timer); - L3AddTimer(&pc->timer, T309, CC_T309); - l3_msg(pc->st, DL_ESTABLISH | REQUEST, NULL); -} - -static void -l3dss1_dl_reest_status(struct l3_process *pc, u_char pr, void *arg) -{ - L3DelTimer(&pc->timer); - - pc->para.cause = 0x1F; /* normal, unspecified */ - l3dss1_status_send(pc, 0, NULL); -} - -/* *INDENT-OFF* */ -static struct stateentry downstatelist[] = -{ - {SBIT(0), - CC_SETUP | REQUEST, l3dss1_setup_req}, - {SBIT(0), - CC_RESUME | REQUEST, l3dss1_resume_req}, - {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(6) | SBIT(7) | SBIT(8) | SBIT(9) | SBIT(10) | SBIT(25), - CC_DISCONNECT | REQUEST, l3dss1_disconnect_req}, - {SBIT(12), - CC_RELEASE | REQUEST, l3dss1_release_req}, - {ALL_STATES, - CC_RESTART | REQUEST, l3dss1_restart}, - {SBIT(6) | SBIT(25), - CC_IGNORE | REQUEST, l3dss1_reset}, - {SBIT(6) | SBIT(25), - CC_REJECT | REQUEST, l3dss1_reject_req}, - {SBIT(6) | SBIT(25), - CC_PROCEED_SEND | REQUEST, l3dss1_proceed_req}, - {SBIT(6), - CC_MORE_INFO | REQUEST, l3dss1_setup_ack_req}, - {SBIT(25), - CC_MORE_INFO | REQUEST, l3dss1_dummy}, - {SBIT(6) | SBIT(9) | SBIT(25), - CC_ALERTING | REQUEST, l3dss1_alert_req}, - {SBIT(6) | SBIT(7) | SBIT(9) | SBIT(25), - CC_SETUP | RESPONSE, l3dss1_setup_rsp}, - {SBIT(10), - CC_SUSPEND | REQUEST, l3dss1_suspend_req}, - {SBIT(7) | SBIT(9) | SBIT(25), - CC_REDIR | REQUEST, l3dss1_redir_req}, - {SBIT(6), - CC_REDIR | REQUEST, l3dss1_redir_req_early}, - {SBIT(9) | SBIT(25), - CC_DISCONNECT | REQUEST, l3dss1_disconnect_req}, - {SBIT(25), - CC_T302, l3dss1_t302}, - {SBIT(1), - CC_T303, l3dss1_t303}, - {SBIT(2), - CC_T304, l3dss1_t304}, - {SBIT(3), - CC_T310, l3dss1_t310}, - {SBIT(8), - CC_T313, l3dss1_t313}, - {SBIT(11), - CC_T305, l3dss1_t305}, - {SBIT(15), - CC_T319, l3dss1_t319}, - {SBIT(17), - CC_T318, l3dss1_t318}, - {SBIT(19), - CC_T308_1, l3dss1_t308_1}, - {SBIT(19), - CC_T308_2, l3dss1_t308_2}, - {SBIT(10), - CC_T309, l3dss1_dl_release}, -}; - -static struct stateentry datastatelist[] = -{ - {ALL_STATES, - MT_STATUS_ENQUIRY, l3dss1_status_enq}, - {ALL_STATES, - MT_FACILITY, l3dss1_facility}, - {SBIT(19), - MT_STATUS, l3dss1_release_ind}, - {ALL_STATES, - MT_STATUS, l3dss1_status}, - {SBIT(0), - MT_SETUP, l3dss1_setup}, - {SBIT(6) | SBIT(7) | SBIT(8) | SBIT(9) | SBIT(10) | SBIT(11) | SBIT(12) | - SBIT(15) | SBIT(17) | SBIT(19) | SBIT(25), - MT_SETUP, l3dss1_dummy}, - {SBIT(1) | SBIT(2), - MT_CALL_PROCEEDING, l3dss1_call_proc}, - {SBIT(1), - MT_SETUP_ACKNOWLEDGE, l3dss1_setup_ack}, - {SBIT(2) | SBIT(3), - MT_ALERTING, l3dss1_alerting}, - {SBIT(2) | SBIT(3), - MT_PROGRESS, l3dss1_progress}, - {SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(9) | SBIT(10) | - SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17) | SBIT(19) | SBIT(25), - MT_INFORMATION, l3dss1_information}, - {SBIT(10) | SBIT(11) | SBIT(15), - MT_NOTIFY, l3dss1_notify}, - {SBIT(0) | SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(10) | - SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17) | SBIT(19) | SBIT(25), - MT_RELEASE_COMPLETE, l3dss1_release_cmpl}, - {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(9) | SBIT(10) | SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17) | SBIT(25), - MT_RELEASE, l3dss1_release}, - {SBIT(19), MT_RELEASE, l3dss1_release_ind}, - {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(9) | SBIT(10) | SBIT(11) | SBIT(15) | SBIT(17) | SBIT(25), - MT_DISCONNECT, l3dss1_disconnect}, - {SBIT(19), - MT_DISCONNECT, l3dss1_dummy}, - {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4), - MT_CONNECT, l3dss1_connect}, - {SBIT(8), - MT_CONNECT_ACKNOWLEDGE, l3dss1_connect_ack}, - {SBIT(15), - MT_SUSPEND_ACKNOWLEDGE, l3dss1_suspend_ack}, - {SBIT(15), - MT_SUSPEND_REJECT, l3dss1_suspend_rej}, - {SBIT(17), - MT_RESUME_ACKNOWLEDGE, l3dss1_resume_ack}, - {SBIT(17), - MT_RESUME_REJECT, l3dss1_resume_rej}, -}; - -static struct stateentry globalmes_list[] = -{ - {ALL_STATES, - MT_STATUS, l3dss1_status}, - {SBIT(0), - MT_RESTART, l3dss1_global_restart}, -/* {SBIT(1), - MT_RESTART_ACKNOWLEDGE, l3dss1_restart_ack}, -*/ -}; - -static struct stateentry manstatelist[] = -{ - {SBIT(2), - DL_ESTABLISH | INDICATION, l3dss1_dl_reset}, - {SBIT(10), - DL_ESTABLISH | CONFIRM, l3dss1_dl_reest_status}, - {SBIT(10), - DL_RELEASE | INDICATION, l3dss1_dl_reestablish}, - {ALL_STATES, - DL_RELEASE | INDICATION, l3dss1_dl_release}, -}; - -/* *INDENT-ON* */ - - -static void -global_handler(struct PStack *st, int mt, struct sk_buff *skb) -{ - u_char tmp[16]; - u_char *p = tmp; - int l; - int i; - struct l3_process *proc = st->l3.global; - - proc->callref = skb->data[2]; /* cr flag */ - for (i = 0; i < ARRAY_SIZE(globalmes_list); i++) - if ((mt == globalmes_list[i].primitive) && - ((1 << proc->state) & globalmes_list[i].state)) - break; - if (i == ARRAY_SIZE(globalmes_list)) { - if (st->l3.debug & L3_DEB_STATE) { - l3_debug(st, "dss1 global state %d mt %x unhandled", - proc->state, mt); - } - MsgHead(p, proc->callref, MT_STATUS); - *p++ = IE_CAUSE; - *p++ = 0x2; - *p++ = 0x80; - *p++ = 81 | 0x80; /* invalid cr */ - *p++ = 0x14; /* CallState */ - *p++ = 0x1; - *p++ = proc->state & 0x3f; - l = p - tmp; - if (!(skb = l3_alloc_skb(l))) - return; - skb_put_data(skb, tmp, l); - l3_msg(proc->st, DL_DATA | REQUEST, skb); - } else { - if (st->l3.debug & L3_DEB_STATE) { - l3_debug(st, "dss1 global %d mt %x", - proc->state, mt); - } - globalmes_list[i].rout(proc, mt, skb); - } -} - -static void -dss1up(struct PStack *st, int pr, void *arg) -{ - int i, mt, cr, callState; - char *ptr; - u_char *p; - struct sk_buff *skb = arg; - struct l3_process *proc; - - switch (pr) { - case (DL_DATA | INDICATION): - case (DL_UNIT_DATA | INDICATION): - break; - case (DL_ESTABLISH | CONFIRM): - case (DL_ESTABLISH | INDICATION): - case (DL_RELEASE | INDICATION): - case (DL_RELEASE | CONFIRM): - l3_msg(st, pr, arg); - return; - break; - default: - printk(KERN_ERR "HiSax dss1up unknown pr=%04x\n", pr); - return; - } - if (skb->len < 3) { - l3_debug(st, "dss1up frame too short(%d)", skb->len); - dev_kfree_skb(skb); - return; - } - - if (skb->data[0] != PROTO_DIS_EURO) { - if (st->l3.debug & L3_DEB_PROTERR) { - l3_debug(st, "dss1up%sunexpected discriminator %x message len %d", - (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ", - skb->data[0], skb->len); - } - dev_kfree_skb(skb); - return; - } - cr = getcallref(skb->data); - if (skb->len < ((skb->data[1] & 0x0f) + 3)) { - l3_debug(st, "dss1up frame too short(%d)", skb->len); - dev_kfree_skb(skb); - return; - } - mt = skb->data[skb->data[1] + 2]; - if (st->l3.debug & L3_DEB_STATE) - l3_debug(st, "dss1up cr %d", cr); - if (cr == -2) { /* wrong Callref */ - if (st->l3.debug & L3_DEB_WARN) - l3_debug(st, "dss1up wrong Callref"); - dev_kfree_skb(skb); - return; - } else if (cr == -1) { /* Dummy Callref */ - if (mt == MT_FACILITY) - if ((p = findie(skb->data, skb->len, IE_FACILITY, 0))) { - l3dss1_parse_facility(st, NULL, - (pr == (DL_DATA | INDICATION)) ? -1 : -2, p); - dev_kfree_skb(skb); - return; - } - if (st->l3.debug & L3_DEB_WARN) - l3_debug(st, "dss1up dummy Callref (no facility msg or ie)"); - dev_kfree_skb(skb); - return; - } else if ((((skb->data[1] & 0x0f) == 1) && (0 == (cr & 0x7f))) || - (((skb->data[1] & 0x0f) == 2) && (0 == (cr & 0x7fff)))) { /* Global CallRef */ - if (st->l3.debug & L3_DEB_STATE) - l3_debug(st, "dss1up Global CallRef"); - global_handler(st, mt, skb); - dev_kfree_skb(skb); - return; - } else if (!(proc = getl3proc(st, cr))) { - /* No transaction process exist, that means no call with - * this callreference is active - */ - if (mt == MT_SETUP) { - /* Setup creates a new transaction process */ - if (skb->data[2] & 0x80) { - /* Setup with wrong CREF flag */ - if (st->l3.debug & L3_DEB_STATE) - l3_debug(st, "dss1up wrong CRef flag"); - dev_kfree_skb(skb); - return; - } - if (!(proc = dss1_new_l3_process(st, cr))) { - /* May be to answer with RELEASE_COMPLETE and - * CAUSE 0x2f "Resource unavailable", but this - * need a new_l3_process too ... arghh - */ - dev_kfree_skb(skb); - return; - } - } else if (mt == MT_STATUS) { - if ((ptr = findie(skb->data, skb->len, IE_CAUSE, 0)) != NULL) { - ptr++; - if (*ptr++ == 2) - ptr++; - } - callState = 0; - if ((ptr = findie(skb->data, skb->len, IE_CALL_STATE, 0)) != NULL) { - ptr++; - if (*ptr++ == 2) - ptr++; - callState = *ptr; - } - /* ETS 300-104 part 2.4.1 - * if setup has not been made and a message type - * MT_STATUS is received with call state == 0, - * we must send nothing - */ - if (callState != 0) { - /* ETS 300-104 part 2.4.2 - * if setup has not been made and a message type - * MT_STATUS is received with call state != 0, - * we must send MT_RELEASE_COMPLETE cause 101 - */ - if ((proc = dss1_new_l3_process(st, cr))) { - proc->para.cause = 101; - l3dss1_msg_without_setup(proc, 0, NULL); - } - } - dev_kfree_skb(skb); - return; - } else if (mt == MT_RELEASE_COMPLETE) { - dev_kfree_skb(skb); - return; - } else { - /* ETS 300-104 part 2 - * if setup has not been made and a message type - * (except MT_SETUP and RELEASE_COMPLETE) is received, - * we must send MT_RELEASE_COMPLETE cause 81 */ - dev_kfree_skb(skb); - if ((proc = dss1_new_l3_process(st, cr))) { - proc->para.cause = 81; - l3dss1_msg_without_setup(proc, 0, NULL); - } - return; - } - } - if (l3dss1_check_messagetype_validity(proc, mt, skb)) { - dev_kfree_skb(skb); - return; - } - if ((p = findie(skb->data, skb->len, IE_DISPLAY, 0)) != NULL) - l3dss1_deliver_display(proc, pr, p); /* Display IE included */ - for (i = 0; i < ARRAY_SIZE(datastatelist); i++) - if ((mt == datastatelist[i].primitive) && - ((1 << proc->state) & datastatelist[i].state)) - break; - if (i == ARRAY_SIZE(datastatelist)) { - if (st->l3.debug & L3_DEB_STATE) { - l3_debug(st, "dss1up%sstate %d mt %#x unhandled", - (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ", - proc->state, mt); - } - if ((MT_RELEASE_COMPLETE != mt) && (MT_RELEASE != mt)) { - proc->para.cause = 101; - l3dss1_status_send(proc, pr, skb); - } - } else { - if (st->l3.debug & L3_DEB_STATE) { - l3_debug(st, "dss1up%sstate %d mt %x", - (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ", - proc->state, mt); - } - datastatelist[i].rout(proc, pr, skb); - } - dev_kfree_skb(skb); - return; -} - -static void -dss1down(struct PStack *st, int pr, void *arg) -{ - int i, cr; - struct l3_process *proc; - struct Channel *chan; - - if ((DL_ESTABLISH | REQUEST) == pr) { - l3_msg(st, pr, NULL); - return; - } else if (((CC_SETUP | REQUEST) == pr) || ((CC_RESUME | REQUEST) == pr)) { - chan = arg; - cr = newcallref(); - cr |= 0x80; - if ((proc = dss1_new_l3_process(st, cr))) { - proc->chan = chan; - chan->proc = proc; - memcpy(&proc->para.setup, &chan->setup, sizeof(setup_parm)); - proc->callref = cr; - } - } else { - proc = arg; - } - if (!proc) { - printk(KERN_ERR "HiSax dss1down without proc pr=%04x\n", pr); - return; - } - - if (pr == (CC_TDSS1_IO | REQUEST)) { - l3dss1_io_timer(proc); /* timer expires */ - return; - } - - for (i = 0; i < ARRAY_SIZE(downstatelist); i++) - if ((pr == downstatelist[i].primitive) && - ((1 << proc->state) & downstatelist[i].state)) - break; - if (i == ARRAY_SIZE(downstatelist)) { - if (st->l3.debug & L3_DEB_STATE) { - l3_debug(st, "dss1down state %d prim %#x unhandled", - proc->state, pr); - } - } else { - if (st->l3.debug & L3_DEB_STATE) { - l3_debug(st, "dss1down state %d prim %#x", - proc->state, pr); - } - downstatelist[i].rout(proc, pr, arg); - } -} - -static void -dss1man(struct PStack *st, int pr, void *arg) -{ - int i; - struct l3_process *proc = arg; - - if (!proc) { - printk(KERN_ERR "HiSax dss1man without proc pr=%04x\n", pr); - return; - } - for (i = 0; i < ARRAY_SIZE(manstatelist); i++) - if ((pr == manstatelist[i].primitive) && - ((1 << proc->state) & manstatelist[i].state)) - break; - if (i == ARRAY_SIZE(manstatelist)) { - if (st->l3.debug & L3_DEB_STATE) { - l3_debug(st, "cr %d dss1man state %d prim %#x unhandled", - proc->callref & 0x7f, proc->state, pr); - } - } else { - if (st->l3.debug & L3_DEB_STATE) { - l3_debug(st, "cr %d dss1man state %d prim %#x", - proc->callref & 0x7f, proc->state, pr); - } - manstatelist[i].rout(proc, pr, arg); - } -} - -void -setstack_dss1(struct PStack *st) -{ - char tmp[64]; - int i; - - st->lli.l4l3 = dss1down; - st->lli.l4l3_proto = l3dss1_cmd_global; - st->l2.l2l3 = dss1up; - st->l3.l3ml3 = dss1man; - st->l3.N303 = 1; - st->prot.dss1.last_invoke_id = 0; - st->prot.dss1.invoke_used[0] = 1; /* Bit 0 must always be set to 1 */ - i = 1; - while (i < 32) - st->prot.dss1.invoke_used[i++] = 0; - - if (!(st->l3.global = kmalloc(sizeof(struct l3_process), GFP_ATOMIC))) { - printk(KERN_ERR "HiSax can't get memory for dss1 global CR\n"); - } else { - st->l3.global->state = 0; - st->l3.global->callref = 0; - st->l3.global->next = NULL; - st->l3.global->debug = L3_DEB_WARN; - st->l3.global->st = st; - st->l3.global->N303 = 1; - st->l3.global->prot.dss1.invoke_id = 0; - - L3InitTimer(st->l3.global, &st->l3.global->timer); - } - strcpy(tmp, dss1_revision); - printk(KERN_INFO "HiSax: DSS1 Rev. %s\n", HiSax_getrev(tmp)); -} diff --git a/drivers/isdn/hisax/l3dss1.h b/drivers/isdn/hisax/l3dss1.h deleted file mode 100644 index a7807e8a94f1..000000000000 --- a/drivers/isdn/hisax/l3dss1.h +++ /dev/null @@ -1,124 +0,0 @@ -/* $Id: l3dss1.h,v 1.10.6.2 2001/09/23 22:24:50 kai Exp $ - * - * DSS1 (Euro) D-channel protocol defines - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#ifndef l3dss1_process - -#define T302 15000 -#define T303 4000 -#define T304 30000 -#define T305 30000 -#define T308 4000 -/* for layer 1 certification T309 < layer1 T3 (e.g. 4000) */ -/* This makes some tests easier and quicker */ -#define T309 40000 -#define T310 30000 -#define T313 4000 -#define T318 4000 -#define T319 4000 - -/* - * Message-Types - */ - -#define MT_ALERTING 0x01 -#define MT_CALL_PROCEEDING 0x02 -#define MT_CONNECT 0x07 -#define MT_CONNECT_ACKNOWLEDGE 0x0f -#define MT_PROGRESS 0x03 -#define MT_SETUP 0x05 -#define MT_SETUP_ACKNOWLEDGE 0x0d -#define MT_RESUME 0x26 -#define MT_RESUME_ACKNOWLEDGE 0x2e -#define MT_RESUME_REJECT 0x22 -#define MT_SUSPEND 0x25 -#define MT_SUSPEND_ACKNOWLEDGE 0x2d -#define MT_SUSPEND_REJECT 0x21 -#define MT_USER_INFORMATION 0x20 -#define MT_DISCONNECT 0x45 -#define MT_RELEASE 0x4d -#define MT_RELEASE_COMPLETE 0x5a -#define MT_RESTART 0x46 -#define MT_RESTART_ACKNOWLEDGE 0x4e -#define MT_SEGMENT 0x60 -#define MT_CONGESTION_CONTROL 0x79 -#define MT_INFORMATION 0x7b -#define MT_FACILITY 0x62 -#define MT_NOTIFY 0x6e -#define MT_STATUS 0x7d -#define MT_STATUS_ENQUIRY 0x75 - -#define IE_SEGMENT 0x00 -#define IE_BEARER 0x04 -#define IE_CAUSE 0x08 -#define IE_CALL_ID 0x10 -#define IE_CALL_STATE 0x14 -#define IE_CHANNEL_ID 0x18 -#define IE_FACILITY 0x1c -#define IE_PROGRESS 0x1e -#define IE_NET_FAC 0x20 -#define IE_NOTIFY 0x27 -#define IE_DISPLAY 0x28 -#define IE_DATE 0x29 -#define IE_KEYPAD 0x2c -#define IE_SIGNAL 0x34 -#define IE_INFORATE 0x40 -#define IE_E2E_TDELAY 0x42 -#define IE_TDELAY_SEL 0x43 -#define IE_PACK_BINPARA 0x44 -#define IE_PACK_WINSIZE 0x45 -#define IE_PACK_SIZE 0x46 -#define IE_CUG 0x47 -#define IE_REV_CHARGE 0x4a -#define IE_CONNECT_PN 0x4c -#define IE_CONNECT_SUB 0x4d -#define IE_CALLING_PN 0x6c -#define IE_CALLING_SUB 0x6d -#define IE_CALLED_PN 0x70 -#define IE_CALLED_SUB 0x71 -#define IE_REDIR_NR 0x74 -#define IE_TRANS_SEL 0x78 -#define IE_RESTART_IND 0x79 -#define IE_LLC 0x7c -#define IE_HLC 0x7d -#define IE_USER_USER 0x7e -#define IE_ESCAPE 0x7f -#define IE_SHIFT 0x90 -#define IE_MORE_DATA 0xa0 -#define IE_COMPLETE 0xa1 -#define IE_CONGESTION 0xb0 -#define IE_REPEAT 0xd0 - -#define IE_MANDATORY 0x0100 -/* mandatory not in every case */ -#define IE_MANDATORY_1 0x0200 - -#define ERR_IE_COMPREHENSION 1 -#define ERR_IE_UNRECOGNIZED -1 -#define ERR_IE_LENGTH -2 -#define ERR_IE_SEQUENCE -3 - -#else /* only l3dss1_process */ - -/* l3dss1 specific data in l3 process */ -typedef struct -{ unsigned char invoke_id; /* used invoke id in remote ops, 0 = not active */ - ulong ll_id; /* remebered ll id */ - u8 remote_operation; /* handled remote operation, 0 = not active */ - int proc; /* rememered procedure */ - ulong remote_result; /* result of remote operation for statcallb */ - char uus1_data[35]; /* data send during alerting or disconnect */ -} dss1_proc_priv; - -/* l3dss1 specific data in protocol stack */ -typedef struct -{ unsigned char last_invoke_id; /* last used value for invoking */ - unsigned char invoke_used[32]; /* 256 bits for 256 values */ -} dss1_stk_priv; - -#endif /* only l3dss1_process */ diff --git a/drivers/isdn/hisax/l3ni1.c b/drivers/isdn/hisax/l3ni1.c deleted file mode 100644 index ea311e7df48e..000000000000 --- a/drivers/isdn/hisax/l3ni1.c +++ /dev/null @@ -1,3182 +0,0 @@ -/* $Id: l3ni1.c,v 2.8.2.3 2004/01/13 14:31:25 keil Exp $ - * - * NI1 D-channel protocol - * - * Author Matt Henderson & Guy Ellis - * Copyright by Traverse Technologies Pty Ltd, www.travers.com.au - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * 2000.6.6 Initial implementation of routines for US NI1 - * Layer 3 protocol based on the EURO/DSS1 D-channel protocol - * driver written by Karsten Keil et al. - * NI-1 Hall of Fame - Thanks to.... - * Ragnar Paulson - for some handy code fragments - * Will Scales - beta tester extraordinaire - * Brett Whittacre - beta tester and remote devel system in Vegas - * - */ - -#include "hisax.h" -#include "isdnl3.h" -#include "l3ni1.h" -#include <linux/ctype.h> -#include <linux/slab.h> - -extern char *HiSax_getrev(const char *revision); -static const char *ni1_revision = "$Revision: 2.8.2.3 $"; - -#define EXT_BEARER_CAPS 1 - -#define MsgHead(ptr, cref, mty) \ - *ptr++ = 0x8; \ - if (cref == -1) { \ - *ptr++ = 0x0; \ - } else { \ - *ptr++ = 0x1; \ - *ptr++ = cref^0x80; \ - } \ - *ptr++ = mty - - -/**********************************************/ -/* get a new invoke id for remote operations. */ -/* Only a return value != 0 is valid */ -/**********************************************/ -static unsigned char new_invoke_id(struct PStack *p) -{ - unsigned char retval; - int i; - - i = 32; /* maximum search depth */ - - retval = p->prot.ni1.last_invoke_id + 1; /* try new id */ - while ((i) && (p->prot.ni1.invoke_used[retval >> 3] == 0xFF)) { - p->prot.ni1.last_invoke_id = (retval & 0xF8) + 8; - i--; - } - if (i) { - while (p->prot.ni1.invoke_used[retval >> 3] & (1 << (retval & 7))) - retval++; - } else - retval = 0; - p->prot.ni1.last_invoke_id = retval; - p->prot.ni1.invoke_used[retval >> 3] |= (1 << (retval & 7)); - return (retval); -} /* new_invoke_id */ - -/*************************/ -/* free a used invoke id */ -/*************************/ -static void free_invoke_id(struct PStack *p, unsigned char id) -{ - - if (!id) return; /* 0 = invalid value */ - - p->prot.ni1.invoke_used[id >> 3] &= ~(1 << (id & 7)); -} /* free_invoke_id */ - - -/**********************************************************/ -/* create a new l3 process and fill in ni1 specific data */ -/**********************************************************/ -static struct l3_process -*ni1_new_l3_process(struct PStack *st, int cr) -{ struct l3_process *proc; - - if (!(proc = new_l3_process(st, cr))) - return (NULL); - - proc->prot.ni1.invoke_id = 0; - proc->prot.ni1.remote_operation = 0; - proc->prot.ni1.uus1_data[0] = '\0'; - - return (proc); -} /* ni1_new_l3_process */ - -/************************************************/ -/* free a l3 process and all ni1 specific data */ -/************************************************/ -static void -ni1_release_l3_process(struct l3_process *p) -{ - free_invoke_id(p->st, p->prot.ni1.invoke_id); - release_l3_process(p); -} /* ni1_release_l3_process */ - -/********************************************************/ -/* search a process with invoke id id and dummy callref */ -/********************************************************/ -static struct l3_process * -l3ni1_search_dummy_proc(struct PStack *st, int id) -{ struct l3_process *pc = st->l3.proc; /* start of processes */ - - if (!id) return (NULL); - - while (pc) - { if ((pc->callref == -1) && (pc->prot.ni1.invoke_id == id)) - return (pc); - pc = pc->next; - } - return (NULL); -} /* l3ni1_search_dummy_proc */ - -/*******************************************************************/ -/* called when a facility message with a dummy callref is received */ -/* and a return result is delivered. id specifies the invoke id. */ -/*******************************************************************/ -static void -l3ni1_dummy_return_result(struct PStack *st, int id, u_char *p, u_char nlen) -{ isdn_ctrl ic; - struct IsdnCardState *cs; - struct l3_process *pc = NULL; - - if ((pc = l3ni1_search_dummy_proc(st, id))) - { L3DelTimer(&pc->timer); /* remove timer */ - - cs = pc->st->l1.hardware; - ic.driver = cs->myid; - ic.command = ISDN_STAT_PROT; - ic.arg = NI1_STAT_INVOKE_RES; - ic.parm.ni1_io.hl_id = pc->prot.ni1.invoke_id; - ic.parm.ni1_io.ll_id = pc->prot.ni1.ll_id; - ic.parm.ni1_io.proc = pc->prot.ni1.proc; - ic.parm.ni1_io.timeout = 0; - ic.parm.ni1_io.datalen = nlen; - ic.parm.ni1_io.data = p; - free_invoke_id(pc->st, pc->prot.ni1.invoke_id); - pc->prot.ni1.invoke_id = 0; /* reset id */ - - cs->iif.statcallb(&ic); - ni1_release_l3_process(pc); - } - else - l3_debug(st, "dummy return result id=0x%x result len=%d", id, nlen); -} /* l3ni1_dummy_return_result */ - -/*******************************************************************/ -/* called when a facility message with a dummy callref is received */ -/* and a return error is delivered. id specifies the invoke id. */ -/*******************************************************************/ -static void -l3ni1_dummy_error_return(struct PStack *st, int id, ulong error) -{ isdn_ctrl ic; - struct IsdnCardState *cs; - struct l3_process *pc = NULL; - - if ((pc = l3ni1_search_dummy_proc(st, id))) - { L3DelTimer(&pc->timer); /* remove timer */ - - cs = pc->st->l1.hardware; - ic.driver = cs->myid; - ic.command = ISDN_STAT_PROT; - ic.arg = NI1_STAT_INVOKE_ERR; - ic.parm.ni1_io.hl_id = pc->prot.ni1.invoke_id; - ic.parm.ni1_io.ll_id = pc->prot.ni1.ll_id; - ic.parm.ni1_io.proc = pc->prot.ni1.proc; - ic.parm.ni1_io.timeout = error; - ic.parm.ni1_io.datalen = 0; - ic.parm.ni1_io.data = NULL; - free_invoke_id(pc->st, pc->prot.ni1.invoke_id); - pc->prot.ni1.invoke_id = 0; /* reset id */ - - cs->iif.statcallb(&ic); - ni1_release_l3_process(pc); - } - else - l3_debug(st, "dummy return error id=0x%x error=0x%lx", id, error); -} /* l3ni1_error_return */ - -/*******************************************************************/ -/* called when a facility message with a dummy callref is received */ -/* and a invoke is delivered. id specifies the invoke id. */ -/*******************************************************************/ -static void -l3ni1_dummy_invoke(struct PStack *st, int cr, int id, - int ident, u_char *p, u_char nlen) -{ isdn_ctrl ic; - struct IsdnCardState *cs; - - l3_debug(st, "dummy invoke %s id=0x%x ident=0x%x datalen=%d", - (cr == -1) ? "local" : "broadcast", id, ident, nlen); - if (cr >= -1) return; /* ignore local data */ - - cs = st->l1.hardware; - ic.driver = cs->myid; - ic.command = ISDN_STAT_PROT; - ic.arg = NI1_STAT_INVOKE_BRD; - ic.parm.ni1_io.hl_id = id; - ic.parm.ni1_io.ll_id = 0; - ic.parm.ni1_io.proc = ident; - ic.parm.ni1_io.timeout = 0; - ic.parm.ni1_io.datalen = nlen; - ic.parm.ni1_io.data = p; - - cs->iif.statcallb(&ic); -} /* l3ni1_dummy_invoke */ - -static void -l3ni1_parse_facility(struct PStack *st, struct l3_process *pc, - int cr, u_char *p) -{ - int qd_len = 0; - unsigned char nlen = 0, ilen, cp_tag; - int ident, id; - ulong err_ret; - - if (pc) - st = pc->st; /* valid Stack */ - else - if ((!st) || (cr >= 0)) return; /* neither pc nor st specified */ - - p++; - qd_len = *p++; - if (qd_len == 0) { - l3_debug(st, "qd_len == 0"); - return; - } - if ((*p & 0x1F) != 0x11) { /* Service discriminator, supplementary service */ - l3_debug(st, "supplementary service != 0x11"); - return; - } - while (qd_len > 0 && !(*p & 0x80)) { /* extension ? */ - p++; - qd_len--; - } - if (qd_len < 2) { - l3_debug(st, "qd_len < 2"); - return; - } - p++; - qd_len--; - if ((*p & 0xE0) != 0xA0) { /* class and form */ - l3_debug(st, "class and form != 0xA0"); - return; - } - - cp_tag = *p & 0x1F; /* remember tag value */ - - p++; - qd_len--; - if (qd_len < 1) - { l3_debug(st, "qd_len < 1"); - return; - } - if (*p & 0x80) - { /* length format indefinite or limited */ - nlen = *p++ & 0x7F; /* number of len bytes or indefinite */ - if ((qd_len-- < ((!nlen) ? 3 : (1 + nlen))) || - (nlen > 1)) - { l3_debug(st, "length format error or not implemented"); - return; - } - if (nlen == 1) - { nlen = *p++; /* complete length */ - qd_len--; - } - else - { qd_len -= 2; /* trailing null bytes */ - if ((*(p + qd_len)) || (*(p + qd_len + 1))) - { l3_debug(st, "length format indefinite error"); - return; - } - nlen = qd_len; - } - } - else - { nlen = *p++; - qd_len--; - } - if (qd_len < nlen) - { l3_debug(st, "qd_len < nlen"); - return; - } - qd_len -= nlen; - - if (nlen < 2) - { l3_debug(st, "nlen < 2"); - return; - } - if (*p != 0x02) - { /* invoke identifier tag */ - l3_debug(st, "invoke identifier tag !=0x02"); - return; - } - p++; - nlen--; - if (*p & 0x80) - { /* length format */ - l3_debug(st, "invoke id length format 2"); - return; - } - ilen = *p++; - nlen--; - if (ilen > nlen || ilen == 0) - { l3_debug(st, "ilen > nlen || ilen == 0"); - return; - } - nlen -= ilen; - id = 0; - while (ilen > 0) - { id = (id << 8) | (*p++ & 0xFF); /* invoke identifier */ - ilen--; - } - - switch (cp_tag) { /* component tag */ - case 1: /* invoke */ - if (nlen < 2) { - l3_debug(st, "nlen < 2 22"); - return; - } - if (*p != 0x02) { /* operation value */ - l3_debug(st, "operation value !=0x02"); - return; - } - p++; - nlen--; - ilen = *p++; - nlen--; - if (ilen > nlen || ilen == 0) { - l3_debug(st, "ilen > nlen || ilen == 0 22"); - return; - } - nlen -= ilen; - ident = 0; - while (ilen > 0) { - ident = (ident << 8) | (*p++ & 0xFF); - ilen--; - } - - if (!pc) - { - l3ni1_dummy_invoke(st, cr, id, ident, p, nlen); - return; - } - l3_debug(st, "invoke break"); - break; - case 2: /* return result */ - /* if no process available handle separately */ - if (!pc) - { if (cr == -1) - l3ni1_dummy_return_result(st, id, p, nlen); - return; - } - if ((pc->prot.ni1.invoke_id) && (pc->prot.ni1.invoke_id == id)) - { /* Diversion successful */ - free_invoke_id(st, pc->prot.ni1.invoke_id); - pc->prot.ni1.remote_result = 0; /* success */ - pc->prot.ni1.invoke_id = 0; - pc->redir_result = pc->prot.ni1.remote_result; - st->l3.l3l4(st, CC_REDIR | INDICATION, pc); } /* Diversion successful */ - else - l3_debug(st, "return error unknown identifier"); - break; - case 3: /* return error */ - err_ret = 0; - if (nlen < 2) - { l3_debug(st, "return error nlen < 2"); - return; - } - if (*p != 0x02) - { /* result tag */ - l3_debug(st, "invoke error tag !=0x02"); - return; - } - p++; - nlen--; - if (*p > 4) - { /* length format */ - l3_debug(st, "invoke return errlen > 4 "); - return; - } - ilen = *p++; - nlen--; - if (ilen > nlen || ilen == 0) - { l3_debug(st, "error return ilen > nlen || ilen == 0"); - return; - } - nlen -= ilen; - while (ilen > 0) - { err_ret = (err_ret << 8) | (*p++ & 0xFF); /* error value */ - ilen--; - } - /* if no process available handle separately */ - if (!pc) - { if (cr == -1) - l3ni1_dummy_error_return(st, id, err_ret); - return; - } - if ((pc->prot.ni1.invoke_id) && (pc->prot.ni1.invoke_id == id)) - { /* Deflection error */ - free_invoke_id(st, pc->prot.ni1.invoke_id); - pc->prot.ni1.remote_result = err_ret; /* result */ - pc->prot.ni1.invoke_id = 0; - pc->redir_result = pc->prot.ni1.remote_result; - st->l3.l3l4(st, CC_REDIR | INDICATION, pc); - } /* Deflection error */ - else - l3_debug(st, "return result unknown identifier"); - break; - default: - l3_debug(st, "facility default break tag=0x%02x", cp_tag); - break; - } -} - -static void -l3ni1_message(struct l3_process *pc, u_char mt) -{ - struct sk_buff *skb; - u_char *p; - - if (!(skb = l3_alloc_skb(4))) - return; - p = skb_put(skb, 4); - MsgHead(p, pc->callref, mt); - l3_msg(pc->st, DL_DATA | REQUEST, skb); -} - -static void -l3ni1_message_plus_chid(struct l3_process *pc, u_char mt) -/* sends an l3 messages plus channel id - added GE 05/09/00 */ -{ - struct sk_buff *skb; - u_char tmp[16]; - u_char *p = tmp; - u_char chid; - - chid = (u_char)(pc->para.bchannel & 0x03) | 0x88; - MsgHead(p, pc->callref, mt); - *p++ = IE_CHANNEL_ID; - *p++ = 0x01; - *p++ = chid; - - if (!(skb = l3_alloc_skb(7))) - return; - skb_put_data(skb, tmp, 7); - l3_msg(pc->st, DL_DATA | REQUEST, skb); -} - -static void -l3ni1_message_cause(struct l3_process *pc, u_char mt, u_char cause) -{ - struct sk_buff *skb; - u_char tmp[16]; - u_char *p = tmp; - int l; - - MsgHead(p, pc->callref, mt); - *p++ = IE_CAUSE; - *p++ = 0x2; - *p++ = 0x80; - *p++ = cause | 0x80; - - l = p - tmp; - if (!(skb = l3_alloc_skb(l))) - return; - skb_put_data(skb, tmp, l); - l3_msg(pc->st, DL_DATA | REQUEST, skb); -} - -static void -l3ni1_status_send(struct l3_process *pc, u_char pr, void *arg) -{ - u_char tmp[16]; - u_char *p = tmp; - int l; - struct sk_buff *skb; - - MsgHead(p, pc->callref, MT_STATUS); - - *p++ = IE_CAUSE; - *p++ = 0x2; - *p++ = 0x80; - *p++ = pc->para.cause | 0x80; - - *p++ = IE_CALL_STATE; - *p++ = 0x1; - *p++ = pc->state & 0x3f; - - l = p - tmp; - if (!(skb = l3_alloc_skb(l))) - return; - skb_put_data(skb, tmp, l); - l3_msg(pc->st, DL_DATA | REQUEST, skb); -} - -static void -l3ni1_msg_without_setup(struct l3_process *pc, u_char pr, void *arg) -{ - /* This routine is called if here was no SETUP made (checks in ni1up and in - * l3ni1_setup) and a RELEASE_COMPLETE have to be sent with an error code - * MT_STATUS_ENQUIRE in the NULL state is handled too - */ - u_char tmp[16]; - u_char *p = tmp; - int l; - struct sk_buff *skb; - - switch (pc->para.cause) { - case 81: /* invalid callreference */ - case 88: /* incomp destination */ - case 96: /* mandory IE missing */ - case 100: /* invalid IE contents */ - case 101: /* incompatible Callstate */ - MsgHead(p, pc->callref, MT_RELEASE_COMPLETE); - *p++ = IE_CAUSE; - *p++ = 0x2; - *p++ = 0x80; - *p++ = pc->para.cause | 0x80; - break; - default: - printk(KERN_ERR "HiSax l3ni1_msg_without_setup wrong cause %d\n", - pc->para.cause); - return; - } - l = p - tmp; - if (!(skb = l3_alloc_skb(l))) - return; - skb_put_data(skb, tmp, l); - l3_msg(pc->st, DL_DATA | REQUEST, skb); - ni1_release_l3_process(pc); -} - -static int ie_ALERTING[] = {IE_BEARER, IE_CHANNEL_ID | IE_MANDATORY_1, - IE_FACILITY, IE_PROGRESS, IE_DISPLAY, IE_SIGNAL, IE_HLC, - IE_USER_USER, -1}; -static int ie_CALL_PROCEEDING[] = {IE_BEARER, IE_CHANNEL_ID | IE_MANDATORY_1, - IE_FACILITY, IE_PROGRESS, IE_DISPLAY, IE_HLC, -1}; -static int ie_CONNECT[] = {IE_BEARER, IE_CHANNEL_ID | IE_MANDATORY_1, - IE_FACILITY, IE_PROGRESS, IE_DISPLAY, IE_DATE, IE_SIGNAL, - IE_CONNECT_PN, IE_CONNECT_SUB, IE_LLC, IE_HLC, IE_USER_USER, -1}; -static int ie_CONNECT_ACKNOWLEDGE[] = {IE_CHANNEL_ID, IE_DISPLAY, IE_SIGNAL, -1}; -static int ie_DISCONNECT[] = {IE_CAUSE | IE_MANDATORY, IE_FACILITY, - IE_PROGRESS, IE_DISPLAY, IE_SIGNAL, IE_USER_USER, -1}; -static int ie_INFORMATION[] = {IE_COMPLETE, IE_DISPLAY, IE_KEYPAD, IE_SIGNAL, - IE_CALLED_PN, -1}; -static int ie_NOTIFY[] = {IE_BEARER, IE_NOTIFY | IE_MANDATORY, IE_DISPLAY, -1}; -static int ie_PROGRESS[] = {IE_BEARER, IE_CAUSE, IE_FACILITY, IE_PROGRESS | - IE_MANDATORY, IE_DISPLAY, IE_HLC, IE_USER_USER, -1}; -static int ie_RELEASE[] = {IE_CAUSE | IE_MANDATORY_1, IE_FACILITY, IE_DISPLAY, - IE_SIGNAL, IE_USER_USER, -1}; -/* a RELEASE_COMPLETE with errors don't require special actions - static int ie_RELEASE_COMPLETE[] = {IE_CAUSE | IE_MANDATORY_1, IE_DISPLAY, IE_SIGNAL, IE_USER_USER, -1}; -*/ -static int ie_RESUME_ACKNOWLEDGE[] = {IE_CHANNEL_ID | IE_MANDATORY, IE_FACILITY, - IE_DISPLAY, -1}; -static int ie_RESUME_REJECT[] = {IE_CAUSE | IE_MANDATORY, IE_DISPLAY, -1}; -static int ie_SETUP[] = {IE_COMPLETE, IE_BEARER | IE_MANDATORY, - IE_CHANNEL_ID | IE_MANDATORY, IE_FACILITY, IE_PROGRESS, - IE_NET_FAC, IE_DISPLAY, IE_KEYPAD, IE_SIGNAL, IE_CALLING_PN, - IE_CALLING_SUB, IE_CALLED_PN, IE_CALLED_SUB, IE_REDIR_NR, - IE_LLC, IE_HLC, IE_USER_USER, -1}; -static int ie_SETUP_ACKNOWLEDGE[] = {IE_CHANNEL_ID | IE_MANDATORY, IE_FACILITY, - IE_PROGRESS, IE_DISPLAY, IE_SIGNAL, -1}; -static int ie_STATUS[] = {IE_CAUSE | IE_MANDATORY, IE_CALL_STATE | - IE_MANDATORY, IE_DISPLAY, -1}; -static int ie_STATUS_ENQUIRY[] = {IE_DISPLAY, -1}; -static int ie_SUSPEND_ACKNOWLEDGE[] = {IE_DISPLAY, IE_FACILITY, -1}; -static int ie_SUSPEND_REJECT[] = {IE_CAUSE | IE_MANDATORY, IE_DISPLAY, -1}; -/* not used - * static int ie_CONGESTION_CONTROL[] = {IE_CONGESTION | IE_MANDATORY, - * IE_CAUSE | IE_MANDATORY, IE_DISPLAY, -1}; - * static int ie_USER_INFORMATION[] = {IE_MORE_DATA, IE_USER_USER | IE_MANDATORY, -1}; - * static int ie_RESTART[] = {IE_CHANNEL_ID, IE_DISPLAY, IE_RESTART_IND | - * IE_MANDATORY, -1}; - */ -static int ie_FACILITY[] = {IE_FACILITY | IE_MANDATORY, IE_DISPLAY, -1}; -static int comp_required[] = {1, 2, 3, 5, 6, 7, 9, 10, 11, 14, 15, -1}; -static int l3_valid_states[] = {0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 15, 17, 19, 25, -1}; - -struct ie_len { - int ie; - int len; -}; - -static -struct ie_len max_ie_len[] = { - {IE_SEGMENT, 4}, - {IE_BEARER, 12}, - {IE_CAUSE, 32}, - {IE_CALL_ID, 10}, - {IE_CALL_STATE, 3}, - {IE_CHANNEL_ID, 34}, - {IE_FACILITY, 255}, - {IE_PROGRESS, 4}, - {IE_NET_FAC, 255}, - {IE_NOTIFY, 3}, - {IE_DISPLAY, 82}, - {IE_DATE, 8}, - {IE_KEYPAD, 34}, - {IE_SIGNAL, 3}, - {IE_INFORATE, 6}, - {IE_E2E_TDELAY, 11}, - {IE_TDELAY_SEL, 5}, - {IE_PACK_BINPARA, 3}, - {IE_PACK_WINSIZE, 4}, - {IE_PACK_SIZE, 4}, - {IE_CUG, 7}, - {IE_REV_CHARGE, 3}, - {IE_CALLING_PN, 24}, - {IE_CALLING_SUB, 23}, - {IE_CALLED_PN, 24}, - {IE_CALLED_SUB, 23}, - {IE_REDIR_NR, 255}, - {IE_TRANS_SEL, 255}, - {IE_RESTART_IND, 3}, - {IE_LLC, 18}, - {IE_HLC, 5}, - {IE_USER_USER, 131}, - {-1, 0}, -}; - -static int -getmax_ie_len(u_char ie) { - int i = 0; - while (max_ie_len[i].ie != -1) { - if (max_ie_len[i].ie == ie) - return (max_ie_len[i].len); - i++; - } - return (255); -} - -static int -ie_in_set(struct l3_process *pc, u_char ie, int *checklist) { - int ret = 1; - - while (*checklist != -1) { - if ((*checklist & 0xff) == ie) { - if (ie & 0x80) - return (-ret); - else - return (ret); - } - ret++; - checklist++; - } - return (0); -} - -static int -check_infoelements(struct l3_process *pc, struct sk_buff *skb, int *checklist) -{ - int *cl = checklist; - u_char mt; - u_char *p, ie; - int l, newpos, oldpos; - int err_seq = 0, err_len = 0, err_compr = 0, err_ureg = 0; - u_char codeset = 0; - u_char old_codeset = 0; - u_char codelock = 1; - - p = skb->data; - /* skip cr */ - p++; - l = (*p++) & 0xf; - p += l; - mt = *p++; - oldpos = 0; - while ((p - skb->data) < skb->len) { - if ((*p & 0xf0) == 0x90) { /* shift codeset */ - old_codeset = codeset; - codeset = *p & 7; - if (*p & 0x08) - codelock = 0; - else - codelock = 1; - if (pc->debug & L3_DEB_CHECK) - l3_debug(pc->st, "check IE shift%scodeset %d->%d", - codelock ? " locking " : " ", old_codeset, codeset); - p++; - continue; - } - if (!codeset) { /* only codeset 0 */ - if ((newpos = ie_in_set(pc, *p, cl))) { - if (newpos > 0) { - if (newpos < oldpos) - err_seq++; - else - oldpos = newpos; - } - } else { - if (ie_in_set(pc, *p, comp_required)) - err_compr++; - else - err_ureg++; - } - } - ie = *p++; - if (ie & 0x80) { - l = 1; - } else { - l = *p++; - p += l; - l += 2; - } - if (!codeset && (l > getmax_ie_len(ie))) - err_len++; - if (!codelock) { - if (pc->debug & L3_DEB_CHECK) - l3_debug(pc->st, "check IE shift back codeset %d->%d", - codeset, old_codeset); - codeset = old_codeset; - codelock = 1; - } - } - if (err_compr | err_ureg | err_len | err_seq) { - if (pc->debug & L3_DEB_CHECK) - l3_debug(pc->st, "check IE MT(%x) %d/%d/%d/%d", - mt, err_compr, err_ureg, err_len, err_seq); - if (err_compr) - return (ERR_IE_COMPREHENSION); - if (err_ureg) - return (ERR_IE_UNRECOGNIZED); - if (err_len) - return (ERR_IE_LENGTH); - if (err_seq) - return (ERR_IE_SEQUENCE); - } - return (0); -} - -/* verify if a message type exists and contain no IE error */ -static int -l3ni1_check_messagetype_validity(struct l3_process *pc, int mt, void *arg) -{ - switch (mt) { - case MT_ALERTING: - case MT_CALL_PROCEEDING: - case MT_CONNECT: - case MT_CONNECT_ACKNOWLEDGE: - case MT_DISCONNECT: - case MT_INFORMATION: - case MT_FACILITY: - case MT_NOTIFY: - case MT_PROGRESS: - case MT_RELEASE: - case MT_RELEASE_COMPLETE: - case MT_SETUP: - case MT_SETUP_ACKNOWLEDGE: - case MT_RESUME_ACKNOWLEDGE: - case MT_RESUME_REJECT: - case MT_SUSPEND_ACKNOWLEDGE: - case MT_SUSPEND_REJECT: - case MT_USER_INFORMATION: - case MT_RESTART: - case MT_RESTART_ACKNOWLEDGE: - case MT_CONGESTION_CONTROL: - case MT_STATUS: - case MT_STATUS_ENQUIRY: - if (pc->debug & L3_DEB_CHECK) - l3_debug(pc->st, "l3ni1_check_messagetype_validity mt(%x) OK", mt); - break; - case MT_RESUME: /* RESUME only in user->net */ - case MT_SUSPEND: /* SUSPEND only in user->net */ - default: - if (pc->debug & (L3_DEB_CHECK | L3_DEB_WARN)) - l3_debug(pc->st, "l3ni1_check_messagetype_validity mt(%x) fail", mt); - pc->para.cause = 97; - l3ni1_status_send(pc, 0, NULL); - return (1); - } - return (0); -} - -static void -l3ni1_std_ie_err(struct l3_process *pc, int ret) { - - if (pc->debug & L3_DEB_CHECK) - l3_debug(pc->st, "check_infoelements ret %d", ret); - switch (ret) { - case 0: - break; - case ERR_IE_COMPREHENSION: - pc->para.cause = 96; - l3ni1_status_send(pc, 0, NULL); - break; - case ERR_IE_UNRECOGNIZED: - pc->para.cause = 99; - l3ni1_status_send(pc, 0, NULL); - break; - case ERR_IE_LENGTH: - pc->para.cause = 100; - l3ni1_status_send(pc, 0, NULL); - break; - case ERR_IE_SEQUENCE: - default: - break; - } -} - -static int -l3ni1_get_channel_id(struct l3_process *pc, struct sk_buff *skb) { - u_char *p; - - p = skb->data; - if ((p = findie(p, skb->len, IE_CHANNEL_ID, 0))) { - p++; - if (*p != 1) { /* len for BRI = 1 */ - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "wrong chid len %d", *p); - return (-2); - } - p++; - if (*p & 0x60) { /* only base rate interface */ - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "wrong chid %x", *p); - return (-3); - } - return (*p & 0x3); - } else - return (-1); -} - -static int -l3ni1_get_cause(struct l3_process *pc, struct sk_buff *skb) { - u_char l, i = 0; - u_char *p; - - p = skb->data; - pc->para.cause = 31; - pc->para.loc = 0; - if ((p = findie(p, skb->len, IE_CAUSE, 0))) { - p++; - l = *p++; - if (l > 30) - return (1); - if (l) { - pc->para.loc = *p++; - l--; - } else { - return (2); - } - if (l && !(pc->para.loc & 0x80)) { - l--; - p++; /* skip recommendation */ - } - if (l) { - pc->para.cause = *p++; - l--; - if (!(pc->para.cause & 0x80)) - return (3); - } else - return (4); - while (l && (i < 6)) { - pc->para.diag[i++] = *p++; - l--; - } - } else - return (-1); - return (0); -} - -static void -l3ni1_msg_with_uus(struct l3_process *pc, u_char cmd) -{ - struct sk_buff *skb; - u_char tmp[16 + 40]; - u_char *p = tmp; - int l; - - MsgHead(p, pc->callref, cmd); - - if (pc->prot.ni1.uus1_data[0]) - { *p++ = IE_USER_USER; /* UUS info element */ - *p++ = strlen(pc->prot.ni1.uus1_data) + 1; - *p++ = 0x04; /* IA5 chars */ - strcpy(p, pc->prot.ni1.uus1_data); - p += strlen(pc->prot.ni1.uus1_data); - pc->prot.ni1.uus1_data[0] = '\0'; - } - - l = p - tmp; - if (!(skb = l3_alloc_skb(l))) - return; - skb_put_data(skb, tmp, l); - l3_msg(pc->st, DL_DATA | REQUEST, skb); -} /* l3ni1_msg_with_uus */ - -static void -l3ni1_release_req(struct l3_process *pc, u_char pr, void *arg) -{ - StopAllL3Timer(pc); - newl3state(pc, 19); - if (!pc->prot.ni1.uus1_data[0]) - l3ni1_message(pc, MT_RELEASE); - else - l3ni1_msg_with_uus(pc, MT_RELEASE); - L3AddTimer(&pc->timer, T308, CC_T308_1); -} - -static void -l3ni1_release_cmpl(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - int ret; - - if ((ret = l3ni1_get_cause(pc, skb)) > 0) { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "RELCMPL get_cause ret(%d)", ret); - } else if (ret < 0) - pc->para.cause = NO_CAUSE; - StopAllL3Timer(pc); - newl3state(pc, 0); - pc->st->l3.l3l4(pc->st, CC_RELEASE | CONFIRM, pc); - ni1_release_l3_process(pc); -} - -#if EXT_BEARER_CAPS - -static u_char * -EncodeASyncParams(u_char *p, u_char si2) -{ // 7c 06 88 90 21 42 00 bb - - p[0] = 0; - p[1] = 0x40; // Intermediate rate: 16 kbit/s jj 2000.02.19 - p[2] = 0x80; - if (si2 & 32) // 7 data bits - - p[2] += 16; - else // 8 data bits - - p[2] += 24; - - if (si2 & 16) // 2 stop bits - - p[2] += 96; - else // 1 stop bit - - p[2] += 32; - - if (si2 & 8) // even parity - - p[2] += 2; - else // no parity - - p[2] += 3; - - switch (si2 & 0x07) { - case 0: - p[0] = 66; // 1200 bit/s - - break; - case 1: - p[0] = 88; // 1200/75 bit/s - - break; - case 2: - p[0] = 87; // 75/1200 bit/s - - break; - case 3: - p[0] = 67; // 2400 bit/s - - break; - case 4: - p[0] = 69; // 4800 bit/s - - break; - case 5: - p[0] = 72; // 9600 bit/s - - break; - case 6: - p[0] = 73; // 14400 bit/s - - break; - case 7: - p[0] = 75; // 19200 bit/s - - break; - } - return p + 3; -} - -static u_char -EncodeSyncParams(u_char si2, u_char ai) -{ - - switch (si2) { - case 0: - return ai + 2; // 1200 bit/s - - case 1: - return ai + 24; // 1200/75 bit/s - - case 2: - return ai + 23; // 75/1200 bit/s - - case 3: - return ai + 3; // 2400 bit/s - - case 4: - return ai + 5; // 4800 bit/s - - case 5: - return ai + 8; // 9600 bit/s - - case 6: - return ai + 9; // 14400 bit/s - - case 7: - return ai + 11; // 19200 bit/s - - case 8: - return ai + 14; // 48000 bit/s - - case 9: - return ai + 15; // 56000 bit/s - - case 15: - return ai + 40; // negotiate bit/s - - default: - break; - } - return ai; -} - - -static u_char -DecodeASyncParams(u_char si2, u_char *p) -{ - u_char info; - - switch (p[5]) { - case 66: // 1200 bit/s - - break; // si2 don't change - - case 88: // 1200/75 bit/s - - si2 += 1; - break; - case 87: // 75/1200 bit/s - - si2 += 2; - break; - case 67: // 2400 bit/s - - si2 += 3; - break; - case 69: // 4800 bit/s - - si2 += 4; - break; - case 72: // 9600 bit/s - - si2 += 5; - break; - case 73: // 14400 bit/s - - si2 += 6; - break; - case 75: // 19200 bit/s - - si2 += 7; - break; - } - - info = p[7] & 0x7f; - if ((info & 16) && (!(info & 8))) // 7 data bits - - si2 += 32; // else 8 data bits - - if ((info & 96) == 96) // 2 stop bits - - si2 += 16; // else 1 stop bit - - if ((info & 2) && (!(info & 1))) // even parity - - si2 += 8; // else no parity - - return si2; -} - - -static u_char -DecodeSyncParams(u_char si2, u_char info) -{ - info &= 0x7f; - switch (info) { - case 40: // bit/s negotiation failed ai := 165 not 175! - - return si2 + 15; - case 15: // 56000 bit/s failed, ai := 0 not 169 ! - - return si2 + 9; - case 14: // 48000 bit/s - - return si2 + 8; - case 11: // 19200 bit/s - - return si2 + 7; - case 9: // 14400 bit/s - - return si2 + 6; - case 8: // 9600 bit/s - - return si2 + 5; - case 5: // 4800 bit/s - - return si2 + 4; - case 3: // 2400 bit/s - - return si2 + 3; - case 23: // 75/1200 bit/s - - return si2 + 2; - case 24: // 1200/75 bit/s - - return si2 + 1; - default: // 1200 bit/s - - return si2; - } -} - -static u_char -DecodeSI2(struct sk_buff *skb) -{ - u_char *p; //, *pend=skb->data + skb->len; - - if ((p = findie(skb->data, skb->len, 0x7c, 0))) { - switch (p[4] & 0x0f) { - case 0x01: - if (p[1] == 0x04) // sync. Bitratenadaption - - return DecodeSyncParams(160, p[5]); // V.110/X.30 - - else if (p[1] == 0x06) // async. Bitratenadaption - - return DecodeASyncParams(192, p); // V.110/X.30 - - break; - case 0x08: // if (p[5] == 0x02) // sync. Bitratenadaption - if (p[1] > 3) - return DecodeSyncParams(176, p[5]); // V.120 - break; - } - } - return 0; -} - -#endif - - -static void -l3ni1_setup_req(struct l3_process *pc, u_char pr, - void *arg) -{ - struct sk_buff *skb; - u_char tmp[128]; - u_char *p = tmp; - - u_char *teln; - u_char *sub; - u_char *sp; - int l; - - MsgHead(p, pc->callref, MT_SETUP); - - teln = pc->para.setup.phone; - - *p++ = 0xa1; /* complete indicator */ - /* - * Set Bearer Capability, Map info from 1TR6-convention to NI1 - */ - switch (pc->para.setup.si1) { - case 1: /* Telephony */ - *p++ = IE_BEARER; - *p++ = 0x3; /* Length */ - *p++ = 0x90; /* 3.1khz Audio */ - *p++ = 0x90; /* Circuit-Mode 64kbps */ - *p++ = 0xa2; /* u-Law Audio */ - break; - case 5: /* Datatransmission 64k, BTX */ - case 7: /* Datatransmission 64k */ - default: - *p++ = IE_BEARER; - *p++ = 0x2; /* Length */ - *p++ = 0x88; /* Coding Std. CCITT, unrestr. dig. Inform. */ - *p++ = 0x90; /* Circuit-Mode 64kbps */ - break; - } - - sub = NULL; - sp = teln; - while (*sp) { - if ('.' == *sp) { - sub = sp; - *sp = 0; - } else - sp++; - } - - *p++ = IE_KEYPAD; - *p++ = strlen(teln); - while (*teln) - *p++ = (*teln++) & 0x7F; - - if (sub) - *sub++ = '.'; - -#if EXT_BEARER_CAPS - if ((pc->para.setup.si2 >= 160) && (pc->para.setup.si2 <= 175)) { // sync. Bitratenadaption, V.110/X.30 - - *p++ = IE_LLC; - *p++ = 0x04; - *p++ = 0x88; - *p++ = 0x90; - *p++ = 0x21; - *p++ = EncodeSyncParams(pc->para.setup.si2 - 160, 0x80); - } else if ((pc->para.setup.si2 >= 176) && (pc->para.setup.si2 <= 191)) { // sync. Bitratenadaption, V.120 - - *p++ = IE_LLC; - *p++ = 0x05; - *p++ = 0x88; - *p++ = 0x90; - *p++ = 0x28; - *p++ = EncodeSyncParams(pc->para.setup.si2 - 176, 0); - *p++ = 0x82; - } else if (pc->para.setup.si2 >= 192) { // async. Bitratenadaption, V.110/X.30 - - *p++ = IE_LLC; - *p++ = 0x06; - *p++ = 0x88; - *p++ = 0x90; - *p++ = 0x21; - p = EncodeASyncParams(p, pc->para.setup.si2 - 192); - } else { - switch (pc->para.setup.si1) { - case 1: /* Telephony */ - *p++ = IE_LLC; - *p++ = 0x3; /* Length */ - *p++ = 0x90; /* Coding Std. CCITT, 3.1 kHz audio */ - *p++ = 0x90; /* Circuit-Mode 64kbps */ - *p++ = 0xa2; /* u-Law Audio */ - break; - case 5: /* Datatransmission 64k, BTX */ - case 7: /* Datatransmission 64k */ - default: - *p++ = IE_LLC; - *p++ = 0x2; /* Length */ - *p++ = 0x88; /* Coding Std. CCITT, unrestr. dig. Inform. */ - *p++ = 0x90; /* Circuit-Mode 64kbps */ - break; - } - } -#endif - l = p - tmp; - if (!(skb = l3_alloc_skb(l))) - { - return; - } - skb_put_data(skb, tmp, l); - L3DelTimer(&pc->timer); - L3AddTimer(&pc->timer, T303, CC_T303); - newl3state(pc, 1); - l3_msg(pc->st, DL_DATA | REQUEST, skb); -} - -static void -l3ni1_call_proc(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - int id, ret; - - if ((id = l3ni1_get_channel_id(pc, skb)) >= 0) { - if ((0 == id) || ((3 == id) && (0x10 == pc->para.moderate))) { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "setup answer with wrong chid %x", id); - pc->para.cause = 100; - l3ni1_status_send(pc, pr, NULL); - return; - } - pc->para.bchannel = id; - } else if (1 == pc->state) { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "setup answer wrong chid (ret %d)", id); - if (id == -1) - pc->para.cause = 96; - else - pc->para.cause = 100; - l3ni1_status_send(pc, pr, NULL); - return; - } - /* Now we are on none mandatory IEs */ - ret = check_infoelements(pc, skb, ie_CALL_PROCEEDING); - if (ERR_IE_COMPREHENSION == ret) { - l3ni1_std_ie_err(pc, ret); - return; - } - L3DelTimer(&pc->timer); - newl3state(pc, 3); - L3AddTimer(&pc->timer, T310, CC_T310); - if (ret) /* STATUS for none mandatory IE errors after actions are taken */ - l3ni1_std_ie_err(pc, ret); - pc->st->l3.l3l4(pc->st, CC_PROCEEDING | INDICATION, pc); -} - -static void -l3ni1_setup_ack(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - int id, ret; - - if ((id = l3ni1_get_channel_id(pc, skb)) >= 0) { - if ((0 == id) || ((3 == id) && (0x10 == pc->para.moderate))) { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "setup answer with wrong chid %x", id); - pc->para.cause = 100; - l3ni1_status_send(pc, pr, NULL); - return; - } - pc->para.bchannel = id; - } else { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "setup answer wrong chid (ret %d)", id); - if (id == -1) - pc->para.cause = 96; - else - pc->para.cause = 100; - l3ni1_status_send(pc, pr, NULL); - return; - } - /* Now we are on none mandatory IEs */ - ret = check_infoelements(pc, skb, ie_SETUP_ACKNOWLEDGE); - if (ERR_IE_COMPREHENSION == ret) { - l3ni1_std_ie_err(pc, ret); - return; - } - L3DelTimer(&pc->timer); - newl3state(pc, 2); - L3AddTimer(&pc->timer, T304, CC_T304); - if (ret) /* STATUS for none mandatory IE errors after actions are taken */ - l3ni1_std_ie_err(pc, ret); - pc->st->l3.l3l4(pc->st, CC_MORE_INFO | INDICATION, pc); -} - -static void -l3ni1_disconnect(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - u_char *p; - int ret; - u_char cause = 0; - - StopAllL3Timer(pc); - if ((ret = l3ni1_get_cause(pc, skb))) { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "DISC get_cause ret(%d)", ret); - if (ret < 0) - cause = 96; - else if (ret > 0) - cause = 100; - } - if ((p = findie(skb->data, skb->len, IE_FACILITY, 0))) - l3ni1_parse_facility(pc->st, pc, pc->callref, p); - ret = check_infoelements(pc, skb, ie_DISCONNECT); - if (ERR_IE_COMPREHENSION == ret) - cause = 96; - else if ((!cause) && (ERR_IE_UNRECOGNIZED == ret)) - cause = 99; - ret = pc->state; - newl3state(pc, 12); - if (cause) - newl3state(pc, 19); - if (11 != ret) - pc->st->l3.l3l4(pc->st, CC_DISCONNECT | INDICATION, pc); - else if (!cause) - l3ni1_release_req(pc, pr, NULL); - if (cause) { - l3ni1_message_cause(pc, MT_RELEASE, cause); - L3AddTimer(&pc->timer, T308, CC_T308_1); - } -} - -static void -l3ni1_connect(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - int ret; - - ret = check_infoelements(pc, skb, ie_CONNECT); - if (ERR_IE_COMPREHENSION == ret) { - l3ni1_std_ie_err(pc, ret); - return; - } - L3DelTimer(&pc->timer); /* T310 */ - newl3state(pc, 10); - pc->para.chargeinfo = 0; - /* here should inserted COLP handling KKe */ - if (ret) - l3ni1_std_ie_err(pc, ret); - pc->st->l3.l3l4(pc->st, CC_SETUP | CONFIRM, pc); -} - -static void -l3ni1_alerting(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - int ret; - - ret = check_infoelements(pc, skb, ie_ALERTING); - if (ERR_IE_COMPREHENSION == ret) { - l3ni1_std_ie_err(pc, ret); - return; - } - L3DelTimer(&pc->timer); /* T304 */ - newl3state(pc, 4); - if (ret) - l3ni1_std_ie_err(pc, ret); - pc->st->l3.l3l4(pc->st, CC_ALERTING | INDICATION, pc); -} - -static void -l3ni1_setup(struct l3_process *pc, u_char pr, void *arg) -{ - u_char *p; - int bcfound = 0; - char tmp[80]; - struct sk_buff *skb = arg; - int id; - int err = 0; - - /* - * Bearer Capabilities - */ - p = skb->data; - /* only the first occurrence 'll be detected ! */ - if ((p = findie(p, skb->len, 0x04, 0))) { - if ((p[1] < 2) || (p[1] > 11)) - err = 1; - else { - pc->para.setup.si2 = 0; - switch (p[2] & 0x7f) { - case 0x00: /* Speech */ - case 0x10: /* 3.1 Khz audio */ - pc->para.setup.si1 = 1; - break; - case 0x08: /* Unrestricted digital information */ - pc->para.setup.si1 = 7; -/* JIM, 05.11.97 I wanna set service indicator 2 */ -#if EXT_BEARER_CAPS - pc->para.setup.si2 = DecodeSI2(skb); -#endif - break; - case 0x09: /* Restricted digital information */ - pc->para.setup.si1 = 2; - break; - case 0x11: - /* Unrestr. digital information with - * tones/announcements ( or 7 kHz audio - */ - pc->para.setup.si1 = 3; - break; - case 0x18: /* Video */ - pc->para.setup.si1 = 4; - break; - default: - err = 2; - break; - } - switch (p[3] & 0x7f) { - case 0x40: /* packed mode */ - pc->para.setup.si1 = 8; - break; - case 0x10: /* 64 kbit */ - case 0x11: /* 2*64 kbit */ - case 0x13: /* 384 kbit */ - case 0x15: /* 1536 kbit */ - case 0x17: /* 1920 kbit */ - pc->para.moderate = p[3] & 0x7f; - break; - default: - err = 3; - break; - } - } - if (pc->debug & L3_DEB_SI) - l3_debug(pc->st, "SI=%d, AI=%d", - pc->para.setup.si1, pc->para.setup.si2); - if (err) { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "setup with wrong bearer(l=%d:%x,%x)", - p[1], p[2], p[3]); - pc->para.cause = 100; - l3ni1_msg_without_setup(pc, pr, NULL); - return; - } - } else { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "setup without bearer capabilities"); - /* ETS 300-104 1.3.3 */ - pc->para.cause = 96; - l3ni1_msg_without_setup(pc, pr, NULL); - return; - } - /* - * Channel Identification - */ - if ((id = l3ni1_get_channel_id(pc, skb)) >= 0) { - if ((pc->para.bchannel = id)) { - if ((3 == id) && (0x10 == pc->para.moderate)) { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "setup with wrong chid %x", - id); - pc->para.cause = 100; - l3ni1_msg_without_setup(pc, pr, NULL); - return; - } - bcfound++; - } else - { if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "setup without bchannel, call waiting"); - bcfound++; - } - } else { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "setup with wrong chid ret %d", id); - if (id == -1) - pc->para.cause = 96; - else - pc->para.cause = 100; - l3ni1_msg_without_setup(pc, pr, NULL); - return; - } - /* Now we are on none mandatory IEs */ - err = check_infoelements(pc, skb, ie_SETUP); - if (ERR_IE_COMPREHENSION == err) { - pc->para.cause = 96; - l3ni1_msg_without_setup(pc, pr, NULL); - return; - } - p = skb->data; - if ((p = findie(p, skb->len, 0x70, 0))) - iecpy(pc->para.setup.eazmsn, p, 1); - else - pc->para.setup.eazmsn[0] = 0; - - p = skb->data; - if ((p = findie(p, skb->len, 0x71, 0))) { - /* Called party subaddress */ - if ((p[1] >= 2) && (p[2] == 0x80) && (p[3] == 0x50)) { - tmp[0] = '.'; - iecpy(&tmp[1], p, 2); - strcat(pc->para.setup.eazmsn, tmp); - } else if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "wrong called subaddress"); - } - p = skb->data; - if ((p = findie(p, skb->len, 0x6c, 0))) { - pc->para.setup.plan = p[2]; - if (p[2] & 0x80) { - iecpy(pc->para.setup.phone, p, 1); - pc->para.setup.screen = 0; - } else { - iecpy(pc->para.setup.phone, p, 2); - pc->para.setup.screen = p[3]; - } - } else { - pc->para.setup.phone[0] = 0; - pc->para.setup.plan = 0; - pc->para.setup.screen = 0; - } - p = skb->data; - if ((p = findie(p, skb->len, 0x6d, 0))) { - /* Calling party subaddress */ - if ((p[1] >= 2) && (p[2] == 0x80) && (p[3] == 0x50)) { - tmp[0] = '.'; - iecpy(&tmp[1], p, 2); - strcat(pc->para.setup.phone, tmp); - } else if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "wrong calling subaddress"); - } - newl3state(pc, 6); - if (err) /* STATUS for none mandatory IE errors after actions are taken */ - l3ni1_std_ie_err(pc, err); - pc->st->l3.l3l4(pc->st, CC_SETUP | INDICATION, pc); -} - -static void -l3ni1_reset(struct l3_process *pc, u_char pr, void *arg) -{ - ni1_release_l3_process(pc); -} - -static void -l3ni1_disconnect_req(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb; - u_char tmp[16 + 40]; - u_char *p = tmp; - int l; - u_char cause = 16; - - if (pc->para.cause != NO_CAUSE) - cause = pc->para.cause; - - StopAllL3Timer(pc); - - MsgHead(p, pc->callref, MT_DISCONNECT); - - *p++ = IE_CAUSE; - *p++ = 0x2; - *p++ = 0x80; - *p++ = cause | 0x80; - - if (pc->prot.ni1.uus1_data[0]) - { *p++ = IE_USER_USER; /* UUS info element */ - *p++ = strlen(pc->prot.ni1.uus1_data) + 1; - *p++ = 0x04; /* IA5 chars */ - strcpy(p, pc->prot.ni1.uus1_data); - p += strlen(pc->prot.ni1.uus1_data); - pc->prot.ni1.uus1_data[0] = '\0'; - } - - l = p - tmp; - if (!(skb = l3_alloc_skb(l))) - return; - skb_put_data(skb, tmp, l); - newl3state(pc, 11); - l3_msg(pc->st, DL_DATA | REQUEST, skb); - L3AddTimer(&pc->timer, T305, CC_T305); -} - -static void -l3ni1_setup_rsp(struct l3_process *pc, u_char pr, - void *arg) -{ - if (!pc->para.bchannel) - { if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "D-chan connect for waiting call"); - l3ni1_disconnect_req(pc, pr, arg); - return; - } - newl3state(pc, 8); - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "D-chan connect for waiting call"); - l3ni1_message_plus_chid(pc, MT_CONNECT); /* GE 05/09/00 */ - L3DelTimer(&pc->timer); - L3AddTimer(&pc->timer, T313, CC_T313); -} - -static void -l3ni1_connect_ack(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - int ret; - - ret = check_infoelements(pc, skb, ie_CONNECT_ACKNOWLEDGE); - if (ERR_IE_COMPREHENSION == ret) { - l3ni1_std_ie_err(pc, ret); - return; - } - newl3state(pc, 10); - L3DelTimer(&pc->timer); - if (ret) - l3ni1_std_ie_err(pc, ret); - pc->st->l3.l3l4(pc->st, CC_SETUP_COMPL | INDICATION, pc); -} - -static void -l3ni1_reject_req(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb; - u_char tmp[16]; - u_char *p = tmp; - int l; - u_char cause = 21; - - if (pc->para.cause != NO_CAUSE) - cause = pc->para.cause; - - MsgHead(p, pc->callref, MT_RELEASE_COMPLETE); - - *p++ = IE_CAUSE; - *p++ = 0x2; - *p++ = 0x80; - *p++ = cause | 0x80; - - l = p - tmp; - if (!(skb = l3_alloc_skb(l))) - return; - skb_put_data(skb, tmp, l); - l3_msg(pc->st, DL_DATA | REQUEST, skb); - pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc); - newl3state(pc, 0); - ni1_release_l3_process(pc); -} - -static void -l3ni1_release(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - u_char *p; - int ret, cause = 0; - - StopAllL3Timer(pc); - if ((ret = l3ni1_get_cause(pc, skb)) > 0) { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "REL get_cause ret(%d)", ret); - } else if (ret < 0) - pc->para.cause = NO_CAUSE; - if ((p = findie(skb->data, skb->len, IE_FACILITY, 0))) { - l3ni1_parse_facility(pc->st, pc, pc->callref, p); - } - if ((ret < 0) && (pc->state != 11)) - cause = 96; - else if (ret > 0) - cause = 100; - ret = check_infoelements(pc, skb, ie_RELEASE); - if (ERR_IE_COMPREHENSION == ret) - cause = 96; - else if ((ERR_IE_UNRECOGNIZED == ret) && (!cause)) - cause = 99; - if (cause) - l3ni1_message_cause(pc, MT_RELEASE_COMPLETE, cause); - else - l3ni1_message(pc, MT_RELEASE_COMPLETE); - pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc); - newl3state(pc, 0); - ni1_release_l3_process(pc); -} - -static void -l3ni1_alert_req(struct l3_process *pc, u_char pr, - void *arg) -{ - newl3state(pc, 7); - if (!pc->prot.ni1.uus1_data[0]) - l3ni1_message(pc, MT_ALERTING); - else - l3ni1_msg_with_uus(pc, MT_ALERTING); -} - -static void -l3ni1_proceed_req(struct l3_process *pc, u_char pr, - void *arg) -{ - newl3state(pc, 9); - l3ni1_message(pc, MT_CALL_PROCEEDING); - pc->st->l3.l3l4(pc->st, CC_PROCEED_SEND | INDICATION, pc); -} - -static void -l3ni1_setup_ack_req(struct l3_process *pc, u_char pr, - void *arg) -{ - newl3state(pc, 25); - L3DelTimer(&pc->timer); - L3AddTimer(&pc->timer, T302, CC_T302); - l3ni1_message(pc, MT_SETUP_ACKNOWLEDGE); -} - -/********************************************/ -/* deliver a incoming display message to HL */ -/********************************************/ -static void -l3ni1_deliver_display(struct l3_process *pc, int pr, u_char *infp) -{ u_char len; - isdn_ctrl ic; - struct IsdnCardState *cs; - char *p; - - if (*infp++ != IE_DISPLAY) return; - if ((len = *infp++) > 80) return; /* total length <= 82 */ - if (!pc->chan) return; - - p = ic.parm.display; - while (len--) - *p++ = *infp++; - *p = '\0'; - ic.command = ISDN_STAT_DISPLAY; - cs = pc->st->l1.hardware; - ic.driver = cs->myid; - ic.arg = pc->chan->chan; - cs->iif.statcallb(&ic); -} /* l3ni1_deliver_display */ - - -static void -l3ni1_progress(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - int err = 0; - u_char *p; - - if ((p = findie(skb->data, skb->len, IE_PROGRESS, 0))) { - if (p[1] != 2) { - err = 1; - pc->para.cause = 100; - } else if (!(p[2] & 0x70)) { - switch (p[2]) { - case 0x80: - case 0x81: - case 0x82: - case 0x84: - case 0x85: - case 0x87: - case 0x8a: - switch (p[3]) { - case 0x81: - case 0x82: - case 0x83: - case 0x84: - case 0x88: - break; - default: - err = 2; - pc->para.cause = 100; - break; - } - break; - default: - err = 3; - pc->para.cause = 100; - break; - } - } - } else { - pc->para.cause = 96; - err = 4; - } - if (err) { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "progress error %d", err); - l3ni1_status_send(pc, pr, NULL); - return; - } - /* Now we are on none mandatory IEs */ - err = check_infoelements(pc, skb, ie_PROGRESS); - if (err) - l3ni1_std_ie_err(pc, err); - if (ERR_IE_COMPREHENSION != err) - pc->st->l3.l3l4(pc->st, CC_PROGRESS | INDICATION, pc); -} - -static void -l3ni1_notify(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - int err = 0; - u_char *p; - - if ((p = findie(skb->data, skb->len, IE_NOTIFY, 0))) { - if (p[1] != 1) { - err = 1; - pc->para.cause = 100; - } else { - switch (p[2]) { - case 0x80: - case 0x81: - case 0x82: - break; - default: - pc->para.cause = 100; - err = 2; - break; - } - } - } else { - pc->para.cause = 96; - err = 3; - } - if (err) { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "notify error %d", err); - l3ni1_status_send(pc, pr, NULL); - return; - } - /* Now we are on none mandatory IEs */ - err = check_infoelements(pc, skb, ie_NOTIFY); - if (err) - l3ni1_std_ie_err(pc, err); - if (ERR_IE_COMPREHENSION != err) - pc->st->l3.l3l4(pc->st, CC_NOTIFY | INDICATION, pc); -} - -static void -l3ni1_status_enq(struct l3_process *pc, u_char pr, void *arg) -{ - int ret; - struct sk_buff *skb = arg; - - ret = check_infoelements(pc, skb, ie_STATUS_ENQUIRY); - l3ni1_std_ie_err(pc, ret); - pc->para.cause = 30; /* response to STATUS_ENQUIRY */ - l3ni1_status_send(pc, pr, NULL); -} - -static void -l3ni1_information(struct l3_process *pc, u_char pr, void *arg) -{ - int ret; - struct sk_buff *skb = arg; - u_char *p; - char tmp[32]; - - ret = check_infoelements(pc, skb, ie_INFORMATION); - if (ret) - l3ni1_std_ie_err(pc, ret); - if (pc->state == 25) { /* overlap receiving */ - L3DelTimer(&pc->timer); - p = skb->data; - if ((p = findie(p, skb->len, 0x70, 0))) { - iecpy(tmp, p, 1); - strcat(pc->para.setup.eazmsn, tmp); - pc->st->l3.l3l4(pc->st, CC_MORE_INFO | INDICATION, pc); - } - L3AddTimer(&pc->timer, T302, CC_T302); - } -} - -/******************************/ -/* handle deflection requests */ -/******************************/ -static void l3ni1_redir_req(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb; - u_char tmp[128]; - u_char *p = tmp; - u_char *subp; - u_char len_phone = 0; - u_char len_sub = 0; - int l; - - - strcpy(pc->prot.ni1.uus1_data, pc->chan->setup.eazmsn); /* copy uus element if available */ - if (!pc->chan->setup.phone[0]) - { pc->para.cause = -1; - l3ni1_disconnect_req(pc, pr, arg); /* disconnect immediately */ - return; - } /* only uus */ - - if (pc->prot.ni1.invoke_id) - free_invoke_id(pc->st, pc->prot.ni1.invoke_id); - - if (!(pc->prot.ni1.invoke_id = new_invoke_id(pc->st))) - return; - - MsgHead(p, pc->callref, MT_FACILITY); - - for (subp = pc->chan->setup.phone; (*subp) && (*subp != '.'); subp++) len_phone++; /* len of phone number */ - if (*subp++ == '.') len_sub = strlen(subp) + 2; /* length including info subaddress element */ - - *p++ = 0x1c; /* Facility info element */ - *p++ = len_phone + len_sub + 2 + 2 + 8 + 3 + 3; /* length of element */ - *p++ = 0x91; /* remote operations protocol */ - *p++ = 0xa1; /* invoke component */ - - *p++ = len_phone + len_sub + 2 + 2 + 8 + 3; /* length of data */ - *p++ = 0x02; /* invoke id tag, integer */ - *p++ = 0x01; /* length */ - *p++ = pc->prot.ni1.invoke_id; /* invoke id */ - *p++ = 0x02; /* operation value tag, integer */ - *p++ = 0x01; /* length */ - *p++ = 0x0D; /* Call Deflect */ - - *p++ = 0x30; /* sequence phone number */ - *p++ = len_phone + 2 + 2 + 3 + len_sub; /* length */ - - *p++ = 0x30; /* Deflected to UserNumber */ - *p++ = len_phone + 2 + len_sub; /* length */ - *p++ = 0x80; /* NumberDigits */ - *p++ = len_phone; /* length */ - for (l = 0; l < len_phone; l++) - *p++ = pc->chan->setup.phone[l]; - - if (len_sub) - { *p++ = 0x04; /* called party subaddress */ - *p++ = len_sub - 2; - while (*subp) *p++ = *subp++; - } - - *p++ = 0x01; /* screening identifier */ - *p++ = 0x01; - *p++ = pc->chan->setup.screen; - - l = p - tmp; - if (!(skb = l3_alloc_skb(l))) return; - skb_put_data(skb, tmp, l); - - l3_msg(pc->st, DL_DATA | REQUEST, skb); -} /* l3ni1_redir_req */ - -/********************************************/ -/* handle deflection request in early state */ -/********************************************/ -static void l3ni1_redir_req_early(struct l3_process *pc, u_char pr, void *arg) -{ - l3ni1_proceed_req(pc, pr, arg); - l3ni1_redir_req(pc, pr, arg); -} /* l3ni1_redir_req_early */ - -/***********************************************/ -/* handle special commands for this protocol. */ -/* Examples are call independent services like */ -/* remote operations with dummy callref. */ -/***********************************************/ -static int l3ni1_cmd_global(struct PStack *st, isdn_ctrl *ic) -{ u_char id; - u_char temp[265]; - u_char *p = temp; - int i, l, proc_len; - struct sk_buff *skb; - struct l3_process *pc = NULL; - - switch (ic->arg) - { case NI1_CMD_INVOKE: - if (ic->parm.ni1_io.datalen < 0) return (-2); /* invalid parameter */ - - for (proc_len = 1, i = ic->parm.ni1_io.proc >> 8; i; i++) - i = i >> 8; /* add one byte */ - l = ic->parm.ni1_io.datalen + proc_len + 8; /* length excluding ie header */ - if (l > 255) - return (-2); /* too long */ - - if (!(id = new_invoke_id(st))) - return (0); /* first get a invoke id -> return if no available */ - - i = -1; - MsgHead(p, i, MT_FACILITY); /* build message head */ - *p++ = 0x1C; /* Facility IE */ - *p++ = l; /* length of ie */ - *p++ = 0x91; /* remote operations */ - *p++ = 0xA1; /* invoke */ - *p++ = l - 3; /* length of invoke */ - *p++ = 0x02; /* invoke id tag */ - *p++ = 0x01; /* length is 1 */ - *p++ = id; /* invoke id */ - *p++ = 0x02; /* operation */ - *p++ = proc_len; /* length of operation */ - - for (i = proc_len; i; i--) - *p++ = (ic->parm.ni1_io.proc >> (i - 1)) & 0xFF; - memcpy(p, ic->parm.ni1_io.data, ic->parm.ni1_io.datalen); /* copy data */ - l = (p - temp) + ic->parm.ni1_io.datalen; /* total length */ - - if (ic->parm.ni1_io.timeout > 0) { - pc = ni1_new_l3_process(st, -1); - if (!pc) { - free_invoke_id(st, id); - return (-2); - } - /* remember id */ - pc->prot.ni1.ll_id = ic->parm.ni1_io.ll_id; - /* and procedure */ - pc->prot.ni1.proc = ic->parm.ni1_io.proc; - } - - if (!(skb = l3_alloc_skb(l))) - { free_invoke_id(st, id); - if (pc) ni1_release_l3_process(pc); - return (-2); - } - skb_put_data(skb, temp, l); - - if (pc) - { pc->prot.ni1.invoke_id = id; /* remember id */ - L3AddTimer(&pc->timer, ic->parm.ni1_io.timeout, CC_TNI1_IO | REQUEST); - } - - l3_msg(st, DL_DATA | REQUEST, skb); - ic->parm.ni1_io.hl_id = id; /* return id */ - return (0); - - case NI1_CMD_INVOKE_ABORT: - if ((pc = l3ni1_search_dummy_proc(st, ic->parm.ni1_io.hl_id))) - { L3DelTimer(&pc->timer); /* remove timer */ - ni1_release_l3_process(pc); - return (0); - } - else - { l3_debug(st, "l3ni1_cmd_global abort unknown id"); - return (-2); - } - break; - - default: - l3_debug(st, "l3ni1_cmd_global unknown cmd 0x%lx", ic->arg); - return (-1); - } /* switch ic-> arg */ - return (-1); -} /* l3ni1_cmd_global */ - -static void -l3ni1_io_timer(struct l3_process *pc) -{ isdn_ctrl ic; - struct IsdnCardState *cs = pc->st->l1.hardware; - - L3DelTimer(&pc->timer); /* remove timer */ - - ic.driver = cs->myid; - ic.command = ISDN_STAT_PROT; - ic.arg = NI1_STAT_INVOKE_ERR; - ic.parm.ni1_io.hl_id = pc->prot.ni1.invoke_id; - ic.parm.ni1_io.ll_id = pc->prot.ni1.ll_id; - ic.parm.ni1_io.proc = pc->prot.ni1.proc; - ic.parm.ni1_io.timeout = -1; - ic.parm.ni1_io.datalen = 0; - ic.parm.ni1_io.data = NULL; - free_invoke_id(pc->st, pc->prot.ni1.invoke_id); - pc->prot.ni1.invoke_id = 0; /* reset id */ - - cs->iif.statcallb(&ic); - - ni1_release_l3_process(pc); -} /* l3ni1_io_timer */ - -static void -l3ni1_release_ind(struct l3_process *pc, u_char pr, void *arg) -{ - u_char *p; - struct sk_buff *skb = arg; - int callState = 0; - p = skb->data; - - if ((p = findie(p, skb->len, IE_CALL_STATE, 0))) { - p++; - if (1 == *p++) - callState = *p; - } - if (callState == 0) { - /* ETS 300-104 7.6.1, 8.6.1, 10.6.1... and 16.1 - * set down layer 3 without sending any message - */ - pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc); - newl3state(pc, 0); - ni1_release_l3_process(pc); - } else { - pc->st->l3.l3l4(pc->st, CC_IGNORE | INDICATION, pc); - } -} - -static void -l3ni1_dummy(struct l3_process *pc, u_char pr, void *arg) -{ -} - -static void -l3ni1_t302(struct l3_process *pc, u_char pr, void *arg) -{ - L3DelTimer(&pc->timer); - pc->para.loc = 0; - pc->para.cause = 28; /* invalid number */ - l3ni1_disconnect_req(pc, pr, NULL); - pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc); -} - -static void -l3ni1_t303(struct l3_process *pc, u_char pr, void *arg) -{ - if (pc->N303 > 0) { - pc->N303--; - L3DelTimer(&pc->timer); - l3ni1_setup_req(pc, pr, arg); - } else { - L3DelTimer(&pc->timer); - l3ni1_message_cause(pc, MT_RELEASE_COMPLETE, 102); - pc->st->l3.l3l4(pc->st, CC_NOSETUP_RSP, pc); - ni1_release_l3_process(pc); - } -} - -static void -l3ni1_t304(struct l3_process *pc, u_char pr, void *arg) -{ - L3DelTimer(&pc->timer); - pc->para.loc = 0; - pc->para.cause = 102; - l3ni1_disconnect_req(pc, pr, NULL); - pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc); - -} - -static void -l3ni1_t305(struct l3_process *pc, u_char pr, void *arg) -{ - u_char tmp[16]; - u_char *p = tmp; - int l; - struct sk_buff *skb; - u_char cause = 16; - - L3DelTimer(&pc->timer); - if (pc->para.cause != NO_CAUSE) - cause = pc->para.cause; - - MsgHead(p, pc->callref, MT_RELEASE); - - *p++ = IE_CAUSE; - *p++ = 0x2; - *p++ = 0x80; - *p++ = cause | 0x80; - - l = p - tmp; - if (!(skb = l3_alloc_skb(l))) - return; - skb_put_data(skb, tmp, l); - newl3state(pc, 19); - l3_msg(pc->st, DL_DATA | REQUEST, skb); - L3AddTimer(&pc->timer, T308, CC_T308_1); -} - -static void -l3ni1_t310(struct l3_process *pc, u_char pr, void *arg) -{ - L3DelTimer(&pc->timer); - pc->para.loc = 0; - pc->para.cause = 102; - l3ni1_disconnect_req(pc, pr, NULL); - pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc); -} - -static void -l3ni1_t313(struct l3_process *pc, u_char pr, void *arg) -{ - L3DelTimer(&pc->timer); - pc->para.loc = 0; - pc->para.cause = 102; - l3ni1_disconnect_req(pc, pr, NULL); - pc->st->l3.l3l4(pc->st, CC_CONNECT_ERR, pc); -} - -static void -l3ni1_t308_1(struct l3_process *pc, u_char pr, void *arg) -{ - newl3state(pc, 19); - L3DelTimer(&pc->timer); - l3ni1_message(pc, MT_RELEASE); - L3AddTimer(&pc->timer, T308, CC_T308_2); -} - -static void -l3ni1_t308_2(struct l3_process *pc, u_char pr, void *arg) -{ - L3DelTimer(&pc->timer); - pc->st->l3.l3l4(pc->st, CC_RELEASE_ERR, pc); - ni1_release_l3_process(pc); -} - -static void -l3ni1_t318(struct l3_process *pc, u_char pr, void *arg) -{ - L3DelTimer(&pc->timer); - pc->para.cause = 102; /* Timer expiry */ - pc->para.loc = 0; /* local */ - pc->st->l3.l3l4(pc->st, CC_RESUME_ERR, pc); - newl3state(pc, 19); - l3ni1_message(pc, MT_RELEASE); - L3AddTimer(&pc->timer, T308, CC_T308_1); -} - -static void -l3ni1_t319(struct l3_process *pc, u_char pr, void *arg) -{ - L3DelTimer(&pc->timer); - pc->para.cause = 102; /* Timer expiry */ - pc->para.loc = 0; /* local */ - pc->st->l3.l3l4(pc->st, CC_SUSPEND_ERR, pc); - newl3state(pc, 10); -} - -static void -l3ni1_restart(struct l3_process *pc, u_char pr, void *arg) -{ - L3DelTimer(&pc->timer); - pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc); - ni1_release_l3_process(pc); -} - -static void -l3ni1_status(struct l3_process *pc, u_char pr, void *arg) -{ - u_char *p; - struct sk_buff *skb = arg; - int ret; - u_char cause = 0, callState = 0; - - if ((ret = l3ni1_get_cause(pc, skb))) { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "STATUS get_cause ret(%d)", ret); - if (ret < 0) - cause = 96; - else if (ret > 0) - cause = 100; - } - if ((p = findie(skb->data, skb->len, IE_CALL_STATE, 0))) { - p++; - if (1 == *p++) { - callState = *p; - if (!ie_in_set(pc, *p, l3_valid_states)) - cause = 100; - } else - cause = 100; - } else - cause = 96; - if (!cause) { /* no error before */ - ret = check_infoelements(pc, skb, ie_STATUS); - if (ERR_IE_COMPREHENSION == ret) - cause = 96; - else if (ERR_IE_UNRECOGNIZED == ret) - cause = 99; - } - if (cause) { - u_char tmp; - - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "STATUS error(%d/%d)", ret, cause); - tmp = pc->para.cause; - pc->para.cause = cause; - l3ni1_status_send(pc, 0, NULL); - if (cause == 99) - pc->para.cause = tmp; - else - return; - } - cause = pc->para.cause; - if (((cause & 0x7f) == 111) && (callState == 0)) { - /* ETS 300-104 7.6.1, 8.6.1, 10.6.1... - * if received MT_STATUS with cause == 111 and call - * state == 0, then we must set down layer 3 - */ - pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc); - newl3state(pc, 0); - ni1_release_l3_process(pc); - } -} - -static void -l3ni1_facility(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - int ret; - - ret = check_infoelements(pc, skb, ie_FACILITY); - l3ni1_std_ie_err(pc, ret); - { - u_char *p; - if ((p = findie(skb->data, skb->len, IE_FACILITY, 0))) - l3ni1_parse_facility(pc->st, pc, pc->callref, p); - } -} - -static void -l3ni1_suspend_req(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb; - u_char tmp[32]; - u_char *p = tmp; - u_char i, l; - u_char *msg = pc->chan->setup.phone; - - MsgHead(p, pc->callref, MT_SUSPEND); - l = *msg++; - if (l && (l <= 10)) { /* Max length 10 octets */ - *p++ = IE_CALL_ID; - *p++ = l; - for (i = 0; i < l; i++) - *p++ = *msg++; - } else if (l) { - l3_debug(pc->st, "SUS wrong CALL_ID len %d", l); - return; - } - l = p - tmp; - if (!(skb = l3_alloc_skb(l))) - return; - skb_put_data(skb, tmp, l); - l3_msg(pc->st, DL_DATA | REQUEST, skb); - newl3state(pc, 15); - L3AddTimer(&pc->timer, T319, CC_T319); -} - -static void -l3ni1_suspend_ack(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - int ret; - - L3DelTimer(&pc->timer); - newl3state(pc, 0); - pc->para.cause = NO_CAUSE; - pc->st->l3.l3l4(pc->st, CC_SUSPEND | CONFIRM, pc); - /* We don't handle suspend_ack for IE errors now */ - if ((ret = check_infoelements(pc, skb, ie_SUSPEND_ACKNOWLEDGE))) - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "SUSPACK check ie(%d)", ret); - ni1_release_l3_process(pc); -} - -static void -l3ni1_suspend_rej(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - int ret; - - if ((ret = l3ni1_get_cause(pc, skb))) { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "SUSP_REJ get_cause ret(%d)", ret); - if (ret < 0) - pc->para.cause = 96; - else - pc->para.cause = 100; - l3ni1_status_send(pc, pr, NULL); - return; - } - ret = check_infoelements(pc, skb, ie_SUSPEND_REJECT); - if (ERR_IE_COMPREHENSION == ret) { - l3ni1_std_ie_err(pc, ret); - return; - } - L3DelTimer(&pc->timer); - pc->st->l3.l3l4(pc->st, CC_SUSPEND_ERR, pc); - newl3state(pc, 10); - if (ret) /* STATUS for none mandatory IE errors after actions are taken */ - l3ni1_std_ie_err(pc, ret); -} - -static void -l3ni1_resume_req(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb; - u_char tmp[32]; - u_char *p = tmp; - u_char i, l; - u_char *msg = pc->para.setup.phone; - - MsgHead(p, pc->callref, MT_RESUME); - - l = *msg++; - if (l && (l <= 10)) { /* Max length 10 octets */ - *p++ = IE_CALL_ID; - *p++ = l; - for (i = 0; i < l; i++) - *p++ = *msg++; - } else if (l) { - l3_debug(pc->st, "RES wrong CALL_ID len %d", l); - return; - } - l = p - tmp; - if (!(skb = l3_alloc_skb(l))) - return; - skb_put_data(skb, tmp, l); - l3_msg(pc->st, DL_DATA | REQUEST, skb); - newl3state(pc, 17); - L3AddTimer(&pc->timer, T318, CC_T318); -} - -static void -l3ni1_resume_ack(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - int id, ret; - - if ((id = l3ni1_get_channel_id(pc, skb)) > 0) { - if ((0 == id) || ((3 == id) && (0x10 == pc->para.moderate))) { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "resume ack with wrong chid %x", id); - pc->para.cause = 100; - l3ni1_status_send(pc, pr, NULL); - return; - } - pc->para.bchannel = id; - } else if (1 == pc->state) { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "resume ack without chid (ret %d)", id); - pc->para.cause = 96; - l3ni1_status_send(pc, pr, NULL); - return; - } - ret = check_infoelements(pc, skb, ie_RESUME_ACKNOWLEDGE); - if (ERR_IE_COMPREHENSION == ret) { - l3ni1_std_ie_err(pc, ret); - return; - } - L3DelTimer(&pc->timer); - pc->st->l3.l3l4(pc->st, CC_RESUME | CONFIRM, pc); - newl3state(pc, 10); - if (ret) /* STATUS for none mandatory IE errors after actions are taken */ - l3ni1_std_ie_err(pc, ret); -} - -static void -l3ni1_resume_rej(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - int ret; - - if ((ret = l3ni1_get_cause(pc, skb))) { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "RES_REJ get_cause ret(%d)", ret); - if (ret < 0) - pc->para.cause = 96; - else - pc->para.cause = 100; - l3ni1_status_send(pc, pr, NULL); - return; - } - ret = check_infoelements(pc, skb, ie_RESUME_REJECT); - if (ERR_IE_COMPREHENSION == ret) { - l3ni1_std_ie_err(pc, ret); - return; - } - L3DelTimer(&pc->timer); - pc->st->l3.l3l4(pc->st, CC_RESUME_ERR, pc); - newl3state(pc, 0); - if (ret) /* STATUS for none mandatory IE errors after actions are taken */ - l3ni1_std_ie_err(pc, ret); - ni1_release_l3_process(pc); -} - -static void -l3ni1_global_restart(struct l3_process *pc, u_char pr, void *arg) -{ - u_char tmp[32]; - u_char *p; - u_char ri, ch = 0, chan = 0; - int l; - struct sk_buff *skb = arg; - struct l3_process *up; - - newl3state(pc, 2); - L3DelTimer(&pc->timer); - p = skb->data; - if ((p = findie(p, skb->len, IE_RESTART_IND, 0))) { - ri = p[2]; - l3_debug(pc->st, "Restart %x", ri); - } else { - l3_debug(pc->st, "Restart without restart IE"); - ri = 0x86; - } - p = skb->data; - if ((p = findie(p, skb->len, IE_CHANNEL_ID, 0))) { - chan = p[2] & 3; - ch = p[2]; - if (pc->st->l3.debug) - l3_debug(pc->st, "Restart for channel %d", chan); - } - newl3state(pc, 2); - up = pc->st->l3.proc; - while (up) { - if ((ri & 7) == 7) - up->st->lli.l4l3(up->st, CC_RESTART | REQUEST, up); - else if (up->para.bchannel == chan) - up->st->lli.l4l3(up->st, CC_RESTART | REQUEST, up); - - up = up->next; - } - p = tmp; - MsgHead(p, pc->callref, MT_RESTART_ACKNOWLEDGE); - if (chan) { - *p++ = IE_CHANNEL_ID; - *p++ = 1; - *p++ = ch | 0x80; - } - *p++ = 0x79; /* RESTART Ind */ - *p++ = 1; - *p++ = ri; - l = p - tmp; - if (!(skb = l3_alloc_skb(l))) - return; - skb_put_data(skb, tmp, l); - newl3state(pc, 0); - l3_msg(pc->st, DL_DATA | REQUEST, skb); -} - -static void -l3ni1_dl_reset(struct l3_process *pc, u_char pr, void *arg) -{ - pc->para.cause = 0x29; /* Temporary failure */ - pc->para.loc = 0; - l3ni1_disconnect_req(pc, pr, NULL); - pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc); -} - -static void -l3ni1_dl_release(struct l3_process *pc, u_char pr, void *arg) -{ - newl3state(pc, 0); - pc->para.cause = 0x1b; /* Destination out of order */ - pc->para.loc = 0; - pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc); - release_l3_process(pc); -} - -static void -l3ni1_dl_reestablish(struct l3_process *pc, u_char pr, void *arg) -{ - L3DelTimer(&pc->timer); - L3AddTimer(&pc->timer, T309, CC_T309); - l3_msg(pc->st, DL_ESTABLISH | REQUEST, NULL); -} - -static void -l3ni1_dl_reest_status(struct l3_process *pc, u_char pr, void *arg) -{ - L3DelTimer(&pc->timer); - - pc->para.cause = 0x1F; /* normal, unspecified */ - l3ni1_status_send(pc, 0, NULL); -} - -static void l3ni1_SendSpid(struct l3_process *pc, u_char pr, struct sk_buff *skb, int iNewState) -{ - u_char *p; - char *pSPID; - struct Channel *pChan = pc->st->lli.userdata; - int l; - - if (skb) - dev_kfree_skb(skb); - - if (!(pSPID = strchr(pChan->setup.eazmsn, ':'))) - { - printk(KERN_ERR "SPID not supplied in EAZMSN %s\n", pChan->setup.eazmsn); - newl3state(pc, 0); - pc->st->l3.l3l2(pc->st, DL_RELEASE | REQUEST, NULL); - return; - } - - l = strlen(++pSPID); - if (!(skb = l3_alloc_skb(5 + l))) - { - printk(KERN_ERR "HiSax can't get memory to send SPID\n"); - return; - } - - p = skb_put(skb, 5); - *p++ = PROTO_DIS_EURO; - *p++ = 0; - *p++ = MT_INFORMATION; - *p++ = IE_SPID; - *p++ = l; - - skb_put_data(skb, pSPID, l); - - newl3state(pc, iNewState); - - L3DelTimer(&pc->timer); - L3AddTimer(&pc->timer, TSPID, CC_TSPID); - - pc->st->l3.l3l2(pc->st, DL_DATA | REQUEST, skb); -} - -static void l3ni1_spid_send(struct l3_process *pc, u_char pr, void *arg) -{ - l3ni1_SendSpid(pc, pr, arg, 20); -} - -static void l3ni1_spid_epid(struct l3_process *pc, u_char pr, void *arg) -{ - struct sk_buff *skb = arg; - - if (skb->data[1] == 0) - if (skb->data[3] == IE_ENDPOINT_ID) - { - L3DelTimer(&pc->timer); - newl3state(pc, 0); - l3_msg(pc->st, DL_ESTABLISH | CONFIRM, NULL); - } - dev_kfree_skb(skb); -} - -static void l3ni1_spid_tout(struct l3_process *pc, u_char pr, void *arg) -{ - if (pc->state < 22) - l3ni1_SendSpid(pc, pr, arg, pc->state + 1); - else - { - L3DelTimer(&pc->timer); - dev_kfree_skb(arg); - - printk(KERN_ERR "SPID not accepted\n"); - newl3state(pc, 0); - pc->st->l3.l3l2(pc->st, DL_RELEASE | REQUEST, NULL); - } -} - -/* *INDENT-OFF* */ -static struct stateentry downstatelist[] = -{ - {SBIT(0), - CC_SETUP | REQUEST, l3ni1_setup_req}, - {SBIT(0), - CC_RESUME | REQUEST, l3ni1_resume_req}, - {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(6) | SBIT(7) | SBIT(8) | SBIT(9) | SBIT(10) | SBIT(25), - CC_DISCONNECT | REQUEST, l3ni1_disconnect_req}, - {SBIT(12), - CC_RELEASE | REQUEST, l3ni1_release_req}, - {ALL_STATES, - CC_RESTART | REQUEST, l3ni1_restart}, - {SBIT(6) | SBIT(25), - CC_IGNORE | REQUEST, l3ni1_reset}, - {SBIT(6) | SBIT(25), - CC_REJECT | REQUEST, l3ni1_reject_req}, - {SBIT(6) | SBIT(25), - CC_PROCEED_SEND | REQUEST, l3ni1_proceed_req}, - {SBIT(6), - CC_MORE_INFO | REQUEST, l3ni1_setup_ack_req}, - {SBIT(25), - CC_MORE_INFO | REQUEST, l3ni1_dummy}, - {SBIT(6) | SBIT(9) | SBIT(25), - CC_ALERTING | REQUEST, l3ni1_alert_req}, - {SBIT(6) | SBIT(7) | SBIT(9) | SBIT(25), - CC_SETUP | RESPONSE, l3ni1_setup_rsp}, - {SBIT(10), - CC_SUSPEND | REQUEST, l3ni1_suspend_req}, - {SBIT(7) | SBIT(9) | SBIT(25), - CC_REDIR | REQUEST, l3ni1_redir_req}, - {SBIT(6), - CC_REDIR | REQUEST, l3ni1_redir_req_early}, - {SBIT(9) | SBIT(25), - CC_DISCONNECT | REQUEST, l3ni1_disconnect_req}, - {SBIT(25), - CC_T302, l3ni1_t302}, - {SBIT(1), - CC_T303, l3ni1_t303}, - {SBIT(2), - CC_T304, l3ni1_t304}, - {SBIT(3), - CC_T310, l3ni1_t310}, - {SBIT(8), - CC_T313, l3ni1_t313}, - {SBIT(11), - CC_T305, l3ni1_t305}, - {SBIT(15), - CC_T319, l3ni1_t319}, - {SBIT(17), - CC_T318, l3ni1_t318}, - {SBIT(19), - CC_T308_1, l3ni1_t308_1}, - {SBIT(19), - CC_T308_2, l3ni1_t308_2}, - {SBIT(10), - CC_T309, l3ni1_dl_release}, - { SBIT(20) | SBIT(21) | SBIT(22), - CC_TSPID, l3ni1_spid_tout }, -}; - -static struct stateentry datastatelist[] = -{ - {ALL_STATES, - MT_STATUS_ENQUIRY, l3ni1_status_enq}, - {ALL_STATES, - MT_FACILITY, l3ni1_facility}, - {SBIT(19), - MT_STATUS, l3ni1_release_ind}, - {ALL_STATES, - MT_STATUS, l3ni1_status}, - {SBIT(0), - MT_SETUP, l3ni1_setup}, - {SBIT(6) | SBIT(7) | SBIT(8) | SBIT(9) | SBIT(10) | SBIT(11) | SBIT(12) | - SBIT(15) | SBIT(17) | SBIT(19) | SBIT(25), - MT_SETUP, l3ni1_dummy}, - {SBIT(1) | SBIT(2), - MT_CALL_PROCEEDING, l3ni1_call_proc}, - {SBIT(1), - MT_SETUP_ACKNOWLEDGE, l3ni1_setup_ack}, - {SBIT(2) | SBIT(3), - MT_ALERTING, l3ni1_alerting}, - {SBIT(2) | SBIT(3), - MT_PROGRESS, l3ni1_progress}, - {SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(9) | SBIT(10) | - SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17) | SBIT(19) | SBIT(25), - MT_INFORMATION, l3ni1_information}, - {SBIT(10) | SBIT(11) | SBIT(15), - MT_NOTIFY, l3ni1_notify}, - {SBIT(0) | SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(10) | - SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17) | SBIT(19) | SBIT(25), - MT_RELEASE_COMPLETE, l3ni1_release_cmpl}, - {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(9) | SBIT(10) | SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17) | SBIT(25), - MT_RELEASE, l3ni1_release}, - {SBIT(19), MT_RELEASE, l3ni1_release_ind}, - {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(9) | SBIT(10) | SBIT(11) | SBIT(15) | SBIT(17) | SBIT(25), - MT_DISCONNECT, l3ni1_disconnect}, - {SBIT(19), - MT_DISCONNECT, l3ni1_dummy}, - {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4), - MT_CONNECT, l3ni1_connect}, - {SBIT(8), - MT_CONNECT_ACKNOWLEDGE, l3ni1_connect_ack}, - {SBIT(15), - MT_SUSPEND_ACKNOWLEDGE, l3ni1_suspend_ack}, - {SBIT(15), - MT_SUSPEND_REJECT, l3ni1_suspend_rej}, - {SBIT(17), - MT_RESUME_ACKNOWLEDGE, l3ni1_resume_ack}, - {SBIT(17), - MT_RESUME_REJECT, l3ni1_resume_rej}, -}; - -static struct stateentry globalmes_list[] = -{ - {ALL_STATES, - MT_STATUS, l3ni1_status}, - {SBIT(0), - MT_RESTART, l3ni1_global_restart}, -/* {SBIT(1), - MT_RESTART_ACKNOWLEDGE, l3ni1_restart_ack}, -*/ - { SBIT(0), MT_DL_ESTABLISHED, l3ni1_spid_send }, - { SBIT(20) | SBIT(21) | SBIT(22), MT_INFORMATION, l3ni1_spid_epid }, -}; - -static struct stateentry manstatelist[] = -{ - {SBIT(2), - DL_ESTABLISH | INDICATION, l3ni1_dl_reset}, - {SBIT(10), - DL_ESTABLISH | CONFIRM, l3ni1_dl_reest_status}, - {SBIT(10), - DL_RELEASE | INDICATION, l3ni1_dl_reestablish}, - {ALL_STATES, - DL_RELEASE | INDICATION, l3ni1_dl_release}, -}; - -/* *INDENT-ON* */ - - -static void -global_handler(struct PStack *st, int mt, struct sk_buff *skb) -{ - u_char tmp[16]; - u_char *p = tmp; - int l; - int i; - struct l3_process *proc = st->l3.global; - - if (skb) - proc->callref = skb->data[2]; /* cr flag */ - else - proc->callref = 0; - for (i = 0; i < ARRAY_SIZE(globalmes_list); i++) - if ((mt == globalmes_list[i].primitive) && - ((1 << proc->state) & globalmes_list[i].state)) - break; - if (i == ARRAY_SIZE(globalmes_list)) { - if (st->l3.debug & L3_DEB_STATE) { - l3_debug(st, "ni1 global state %d mt %x unhandled", - proc->state, mt); - } - MsgHead(p, proc->callref, MT_STATUS); - *p++ = IE_CAUSE; - *p++ = 0x2; - *p++ = 0x80; - *p++ = 81 | 0x80; /* invalid cr */ - *p++ = 0x14; /* CallState */ - *p++ = 0x1; - *p++ = proc->state & 0x3f; - l = p - tmp; - if (!(skb = l3_alloc_skb(l))) - return; - skb_put_data(skb, tmp, l); - l3_msg(proc->st, DL_DATA | REQUEST, skb); - } else { - if (st->l3.debug & L3_DEB_STATE) { - l3_debug(st, "ni1 global %d mt %x", - proc->state, mt); - } - globalmes_list[i].rout(proc, mt, skb); - } -} - -static void -ni1up(struct PStack *st, int pr, void *arg) -{ - int i, mt, cr, callState; - char *ptr; - u_char *p; - struct sk_buff *skb = arg; - struct l3_process *proc; - - switch (pr) { - case (DL_DATA | INDICATION): - case (DL_UNIT_DATA | INDICATION): - break; - case (DL_ESTABLISH | INDICATION): - case (DL_RELEASE | INDICATION): - case (DL_RELEASE | CONFIRM): - l3_msg(st, pr, arg); - return; - break; - - case (DL_ESTABLISH | CONFIRM): - global_handler(st, MT_DL_ESTABLISHED, NULL); - return; - - default: - printk(KERN_ERR "HiSax ni1up unknown pr=%04x\n", pr); - return; - } - if (skb->len < 3) { - l3_debug(st, "ni1up frame too short(%d)", skb->len); - dev_kfree_skb(skb); - return; - } - - if (skb->data[0] != PROTO_DIS_EURO) { - if (st->l3.debug & L3_DEB_PROTERR) { - l3_debug(st, "ni1up%sunexpected discriminator %x message len %d", - (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ", - skb->data[0], skb->len); - } - dev_kfree_skb(skb); - return; - } - cr = getcallref(skb->data); - if (skb->len < ((skb->data[1] & 0x0f) + 3)) { - l3_debug(st, "ni1up frame too short(%d)", skb->len); - dev_kfree_skb(skb); - return; - } - mt = skb->data[skb->data[1] + 2]; - if (st->l3.debug & L3_DEB_STATE) - l3_debug(st, "ni1up cr %d", cr); - if (cr == -2) { /* wrong Callref */ - if (st->l3.debug & L3_DEB_WARN) - l3_debug(st, "ni1up wrong Callref"); - dev_kfree_skb(skb); - return; - } else if (cr == -1) { /* Dummy Callref */ - if (mt == MT_FACILITY) - { - if ((p = findie(skb->data, skb->len, IE_FACILITY, 0))) { - l3ni1_parse_facility(st, NULL, - (pr == (DL_DATA | INDICATION)) ? -1 : -2, p); - dev_kfree_skb(skb); - return; - } - } - else - { - global_handler(st, mt, skb); - return; - } - - if (st->l3.debug & L3_DEB_WARN) - l3_debug(st, "ni1up dummy Callref (no facility msg or ie)"); - dev_kfree_skb(skb); - return; - } else if ((((skb->data[1] & 0x0f) == 1) && (0 == (cr & 0x7f))) || - (((skb->data[1] & 0x0f) == 2) && (0 == (cr & 0x7fff)))) { /* Global CallRef */ - if (st->l3.debug & L3_DEB_STATE) - l3_debug(st, "ni1up Global CallRef"); - global_handler(st, mt, skb); - dev_kfree_skb(skb); - return; - } else if (!(proc = getl3proc(st, cr))) { - /* No transaction process exist, that means no call with - * this callreference is active - */ - if (mt == MT_SETUP) { - /* Setup creates a new transaction process */ - if (skb->data[2] & 0x80) { - /* Setup with wrong CREF flag */ - if (st->l3.debug & L3_DEB_STATE) - l3_debug(st, "ni1up wrong CRef flag"); - dev_kfree_skb(skb); - return; - } - if (!(proc = ni1_new_l3_process(st, cr))) { - /* May be to answer with RELEASE_COMPLETE and - * CAUSE 0x2f "Resource unavailable", but this - * need a new_l3_process too ... arghh - */ - dev_kfree_skb(skb); - return; - } - } else if (mt == MT_STATUS) { - if ((ptr = findie(skb->data, skb->len, IE_CAUSE, 0)) != NULL) { - ptr++; - if (*ptr++ == 2) - ptr++; - } - callState = 0; - if ((ptr = findie(skb->data, skb->len, IE_CALL_STATE, 0)) != NULL) { - ptr++; - if (*ptr++ == 2) - ptr++; - callState = *ptr; - } - /* ETS 300-104 part 2.4.1 - * if setup has not been made and a message type - * MT_STATUS is received with call state == 0, - * we must send nothing - */ - if (callState != 0) { - /* ETS 300-104 part 2.4.2 - * if setup has not been made and a message type - * MT_STATUS is received with call state != 0, - * we must send MT_RELEASE_COMPLETE cause 101 - */ - if ((proc = ni1_new_l3_process(st, cr))) { - proc->para.cause = 101; - l3ni1_msg_without_setup(proc, 0, NULL); - } - } - dev_kfree_skb(skb); - return; - } else if (mt == MT_RELEASE_COMPLETE) { - dev_kfree_skb(skb); - return; - } else { - /* ETS 300-104 part 2 - * if setup has not been made and a message type - * (except MT_SETUP and RELEASE_COMPLETE) is received, - * we must send MT_RELEASE_COMPLETE cause 81 */ - dev_kfree_skb(skb); - if ((proc = ni1_new_l3_process(st, cr))) { - proc->para.cause = 81; - l3ni1_msg_without_setup(proc, 0, NULL); - } - return; - } - } - if (l3ni1_check_messagetype_validity(proc, mt, skb)) { - dev_kfree_skb(skb); - return; - } - if ((p = findie(skb->data, skb->len, IE_DISPLAY, 0)) != NULL) - l3ni1_deliver_display(proc, pr, p); /* Display IE included */ - for (i = 0; i < ARRAY_SIZE(datastatelist); i++) - if ((mt == datastatelist[i].primitive) && - ((1 << proc->state) & datastatelist[i].state)) - break; - if (i == ARRAY_SIZE(datastatelist)) { - if (st->l3.debug & L3_DEB_STATE) { - l3_debug(st, "ni1up%sstate %d mt %#x unhandled", - (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ", - proc->state, mt); - } - if ((MT_RELEASE_COMPLETE != mt) && (MT_RELEASE != mt)) { - proc->para.cause = 101; - l3ni1_status_send(proc, pr, skb); - } - } else { - if (st->l3.debug & L3_DEB_STATE) { - l3_debug(st, "ni1up%sstate %d mt %x", - (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ", - proc->state, mt); - } - datastatelist[i].rout(proc, pr, skb); - } - dev_kfree_skb(skb); - return; -} - -static void -ni1down(struct PStack *st, int pr, void *arg) -{ - int i, cr; - struct l3_process *proc; - struct Channel *chan; - - if ((DL_ESTABLISH | REQUEST) == pr) { - l3_msg(st, pr, NULL); - return; - } else if (((CC_SETUP | REQUEST) == pr) || ((CC_RESUME | REQUEST) == pr)) { - chan = arg; - cr = newcallref(); - cr |= 0x80; - if ((proc = ni1_new_l3_process(st, cr))) { - proc->chan = chan; - chan->proc = proc; - memcpy(&proc->para.setup, &chan->setup, sizeof(setup_parm)); - proc->callref = cr; - } - } else { - proc = arg; - } - if (!proc) { - printk(KERN_ERR "HiSax ni1down without proc pr=%04x\n", pr); - return; - } - - if (pr == (CC_TNI1_IO | REQUEST)) { - l3ni1_io_timer(proc); /* timer expires */ - return; - } - - for (i = 0; i < ARRAY_SIZE(downstatelist); i++) - if ((pr == downstatelist[i].primitive) && - ((1 << proc->state) & downstatelist[i].state)) - break; - if (i == ARRAY_SIZE(downstatelist)) { - if (st->l3.debug & L3_DEB_STATE) { - l3_debug(st, "ni1down state %d prim %#x unhandled", - proc->state, pr); - } - } else { - if (st->l3.debug & L3_DEB_STATE) { - l3_debug(st, "ni1down state %d prim %#x", - proc->state, pr); - } - downstatelist[i].rout(proc, pr, arg); - } -} - -static void -ni1man(struct PStack *st, int pr, void *arg) -{ - int i; - struct l3_process *proc = arg; - - if (!proc) { - printk(KERN_ERR "HiSax ni1man without proc pr=%04x\n", pr); - return; - } - for (i = 0; i < ARRAY_SIZE(manstatelist); i++) - if ((pr == manstatelist[i].primitive) && - ((1 << proc->state) & manstatelist[i].state)) - break; - if (i == ARRAY_SIZE(manstatelist)) { - if (st->l3.debug & L3_DEB_STATE) { - l3_debug(st, "cr %d ni1man state %d prim %#x unhandled", - proc->callref & 0x7f, proc->state, pr); - } - } else { - if (st->l3.debug & L3_DEB_STATE) { - l3_debug(st, "cr %d ni1man state %d prim %#x", - proc->callref & 0x7f, proc->state, pr); - } - manstatelist[i].rout(proc, pr, arg); - } -} - -void -setstack_ni1(struct PStack *st) -{ - char tmp[64]; - int i; - - st->lli.l4l3 = ni1down; - st->lli.l4l3_proto = l3ni1_cmd_global; - st->l2.l2l3 = ni1up; - st->l3.l3ml3 = ni1man; - st->l3.N303 = 1; - st->prot.ni1.last_invoke_id = 0; - st->prot.ni1.invoke_used[0] = 1; /* Bit 0 must always be set to 1 */ - i = 1; - while (i < 32) - st->prot.ni1.invoke_used[i++] = 0; - - if (!(st->l3.global = kmalloc(sizeof(struct l3_process), GFP_ATOMIC))) { - printk(KERN_ERR "HiSax can't get memory for ni1 global CR\n"); - } else { - st->l3.global->state = 0; - st->l3.global->callref = 0; - st->l3.global->next = NULL; - st->l3.global->debug = L3_DEB_WARN; - st->l3.global->st = st; - st->l3.global->N303 = 1; - st->l3.global->prot.ni1.invoke_id = 0; - - L3InitTimer(st->l3.global, &st->l3.global->timer); - } - strcpy(tmp, ni1_revision); - printk(KERN_INFO "HiSax: National ISDN-1 Rev. %s\n", HiSax_getrev(tmp)); -} diff --git a/drivers/isdn/hisax/l3ni1.h b/drivers/isdn/hisax/l3ni1.h deleted file mode 100644 index 99d37d2cea4f..000000000000 --- a/drivers/isdn/hisax/l3ni1.h +++ /dev/null @@ -1,136 +0,0 @@ -/* $Id: l3ni1.h,v 2.3.6.2 2001/09/23 22:24:50 kai Exp $ - * - * NI1 D-channel protocol - * - * Author Matt Henderson & Guy Ellis - * Copyright by Traverse Technologies Pty Ltd, www.travers.com.au - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * 2000.6.6 Initial implementation of routines for US NI1 - * Layer 3 protocol based on the EURO/DSS1 D-channel protocol - * driver written by Karsten Keil et al. Thanks also for the - * code provided by Ragnar Paulson. - * - */ - -#ifndef l3ni1_process - -#define T302 15000 -#define T303 4000 -#define T304 30000 -#define T305 30000 -#define T308 4000 -/* for layer 1 certification T309 < layer1 T3 (e.g. 4000) */ -/* This makes some tests easier and quicker */ -#define T309 40000 -#define T310 30000 -#define T313 4000 -#define T318 4000 -#define T319 4000 -#define TSPID 5000 /* was 2000 - Guy Ellis */ - -/* - * Message-Types - */ - -#define MT_ALERTING 0x01 -#define MT_CALL_PROCEEDING 0x02 -#define MT_CONNECT 0x07 -#define MT_CONNECT_ACKNOWLEDGE 0x0f -#define MT_PROGRESS 0x03 -#define MT_SETUP 0x05 -#define MT_SETUP_ACKNOWLEDGE 0x0d -#define MT_RESUME 0x26 -#define MT_RESUME_ACKNOWLEDGE 0x2e -#define MT_RESUME_REJECT 0x22 -#define MT_SUSPEND 0x25 -#define MT_SUSPEND_ACKNOWLEDGE 0x2d -#define MT_SUSPEND_REJECT 0x21 -#define MT_USER_INFORMATION 0x20 -#define MT_DISCONNECT 0x45 -#define MT_RELEASE 0x4d -#define MT_RELEASE_COMPLETE 0x5a -#define MT_RESTART 0x46 -#define MT_RESTART_ACKNOWLEDGE 0x4e -#define MT_SEGMENT 0x60 -#define MT_CONGESTION_CONTROL 0x79 -#define MT_INFORMATION 0x7b -#define MT_FACILITY 0x62 -#define MT_NOTIFY 0x6e -#define MT_STATUS 0x7d -#define MT_STATUS_ENQUIRY 0x75 -#define MT_DL_ESTABLISHED 0xfe - -#define IE_SEGMENT 0x00 -#define IE_BEARER 0x04 -#define IE_CAUSE 0x08 -#define IE_CALL_ID 0x10 -#define IE_CALL_STATE 0x14 -#define IE_CHANNEL_ID 0x18 -#define IE_FACILITY 0x1c -#define IE_PROGRESS 0x1e -#define IE_NET_FAC 0x20 -#define IE_NOTIFY 0x27 -#define IE_DISPLAY 0x28 -#define IE_DATE 0x29 -#define IE_KEYPAD 0x2c -#define IE_SIGNAL 0x34 -#define IE_SPID 0x3a -#define IE_ENDPOINT_ID 0x3b -#define IE_INFORATE 0x40 -#define IE_E2E_TDELAY 0x42 -#define IE_TDELAY_SEL 0x43 -#define IE_PACK_BINPARA 0x44 -#define IE_PACK_WINSIZE 0x45 -#define IE_PACK_SIZE 0x46 -#define IE_CUG 0x47 -#define IE_REV_CHARGE 0x4a -#define IE_CONNECT_PN 0x4c -#define IE_CONNECT_SUB 0x4d -#define IE_CALLING_PN 0x6c -#define IE_CALLING_SUB 0x6d -#define IE_CALLED_PN 0x70 -#define IE_CALLED_SUB 0x71 -#define IE_REDIR_NR 0x74 -#define IE_TRANS_SEL 0x78 -#define IE_RESTART_IND 0x79 -#define IE_LLC 0x7c -#define IE_HLC 0x7d -#define IE_USER_USER 0x7e -#define IE_ESCAPE 0x7f -#define IE_SHIFT 0x90 -#define IE_MORE_DATA 0xa0 -#define IE_COMPLETE 0xa1 -#define IE_CONGESTION 0xb0 -#define IE_REPEAT 0xd0 - -#define IE_MANDATORY 0x0100 -/* mandatory not in every case */ -#define IE_MANDATORY_1 0x0200 - -#define ERR_IE_COMPREHENSION 1 -#define ERR_IE_UNRECOGNIZED -1 -#define ERR_IE_LENGTH -2 -#define ERR_IE_SEQUENCE -3 - -#else /* only l3ni1_process */ - -/* l3ni1 specific data in l3 process */ -typedef struct -{ unsigned char invoke_id; /* used invoke id in remote ops, 0 = not active */ - ulong ll_id; /* remebered ll id */ - u8 remote_operation; /* handled remote operation, 0 = not active */ - int proc; /* rememered procedure */ - ulong remote_result; /* result of remote operation for statcallb */ - char uus1_data[35]; /* data send during alerting or disconnect */ -} ni1_proc_priv; - -/* l3dni1 specific data in protocol stack */ -typedef struct -{ unsigned char last_invoke_id; /* last used value for invoking */ - unsigned char invoke_used[32]; /* 256 bits for 256 values */ -} ni1_stk_priv; - -#endif /* only l3dni1_process */ diff --git a/drivers/isdn/hisax/lmgr.c b/drivers/isdn/hisax/lmgr.c deleted file mode 100644 index 5b63eb6601aa..000000000000 --- a/drivers/isdn/hisax/lmgr.c +++ /dev/null @@ -1,50 +0,0 @@ -/* $Id: lmgr.c,v 1.7.6.2 2001/09/23 22:24:50 kai Exp $ - * - * Layermanagement module - * - * Author Karsten Keil - * Copyright by Karsten Keil <keil@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#include "hisax.h" - -static void -error_handling_dchan(struct PStack *st, int Error) -{ - switch (Error) { - case 'C': - case 'D': - case 'G': - case 'H': - st->l2.l2tei(st, MDL_ERROR | REQUEST, NULL); - break; - } -} - -static void -hisax_manager(struct PStack *st, int pr, void *arg) -{ - long Code; - - switch (pr) { - case (MDL_ERROR | INDICATION): - Code = (long) arg; - HiSax_putstatus(st->l1.hardware, "manager: MDL_ERROR", - " %c %s", (char)Code, - test_bit(FLG_LAPD, &st->l2.flag) ? - "D-channel" : "B-channel"); - if (test_bit(FLG_LAPD, &st->l2.flag)) - error_handling_dchan(st, Code); - break; - } -} - -void -setstack_manager(struct PStack *st) -{ - st->ma.layer = hisax_manager; -} diff --git a/drivers/isdn/hisax/mic.c b/drivers/isdn/hisax/mic.c deleted file mode 100644 index 93398676f78f..000000000000 --- a/drivers/isdn/hisax/mic.c +++ /dev/null @@ -1,235 +0,0 @@ -/* $Id: mic.c,v 1.12.2.4 2004/01/13 23:48:39 keil Exp $ - * - * low level stuff for mic cards - * - * Author Stephan von Krawczynski - * Copyright by Stephan von Krawczynski <skraw@ithnet.com> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#include <linux/init.h> -#include "hisax.h" -#include "isac.h" -#include "hscx.h" -#include "isdnl1.h" - -static const char *mic_revision = "$Revision: 1.12.2.4 $"; - -#define byteout(addr, val) outb(val, addr) -#define bytein(addr) inb(addr) - -#define MIC_ISAC 2 -#define MIC_HSCX 1 -#define MIC_ADR 7 - -/* CARD_ADR (Write) */ -#define MIC_RESET 0x3 /* same as DOS driver */ - -static inline u_char -readreg(unsigned int ale, unsigned int adr, u_char off) -{ - register u_char ret; - - byteout(ale, off); - ret = bytein(adr); - return (ret); -} - -static inline void -readfifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size) -{ - byteout(ale, off); - insb(adr, data, size); -} - - -static inline void -writereg(unsigned int ale, unsigned int adr, u_char off, u_char data) -{ - byteout(ale, off); - byteout(adr, data); -} - -static inline void -writefifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size) -{ - byteout(ale, off); - outsb(adr, data, size); -} - -/* Interface functions */ - -static u_char -ReadISAC(struct IsdnCardState *cs, u_char offset) -{ - return (readreg(cs->hw.mic.adr, cs->hw.mic.isac, offset)); -} - -static void -WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value) -{ - writereg(cs->hw.mic.adr, cs->hw.mic.isac, offset, value); -} - -static void -ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - readfifo(cs->hw.mic.adr, cs->hw.mic.isac, 0, data, size); -} - -static void -WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - writefifo(cs->hw.mic.adr, cs->hw.mic.isac, 0, data, size); -} - -static u_char -ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset) -{ - return (readreg(cs->hw.mic.adr, - cs->hw.mic.hscx, offset + (hscx ? 0x40 : 0))); -} - -static void -WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) -{ - writereg(cs->hw.mic.adr, - cs->hw.mic.hscx, offset + (hscx ? 0x40 : 0), value); -} - -/* - * fast interrupt HSCX stuff goes here - */ - -#define READHSCX(cs, nr, reg) readreg(cs->hw.mic.adr, \ - cs->hw.mic.hscx, reg + (nr ? 0x40 : 0)) -#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.mic.adr, \ - cs->hw.mic.hscx, reg + (nr ? 0x40 : 0), data) - -#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.mic.adr, \ - cs->hw.mic.hscx, (nr ? 0x40 : 0), ptr, cnt) - -#define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.mic.adr, \ - cs->hw.mic.hscx, (nr ? 0x40 : 0), ptr, cnt) - -#include "hscx_irq.c" - -static irqreturn_t -mic_interrupt(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - u_char val; - u_long flags; - - spin_lock_irqsave(&cs->lock, flags); - val = readreg(cs->hw.mic.adr, cs->hw.mic.hscx, HSCX_ISTA + 0x40); -Start_HSCX: - if (val) - hscx_int_main(cs, val); - val = readreg(cs->hw.mic.adr, cs->hw.mic.isac, ISAC_ISTA); -Start_ISAC: - if (val) - isac_interrupt(cs, val); - val = readreg(cs->hw.mic.adr, cs->hw.mic.hscx, HSCX_ISTA + 0x40); - if (val) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "HSCX IntStat after IntRoutine"); - goto Start_HSCX; - } - val = readreg(cs->hw.mic.adr, cs->hw.mic.isac, ISAC_ISTA); - if (val) { - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "ISAC IntStat after IntRoutine"); - goto Start_ISAC; - } - writereg(cs->hw.mic.adr, cs->hw.mic.hscx, HSCX_MASK, 0xFF); - writereg(cs->hw.mic.adr, cs->hw.mic.hscx, HSCX_MASK + 0x40, 0xFF); - writereg(cs->hw.mic.adr, cs->hw.mic.isac, ISAC_MASK, 0xFF); - writereg(cs->hw.mic.adr, cs->hw.mic.isac, ISAC_MASK, 0x0); - writereg(cs->hw.mic.adr, cs->hw.mic.hscx, HSCX_MASK, 0x0); - writereg(cs->hw.mic.adr, cs->hw.mic.hscx, HSCX_MASK + 0x40, 0x0); - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -static void -release_io_mic(struct IsdnCardState *cs) -{ - int bytecnt = 8; - - if (cs->hw.mic.cfg_reg) - release_region(cs->hw.mic.cfg_reg, bytecnt); -} - -static int -mic_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - u_long flags; - - switch (mt) { - case CARD_RESET: - return (0); - case CARD_RELEASE: - release_io_mic(cs); - return (0); - case CARD_INIT: - spin_lock_irqsave(&cs->lock, flags); - inithscx(cs); /* /RTSA := ISAC RST */ - inithscxisac(cs, 3); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_TEST: - return (0); - } - return (0); -} - -int setup_mic(struct IsdnCard *card) -{ - int bytecnt; - struct IsdnCardState *cs = card->cs; - char tmp[64]; - - strcpy(tmp, mic_revision); - printk(KERN_INFO "HiSax: mic driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_MIC) - return (0); - - bytecnt = 8; - cs->hw.mic.cfg_reg = card->para[1]; - cs->irq = card->para[0]; - cs->hw.mic.adr = cs->hw.mic.cfg_reg + MIC_ADR; - cs->hw.mic.isac = cs->hw.mic.cfg_reg + MIC_ISAC; - cs->hw.mic.hscx = cs->hw.mic.cfg_reg + MIC_HSCX; - - if (!request_region(cs->hw.mic.cfg_reg, bytecnt, "mic isdn")) { - printk(KERN_WARNING - "HiSax: ith mic config port %x-%x already in use\n", - cs->hw.mic.cfg_reg, - cs->hw.mic.cfg_reg + bytecnt); - return (0); - } - printk(KERN_INFO "mic: defined at 0x%x IRQ %d\n", - cs->hw.mic.cfg_reg, cs->irq); - setup_isac(cs); - cs->readisac = &ReadISAC; - cs->writeisac = &WriteISAC; - cs->readisacfifo = &ReadISACfifo; - cs->writeisacfifo = &WriteISACfifo; - cs->BC_Read_Reg = &ReadHSCX; - cs->BC_Write_Reg = &WriteHSCX; - cs->BC_Send_Data = &hscx_fill_fifo; - cs->cardmsg = &mic_card_msg; - cs->irq_func = &mic_interrupt; - ISACVersion(cs, "mic:"); - if (HscxVersion(cs, "mic:")) { - printk(KERN_WARNING - "mic: wrong HSCX versions check IO address\n"); - release_io_mic(cs); - return (0); - } - return (1); -} diff --git a/drivers/isdn/hisax/netjet.c b/drivers/isdn/hisax/netjet.c deleted file mode 100644 index d7b011c8d692..000000000000 --- a/drivers/isdn/hisax/netjet.c +++ /dev/null @@ -1,985 +0,0 @@ -/* $Id: netjet.c,v 1.29.2.4 2004/02/11 13:21:34 keil Exp $ - * - * low level stuff for Traverse Technologie NETJet ISDN cards - * - * Author Karsten Keil - * Copyright by Karsten Keil <keil@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * Thanks to Traverse Technologies Australia for documents and information - * - * 16-Apr-2002 - led code added - Guy Ellis (guy@traverse.com.au) - * - */ - -#include <linux/init.h> -#include "hisax.h" -#include "isac.h" -#include "hscx.h" -#include "isdnl1.h" -#include <linux/interrupt.h> -#include <linux/ppp_defs.h> -#include <linux/slab.h> -#include <asm/io.h> -#include "netjet.h" - -/* Interface functions */ - -u_char -NETjet_ReadIC(struct IsdnCardState *cs, u_char offset) -{ - u_char ret; - - cs->hw.njet.auxd &= 0xfc; - cs->hw.njet.auxd |= (offset >> 4) & 3; - byteout(cs->hw.njet.auxa, cs->hw.njet.auxd); - ret = bytein(cs->hw.njet.isac + ((offset & 0xf) << 2)); - return (ret); -} - -void -NETjet_WriteIC(struct IsdnCardState *cs, u_char offset, u_char value) -{ - cs->hw.njet.auxd &= 0xfc; - cs->hw.njet.auxd |= (offset >> 4) & 3; - byteout(cs->hw.njet.auxa, cs->hw.njet.auxd); - byteout(cs->hw.njet.isac + ((offset & 0xf) << 2), value); -} - -void -NETjet_ReadICfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - cs->hw.njet.auxd &= 0xfc; - byteout(cs->hw.njet.auxa, cs->hw.njet.auxd); - insb(cs->hw.njet.isac, data, size); -} - -void -NETjet_WriteICfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - cs->hw.njet.auxd &= 0xfc; - byteout(cs->hw.njet.auxa, cs->hw.njet.auxd); - outsb(cs->hw.njet.isac, data, size); -} - -static void fill_mem(struct BCState *bcs, u_int *pos, u_int cnt, int chan, u_char fill) -{ - u_int mask = 0x000000ff, val = 0, *p = pos; - u_int i; - - val |= fill; - if (chan) { - val <<= 8; - mask <<= 8; - } - mask ^= 0xffffffff; - for (i = 0; i < cnt; i++) { - *p &= mask; - *p++ |= val; - if (p > bcs->hw.tiger.s_end) - p = bcs->hw.tiger.send; - } -} - -static void -mode_tiger(struct BCState *bcs, int mode, int bc) -{ - struct IsdnCardState *cs = bcs->cs; - u_char led; - - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "Tiger mode %d bchan %d/%d", - mode, bc, bcs->channel); - bcs->mode = mode; - bcs->channel = bc; - switch (mode) { - case (L1_MODE_NULL): - fill_mem(bcs, bcs->hw.tiger.send, - NETJET_DMA_TXSIZE, bc, 0xff); - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "Tiger stat rec %d/%d send %d", - bcs->hw.tiger.r_tot, bcs->hw.tiger.r_err, - bcs->hw.tiger.s_tot); - if ((cs->bcs[0].mode == L1_MODE_NULL) && - (cs->bcs[1].mode == L1_MODE_NULL)) { - cs->hw.njet.dmactrl = 0; - byteout(cs->hw.njet.base + NETJET_DMACTRL, - cs->hw.njet.dmactrl); - byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0); - } - if (cs->typ == ISDN_CTYPE_NETJET_S) - { - // led off - led = bc & 0x01; - led = 0x01 << (6 + led); // convert to mask - led = ~led; - cs->hw.njet.auxd &= led; - byteout(cs->hw.njet.auxa, cs->hw.njet.auxd); - } - break; - case (L1_MODE_TRANS): - break; - case (L1_MODE_HDLC_56K): - case (L1_MODE_HDLC): - fill_mem(bcs, bcs->hw.tiger.send, - NETJET_DMA_TXSIZE, bc, 0xff); - bcs->hw.tiger.r_state = HDLC_ZERO_SEARCH; - bcs->hw.tiger.r_tot = 0; - bcs->hw.tiger.r_bitcnt = 0; - bcs->hw.tiger.r_one = 0; - bcs->hw.tiger.r_err = 0; - bcs->hw.tiger.s_tot = 0; - if (!cs->hw.njet.dmactrl) { - fill_mem(bcs, bcs->hw.tiger.send, - NETJET_DMA_TXSIZE, !bc, 0xff); - cs->hw.njet.dmactrl = 1; - byteout(cs->hw.njet.base + NETJET_DMACTRL, - cs->hw.njet.dmactrl); - byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0x0f); - /* was 0x3f now 0x0f for TJ300 and TJ320 GE 13/07/00 */ - } - bcs->hw.tiger.sendp = bcs->hw.tiger.send; - bcs->hw.tiger.free = NETJET_DMA_TXSIZE; - test_and_set_bit(BC_FLG_EMPTY, &bcs->Flag); - if (cs->typ == ISDN_CTYPE_NETJET_S) - { - // led on - led = bc & 0x01; - led = 0x01 << (6 + led); // convert to mask - cs->hw.njet.auxd |= led; - byteout(cs->hw.njet.auxa, cs->hw.njet.auxd); - } - break; - } - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "tiger: set %x %x %x %x/%x pulse=%d", - bytein(cs->hw.njet.base + NETJET_DMACTRL), - bytein(cs->hw.njet.base + NETJET_IRQMASK0), - bytein(cs->hw.njet.base + NETJET_IRQSTAT0), - inl(cs->hw.njet.base + NETJET_DMA_READ_ADR), - inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR), - bytein(cs->hw.njet.base + NETJET_PULSE_CNT)); -} - -static void printframe(struct IsdnCardState *cs, u_char *buf, int count, char *s) { - char tmp[128]; - char *t = tmp; - int i = count, j; - u_char *p = buf; - - t += sprintf(t, "tiger %s(%4d)", s, count); - while (i > 0) { - if (i > 16) - j = 16; - else - j = i; - QuickHex(t, p, j); - debugl1(cs, "%s", tmp); - p += j; - i -= j; - t = tmp; - t += sprintf(t, "tiger %s ", s); - } -} - -// macro for 64k - -#define MAKE_RAW_BYTE for (j = 0; j < 8; j++) { \ - bitcnt++; \ - s_val >>= 1; \ - if (val & 1) { \ - s_one++; \ - s_val |= 0x80; \ - } else { \ - s_one = 0; \ - s_val &= 0x7f; \ - } \ - if (bitcnt == 8) { \ - bcs->hw.tiger.sendbuf[s_cnt++] = s_val; \ - bitcnt = 0; \ - } \ - if (s_one == 5) { \ - s_val >>= 1; \ - s_val &= 0x7f; \ - bitcnt++; \ - s_one = 0; \ - } \ - if (bitcnt == 8) { \ - bcs->hw.tiger.sendbuf[s_cnt++] = s_val; \ - bitcnt = 0; \ - } \ - val >>= 1; \ - } - -static int make_raw_data(struct BCState *bcs) { -// this make_raw is for 64k - register u_int i, s_cnt = 0; - register u_char j; - register u_char val; - register u_char s_one = 0; - register u_char s_val = 0; - register u_char bitcnt = 0; - u_int fcs; - - if (!bcs->tx_skb) { - debugl1(bcs->cs, "tiger make_raw: NULL skb"); - return (1); - } - bcs->hw.tiger.sendbuf[s_cnt++] = HDLC_FLAG_VALUE; - fcs = PPP_INITFCS; - for (i = 0; i < bcs->tx_skb->len; i++) { - val = bcs->tx_skb->data[i]; - fcs = PPP_FCS(fcs, val); - MAKE_RAW_BYTE; - } - fcs ^= 0xffff; - val = fcs & 0xff; - MAKE_RAW_BYTE; - val = (fcs >> 8) & 0xff; - MAKE_RAW_BYTE; - val = HDLC_FLAG_VALUE; - for (j = 0; j < 8; j++) { - bitcnt++; - s_val >>= 1; - if (val & 1) - s_val |= 0x80; - else - s_val &= 0x7f; - if (bitcnt == 8) { - bcs->hw.tiger.sendbuf[s_cnt++] = s_val; - bitcnt = 0; - } - val >>= 1; - } - if (bcs->cs->debug & L1_DEB_HSCX) - debugl1(bcs->cs, "tiger make_raw: in %u out %d.%d", - bcs->tx_skb->len, s_cnt, bitcnt); - if (bitcnt) { - while (8 > bitcnt++) { - s_val >>= 1; - s_val |= 0x80; - } - bcs->hw.tiger.sendbuf[s_cnt++] = s_val; - bcs->hw.tiger.sendbuf[s_cnt++] = 0xff; // NJ<->NJ thoughput bug fix - } - bcs->hw.tiger.sendcnt = s_cnt; - bcs->tx_cnt -= bcs->tx_skb->len; - bcs->hw.tiger.sp = bcs->hw.tiger.sendbuf; - return (0); -} - -// macro for 56k - -#define MAKE_RAW_BYTE_56K for (j = 0; j < 8; j++) { \ - bitcnt++; \ - s_val >>= 1; \ - if (val & 1) { \ - s_one++; \ - s_val |= 0x80; \ - } else { \ - s_one = 0; \ - s_val &= 0x7f; \ - } \ - if (bitcnt == 7) { \ - s_val >>= 1; \ - s_val |= 0x80; \ - bcs->hw.tiger.sendbuf[s_cnt++] = s_val; \ - bitcnt = 0; \ - } \ - if (s_one == 5) { \ - s_val >>= 1; \ - s_val &= 0x7f; \ - bitcnt++; \ - s_one = 0; \ - } \ - if (bitcnt == 7) { \ - s_val >>= 1; \ - s_val |= 0x80; \ - bcs->hw.tiger.sendbuf[s_cnt++] = s_val; \ - bitcnt = 0; \ - } \ - val >>= 1; \ - } - -static int make_raw_data_56k(struct BCState *bcs) { -// this make_raw is for 56k - register u_int i, s_cnt = 0; - register u_char j; - register u_char val; - register u_char s_one = 0; - register u_char s_val = 0; - register u_char bitcnt = 0; - u_int fcs; - - if (!bcs->tx_skb) { - debugl1(bcs->cs, "tiger make_raw_56k: NULL skb"); - return (1); - } - val = HDLC_FLAG_VALUE; - for (j = 0; j < 8; j++) { - bitcnt++; - s_val >>= 1; - if (val & 1) - s_val |= 0x80; - else - s_val &= 0x7f; - if (bitcnt == 7) { - s_val >>= 1; - s_val |= 0x80; - bcs->hw.tiger.sendbuf[s_cnt++] = s_val; - bitcnt = 0; - } - val >>= 1; - } - fcs = PPP_INITFCS; - for (i = 0; i < bcs->tx_skb->len; i++) { - val = bcs->tx_skb->data[i]; - fcs = PPP_FCS(fcs, val); - MAKE_RAW_BYTE_56K; - } - fcs ^= 0xffff; - val = fcs & 0xff; - MAKE_RAW_BYTE_56K; - val = (fcs >> 8) & 0xff; - MAKE_RAW_BYTE_56K; - val = HDLC_FLAG_VALUE; - for (j = 0; j < 8; j++) { - bitcnt++; - s_val >>= 1; - if (val & 1) - s_val |= 0x80; - else - s_val &= 0x7f; - if (bitcnt == 7) { - s_val >>= 1; - s_val |= 0x80; - bcs->hw.tiger.sendbuf[s_cnt++] = s_val; - bitcnt = 0; - } - val >>= 1; - } - if (bcs->cs->debug & L1_DEB_HSCX) - debugl1(bcs->cs, "tiger make_raw_56k: in %u out %d.%d", - bcs->tx_skb->len, s_cnt, bitcnt); - if (bitcnt) { - while (8 > bitcnt++) { - s_val >>= 1; - s_val |= 0x80; - } - bcs->hw.tiger.sendbuf[s_cnt++] = s_val; - bcs->hw.tiger.sendbuf[s_cnt++] = 0xff; // NJ<->NJ thoughput bug fix - } - bcs->hw.tiger.sendcnt = s_cnt; - bcs->tx_cnt -= bcs->tx_skb->len; - bcs->hw.tiger.sp = bcs->hw.tiger.sendbuf; - return (0); -} - -static void got_frame(struct BCState *bcs, int count) { - struct sk_buff *skb; - - if (!(skb = dev_alloc_skb(count))) - printk(KERN_WARNING "TIGER: receive out of memory\n"); - else { - skb_put_data(skb, bcs->hw.tiger.rcvbuf, count); - skb_queue_tail(&bcs->rqueue, skb); - } - test_and_set_bit(B_RCVBUFREADY, &bcs->event); - schedule_work(&bcs->tqueue); - - if (bcs->cs->debug & L1_DEB_RECEIVE_FRAME) - printframe(bcs->cs, bcs->hw.tiger.rcvbuf, count, "rec"); -} - - - -static void read_raw(struct BCState *bcs, u_int *buf, int cnt) { - int i; - register u_char j; - register u_char val; - u_int *pend = bcs->hw.tiger.rec + NETJET_DMA_RXSIZE - 1; - register u_char state = bcs->hw.tiger.r_state; - register u_char r_one = bcs->hw.tiger.r_one; - register u_char r_val = bcs->hw.tiger.r_val; - register u_int bitcnt = bcs->hw.tiger.r_bitcnt; - u_int *p = buf; - int bits; - u_char mask; - - if (bcs->mode == L1_MODE_HDLC) { // it's 64k - mask = 0xff; - bits = 8; - } - else { // it's 56K - mask = 0x7f; - bits = 7; - } - for (i = 0; i < cnt; i++) { - val = bcs->channel ? ((*p >> 8) & 0xff) : (*p & 0xff); - p++; - if (p > pend) - p = bcs->hw.tiger.rec; - if ((val & mask) == mask) { - state = HDLC_ZERO_SEARCH; - bcs->hw.tiger.r_tot++; - bitcnt = 0; - r_one = 0; - continue; - } - for (j = 0; j < bits; j++) { - if (state == HDLC_ZERO_SEARCH) { - if (val & 1) { - r_one++; - } else { - r_one = 0; - state = HDLC_FLAG_SEARCH; - if (bcs->cs->debug & L1_DEB_HSCX) - debugl1(bcs->cs, "tiger read_raw: zBit(%d,%d,%d) %x", - bcs->hw.tiger.r_tot, i, j, val); - } - } else if (state == HDLC_FLAG_SEARCH) { - if (val & 1) { - r_one++; - if (r_one > 6) { - state = HDLC_ZERO_SEARCH; - } - } else { - if (r_one == 6) { - bitcnt = 0; - r_val = 0; - state = HDLC_FLAG_FOUND; - if (bcs->cs->debug & L1_DEB_HSCX) - debugl1(bcs->cs, "tiger read_raw: flag(%d,%d,%d) %x", - bcs->hw.tiger.r_tot, i, j, val); - } - r_one = 0; - } - } else if (state == HDLC_FLAG_FOUND) { - if (val & 1) { - r_one++; - if (r_one > 6) { - state = HDLC_ZERO_SEARCH; - } else { - r_val >>= 1; - r_val |= 0x80; - bitcnt++; - } - } else { - if (r_one == 6) { - bitcnt = 0; - r_val = 0; - r_one = 0; - val >>= 1; - continue; - } else if (r_one != 5) { - r_val >>= 1; - r_val &= 0x7f; - bitcnt++; - } - r_one = 0; - } - if ((state != HDLC_ZERO_SEARCH) && - !(bitcnt & 7)) { - state = HDLC_FRAME_FOUND; - bcs->hw.tiger.r_fcs = PPP_INITFCS; - bcs->hw.tiger.rcvbuf[0] = r_val; - bcs->hw.tiger.r_fcs = PPP_FCS(bcs->hw.tiger.r_fcs, r_val); - if (bcs->cs->debug & L1_DEB_HSCX) - debugl1(bcs->cs, "tiger read_raw: byte1(%d,%d,%d) rval %x val %x i %x", - bcs->hw.tiger.r_tot, i, j, r_val, val, - bcs->cs->hw.njet.irqstat0); - } - } else if (state == HDLC_FRAME_FOUND) { - if (val & 1) { - r_one++; - if (r_one > 6) { - state = HDLC_ZERO_SEARCH; - bitcnt = 0; - } else { - r_val >>= 1; - r_val |= 0x80; - bitcnt++; - } - } else { - if (r_one == 6) { - r_val = 0; - r_one = 0; - bitcnt++; - if (bitcnt & 7) { - debugl1(bcs->cs, "tiger: frame not byte aligned"); - state = HDLC_FLAG_SEARCH; - bcs->hw.tiger.r_err++; -#ifdef ERROR_STATISTIC - bcs->err_inv++; -#endif - } else { - if (bcs->cs->debug & L1_DEB_HSCX) - debugl1(bcs->cs, "tiger frame end(%d,%d): fcs(%x) i %x", - i, j, bcs->hw.tiger.r_fcs, bcs->cs->hw.njet.irqstat0); - if (bcs->hw.tiger.r_fcs == PPP_GOODFCS) { - got_frame(bcs, (bitcnt >> 3) - 3); - } else { - if (bcs->cs->debug) { - debugl1(bcs->cs, "tiger FCS error"); - printframe(bcs->cs, bcs->hw.tiger.rcvbuf, - (bitcnt >> 3) - 1, "rec"); - bcs->hw.tiger.r_err++; - } -#ifdef ERROR_STATISTIC - bcs->err_crc++; -#endif - } - state = HDLC_FLAG_FOUND; - } - bitcnt = 0; - } else if (r_one == 5) { - val >>= 1; - r_one = 0; - continue; - } else { - r_val >>= 1; - r_val &= 0x7f; - bitcnt++; - } - r_one = 0; - } - if ((state == HDLC_FRAME_FOUND) && - !(bitcnt & 7)) { - if ((bitcnt >> 3) >= HSCX_BUFMAX) { - debugl1(bcs->cs, "tiger: frame too big"); - r_val = 0; - state = HDLC_FLAG_SEARCH; - bcs->hw.tiger.r_err++; -#ifdef ERROR_STATISTIC - bcs->err_inv++; -#endif - } else { - bcs->hw.tiger.rcvbuf[(bitcnt >> 3) - 1] = r_val; - bcs->hw.tiger.r_fcs = - PPP_FCS(bcs->hw.tiger.r_fcs, r_val); - } - } - } - val >>= 1; - } - bcs->hw.tiger.r_tot++; - } - bcs->hw.tiger.r_state = state; - bcs->hw.tiger.r_one = r_one; - bcs->hw.tiger.r_val = r_val; - bcs->hw.tiger.r_bitcnt = bitcnt; -} - -void read_tiger(struct IsdnCardState *cs) { - u_int *p; - int cnt = NETJET_DMA_RXSIZE / 2; - - if ((cs->hw.njet.irqstat0 & cs->hw.njet.last_is0) & NETJET_IRQM0_READ) { - debugl1(cs, "tiger warn read double dma %x/%x", - cs->hw.njet.irqstat0, cs->hw.njet.last_is0); -#ifdef ERROR_STATISTIC - if (cs->bcs[0].mode) - cs->bcs[0].err_rdo++; - if (cs->bcs[1].mode) - cs->bcs[1].err_rdo++; -#endif - return; - } else { - cs->hw.njet.last_is0 &= ~NETJET_IRQM0_READ; - cs->hw.njet.last_is0 |= (cs->hw.njet.irqstat0 & NETJET_IRQM0_READ); - } - if (cs->hw.njet.irqstat0 & NETJET_IRQM0_READ_1) - p = cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE - 1; - else - p = cs->bcs[0].hw.tiger.rec + cnt - 1; - if ((cs->bcs[0].mode == L1_MODE_HDLC) || (cs->bcs[0].mode == L1_MODE_HDLC_56K)) - read_raw(cs->bcs, p, cnt); - - if ((cs->bcs[1].mode == L1_MODE_HDLC) || (cs->bcs[1].mode == L1_MODE_HDLC_56K)) - read_raw(cs->bcs + 1, p, cnt); - cs->hw.njet.irqstat0 &= ~NETJET_IRQM0_READ; -} - -static void write_raw(struct BCState *bcs, u_int *buf, int cnt); - -void netjet_fill_dma(struct BCState *bcs) -{ - register u_int *p, *sp; - register int cnt; - - if (!bcs->tx_skb) - return; - if (bcs->cs->debug & L1_DEB_HSCX) - debugl1(bcs->cs, "tiger fill_dma1: c%d %4lx", bcs->channel, - bcs->Flag); - if (test_and_set_bit(BC_FLG_BUSY, &bcs->Flag)) - return; - if (bcs->mode == L1_MODE_HDLC) { // it's 64k - if (make_raw_data(bcs)) - return; - } - else { // it's 56k - if (make_raw_data_56k(bcs)) - return; - } - if (bcs->cs->debug & L1_DEB_HSCX) - debugl1(bcs->cs, "tiger fill_dma2: c%d %4lx", bcs->channel, - bcs->Flag); - if (test_and_clear_bit(BC_FLG_NOFRAME, &bcs->Flag)) { - write_raw(bcs, bcs->hw.tiger.sendp, bcs->hw.tiger.free); - } else if (test_and_clear_bit(BC_FLG_HALF, &bcs->Flag)) { - p = bus_to_virt(inl(bcs->cs->hw.njet.base + NETJET_DMA_READ_ADR)); - sp = bcs->hw.tiger.sendp; - if (p == bcs->hw.tiger.s_end) - p = bcs->hw.tiger.send - 1; - if (sp == bcs->hw.tiger.s_end) - sp = bcs->hw.tiger.send - 1; - cnt = p - sp; - if (cnt < 0) { - write_raw(bcs, bcs->hw.tiger.sendp, bcs->hw.tiger.free); - } else { - p++; - cnt++; - if (p > bcs->hw.tiger.s_end) - p = bcs->hw.tiger.send; - p++; - cnt++; - if (p > bcs->hw.tiger.s_end) - p = bcs->hw.tiger.send; - write_raw(bcs, p, bcs->hw.tiger.free - cnt); - } - } else if (test_and_clear_bit(BC_FLG_EMPTY, &bcs->Flag)) { - p = bus_to_virt(inl(bcs->cs->hw.njet.base + NETJET_DMA_READ_ADR)); - cnt = bcs->hw.tiger.s_end - p; - if (cnt < 2) { - p = bcs->hw.tiger.send + 1; - cnt = NETJET_DMA_TXSIZE / 2 - 2; - } else { - p++; - p++; - if (cnt <= (NETJET_DMA_TXSIZE / 2)) - cnt += NETJET_DMA_TXSIZE / 2; - cnt--; - cnt--; - } - write_raw(bcs, p, cnt); - } - if (bcs->cs->debug & L1_DEB_HSCX) - debugl1(bcs->cs, "tiger fill_dma3: c%d %4lx", bcs->channel, - bcs->Flag); -} - -static void write_raw(struct BCState *bcs, u_int *buf, int cnt) { - u_int mask, val, *p = buf; - u_int i, s_cnt; - - if (cnt <= 0) - return; - if (test_bit(BC_FLG_BUSY, &bcs->Flag)) { - if (bcs->hw.tiger.sendcnt > cnt) { - s_cnt = cnt; - bcs->hw.tiger.sendcnt -= cnt; - } else { - s_cnt = bcs->hw.tiger.sendcnt; - bcs->hw.tiger.sendcnt = 0; - } - if (bcs->channel) - mask = 0xffff00ff; - else - mask = 0xffffff00; - for (i = 0; i < s_cnt; i++) { - val = bcs->channel ? ((bcs->hw.tiger.sp[i] << 8) & 0xff00) : - (bcs->hw.tiger.sp[i]); - *p &= mask; - *p++ |= val; - if (p > bcs->hw.tiger.s_end) - p = bcs->hw.tiger.send; - } - bcs->hw.tiger.s_tot += s_cnt; - if (bcs->cs->debug & L1_DEB_HSCX) - debugl1(bcs->cs, "tiger write_raw: c%d %p-%p %d/%d %d %x", bcs->channel, - buf, p, s_cnt, cnt, - bcs->hw.tiger.sendcnt, bcs->cs->hw.njet.irqstat0); - if (bcs->cs->debug & L1_DEB_HSCX_FIFO) - printframe(bcs->cs, bcs->hw.tiger.sp, s_cnt, "snd"); - bcs->hw.tiger.sp += s_cnt; - bcs->hw.tiger.sendp = p; - if (!bcs->hw.tiger.sendcnt) { - if (!bcs->tx_skb) { - debugl1(bcs->cs, "tiger write_raw: NULL skb s_cnt %d", s_cnt); - } else { - if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) && - (PACKET_NOACK != bcs->tx_skb->pkt_type)) { - u_long flags; - spin_lock_irqsave(&bcs->aclock, flags); - bcs->ackcnt += bcs->tx_skb->len; - spin_unlock_irqrestore(&bcs->aclock, flags); - schedule_event(bcs, B_ACKPENDING); - } - dev_kfree_skb_any(bcs->tx_skb); - bcs->tx_skb = NULL; - } - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - bcs->hw.tiger.free = cnt - s_cnt; - if (bcs->hw.tiger.free > (NETJET_DMA_TXSIZE / 2)) - test_and_set_bit(BC_FLG_HALF, &bcs->Flag); - else { - test_and_clear_bit(BC_FLG_HALF, &bcs->Flag); - test_and_set_bit(BC_FLG_NOFRAME, &bcs->Flag); - } - if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) { - netjet_fill_dma(bcs); - } else { - mask ^= 0xffffffff; - if (s_cnt < cnt) { - for (i = s_cnt; i < cnt; i++) { - *p++ |= mask; - if (p > bcs->hw.tiger.s_end) - p = bcs->hw.tiger.send; - } - if (bcs->cs->debug & L1_DEB_HSCX) - debugl1(bcs->cs, "tiger write_raw: fill rest %d", - cnt - s_cnt); - } - test_and_set_bit(B_XMTBUFREADY, &bcs->event); - schedule_work(&bcs->tqueue); - } - } - } else if (test_and_clear_bit(BC_FLG_NOFRAME, &bcs->Flag)) { - test_and_set_bit(BC_FLG_HALF, &bcs->Flag); - fill_mem(bcs, buf, cnt, bcs->channel, 0xff); - bcs->hw.tiger.free += cnt; - if (bcs->cs->debug & L1_DEB_HSCX) - debugl1(bcs->cs, "tiger write_raw: fill half"); - } else if (test_and_clear_bit(BC_FLG_HALF, &bcs->Flag)) { - test_and_set_bit(BC_FLG_EMPTY, &bcs->Flag); - fill_mem(bcs, buf, cnt, bcs->channel, 0xff); - if (bcs->cs->debug & L1_DEB_HSCX) - debugl1(bcs->cs, "tiger write_raw: fill full"); - } -} - -void write_tiger(struct IsdnCardState *cs) { - u_int *p, cnt = NETJET_DMA_TXSIZE / 2; - - if ((cs->hw.njet.irqstat0 & cs->hw.njet.last_is0) & NETJET_IRQM0_WRITE) { - debugl1(cs, "tiger warn write double dma %x/%x", - cs->hw.njet.irqstat0, cs->hw.njet.last_is0); -#ifdef ERROR_STATISTIC - if (cs->bcs[0].mode) - cs->bcs[0].err_tx++; - if (cs->bcs[1].mode) - cs->bcs[1].err_tx++; -#endif - return; - } else { - cs->hw.njet.last_is0 &= ~NETJET_IRQM0_WRITE; - cs->hw.njet.last_is0 |= (cs->hw.njet.irqstat0 & NETJET_IRQM0_WRITE); - } - if (cs->hw.njet.irqstat0 & NETJET_IRQM0_WRITE_1) - p = cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE - 1; - else - p = cs->bcs[0].hw.tiger.send + cnt - 1; - if ((cs->bcs[0].mode == L1_MODE_HDLC) || (cs->bcs[0].mode == L1_MODE_HDLC_56K)) - write_raw(cs->bcs, p, cnt); - if ((cs->bcs[1].mode == L1_MODE_HDLC) || (cs->bcs[1].mode == L1_MODE_HDLC_56K)) - write_raw(cs->bcs + 1, p, cnt); - cs->hw.njet.irqstat0 &= ~NETJET_IRQM0_WRITE; -} - -static void -tiger_l2l1(struct PStack *st, int pr, void *arg) -{ - struct BCState *bcs = st->l1.bcs; - struct sk_buff *skb = arg; - u_long flags; - - switch (pr) { - case (PH_DATA | REQUEST): - spin_lock_irqsave(&bcs->cs->lock, flags); - if (bcs->tx_skb) { - skb_queue_tail(&bcs->squeue, skb); - } else { - bcs->tx_skb = skb; - bcs->cs->BC_Send_Data(bcs); - } - spin_unlock_irqrestore(&bcs->cs->lock, flags); - break; - case (PH_PULL | INDICATION): - spin_lock_irqsave(&bcs->cs->lock, flags); - if (bcs->tx_skb) { - printk(KERN_WARNING "tiger_l2l1: this shouldn't happen\n"); - } else { - bcs->tx_skb = skb; - bcs->cs->BC_Send_Data(bcs); - } - spin_unlock_irqrestore(&bcs->cs->lock, flags); - break; - case (PH_PULL | REQUEST): - if (!bcs->tx_skb) { - test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); - } else - test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - break; - case (PH_ACTIVATE | REQUEST): - spin_lock_irqsave(&bcs->cs->lock, flags); - test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag); - mode_tiger(bcs, st->l1.mode, st->l1.bc); - /* 2001/10/04 Christoph Ersfeld, Formula-n Europe AG */ - spin_unlock_irqrestore(&bcs->cs->lock, flags); - bcs->cs->cardmsg(bcs->cs, MDL_BC_ASSIGN, (void *)(&st->l1.bc)); - l1_msg_b(st, pr, arg); - break; - case (PH_DEACTIVATE | REQUEST): - /* 2001/10/04 Christoph Ersfeld, Formula-n Europe AG */ - bcs->cs->cardmsg(bcs->cs, MDL_BC_RELEASE, (void *)(&st->l1.bc)); - l1_msg_b(st, pr, arg); - break; - case (PH_DEACTIVATE | CONFIRM): - spin_lock_irqsave(&bcs->cs->lock, flags); - test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag); - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - mode_tiger(bcs, 0, st->l1.bc); - spin_unlock_irqrestore(&bcs->cs->lock, flags); - st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL); - break; - } -} - - -static void -close_tigerstate(struct BCState *bcs) -{ - mode_tiger(bcs, 0, bcs->channel); - if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) { - kfree(bcs->hw.tiger.rcvbuf); - bcs->hw.tiger.rcvbuf = NULL; - kfree(bcs->hw.tiger.sendbuf); - bcs->hw.tiger.sendbuf = NULL; - skb_queue_purge(&bcs->rqueue); - skb_queue_purge(&bcs->squeue); - if (bcs->tx_skb) { - dev_kfree_skb_any(bcs->tx_skb); - bcs->tx_skb = NULL; - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - } - } -} - -static int -open_tigerstate(struct IsdnCardState *cs, struct BCState *bcs) -{ - if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { - if (!(bcs->hw.tiger.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) { - printk(KERN_WARNING - "HiSax: No memory for tiger.rcvbuf\n"); - return (1); - } - if (!(bcs->hw.tiger.sendbuf = kmalloc(RAW_BUFMAX, GFP_ATOMIC))) { - printk(KERN_WARNING - "HiSax: No memory for tiger.sendbuf\n"); - return (1); - } - skb_queue_head_init(&bcs->rqueue); - skb_queue_head_init(&bcs->squeue); - } - bcs->tx_skb = NULL; - bcs->hw.tiger.sendcnt = 0; - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - bcs->event = 0; - bcs->tx_cnt = 0; - return (0); -} - -static int -setstack_tiger(struct PStack *st, struct BCState *bcs) -{ - bcs->channel = st->l1.bc; - if (open_tigerstate(st->l1.hardware, bcs)) - return (-1); - st->l1.bcs = bcs; - st->l2.l2l1 = tiger_l2l1; - setstack_manager(st); - bcs->st = st; - setstack_l1_B(st); - return (0); -} - - -void -inittiger(struct IsdnCardState *cs) -{ - cs->bcs[0].hw.tiger.send = kmalloc_array(NETJET_DMA_TXSIZE, - sizeof(unsigned int), - GFP_KERNEL | GFP_DMA); - if (!cs->bcs[0].hw.tiger.send) { - printk(KERN_WARNING - "HiSax: No memory for tiger.send\n"); - return; - } - cs->bcs[0].hw.tiger.s_irq = cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE / 2 - 1; - cs->bcs[0].hw.tiger.s_end = cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE - 1; - cs->bcs[1].hw.tiger.send = cs->bcs[0].hw.tiger.send; - cs->bcs[1].hw.tiger.s_irq = cs->bcs[0].hw.tiger.s_irq; - cs->bcs[1].hw.tiger.s_end = cs->bcs[0].hw.tiger.s_end; - - memset(cs->bcs[0].hw.tiger.send, 0xff, NETJET_DMA_TXSIZE * sizeof(unsigned int)); - debugl1(cs, "tiger: send buf %p - %p", cs->bcs[0].hw.tiger.send, - cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE - 1); - outl(virt_to_bus(cs->bcs[0].hw.tiger.send), - cs->hw.njet.base + NETJET_DMA_READ_START); - outl(virt_to_bus(cs->bcs[0].hw.tiger.s_irq), - cs->hw.njet.base + NETJET_DMA_READ_IRQ); - outl(virt_to_bus(cs->bcs[0].hw.tiger.s_end), - cs->hw.njet.base + NETJET_DMA_READ_END); - cs->bcs[0].hw.tiger.rec = kmalloc_array(NETJET_DMA_RXSIZE, - sizeof(unsigned int), - GFP_KERNEL | GFP_DMA); - if (!cs->bcs[0].hw.tiger.rec) { - printk(KERN_WARNING - "HiSax: No memory for tiger.rec\n"); - return; - } - debugl1(cs, "tiger: rec buf %p - %p", cs->bcs[0].hw.tiger.rec, - cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE - 1); - cs->bcs[1].hw.tiger.rec = cs->bcs[0].hw.tiger.rec; - memset(cs->bcs[0].hw.tiger.rec, 0xff, NETJET_DMA_RXSIZE * sizeof(unsigned int)); - outl(virt_to_bus(cs->bcs[0].hw.tiger.rec), - cs->hw.njet.base + NETJET_DMA_WRITE_START); - outl(virt_to_bus(cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE / 2 - 1), - cs->hw.njet.base + NETJET_DMA_WRITE_IRQ); - outl(virt_to_bus(cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE - 1), - cs->hw.njet.base + NETJET_DMA_WRITE_END); - debugl1(cs, "tiger: dmacfg %x/%x pulse=%d", - inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR), - inl(cs->hw.njet.base + NETJET_DMA_READ_ADR), - bytein(cs->hw.njet.base + NETJET_PULSE_CNT)); - cs->hw.njet.last_is0 = 0; - cs->bcs[0].BC_SetStack = setstack_tiger; - cs->bcs[1].BC_SetStack = setstack_tiger; - cs->bcs[0].BC_Close = close_tigerstate; - cs->bcs[1].BC_Close = close_tigerstate; -} - -static void -releasetiger(struct IsdnCardState *cs) -{ - kfree(cs->bcs[0].hw.tiger.send); - cs->bcs[0].hw.tiger.send = NULL; - cs->bcs[1].hw.tiger.send = NULL; - kfree(cs->bcs[0].hw.tiger.rec); - cs->bcs[0].hw.tiger.rec = NULL; - cs->bcs[1].hw.tiger.rec = NULL; -} - -void -release_io_netjet(struct IsdnCardState *cs) -{ - byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0); - byteout(cs->hw.njet.base + NETJET_IRQMASK1, 0); - releasetiger(cs); - release_region(cs->hw.njet.base, 256); -} diff --git a/drivers/isdn/hisax/netjet.h b/drivers/isdn/hisax/netjet.h deleted file mode 100644 index 70590d5d5e64..000000000000 --- a/drivers/isdn/hisax/netjet.h +++ /dev/null @@ -1,69 +0,0 @@ -/* $Id: netjet.h,v 2.8.2.2 2004/01/12 22:52:28 keil Exp $ - * - * NETjet common header file - * - * Author Karsten Keil - * Copyright by Karsten Keil <keil@isdn4linux.de> - * by Matt Henderson, - * Traverse Technologies P/L www.traverse.com.au - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#define byteout(addr, val) outb(val, addr) -#define bytein(addr) inb(addr) - -#define NETJET_CTRL 0x00 -#define NETJET_DMACTRL 0x01 -#define NETJET_AUXCTRL 0x02 -#define NETJET_AUXDATA 0x03 -#define NETJET_IRQMASK0 0x04 -#define NETJET_IRQMASK1 0x05 -#define NETJET_IRQSTAT0 0x06 -#define NETJET_IRQSTAT1 0x07 -#define NETJET_DMA_READ_START 0x08 -#define NETJET_DMA_READ_IRQ 0x0c -#define NETJET_DMA_READ_END 0x10 -#define NETJET_DMA_READ_ADR 0x14 -#define NETJET_DMA_WRITE_START 0x18 -#define NETJET_DMA_WRITE_IRQ 0x1c -#define NETJET_DMA_WRITE_END 0x20 -#define NETJET_DMA_WRITE_ADR 0x24 -#define NETJET_PULSE_CNT 0x28 - -#define NETJET_ISAC_OFF 0xc0 -#define NETJET_ISACIRQ 0x10 -#define NETJET_IRQM0_READ 0x0c -#define NETJET_IRQM0_READ_1 0x04 -#define NETJET_IRQM0_READ_2 0x08 -#define NETJET_IRQM0_WRITE 0x03 -#define NETJET_IRQM0_WRITE_1 0x01 -#define NETJET_IRQM0_WRITE_2 0x02 - -#define NETJET_DMA_TXSIZE 512 -#define NETJET_DMA_RXSIZE 128 - -#define HDLC_ZERO_SEARCH 0 -#define HDLC_FLAG_SEARCH 1 -#define HDLC_FLAG_FOUND 2 -#define HDLC_FRAME_FOUND 3 -#define HDLC_NULL 4 -#define HDLC_PART 5 -#define HDLC_FULL 6 - -#define HDLC_FLAG_VALUE 0x7e - -u_char NETjet_ReadIC(struct IsdnCardState *cs, u_char offset); -void NETjet_WriteIC(struct IsdnCardState *cs, u_char offset, u_char value); -void NETjet_ReadICfifo(struct IsdnCardState *cs, u_char *data, int size); -void NETjet_WriteICfifo(struct IsdnCardState *cs, u_char *data, int size); - -void read_tiger(struct IsdnCardState *cs); -void write_tiger(struct IsdnCardState *cs); - -void netjet_fill_dma(struct BCState *bcs); -void netjet_interrupt(int intno, void *dev_id); -void inittiger(struct IsdnCardState *cs); -void release_io_netjet(struct IsdnCardState *cs); diff --git a/drivers/isdn/hisax/niccy.c b/drivers/isdn/hisax/niccy.c deleted file mode 100644 index dfbcd2eaa81a..000000000000 --- a/drivers/isdn/hisax/niccy.c +++ /dev/null @@ -1,380 +0,0 @@ -/* $Id: niccy.c,v 1.21.2.4 2004/01/13 23:48:39 keil Exp $ - * - * low level stuff for Dr. Neuhaus NICCY PnP and NICCY PCI and - * compatible (SAGEM cybermodem) - * - * Author Karsten Keil - * Copyright by Karsten Keil <keil@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * Thanks to Dr. Neuhaus and SAGEM for information - * - */ - -#include <linux/init.h> -#include "hisax.h" -#include "isac.h" -#include "hscx.h" -#include "isdnl1.h" -#include <linux/pci.h> -#include <linux/isapnp.h> - -static const char *niccy_revision = "$Revision: 1.21.2.4 $"; - -#define byteout(addr, val) outb(val, addr) -#define bytein(addr) inb(addr) - -#define ISAC_PCI_DATA 0 -#define HSCX_PCI_DATA 1 -#define ISAC_PCI_ADDR 2 -#define HSCX_PCI_ADDR 3 -#define ISAC_PNP 0 -#define HSCX_PNP 1 - -/* SUB Types */ -#define NICCY_PNP 1 -#define NICCY_PCI 2 - -/* PCI stuff */ -#define PCI_IRQ_CTRL_REG 0x38 -#define PCI_IRQ_ENABLE 0x1f00 -#define PCI_IRQ_DISABLE 0xff0000 -#define PCI_IRQ_ASSERT 0x800000 - -static inline u_char readreg(unsigned int ale, unsigned int adr, u_char off) -{ - register u_char ret; - - byteout(ale, off); - ret = bytein(adr); - return ret; -} - -static inline void readfifo(unsigned int ale, unsigned int adr, u_char off, - u_char *data, int size) -{ - byteout(ale, off); - insb(adr, data, size); -} - -static inline void writereg(unsigned int ale, unsigned int adr, u_char off, - u_char data) -{ - byteout(ale, off); - byteout(adr, data); -} - -static inline void writefifo(unsigned int ale, unsigned int adr, u_char off, - u_char *data, int size) -{ - byteout(ale, off); - outsb(adr, data, size); -} - -/* Interface functions */ - -static u_char ReadISAC(struct IsdnCardState *cs, u_char offset) -{ - return readreg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, offset); -} - -static void WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value) -{ - writereg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, offset, value); -} - -static void ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - readfifo(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, 0, data, size); -} - -static void WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - writefifo(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, 0, data, size); -} - -static u_char ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset) -{ - return readreg(cs->hw.niccy.hscx_ale, - cs->hw.niccy.hscx, offset + (hscx ? 0x40 : 0)); -} - -static void WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, - u_char value) -{ - writereg(cs->hw.niccy.hscx_ale, - cs->hw.niccy.hscx, offset + (hscx ? 0x40 : 0), value); -} - -#define READHSCX(cs, nr, reg) readreg(cs->hw.niccy.hscx_ale, \ - cs->hw.niccy.hscx, reg + (nr ? 0x40 : 0)) -#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.niccy.hscx_ale, \ - cs->hw.niccy.hscx, reg + (nr ? 0x40 : 0), data) - -#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.niccy.hscx_ale, \ - cs->hw.niccy.hscx, (nr ? 0x40 : 0), ptr, cnt) - -#define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.niccy.hscx_ale, \ - cs->hw.niccy.hscx, (nr ? 0x40 : 0), ptr, cnt) - -#include "hscx_irq.c" - -static irqreturn_t niccy_interrupt(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - u_char val; - u_long flags; - - spin_lock_irqsave(&cs->lock, flags); - if (cs->subtyp == NICCY_PCI) { - int ival; - ival = inl(cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG); - if (!(ival & PCI_IRQ_ASSERT)) { /* IRQ not for us (shared) */ - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_NONE; - } - outl(ival, cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG); - } - val = readreg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, - HSCX_ISTA + 0x40); -Start_HSCX: - if (val) - hscx_int_main(cs, val); - val = readreg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, ISAC_ISTA); -Start_ISAC: - if (val) - isac_interrupt(cs, val); - val = readreg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, - HSCX_ISTA + 0x40); - if (val) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "HSCX IntStat after IntRoutine"); - goto Start_HSCX; - } - val = readreg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, ISAC_ISTA); - if (val) { - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "ISAC IntStat after IntRoutine"); - goto Start_ISAC; - } - writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK, 0xFF); - writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK + 0x40, - 0xFF); - writereg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, ISAC_MASK, 0xFF); - writereg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, ISAC_MASK, 0); - writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK, 0); - writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK + 0x40, 0); - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -static void release_io_niccy(struct IsdnCardState *cs) -{ - if (cs->subtyp == NICCY_PCI) { - int val; - - val = inl(cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG); - val &= PCI_IRQ_DISABLE; - outl(val, cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG); - release_region(cs->hw.niccy.cfg_reg, 0x40); - release_region(cs->hw.niccy.isac, 4); - } else { - release_region(cs->hw.niccy.isac, 2); - release_region(cs->hw.niccy.isac_ale, 2); - } -} - -static void niccy_reset(struct IsdnCardState *cs) -{ - if (cs->subtyp == NICCY_PCI) { - int val; - - val = inl(cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG); - val |= PCI_IRQ_ENABLE; - outl(val, cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG); - } - inithscxisac(cs, 3); -} - -static int niccy_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - u_long flags; - - switch (mt) { - case CARD_RESET: - spin_lock_irqsave(&cs->lock, flags); - niccy_reset(cs); - spin_unlock_irqrestore(&cs->lock, flags); - return 0; - case CARD_RELEASE: - release_io_niccy(cs); - return 0; - case CARD_INIT: - spin_lock_irqsave(&cs->lock, flags); - niccy_reset(cs); - spin_unlock_irqrestore(&cs->lock, flags); - return 0; - case CARD_TEST: - return 0; - } - return 0; -} - -#ifdef __ISAPNP__ -static struct pnp_card *pnp_c = NULL; -#endif - -int setup_niccy(struct IsdnCard *card) -{ - struct IsdnCardState *cs = card->cs; - char tmp[64]; - - strcpy(tmp, niccy_revision); - printk(KERN_INFO "HiSax: Niccy driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_NICCY) - return 0; -#ifdef __ISAPNP__ - if (!card->para[1] && isapnp_present()) { - struct pnp_dev *pnp_d = NULL; - int err; - - pnp_c = pnp_find_card(ISAPNP_VENDOR('S', 'D', 'A'), - ISAPNP_FUNCTION(0x0150), pnp_c); - if (pnp_c) { - pnp_d = pnp_find_dev(pnp_c, - ISAPNP_VENDOR('S', 'D', 'A'), - ISAPNP_FUNCTION(0x0150), pnp_d); - if (!pnp_d) { - printk(KERN_ERR "NiccyPnP: PnP error card " - "found, no device\n"); - return 0; - } - pnp_disable_dev(pnp_d); - err = pnp_activate_dev(pnp_d); - if (err < 0) { - printk(KERN_WARNING "%s: pnp_activate_dev " - "ret(%d)\n", __func__, err); - return 0; - } - card->para[1] = pnp_port_start(pnp_d, 0); - card->para[2] = pnp_port_start(pnp_d, 1); - card->para[0] = pnp_irq(pnp_d, 0); - if (card->para[0] == -1 || !card->para[1] || - !card->para[2]) { - printk(KERN_ERR "NiccyPnP:some resources are " - "missing %ld/%lx/%lx\n", - card->para[0], card->para[1], - card->para[2]); - pnp_disable_dev(pnp_d); - return 0; - } - } else - printk(KERN_INFO "NiccyPnP: no ISAPnP card found\n"); - } -#endif - if (card->para[1]) { - cs->hw.niccy.isac = card->para[1] + ISAC_PNP; - cs->hw.niccy.hscx = card->para[1] + HSCX_PNP; - cs->hw.niccy.isac_ale = card->para[2] + ISAC_PNP; - cs->hw.niccy.hscx_ale = card->para[2] + HSCX_PNP; - cs->hw.niccy.cfg_reg = 0; - cs->subtyp = NICCY_PNP; - cs->irq = card->para[0]; - if (!request_region(cs->hw.niccy.isac, 2, "niccy data")) { - printk(KERN_WARNING "HiSax: NICCY data port %x-%x " - "already in use\n", - cs->hw.niccy.isac, cs->hw.niccy.isac + 1); - return 0; - } - if (!request_region(cs->hw.niccy.isac_ale, 2, "niccy addr")) { - printk(KERN_WARNING "HiSax: NICCY address port %x-%x " - "already in use\n", - cs->hw.niccy.isac_ale, - cs->hw.niccy.isac_ale + 1); - release_region(cs->hw.niccy.isac, 2); - return 0; - } - } else { -#ifdef CONFIG_PCI - static struct pci_dev *niccy_dev; - - u_int pci_ioaddr; - cs->subtyp = 0; - if ((niccy_dev = hisax_find_pci_device(PCI_VENDOR_ID_SATSAGEM, - PCI_DEVICE_ID_SATSAGEM_NICCY, - niccy_dev))) { - if (pci_enable_device(niccy_dev)) - return 0; - /* get IRQ */ - if (!niccy_dev->irq) { - printk(KERN_WARNING - "Niccy: No IRQ for PCI card found\n"); - return 0; - } - cs->irq = niccy_dev->irq; - cs->hw.niccy.cfg_reg = pci_resource_start(niccy_dev, 0); - if (!cs->hw.niccy.cfg_reg) { - printk(KERN_WARNING - "Niccy: No IO-Adr for PCI cfg found\n"); - return 0; - } - pci_ioaddr = pci_resource_start(niccy_dev, 1); - if (!pci_ioaddr) { - printk(KERN_WARNING - "Niccy: No IO-Adr for PCI card found\n"); - return 0; - } - cs->subtyp = NICCY_PCI; - } else { - printk(KERN_WARNING "Niccy: No PCI card found\n"); - return 0; - } - cs->irq_flags |= IRQF_SHARED; - cs->hw.niccy.isac = pci_ioaddr + ISAC_PCI_DATA; - cs->hw.niccy.isac_ale = pci_ioaddr + ISAC_PCI_ADDR; - cs->hw.niccy.hscx = pci_ioaddr + HSCX_PCI_DATA; - cs->hw.niccy.hscx_ale = pci_ioaddr + HSCX_PCI_ADDR; - if (!request_region(cs->hw.niccy.isac, 4, "niccy")) { - printk(KERN_WARNING - "HiSax: NICCY data port %x-%x already in use\n", - cs->hw.niccy.isac, cs->hw.niccy.isac + 4); - return 0; - } - if (!request_region(cs->hw.niccy.cfg_reg, 0x40, "niccy pci")) { - printk(KERN_WARNING - "HiSax: NICCY pci port %x-%x already in use\n", - cs->hw.niccy.cfg_reg, - cs->hw.niccy.cfg_reg + 0x40); - release_region(cs->hw.niccy.isac, 4); - return 0; - } -#else - printk(KERN_WARNING "Niccy: io0 0 and NO_PCI_BIOS\n"); - printk(KERN_WARNING "Niccy: unable to config NICCY PCI\n"); - return 0; -#endif /* CONFIG_PCI */ - } - printk(KERN_INFO "HiSax: NICCY %s config irq:%d data:0x%X ale:0x%X\n", - (cs->subtyp == 1) ? "PnP" : "PCI", - cs->irq, cs->hw.niccy.isac, cs->hw.niccy.isac_ale); - setup_isac(cs); - cs->readisac = &ReadISAC; - cs->writeisac = &WriteISAC; - cs->readisacfifo = &ReadISACfifo; - cs->writeisacfifo = &WriteISACfifo; - cs->BC_Read_Reg = &ReadHSCX; - cs->BC_Write_Reg = &WriteHSCX; - cs->BC_Send_Data = &hscx_fill_fifo; - cs->cardmsg = &niccy_card_msg; - cs->irq_func = &niccy_interrupt; - ISACVersion(cs, "Niccy:"); - if (HscxVersion(cs, "Niccy:")) { - printk(KERN_WARNING "Niccy: wrong HSCX versions check IO " - "address\n"); - release_io_niccy(cs); - return 0; - } - return 1; -} diff --git a/drivers/isdn/hisax/nj_s.c b/drivers/isdn/hisax/nj_s.c deleted file mode 100644 index 32b4bbd18eb9..000000000000 --- a/drivers/isdn/hisax/nj_s.c +++ /dev/null @@ -1,294 +0,0 @@ -/* $Id: nj_s.c,v 2.13.2.4 2004/01/16 01:53:48 keil Exp $ - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#include <linux/init.h> -#include "hisax.h" -#include "isac.h" -#include "isdnl1.h" -#include <linux/pci.h> -#include <linux/interrupt.h> -#include <linux/ppp_defs.h> -#include "netjet.h" - -static const char *NETjet_S_revision = "$Revision: 2.13.2.4 $"; - -static u_char dummyrr(struct IsdnCardState *cs, int chan, u_char off) -{ - return (5); -} - -static void dummywr(struct IsdnCardState *cs, int chan, u_char off, u_char value) -{ -} - -static irqreturn_t -netjet_s_interrupt(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - u_char val, s1val, s0val; - u_long flags; - - spin_lock_irqsave(&cs->lock, flags); - s1val = bytein(cs->hw.njet.base + NETJET_IRQSTAT1); - if (!(s1val & NETJET_ISACIRQ)) { - val = NETjet_ReadIC(cs, ISAC_ISTA); - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "tiger: i1 %x %x", s1val, val); - if (val) { - isac_interrupt(cs, val); - NETjet_WriteIC(cs, ISAC_MASK, 0xFF); - NETjet_WriteIC(cs, ISAC_MASK, 0x0); - } - s1val = 1; - } else - s1val = 0; - /* - * read/write stat0 is better, because lower IRQ rate - * Note the IRQ is on for 125 us if a condition match - * thats long on modern CPU and so the IRQ is reentered - * all the time. - */ - s0val = bytein(cs->hw.njet.base + NETJET_IRQSTAT0); - if ((s0val | s1val) == 0) { // shared IRQ - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_NONE; - } - if (s0val) - byteout(cs->hw.njet.base + NETJET_IRQSTAT0, s0val); - /* start new code 13/07/00 GE */ - /* set bits in sval to indicate which page is free */ - if (inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR) < - inl(cs->hw.njet.base + NETJET_DMA_WRITE_IRQ)) - /* the 2nd write page is free */ - s0val = 0x08; - else /* the 1st write page is free */ - s0val = 0x04; - if (inl(cs->hw.njet.base + NETJET_DMA_READ_ADR) < - inl(cs->hw.njet.base + NETJET_DMA_READ_IRQ)) - /* the 2nd read page is free */ - s0val |= 0x02; - else /* the 1st read page is free */ - s0val |= 0x01; - if (s0val != cs->hw.njet.last_is0) /* we have a DMA interrupt */ - { - if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - printk(KERN_WARNING "nj LOCK_ATOMIC s0val %x->%x\n", - cs->hw.njet.last_is0, s0val); - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; - } - cs->hw.njet.irqstat0 = s0val; - if ((cs->hw.njet.irqstat0 & NETJET_IRQM0_READ) != - (cs->hw.njet.last_is0 & NETJET_IRQM0_READ)) - /* we have a read dma int */ - read_tiger(cs); - if ((cs->hw.njet.irqstat0 & NETJET_IRQM0_WRITE) != - (cs->hw.njet.last_is0 & NETJET_IRQM0_WRITE)) - /* we have a write dma int */ - write_tiger(cs); - /* end new code 13/07/00 GE */ - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - } - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -static void -reset_netjet_s(struct IsdnCardState *cs) -{ - cs->hw.njet.ctrl_reg = 0xff; /* Reset On */ - byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); - mdelay(10); - /* now edge triggered for TJ320 GE 13/07/00 */ - /* see comment in IRQ function */ - if (cs->subtyp) /* TJ320 */ - cs->hw.njet.ctrl_reg = 0x40; /* Reset Off and status read clear */ - else - cs->hw.njet.ctrl_reg = 0x00; /* Reset Off and status read clear */ - byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); - mdelay(10); - cs->hw.njet.auxd = 0; - cs->hw.njet.dmactrl = 0; - byteout(cs->hw.njet.base + NETJET_AUXCTRL, ~NETJET_ISACIRQ); - byteout(cs->hw.njet.base + NETJET_IRQMASK1, NETJET_ISACIRQ); - byteout(cs->hw.njet.auxa, cs->hw.njet.auxd); -} - -static int -NETjet_S_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - u_long flags; - - switch (mt) { - case CARD_RESET: - spin_lock_irqsave(&cs->lock, flags); - reset_netjet_s(cs); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_RELEASE: - release_io_netjet(cs); - return (0); - case CARD_INIT: - reset_netjet_s(cs); - inittiger(cs); - spin_lock_irqsave(&cs->lock, flags); - clear_pending_isac_ints(cs); - initisac(cs); - /* Reenable all IRQ */ - cs->writeisac(cs, ISAC_MASK, 0); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_TEST: - return (0); - } - return (0); -} - -static int njs_pci_probe(struct pci_dev *dev_netjet, struct IsdnCardState *cs) -{ - u32 cfg; - - if (pci_enable_device(dev_netjet)) - return (0); - pci_set_master(dev_netjet); - cs->irq = dev_netjet->irq; - if (!cs->irq) { - printk(KERN_WARNING "NETjet-S: No IRQ for PCI card found\n"); - return (0); - } - cs->hw.njet.base = pci_resource_start(dev_netjet, 0); - if (!cs->hw.njet.base) { - printk(KERN_WARNING "NETjet-S: No IO-Adr for PCI card found\n"); - return (0); - } - /* the TJ300 and TJ320 must be detected, the IRQ handling is different - * unfortunately the chips use the same device ID, but the TJ320 has - * the bit20 in status PCI cfg register set - */ - pci_read_config_dword(dev_netjet, 0x04, &cfg); - if (cfg & 0x00100000) - cs->subtyp = 1; /* TJ320 */ - else - cs->subtyp = 0; /* TJ300 */ - /* 2001/10/04 Christoph Ersfeld, Formula-n Europe AG www.formula-n.com */ - if ((dev_netjet->subsystem_vendor == 0x55) && - (dev_netjet->subsystem_device == 0x02)) { - printk(KERN_WARNING "Netjet: You tried to load this driver with an incompatible TigerJet-card\n"); - printk(KERN_WARNING "Use type=41 for Formula-n enter:now ISDN PCI and compatible\n"); - return (0); - } - /* end new code */ - - return (1); -} - -static int njs_cs_init(struct IsdnCard *card, struct IsdnCardState *cs) -{ - - cs->hw.njet.auxa = cs->hw.njet.base + NETJET_AUXDATA; - cs->hw.njet.isac = cs->hw.njet.base | NETJET_ISAC_OFF; - - cs->hw.njet.ctrl_reg = 0xff; /* Reset On */ - byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); - mdelay(10); - - cs->hw.njet.ctrl_reg = 0x00; /* Reset Off and status read clear */ - byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); - mdelay(10); - - cs->hw.njet.auxd = 0xC0; - cs->hw.njet.dmactrl = 0; - - byteout(cs->hw.njet.base + NETJET_AUXCTRL, ~NETJET_ISACIRQ); - byteout(cs->hw.njet.base + NETJET_IRQMASK1, NETJET_ISACIRQ); - byteout(cs->hw.njet.auxa, cs->hw.njet.auxd); - - switch (((NETjet_ReadIC(cs, ISAC_RBCH) >> 5) & 3)) - { - case 0: - return 1; /* end loop */ - - case 3: - printk(KERN_WARNING "NETjet-S: NETspider-U PCI card found\n"); - return -1; /* continue looping */ - - default: - printk(KERN_WARNING "NETjet-S: No PCI card found\n"); - return 0; /* end loop & function */ - } - return 1; /* end loop */ -} - -static int njs_cs_init_rest(struct IsdnCard *card, struct IsdnCardState *cs) -{ - const int bytecnt = 256; - - printk(KERN_INFO - "NETjet-S: %s card configured at %#lx IRQ %d\n", - cs->subtyp ? "TJ320" : "TJ300", cs->hw.njet.base, cs->irq); - if (!request_region(cs->hw.njet.base, bytecnt, "netjet-s isdn")) { - printk(KERN_WARNING - "HiSax: NETjet-S config port %#lx-%#lx already in use\n", - cs->hw.njet.base, - cs->hw.njet.base + bytecnt); - return (0); - } - cs->readisac = &NETjet_ReadIC; - cs->writeisac = &NETjet_WriteIC; - cs->readisacfifo = &NETjet_ReadICfifo; - cs->writeisacfifo = &NETjet_WriteICfifo; - cs->BC_Read_Reg = &dummyrr; - cs->BC_Write_Reg = &dummywr; - cs->BC_Send_Data = &netjet_fill_dma; - setup_isac(cs); - cs->cardmsg = &NETjet_S_card_msg; - cs->irq_func = &netjet_s_interrupt; - cs->irq_flags |= IRQF_SHARED; - ISACVersion(cs, "NETjet-S:"); - - return (1); -} - -static struct pci_dev *dev_netjet = NULL; - -int setup_netjet_s(struct IsdnCard *card) -{ - int ret; - struct IsdnCardState *cs = card->cs; - char tmp[64]; - -#ifdef __BIG_ENDIAN -#error "not running on big endian machines now" -#endif - strcpy(tmp, NETjet_S_revision); - printk(KERN_INFO "HiSax: Traverse Tech. NETjet-S driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_NETJET_S) - return (0); - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - - for (;;) - { - if ((dev_netjet = hisax_find_pci_device(PCI_VENDOR_ID_TIGERJET, - PCI_DEVICE_ID_TIGERJET_300, dev_netjet))) { - ret = njs_pci_probe(dev_netjet, cs); - if (!ret) - return (0); - } else { - printk(KERN_WARNING "NETjet-S: No PCI card found\n"); - return (0); - } - - ret = njs_cs_init(card, cs); - if (!ret) - return (0); - if (ret > 0) - break; - /* otherwise, ret < 0, continue looping */ - } - - return njs_cs_init_rest(card, cs); -} diff --git a/drivers/isdn/hisax/nj_u.c b/drivers/isdn/hisax/nj_u.c deleted file mode 100644 index 4e8adbede361..000000000000 --- a/drivers/isdn/hisax/nj_u.c +++ /dev/null @@ -1,258 +0,0 @@ -/* $Id: nj_u.c,v 2.14.2.3 2004/01/13 14:31:26 keil Exp $ - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#include <linux/init.h> -#include "hisax.h" -#include "icc.h" -#include "isdnl1.h" -#include <linux/pci.h> -#include <linux/interrupt.h> -#include <linux/ppp_defs.h> -#include "netjet.h" - -static const char *NETjet_U_revision = "$Revision: 2.14.2.3 $"; - -static u_char dummyrr(struct IsdnCardState *cs, int chan, u_char off) -{ - return (5); -} - -static void dummywr(struct IsdnCardState *cs, int chan, u_char off, u_char value) -{ -} - -static irqreturn_t -netjet_u_interrupt(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - u_char val, sval; - u_long flags; - - spin_lock_irqsave(&cs->lock, flags); - if (!((sval = bytein(cs->hw.njet.base + NETJET_IRQSTAT1)) & - NETJET_ISACIRQ)) { - val = NETjet_ReadIC(cs, ICC_ISTA); - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "tiger: i1 %x %x", sval, val); - if (val) { - icc_interrupt(cs, val); - NETjet_WriteIC(cs, ICC_MASK, 0xFF); - NETjet_WriteIC(cs, ICC_MASK, 0x0); - } - } - /* start new code 13/07/00 GE */ - /* set bits in sval to indicate which page is free */ - if (inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR) < - inl(cs->hw.njet.base + NETJET_DMA_WRITE_IRQ)) - /* the 2nd write page is free */ - sval = 0x08; - else /* the 1st write page is free */ - sval = 0x04; - if (inl(cs->hw.njet.base + NETJET_DMA_READ_ADR) < - inl(cs->hw.njet.base + NETJET_DMA_READ_IRQ)) - /* the 2nd read page is free */ - sval = sval | 0x02; - else /* the 1st read page is free */ - sval = sval | 0x01; - if (sval != cs->hw.njet.last_is0) /* we have a DMA interrupt */ - { - if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; - } - cs->hw.njet.irqstat0 = sval; - if ((cs->hw.njet.irqstat0 & NETJET_IRQM0_READ) != - (cs->hw.njet.last_is0 & NETJET_IRQM0_READ)) - /* we have a read dma int */ - read_tiger(cs); - if ((cs->hw.njet.irqstat0 & NETJET_IRQM0_WRITE) != - (cs->hw.njet.last_is0 & NETJET_IRQM0_WRITE)) - /* we have a write dma int */ - write_tiger(cs); - /* end new code 13/07/00 GE */ - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - } - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -static void -reset_netjet_u(struct IsdnCardState *cs) -{ - cs->hw.njet.ctrl_reg = 0xff; /* Reset On */ - byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); - mdelay(10); - cs->hw.njet.ctrl_reg = 0x40; /* Reset Off and status read clear */ - /* now edge triggered for TJ320 GE 13/07/00 */ - byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); - mdelay(10); - cs->hw.njet.auxd = 0xC0; - cs->hw.njet.dmactrl = 0; - byteout(cs->hw.njet.auxa, 0); - byteout(cs->hw.njet.base + NETJET_AUXCTRL, ~NETJET_ISACIRQ); - byteout(cs->hw.njet.base + NETJET_IRQMASK1, NETJET_ISACIRQ); - byteout(cs->hw.njet.auxa, cs->hw.njet.auxd); -} - -static int -NETjet_U_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - u_long flags; - - switch (mt) { - case CARD_RESET: - spin_lock_irqsave(&cs->lock, flags); - reset_netjet_u(cs); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_RELEASE: - release_io_netjet(cs); - return (0); - case CARD_INIT: - spin_lock_irqsave(&cs->lock, flags); - inittiger(cs); - reset_netjet_u(cs); - clear_pending_icc_ints(cs); - initicc(cs); - /* Reenable all IRQ */ - cs->writeisac(cs, ICC_MASK, 0); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_TEST: - return (0); - } - return (0); -} - -static int nju_pci_probe(struct pci_dev *dev_netjet, struct IsdnCardState *cs) -{ - if (pci_enable_device(dev_netjet)) - return (0); - pci_set_master(dev_netjet); - cs->irq = dev_netjet->irq; - if (!cs->irq) { - printk(KERN_WARNING "NETspider-U: No IRQ for PCI card found\n"); - return (0); - } - cs->hw.njet.base = pci_resource_start(dev_netjet, 0); - if (!cs->hw.njet.base) { - printk(KERN_WARNING "NETspider-U: No IO-Adr for PCI card found\n"); - return (0); - } - - return (1); -} - -static int nju_cs_init(struct IsdnCard *card, struct IsdnCardState *cs) -{ - cs->hw.njet.auxa = cs->hw.njet.base + NETJET_AUXDATA; - cs->hw.njet.isac = cs->hw.njet.base | NETJET_ISAC_OFF; - mdelay(10); - - cs->hw.njet.ctrl_reg = 0xff; /* Reset On */ - byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); - mdelay(10); - - cs->hw.njet.ctrl_reg = 0x00; /* Reset Off and status read clear */ - byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); - mdelay(10); - - cs->hw.njet.auxd = 0xC0; - cs->hw.njet.dmactrl = 0; - - byteout(cs->hw.njet.auxa, 0); - byteout(cs->hw.njet.base + NETJET_AUXCTRL, ~NETJET_ISACIRQ); - byteout(cs->hw.njet.base + NETJET_IRQMASK1, NETJET_ISACIRQ); - byteout(cs->hw.njet.auxa, cs->hw.njet.auxd); - - switch (((NETjet_ReadIC(cs, ICC_RBCH) >> 5) & 3)) - { - case 3: - return 1; /* end loop */ - - case 0: - printk(KERN_WARNING "NETspider-U: NETjet-S PCI card found\n"); - return -1; /* continue looping */ - - default: - printk(KERN_WARNING "NETspider-U: No PCI card found\n"); - return 0; /* end loop & function */ - } - return 1; /* end loop */ -} - -static int nju_cs_init_rest(struct IsdnCard *card, struct IsdnCardState *cs) -{ - const int bytecnt = 256; - - printk(KERN_INFO - "NETspider-U: PCI card configured at %#lx IRQ %d\n", - cs->hw.njet.base, cs->irq); - if (!request_region(cs->hw.njet.base, bytecnt, "netspider-u isdn")) { - printk(KERN_WARNING - "HiSax: NETspider-U config port %#lx-%#lx " - "already in use\n", - cs->hw.njet.base, - cs->hw.njet.base + bytecnt); - return (0); - } - setup_icc(cs); - cs->readisac = &NETjet_ReadIC; - cs->writeisac = &NETjet_WriteIC; - cs->readisacfifo = &NETjet_ReadICfifo; - cs->writeisacfifo = &NETjet_WriteICfifo; - cs->BC_Read_Reg = &dummyrr; - cs->BC_Write_Reg = &dummywr; - cs->BC_Send_Data = &netjet_fill_dma; - cs->cardmsg = &NETjet_U_card_msg; - cs->irq_func = &netjet_u_interrupt; - cs->irq_flags |= IRQF_SHARED; - ICCVersion(cs, "NETspider-U:"); - - return (1); -} - -static struct pci_dev *dev_netjet = NULL; - -int setup_netjet_u(struct IsdnCard *card) -{ - int ret; - struct IsdnCardState *cs = card->cs; - char tmp[64]; - -#ifdef __BIG_ENDIAN -#error "not running on big endian machines now" -#endif - - strcpy(tmp, NETjet_U_revision); - printk(KERN_INFO "HiSax: Traverse Tech. NETspider-U driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_NETJET_U) - return (0); - test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); - - for (;;) - { - if ((dev_netjet = hisax_find_pci_device(PCI_VENDOR_ID_TIGERJET, - PCI_DEVICE_ID_TIGERJET_300, dev_netjet))) { - ret = nju_pci_probe(dev_netjet, cs); - if (!ret) - return (0); - } else { - printk(KERN_WARNING "NETspider-U: No PCI card found\n"); - return (0); - } - - ret = nju_cs_init(card, cs); - if (!ret) - return (0); - if (ret > 0) - break; - /* ret < 0 == continue looping */ - } - - return nju_cs_init_rest(card, cs); -} diff --git a/drivers/isdn/hisax/q931.c b/drivers/isdn/hisax/q931.c deleted file mode 100644 index 6b8c3fbe3965..000000000000 --- a/drivers/isdn/hisax/q931.c +++ /dev/null @@ -1,1513 +0,0 @@ -/* $Id: q931.c,v 1.12.2.3 2004/01/13 14:31:26 keil Exp $ - * - * code to decode ITU Q.931 call control messages - * - * Author Jan den Ouden - * Copyright by Jan den Ouden - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * Changelog: - * - * Pauline Middelink general improvements - * Beat Doebeli cause texts, display information element - * Karsten Keil cause texts, display information element for 1TR6 - * - */ - - -#include "hisax.h" -#include "l3_1tr6.h" - -void -iecpy(u_char *dest, u_char *iestart, int ieoffset) -{ - u_char *p; - int l; - - p = iestart + ieoffset + 2; - l = iestart[1] - ieoffset; - while (l--) - *dest++ = *p++; - *dest++ = '\0'; -} - -/* - * According to Table 4-2/Q.931 - */ -static -struct MessageType { - u_char nr; - char *descr; -} mtlist[] = { - - { - 0x1, "ALERTING" - }, - { - 0x2, "CALL PROCEEDING" - }, - { - 0x7, "CONNECT" - }, - { - 0xf, "CONNECT ACKNOWLEDGE" - }, - { - 0x3, "PROGRESS" - }, - { - 0x5, "SETUP" - }, - { - 0xd, "SETUP ACKNOWLEDGE" - }, - { - 0x24, "HOLD" - }, - { - 0x28, "HOLD ACKNOWLEDGE" - }, - { - 0x30, "HOLD REJECT" - }, - { - 0x31, "RETRIEVE" - }, - { - 0x33, "RETRIEVE ACKNOWLEDGE" - }, - { - 0x37, "RETRIEVE REJECT" - }, - { - 0x26, "RESUME" - }, - { - 0x2e, "RESUME ACKNOWLEDGE" - }, - { - 0x22, "RESUME REJECT" - }, - { - 0x25, "SUSPEND" - }, - { - 0x2d, "SUSPEND ACKNOWLEDGE" - }, - { - 0x21, "SUSPEND REJECT" - }, - { - 0x20, "USER INFORMATION" - }, - { - 0x45, "DISCONNECT" - }, - { - 0x4d, "RELEASE" - }, - { - 0x5a, "RELEASE COMPLETE" - }, - { - 0x46, "RESTART" - }, - { - 0x4e, "RESTART ACKNOWLEDGE" - }, - { - 0x60, "SEGMENT" - }, - { - 0x79, "CONGESTION CONTROL" - }, - { - 0x7b, "INFORMATION" - }, - { - 0x62, "FACILITY" - }, - { - 0x6e, "NOTIFY" - }, - { - 0x7d, "STATUS" - }, - { - 0x75, "STATUS ENQUIRY" - } -}; - -#define MTSIZE ARRAY_SIZE(mtlist) - -static -struct MessageType mt_n0[] = -{ - {MT_N0_REG_IND, "REGister INDication"}, - {MT_N0_CANC_IND, "CANCel INDication"}, - {MT_N0_FAC_STA, "FACility STAtus"}, - {MT_N0_STA_ACK, "STAtus ACKnowledge"}, - {MT_N0_STA_REJ, "STAtus REJect"}, - {MT_N0_FAC_INF, "FACility INFormation"}, - {MT_N0_INF_ACK, "INFormation ACKnowledge"}, - {MT_N0_INF_REJ, "INFormation REJect"}, - {MT_N0_CLOSE, "CLOSE"}, - {MT_N0_CLO_ACK, "CLOse ACKnowledge"} -}; - -#define MT_N0_LEN ARRAY_SIZE(mt_n0) - -static -struct MessageType mt_n1[] = -{ - {MT_N1_ESC, "ESCape"}, - {MT_N1_ALERT, "ALERT"}, - {MT_N1_CALL_SENT, "CALL SENT"}, - {MT_N1_CONN, "CONNect"}, - {MT_N1_CONN_ACK, "CONNect ACKnowledge"}, - {MT_N1_SETUP, "SETUP"}, - {MT_N1_SETUP_ACK, "SETUP ACKnowledge"}, - {MT_N1_RES, "RESume"}, - {MT_N1_RES_ACK, "RESume ACKnowledge"}, - {MT_N1_RES_REJ, "RESume REJect"}, - {MT_N1_SUSP, "SUSPend"}, - {MT_N1_SUSP_ACK, "SUSPend ACKnowledge"}, - {MT_N1_SUSP_REJ, "SUSPend REJect"}, - {MT_N1_USER_INFO, "USER INFO"}, - {MT_N1_DET, "DETach"}, - {MT_N1_DISC, "DISConnect"}, - {MT_N1_REL, "RELease"}, - {MT_N1_REL_ACK, "RELease ACKnowledge"}, - {MT_N1_CANC_ACK, "CANCel ACKnowledge"}, - {MT_N1_CANC_REJ, "CANCel REJect"}, - {MT_N1_CON_CON, "CONgestion CONtrol"}, - {MT_N1_FAC, "FACility"}, - {MT_N1_FAC_ACK, "FACility ACKnowledge"}, - {MT_N1_FAC_CAN, "FACility CANcel"}, - {MT_N1_FAC_REG, "FACility REGister"}, - {MT_N1_FAC_REJ, "FACility REJect"}, - {MT_N1_INFO, "INFOrmation"}, - {MT_N1_REG_ACK, "REGister ACKnowledge"}, - {MT_N1_REG_REJ, "REGister REJect"}, - {MT_N1_STAT, "STATus"} -}; - -#define MT_N1_LEN ARRAY_SIZE(mt_n1) - - -static int -prbits(char *dest, u_char b, int start, int len) -{ - char *dp = dest; - - b = b << (8 - start); - while (len--) { - if (b & 0x80) - *dp++ = '1'; - else - *dp++ = '0'; - b = b << 1; - } - return (dp - dest); -} - -static -u_char * -skipext(u_char *p) -{ - while (!(*p++ & 0x80)); - return (p); -} - -/* - * Cause Values According to Q.850 - * edescr: English description - * ddescr: German description used by Swissnet II (Swiss Telecom - * not yet written... - */ - -static -struct CauseValue { - u_char nr; - char *edescr; - char *ddescr; -} cvlist[] = { - - { - 0x01, "Unallocated (unassigned) number", "Nummer nicht zugeteilt" - }, - { - 0x02, "No route to specified transit network", "" - }, - { - 0x03, "No route to destination", "" - }, - { - 0x04, "Send special information tone", "" - }, - { - 0x05, "Misdialled trunk prefix", "" - }, - { - 0x06, "Channel unacceptable", "Kanal nicht akzeptierbar" - }, - { - 0x07, "Channel awarded and being delivered in an established channel", "" - }, - { - 0x08, "Preemption", "" - }, - { - 0x09, "Preemption - circuit reserved for reuse", "" - }, - { - 0x10, "Normal call clearing", "Normale Ausloesung" - }, - { - 0x11, "User busy", "TNB besetzt" - }, - { - 0x12, "No user responding", "" - }, - { - 0x13, "No answer from user (user alerted)", "" - }, - { - 0x14, "Subscriber absent", "" - }, - { - 0x15, "Call rejected", "" - }, - { - 0x16, "Number changed", "" - }, - { - 0x1a, "non-selected user clearing", "" - }, - { - 0x1b, "Destination out of order", "" - }, - { - 0x1c, "Invalid number format (address incomplete)", "" - }, - { - 0x1d, "Facility rejected", "" - }, - { - 0x1e, "Response to Status enquiry", "" - }, - { - 0x1f, "Normal, unspecified", "" - }, - { - 0x22, "No circuit/channel available", "" - }, - { - 0x26, "Network out of order", "" - }, - { - 0x27, "Permanent frame mode connection out-of-service", "" - }, - { - 0x28, "Permanent frame mode connection operational", "" - }, - { - 0x29, "Temporary failure", "" - }, - { - 0x2a, "Switching equipment congestion", "" - }, - { - 0x2b, "Access information discarded", "" - }, - { - 0x2c, "Requested circuit/channel not available", "" - }, - { - 0x2e, "Precedence call blocked", "" - }, - { - 0x2f, "Resource unavailable, unspecified", "" - }, - { - 0x31, "Quality of service unavailable", "" - }, - { - 0x32, "Requested facility not subscribed", "" - }, - { - 0x35, "Outgoing calls barred within CUG", "" - }, - { - 0x37, "Incoming calls barred within CUG", "" - }, - { - 0x39, "Bearer capability not authorized", "" - }, - { - 0x3a, "Bearer capability not presently available", "" - }, - { - 0x3e, "Inconsistency in designated outgoing access information and subscriber class ", " " - }, - { - 0x3f, "Service or option not available, unspecified", "" - }, - { - 0x41, "Bearer capability not implemented", "" - }, - { - 0x42, "Channel type not implemented", "" - }, - { - 0x43, "Requested facility not implemented", "" - }, - { - 0x44, "Only restricted digital information bearer capability is available", "" - }, - { - 0x4f, "Service or option not implemented", "" - }, - { - 0x51, "Invalid call reference value", "" - }, - { - 0x52, "Identified channel does not exist", "" - }, - { - 0x53, "A suspended call exists, but this call identity does not", "" - }, - { - 0x54, "Call identity in use", "" - }, - { - 0x55, "No call suspended", "" - }, - { - 0x56, "Call having the requested call identity has been cleared", "" - }, - { - 0x57, "User not member of CUG", "" - }, - { - 0x58, "Incompatible destination", "" - }, - { - 0x5a, "Non-existent CUG", "" - }, - { - 0x5b, "Invalid transit network selection", "" - }, - { - 0x5f, "Invalid message, unspecified", "" - }, - { - 0x60, "Mandatory information element is missing", "" - }, - { - 0x61, "Message type non-existent or not implemented", "" - }, - { - 0x62, "Message not compatible with call state or message type non-existent or not implemented ", " " - }, - { - 0x63, "Information element/parameter non-existent or not implemented", "" - }, - { - 0x64, "Invalid information element contents", "" - }, - { - 0x65, "Message not compatible with call state", "" - }, - { - 0x66, "Recovery on timer expiry", "" - }, - { - 0x67, "Parameter non-existent or not implemented - passed on", "" - }, - { - 0x6e, "Message with unrecognized parameter discarded", "" - }, - { - 0x6f, "Protocol error, unspecified", "" - }, - { - 0x7f, "Interworking, unspecified", "" - }, -}; - -#define CVSIZE ARRAY_SIZE(cvlist) - -static -int -prcause(char *dest, u_char *p) -{ - u_char *end; - char *dp = dest; - int i, cause; - - end = p + p[1] + 1; - p += 2; - dp += sprintf(dp, " coding "); - dp += prbits(dp, *p, 7, 2); - dp += sprintf(dp, " location "); - dp += prbits(dp, *p, 4, 4); - *dp++ = '\n'; - p = skipext(p); - - cause = 0x7f & *p++; - - /* locate cause value */ - for (i = 0; i < CVSIZE; i++) - if (cvlist[i].nr == cause) - break; - - /* display cause value if it exists */ - if (i == CVSIZE) - dp += sprintf(dp, "Unknown cause type %x!\n", cause); - else - dp += sprintf(dp, " cause value %x : %s \n", cause, cvlist[i].edescr); - - while (!0) { - if (p > end) - break; - dp += sprintf(dp, " diag attribute %d ", *p++ & 0x7f); - dp += sprintf(dp, " rej %d ", *p & 0x7f); - if (*p & 0x80) { - *dp++ = '\n'; - break; - } else - dp += sprintf(dp, " av %d\n", (*++p) & 0x7f); - } - return (dp - dest); - -} - -static -struct MessageType cause_1tr6[] = -{ - {CAUSE_InvCRef, "Invalid Call Reference"}, - {CAUSE_BearerNotImpl, "Bearer Service Not Implemented"}, - {CAUSE_CIDunknown, "Caller Identity unknown"}, - {CAUSE_CIDinUse, "Caller Identity in Use"}, - {CAUSE_NoChans, "No Channels available"}, - {CAUSE_FacNotImpl, "Facility Not Implemented"}, - {CAUSE_FacNotSubscr, "Facility Not Subscribed"}, - {CAUSE_OutgoingBarred, "Outgoing calls barred"}, - {CAUSE_UserAccessBusy, "User Access Busy"}, - {CAUSE_NegativeGBG, "Negative GBG"}, - {CAUSE_UnknownGBG, "Unknown GBG"}, - {CAUSE_NoSPVknown, "No SPV known"}, - {CAUSE_DestNotObtain, "Destination not obtainable"}, - {CAUSE_NumberChanged, "Number changed"}, - {CAUSE_OutOfOrder, "Out Of Order"}, - {CAUSE_NoUserResponse, "No User Response"}, - {CAUSE_UserBusy, "User Busy"}, - {CAUSE_IncomingBarred, "Incoming Barred"}, - {CAUSE_CallRejected, "Call Rejected"}, - {CAUSE_NetworkCongestion, "Network Congestion"}, - {CAUSE_RemoteUser, "Remote User initiated"}, - {CAUSE_LocalProcErr, "Local Procedure Error"}, - {CAUSE_RemoteProcErr, "Remote Procedure Error"}, - {CAUSE_RemoteUserSuspend, "Remote User Suspend"}, - {CAUSE_RemoteUserResumed, "Remote User Resumed"}, - {CAUSE_UserInfoDiscarded, "User Info Discarded"} -}; - -static int cause_1tr6_len = ARRAY_SIZE(cause_1tr6); - -static int -prcause_1tr6(char *dest, u_char *p) -{ - char *dp = dest; - int i, cause; - - p++; - if (0 == *p) { - dp += sprintf(dp, " OK (cause length=0)\n"); - return (dp - dest); - } else if (*p > 1) { - dp += sprintf(dp, " coding "); - dp += prbits(dp, p[2], 7, 2); - dp += sprintf(dp, " location "); - dp += prbits(dp, p[2], 4, 4); - *dp++ = '\n'; - } - p++; - cause = 0x7f & *p; - - /* locate cause value */ - for (i = 0; i < cause_1tr6_len; i++) - if (cause_1tr6[i].nr == cause) - break; - - /* display cause value if it exists */ - if (i == cause_1tr6_len) - dp += sprintf(dp, "Unknown cause type %x!\n", cause); - else - dp += sprintf(dp, " cause value %x : %s \n", cause, cause_1tr6[i].descr); - - return (dp - dest); - -} - -static int -prchident(char *dest, u_char *p) -{ - char *dp = dest; - - p += 2; - dp += sprintf(dp, " octet 3 "); - dp += prbits(dp, *p, 8, 8); - *dp++ = '\n'; - return (dp - dest); -} - -static int -prcalled(char *dest, u_char *p) -{ - int l; - char *dp = dest; - - p++; - l = *p++ - 1; - dp += sprintf(dp, " octet 3 "); - dp += prbits(dp, *p++, 8, 8); - *dp++ = '\n'; - dp += sprintf(dp, " number digits "); - while (l--) - *dp++ = *p++; - *dp++ = '\n'; - return (dp - dest); -} -static int -prcalling(char *dest, u_char *p) -{ - int l; - char *dp = dest; - - p++; - l = *p++ - 1; - dp += sprintf(dp, " octet 3 "); - dp += prbits(dp, *p, 8, 8); - *dp++ = '\n'; - if (!(*p & 0x80)) { - dp += sprintf(dp, " octet 3a "); - dp += prbits(dp, *++p, 8, 8); - *dp++ = '\n'; - l--; - } - p++; - - dp += sprintf(dp, " number digits "); - while (l--) - *dp++ = *p++; - *dp++ = '\n'; - return (dp - dest); -} - -static -int -prbearer(char *dest, u_char *p) -{ - char *dp = dest, ch; - - p += 2; - dp += sprintf(dp, " octet 3 "); - dp += prbits(dp, *p++, 8, 8); - *dp++ = '\n'; - dp += sprintf(dp, " octet 4 "); - dp += prbits(dp, *p, 8, 8); - *dp++ = '\n'; - if ((*p++ & 0x1f) == 0x18) { - dp += sprintf(dp, " octet 4.1 "); - dp += prbits(dp, *p++, 8, 8); - *dp++ = '\n'; - } - /* check for user information layer 1 */ - if ((*p & 0x60) == 0x20) { - ch = ' '; - do { - dp += sprintf(dp, " octet 5%c ", ch); - dp += prbits(dp, *p, 8, 8); - *dp++ = '\n'; - if (ch == ' ') - ch = 'a'; - else - ch++; - } - while (!(*p++ & 0x80)); - } - /* check for user information layer 2 */ - if ((*p & 0x60) == 0x40) { - dp += sprintf(dp, " octet 6 "); - dp += prbits(dp, *p++, 8, 8); - *dp++ = '\n'; - } - /* check for user information layer 3 */ - if ((*p & 0x60) == 0x60) { - dp += sprintf(dp, " octet 7 "); - dp += prbits(dp, *p++, 8, 8); - *dp++ = '\n'; - } - return (dp - dest); -} - - -static -int -prbearer_ni1(char *dest, u_char *p) -{ - char *dp = dest; - u_char len; - - p++; - len = *p++; - dp += sprintf(dp, " octet 3 "); - dp += prbits(dp, *p, 8, 8); - switch (*p++) { - case 0x80: - dp += sprintf(dp, " Speech"); - break; - case 0x88: - dp += sprintf(dp, " Unrestricted digital information"); - break; - case 0x90: - dp += sprintf(dp, " 3.1 kHz audio"); - break; - default: - dp += sprintf(dp, " Unknown information-transfer capability"); - } - *dp++ = '\n'; - dp += sprintf(dp, " octet 4 "); - dp += prbits(dp, *p, 8, 8); - switch (*p++) { - case 0x90: - dp += sprintf(dp, " 64 kbps, circuit mode"); - break; - case 0xc0: - dp += sprintf(dp, " Packet mode"); - break; - default: - dp += sprintf(dp, " Unknown transfer mode"); - } - *dp++ = '\n'; - if (len > 2) { - dp += sprintf(dp, " octet 5 "); - dp += prbits(dp, *p, 8, 8); - switch (*p++) { - case 0x21: - dp += sprintf(dp, " Rate adaption\n"); - dp += sprintf(dp, " octet 5a "); - dp += prbits(dp, *p, 8, 8); - break; - case 0xa2: - dp += sprintf(dp, " u-law"); - break; - default: - dp += sprintf(dp, " Unknown UI layer 1 protocol"); - } - *dp++ = '\n'; - } - return (dp - dest); -} - -static int -general(char *dest, u_char *p) -{ - char *dp = dest; - char ch = ' '; - int l, octet = 3; - - p++; - l = *p++; - /* Iterate over all octets in the information element */ - while (l--) { - dp += sprintf(dp, " octet %d%c ", octet, ch); - dp += prbits(dp, *p++, 8, 8); - *dp++ = '\n'; - - /* last octet in group? */ - if (*p & 0x80) { - octet++; - ch = ' '; - } else if (ch == ' ') - ch = 'a'; - else - ch++; - } - return (dp - dest); -} - -static int -general_ni1(char *dest, u_char *p) -{ - char *dp = dest; - char ch = ' '; - int l, octet = 3; - - p++; - l = *p++; - /* Iterate over all octets in the information element */ - while (l--) { - dp += sprintf(dp, " octet %d%c ", octet, ch); - dp += prbits(dp, *p, 8, 8); - *dp++ = '\n'; - - /* last octet in group? */ - if (*p++ & 0x80) { - octet++; - ch = ' '; - } else if (ch == ' ') - ch = 'a'; - else - ch++; - } - return (dp - dest); -} - -static int -prcharge(char *dest, u_char *p) -{ - char *dp = dest; - int l; - - p++; - l = *p++ - 1; - dp += sprintf(dp, " GEA "); - dp += prbits(dp, *p++, 8, 8); - dp += sprintf(dp, " Anzahl: "); - /* Iterate over all octets in the * information element */ - while (l--) - *dp++ = *p++; - *dp++ = '\n'; - return (dp - dest); -} -static int -prtext(char *dest, u_char *p) -{ - char *dp = dest; - int l; - - p++; - l = *p++; - dp += sprintf(dp, " "); - /* Iterate over all octets in the * information element */ - while (l--) - *dp++ = *p++; - *dp++ = '\n'; - return (dp - dest); -} - -static int -prfeatureind(char *dest, u_char *p) -{ - char *dp = dest; - - p += 2; /* skip id, len */ - dp += sprintf(dp, " octet 3 "); - dp += prbits(dp, *p, 8, 8); - *dp++ = '\n'; - if (!(*p++ & 0x80)) { - dp += sprintf(dp, " octet 4 "); - dp += prbits(dp, *p++, 8, 8); - *dp++ = '\n'; - } - dp += sprintf(dp, " Status: "); - switch (*p) { - case 0: - dp += sprintf(dp, "Idle"); - break; - case 1: - dp += sprintf(dp, "Active"); - break; - case 2: - dp += sprintf(dp, "Prompt"); - break; - case 3: - dp += sprintf(dp, "Pending"); - break; - default: - dp += sprintf(dp, "(Reserved)"); - break; - } - *dp++ = '\n'; - return (dp - dest); -} - -static -struct DTag { /* Display tags */ - u_char nr; - char *descr; -} dtaglist[] = { - { 0x82, "Continuation" }, - { 0x83, "Called address" }, - { 0x84, "Cause" }, - { 0x85, "Progress indicator" }, - { 0x86, "Notification indicator" }, - { 0x87, "Prompt" }, - { 0x88, "Accumlated digits" }, - { 0x89, "Status" }, - { 0x8a, "Inband" }, - { 0x8b, "Calling address" }, - { 0x8c, "Reason" }, - { 0x8d, "Calling party name" }, - { 0x8e, "Called party name" }, - { 0x8f, "Original called name" }, - { 0x90, "Redirecting name" }, - { 0x91, "Connected name" }, - { 0x92, "Originating restrictions" }, - { 0x93, "Date & time of day" }, - { 0x94, "Call Appearance ID" }, - { 0x95, "Feature address" }, - { 0x96, "Redirection name" }, - { 0x9e, "Text" }, -}; -#define DTAGSIZE ARRAY_SIZE(dtaglist) - -static int -disptext_ni1(char *dest, u_char *p) -{ - char *dp = dest; - int l, tag, len, i; - - p++; - l = *p++ - 1; - if (*p++ != 0x80) { - dp += sprintf(dp, " Unknown display type\n"); - return (dp - dest); - } - /* Iterate over all tag,length,text fields */ - while (l > 0) { - tag = *p++; - len = *p++; - l -= len + 2; - /* Don't space or skip */ - if ((tag == 0x80) || (tag == 0x81)) p++; - else { - for (i = 0; i < DTAGSIZE; i++) - if (tag == dtaglist[i].nr) - break; - - /* When not found, give appropriate msg */ - if (i != DTAGSIZE) { - dp += sprintf(dp, " %s: ", dtaglist[i].descr); - while (len--) - *dp++ = *p++; - } else { - dp += sprintf(dp, " (unknown display tag %2x): ", tag); - while (len--) - *dp++ = *p++; - } - dp += sprintf(dp, "\n"); - } - } - return (dp - dest); -} -static int -display(char *dest, u_char *p) -{ - char *dp = dest; - char ch = ' '; - int l, octet = 3; - - p++; - l = *p++; - /* Iterate over all octets in the * display-information element */ - dp += sprintf(dp, " \""); - while (l--) { - dp += sprintf(dp, "%c", *p++); - - /* last octet in group? */ - if (*p & 0x80) { - octet++; - ch = ' '; - } else if (ch == ' ') - ch = 'a'; - - else - ch++; - } - *dp++ = '\"'; - *dp++ = '\n'; - return (dp - dest); -} - -static int -prfacility(char *dest, u_char *p) -{ - char *dp = dest; - int l, l2; - - p++; - l = *p++; - dp += sprintf(dp, " octet 3 "); - dp += prbits(dp, *p++, 8, 8); - dp += sprintf(dp, "\n"); - l -= 1; - - while (l > 0) { - dp += sprintf(dp, " octet 4 "); - dp += prbits(dp, *p++, 8, 8); - dp += sprintf(dp, "\n"); - dp += sprintf(dp, " octet 5 %d\n", l2 = *p++ & 0x7f); - l -= 2; - dp += sprintf(dp, " contents "); - while (l2--) { - dp += sprintf(dp, "%2x ", *p++); - l--; - } - dp += sprintf(dp, "\n"); - } - - return (dp - dest); -} - -static -struct InformationElement { - u_char nr; - char *descr; - int (*f) (char *, u_char *); -} ielist[] = { - - { - 0x00, "Segmented message", general - }, - { - 0x04, "Bearer capability", prbearer - }, - { - 0x08, "Cause", prcause - }, - { - 0x10, "Call identity", general - }, - { - 0x14, "Call state", general - }, - { - 0x18, "Channel identification", prchident - }, - { - 0x1c, "Facility", prfacility - }, - { - 0x1e, "Progress indicator", general - }, - { - 0x20, "Network-specific facilities", general - }, - { - 0x27, "Notification indicator", general - }, - { - 0x28, "Display", display - }, - { - 0x29, "Date/Time", general - }, - { - 0x2c, "Keypad facility", general - }, - { - 0x34, "Signal", general - }, - { - 0x40, "Information rate", general - }, - { - 0x42, "End-to-end delay", general - }, - { - 0x43, "Transit delay selection and indication", general - }, - { - 0x44, "Packet layer binary parameters", general - }, - { - 0x45, "Packet layer window size", general - }, - { - 0x46, "Packet size", general - }, - { - 0x47, "Closed user group", general - }, - { - 0x4a, "Reverse charge indication", general - }, - { - 0x6c, "Calling party number", prcalling - }, - { - 0x6d, "Calling party subaddress", general - }, - { - 0x70, "Called party number", prcalled - }, - { - 0x71, "Called party subaddress", general - }, - { - 0x74, "Redirecting number", general - }, - { - 0x78, "Transit network selection", general - }, - { - 0x79, "Restart indicator", general - }, - { - 0x7c, "Low layer compatibility", general - }, - { - 0x7d, "High layer compatibility", general - }, - { - 0x7e, "User-user", general - }, - { - 0x7f, "Escape for extension", general - }, -}; - - -#define IESIZE ARRAY_SIZE(ielist) - -static -struct InformationElement ielist_ni1[] = { - { 0x04, "Bearer Capability", prbearer_ni1 }, - { 0x08, "Cause", prcause }, - { 0x14, "Call State", general_ni1 }, - { 0x18, "Channel Identification", prchident }, - { 0x1e, "Progress Indicator", general_ni1 }, - { 0x27, "Notification Indicator", general_ni1 }, - { 0x2c, "Keypad Facility", prtext }, - { 0x32, "Information Request", general_ni1 }, - { 0x34, "Signal", general_ni1 }, - { 0x38, "Feature Activation", general_ni1 }, - { 0x39, "Feature Indication", prfeatureind }, - { 0x3a, "Service Profile Identification (SPID)", prtext }, - { 0x3b, "Endpoint Identifier", general_ni1 }, - { 0x6c, "Calling Party Number", prcalling }, - { 0x6d, "Calling Party Subaddress", general_ni1 }, - { 0x70, "Called Party Number", prcalled }, - { 0x71, "Called Party Subaddress", general_ni1 }, - { 0x74, "Redirecting Number", general_ni1 }, - { 0x78, "Transit Network Selection", general_ni1 }, - { 0x7c, "Low Layer Compatibility", general_ni1 }, - { 0x7d, "High Layer Compatibility", general_ni1 }, -}; - - -#define IESIZE_NI1 ARRAY_SIZE(ielist_ni1) - -static -struct InformationElement ielist_ni1_cs5[] = { - { 0x1d, "Operator system access", general_ni1 }, - { 0x2a, "Display text", disptext_ni1 }, -}; - -#define IESIZE_NI1_CS5 ARRAY_SIZE(ielist_ni1_cs5) - -static -struct InformationElement ielist_ni1_cs6[] = { - { 0x7b, "Call appearance", general_ni1 }, -}; - -#define IESIZE_NI1_CS6 ARRAY_SIZE(ielist_ni1_cs6) - -static struct InformationElement we_0[] = -{ - {WE0_cause, "Cause", prcause_1tr6}, - {WE0_connAddr, "Connecting Address", prcalled}, - {WE0_callID, "Call IDentity", general}, - {WE0_chanID, "Channel IDentity", general}, - {WE0_netSpecFac, "Network Specific Facility", general}, - {WE0_display, "Display", general}, - {WE0_keypad, "Keypad", general}, - {WE0_origAddr, "Origination Address", prcalled}, - {WE0_destAddr, "Destination Address", prcalled}, - {WE0_userInfo, "User Info", general} -}; - -#define WE_0_LEN ARRAY_SIZE(we_0) - -static struct InformationElement we_6[] = -{ - {WE6_serviceInd, "Service Indicator", general}, - {WE6_chargingInfo, "Charging Information", prcharge}, - {WE6_date, "Date", prtext}, - {WE6_facSelect, "Facility Select", general}, - {WE6_facStatus, "Facility Status", general}, - {WE6_statusCalled, "Status Called", general}, - {WE6_addTransAttr, "Additional Transmission Attributes", general} -}; -#define WE_6_LEN ARRAY_SIZE(we_6) - -int -QuickHex(char *txt, u_char *p, int cnt) -{ - register int i; - register char *t = txt; - - for (i = 0; i < cnt; i++) { - *t++ = ' '; - *t++ = hex_asc_hi(p[i]); - *t++ = hex_asc_lo(p[i]); - } - *t++ = 0; - return (t - txt); -} - -void -LogFrame(struct IsdnCardState *cs, u_char *buf, int size) -{ - char *dp; - - if (size < 1) - return; - dp = cs->dlog; - if (size < MAX_DLOG_SPACE / 3 - 10) { - *dp++ = 'H'; - *dp++ = 'E'; - *dp++ = 'X'; - *dp++ = ':'; - dp += QuickHex(dp, buf, size); - dp--; - *dp++ = '\n'; - *dp = 0; - HiSax_putstatus(cs, NULL, cs->dlog); - } else - HiSax_putstatus(cs, "LogFrame: ", "warning Frame too big (%d)", size); -} - -void -dlogframe(struct IsdnCardState *cs, struct sk_buff *skb, int dir) -{ - u_char *bend, *buf; - char *dp; - unsigned char pd, cr_l, cr, mt; - unsigned char sapi, tei, ftyp; - int i, cset = 0, cs_old = 0, cs_fest = 0; - int size, finish = 0; - - if (skb->len < 3) - return; - /* display header */ - dp = cs->dlog; - dp += jiftime(dp, jiffies); - *dp++ = ' '; - sapi = skb->data[0] >> 2; - tei = skb->data[1] >> 1; - ftyp = skb->data[2]; - buf = skb->data; - dp += sprintf(dp, "frame %s ", dir ? "network->user" : "user->network"); - size = skb->len; - - if (tei == GROUP_TEI) { - if (sapi == CTRL_SAPI) { /* sapi 0 */ - if (ftyp == 3) { - dp += sprintf(dp, "broadcast\n"); - buf += 3; - size -= 3; - } else { - dp += sprintf(dp, "no UI broadcast\n"); - finish = 1; - } - } else if (sapi == TEI_SAPI) { - dp += sprintf(dp, "tei management\n"); - finish = 1; - } else { - dp += sprintf(dp, "unknown sapi %d broadcast\n", sapi); - finish = 1; - } - } else { - if (sapi == CTRL_SAPI) { - if (!(ftyp & 1)) { /* IFrame */ - dp += sprintf(dp, "with tei %d\n", tei); - buf += 4; - size -= 4; - } else { - dp += sprintf(dp, "SFrame with tei %d\n", tei); - finish = 1; - } - } else { - dp += sprintf(dp, "unknown sapi %d tei %d\n", sapi, tei); - finish = 1; - } - } - bend = skb->data + skb->len; - if (buf >= bend) { - dp += sprintf(dp, "frame too short\n"); - finish = 1; - } - if (finish) { - *dp = 0; - HiSax_putstatus(cs, NULL, cs->dlog); - return; - } - if ((0xfe & buf[0]) == PROTO_DIS_N0) { /* 1TR6 */ - /* locate message type */ - pd = *buf++; - cr_l = *buf++; - if (cr_l) - cr = *buf++; - else - cr = 0; - mt = *buf++; - if (pd == PROTO_DIS_N0) { /* N0 */ - for (i = 0; i < MT_N0_LEN; i++) - if (mt_n0[i].nr == mt) - break; - /* display message type if it exists */ - if (i == MT_N0_LEN) - dp += sprintf(dp, "callref %d %s size %d unknown message type N0 %x!\n", - cr & 0x7f, (cr & 0x80) ? "called" : "caller", - size, mt); - else - dp += sprintf(dp, "callref %d %s size %d message type %s\n", - cr & 0x7f, (cr & 0x80) ? "called" : "caller", - size, mt_n0[i].descr); - } else { /* N1 */ - for (i = 0; i < MT_N1_LEN; i++) - if (mt_n1[i].nr == mt) - break; - /* display message type if it exists */ - if (i == MT_N1_LEN) - dp += sprintf(dp, "callref %d %s size %d unknown message type N1 %x!\n", - cr & 0x7f, (cr & 0x80) ? "called" : "caller", - size, mt); - else - dp += sprintf(dp, "callref %d %s size %d message type %s\n", - cr & 0x7f, (cr & 0x80) ? "called" : "caller", - size, mt_n1[i].descr); - } - - /* display each information element */ - while (buf < bend) { - /* Is it a single octet information element? */ - if (*buf & 0x80) { - switch ((*buf >> 4) & 7) { - case 1: - dp += sprintf(dp, " Shift %x\n", *buf & 0xf); - cs_old = cset; - cset = *buf & 7; - cs_fest = *buf & 8; - break; - case 3: - dp += sprintf(dp, " Congestion level %x\n", *buf & 0xf); - break; - case 2: - if (*buf == 0xa0) { - dp += sprintf(dp, " More data\n"); - break; - } - if (*buf == 0xa1) { - dp += sprintf(dp, " Sending complete\n"); - } - break; - /* fall through */ - default: - dp += sprintf(dp, " Reserved %x\n", *buf); - break; - } - buf++; - continue; - } - /* No, locate it in the table */ - if (cset == 0) { - for (i = 0; i < WE_0_LEN; i++) - if (*buf == we_0[i].nr) - break; - - /* When found, give appropriate msg */ - if (i != WE_0_LEN) { - dp += sprintf(dp, " %s\n", we_0[i].descr); - dp += we_0[i].f(dp, buf); - } else - dp += sprintf(dp, " Codeset %d attribute %x attribute size %d\n", cset, *buf, buf[1]); - } else if (cset == 6) { - for (i = 0; i < WE_6_LEN; i++) - if (*buf == we_6[i].nr) - break; - - /* When found, give appropriate msg */ - if (i != WE_6_LEN) { - dp += sprintf(dp, " %s\n", we_6[i].descr); - dp += we_6[i].f(dp, buf); - } else - dp += sprintf(dp, " Codeset %d attribute %x attribute size %d\n", cset, *buf, buf[1]); - } else - dp += sprintf(dp, " Unknown Codeset %d attribute %x attribute size %d\n", cset, *buf, buf[1]); - /* Skip to next element */ - if (cs_fest == 8) { - cset = cs_old; - cs_old = 0; - cs_fest = 0; - } - buf += buf[1] + 2; - } - } else if ((buf[0] == 8) && (cs->protocol == ISDN_PTYPE_NI1)) { /* NI-1 */ - /* locate message type */ - buf++; - cr_l = *buf++; - if (cr_l) - cr = *buf++; - else - cr = 0; - mt = *buf++; - for (i = 0; i < MTSIZE; i++) - if (mtlist[i].nr == mt) - break; - - /* display message type if it exists */ - if (i == MTSIZE) - dp += sprintf(dp, "callref %d %s size %d unknown message type %x!\n", - cr & 0x7f, (cr & 0x80) ? "called" : "caller", - size, mt); - else - dp += sprintf(dp, "callref %d %s size %d message type %s\n", - cr & 0x7f, (cr & 0x80) ? "called" : "caller", - size, mtlist[i].descr); - - /* display each information element */ - while (buf < bend) { - /* Is it a single octet information element? */ - if (*buf & 0x80) { - switch ((*buf >> 4) & 7) { - case 1: - dp += sprintf(dp, " Shift %x\n", *buf & 0xf); - cs_old = cset; - cset = *buf & 7; - cs_fest = *buf & 8; - break; - default: - dp += sprintf(dp, " Unknown single-octet IE %x\n", *buf); - break; - } - buf++; - continue; - } - /* No, locate it in the table */ - if (cset == 0) { - for (i = 0; i < IESIZE_NI1; i++) - if (*buf == ielist_ni1[i].nr) - break; - - /* When not found, give appropriate msg */ - if (i != IESIZE_NI1) { - dp += sprintf(dp, " %s\n", ielist_ni1[i].descr); - dp += ielist_ni1[i].f(dp, buf); - } else - dp += sprintf(dp, " attribute %x attribute size %d\n", *buf, buf[1]); - } else if (cset == 5) { - for (i = 0; i < IESIZE_NI1_CS5; i++) - if (*buf == ielist_ni1_cs5[i].nr) - break; - - /* When not found, give appropriate msg */ - if (i != IESIZE_NI1_CS5) { - dp += sprintf(dp, " %s\n", ielist_ni1_cs5[i].descr); - dp += ielist_ni1_cs5[i].f(dp, buf); - } else - dp += sprintf(dp, " attribute %x attribute size %d\n", *buf, buf[1]); - } else if (cset == 6) { - for (i = 0; i < IESIZE_NI1_CS6; i++) - if (*buf == ielist_ni1_cs6[i].nr) - break; - - /* When not found, give appropriate msg */ - if (i != IESIZE_NI1_CS6) { - dp += sprintf(dp, " %s\n", ielist_ni1_cs6[i].descr); - dp += ielist_ni1_cs6[i].f(dp, buf); - } else - dp += sprintf(dp, " attribute %x attribute size %d\n", *buf, buf[1]); - } else - dp += sprintf(dp, " Unknown Codeset %d attribute %x attribute size %d\n", cset, *buf, buf[1]); - - /* Skip to next element */ - if (cs_fest == 8) { - cset = cs_old; - cs_old = 0; - cs_fest = 0; - } - buf += buf[1] + 2; - } - } else if ((buf[0] == 8) && (cs->protocol == ISDN_PTYPE_EURO)) { /* EURO */ - /* locate message type */ - buf++; - cr_l = *buf++; - if (cr_l) - cr = *buf++; - else - cr = 0; - mt = *buf++; - for (i = 0; i < MTSIZE; i++) - if (mtlist[i].nr == mt) - break; - - /* display message type if it exists */ - if (i == MTSIZE) - dp += sprintf(dp, "callref %d %s size %d unknown message type %x!\n", - cr & 0x7f, (cr & 0x80) ? "called" : "caller", - size, mt); - else - dp += sprintf(dp, "callref %d %s size %d message type %s\n", - cr & 0x7f, (cr & 0x80) ? "called" : "caller", - size, mtlist[i].descr); - - /* display each information element */ - while (buf < bend) { - /* Is it a single octet information element? */ - if (*buf & 0x80) { - switch ((*buf >> 4) & 7) { - case 1: - dp += sprintf(dp, " Shift %x\n", *buf & 0xf); - break; - case 3: - dp += sprintf(dp, " Congestion level %x\n", *buf & 0xf); - break; - case 5: - dp += sprintf(dp, " Repeat indicator %x\n", *buf & 0xf); - break; - case 2: - if (*buf == 0xa0) { - dp += sprintf(dp, " More data\n"); - break; - } - if (*buf == 0xa1) { - dp += sprintf(dp, " Sending complete\n"); - } - break; - /* fall through */ - default: - dp += sprintf(dp, " Reserved %x\n", *buf); - break; - } - buf++; - continue; - } - /* No, locate it in the table */ - for (i = 0; i < IESIZE; i++) - if (*buf == ielist[i].nr) - break; - - /* When not found, give appropriate msg */ - if (i != IESIZE) { - dp += sprintf(dp, " %s\n", ielist[i].descr); - dp += ielist[i].f(dp, buf); - } else - dp += sprintf(dp, " attribute %x attribute size %d\n", *buf, buf[1]); - - /* Skip to next element */ - buf += buf[1] + 2; - } - } else { - dp += sprintf(dp, "Unknown protocol %x!", buf[0]); - } - *dp = 0; - HiSax_putstatus(cs, NULL, cs->dlog); -} diff --git a/drivers/isdn/hisax/s0box.c b/drivers/isdn/hisax/s0box.c deleted file mode 100644 index 4e7d0aa227ad..000000000000 --- a/drivers/isdn/hisax/s0box.c +++ /dev/null @@ -1,260 +0,0 @@ -/* $Id: s0box.c,v 2.6.2.4 2004/01/13 23:48:39 keil Exp $ - * - * low level stuff for Creatix S0BOX - * - * Author Enrik Berkhan - * Copyright by Enrik Berkhan <enrik@starfleet.inka.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#include <linux/init.h> -#include "hisax.h" -#include "isac.h" -#include "hscx.h" -#include "isdnl1.h" - -static const char *s0box_revision = "$Revision: 2.6.2.4 $"; - -static inline void -writereg(unsigned int padr, signed int addr, u_char off, u_char val) { - outb_p(0x1c, padr + 2); - outb_p(0x14, padr + 2); - outb_p((addr + off) & 0x7f, padr); - outb_p(0x16, padr + 2); - outb_p(val, padr); - outb_p(0x17, padr + 2); - outb_p(0x14, padr + 2); - outb_p(0x1c, padr + 2); -} - -static u_char nibtab[] = { 1, 9, 5, 0xd, 3, 0xb, 7, 0xf, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 8, 4, 0xc, 2, 0xa, 6, 0xe }; - -static inline u_char -readreg(unsigned int padr, signed int addr, u_char off) { - register u_char n1, n2; - - outb_p(0x1c, padr + 2); - outb_p(0x14, padr + 2); - outb_p((addr + off) | 0x80, padr); - outb_p(0x16, padr + 2); - outb_p(0x17, padr + 2); - n1 = (inb_p(padr + 1) >> 3) & 0x17; - outb_p(0x16, padr + 2); - n2 = (inb_p(padr + 1) >> 3) & 0x17; - outb_p(0x14, padr + 2); - outb_p(0x1c, padr + 2); - return nibtab[n1] | (nibtab[n2] << 4); -} - -static inline void -read_fifo(unsigned int padr, signed int adr, u_char *data, int size) -{ - int i; - register u_char n1, n2; - - outb_p(0x1c, padr + 2); - outb_p(0x14, padr + 2); - outb_p(adr | 0x80, padr); - outb_p(0x16, padr + 2); - for (i = 0; i < size; i++) { - outb_p(0x17, padr + 2); - n1 = (inb_p(padr + 1) >> 3) & 0x17; - outb_p(0x16, padr + 2); - n2 = (inb_p(padr + 1) >> 3) & 0x17; - *(data++) = nibtab[n1] | (nibtab[n2] << 4); - } - outb_p(0x14, padr + 2); - outb_p(0x1c, padr + 2); - return; -} - -static inline void -write_fifo(unsigned int padr, signed int adr, u_char *data, int size) -{ - int i; - outb_p(0x1c, padr + 2); - outb_p(0x14, padr + 2); - outb_p(adr & 0x7f, padr); - for (i = 0; i < size; i++) { - outb_p(0x16, padr + 2); - outb_p(*(data++), padr); - outb_p(0x17, padr + 2); - } - outb_p(0x14, padr + 2); - outb_p(0x1c, padr + 2); - return; -} - -/* Interface functions */ - -static u_char -ReadISAC(struct IsdnCardState *cs, u_char offset) -{ - return (readreg(cs->hw.teles3.cfg_reg, cs->hw.teles3.isac, offset)); -} - -static void -WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value) -{ - writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.isac, offset, value); -} - -static void -ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - read_fifo(cs->hw.teles3.cfg_reg, cs->hw.teles3.isacfifo, data, size); -} - -static void -WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - write_fifo(cs->hw.teles3.cfg_reg, cs->hw.teles3.isacfifo, data, size); -} - -static u_char -ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset) -{ - return (readreg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[hscx], offset)); -} - -static void -WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) -{ - writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[hscx], offset, value); -} - -/* - * fast interrupt HSCX stuff goes here - */ - -#define READHSCX(cs, nr, reg) readreg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[nr], reg) -#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[nr], reg, data) -#define READHSCXFIFO(cs, nr, ptr, cnt) read_fifo(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscxfifo[nr], ptr, cnt) -#define WRITEHSCXFIFO(cs, nr, ptr, cnt) write_fifo(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscxfifo[nr], ptr, cnt) - -#include "hscx_irq.c" - -static irqreturn_t -s0box_interrupt(int intno, void *dev_id) -{ -#define MAXCOUNT 5 - struct IsdnCardState *cs = dev_id; - u_char val; - u_long flags; - int count = 0; - - spin_lock_irqsave(&cs->lock, flags); - val = readreg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[1], HSCX_ISTA); -Start_HSCX: - if (val) - hscx_int_main(cs, val); - val = readreg(cs->hw.teles3.cfg_reg, cs->hw.teles3.isac, ISAC_ISTA); -Start_ISAC: - if (val) - isac_interrupt(cs, val); - count++; - val = readreg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[1], HSCX_ISTA); - if (val && count < MAXCOUNT) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "HSCX IntStat after IntRoutine"); - goto Start_HSCX; - } - val = readreg(cs->hw.teles3.cfg_reg, cs->hw.teles3.isac, ISAC_ISTA); - if (val && count < MAXCOUNT) { - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "ISAC IntStat after IntRoutine"); - goto Start_ISAC; - } - if (count >= MAXCOUNT) - printk(KERN_WARNING "S0Box: more than %d loops in s0box_interrupt\n", count); - writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[0], HSCX_MASK, 0xFF); - writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[1], HSCX_MASK, 0xFF); - writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.isac, ISAC_MASK, 0xFF); - writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.isac, ISAC_MASK, 0x0); - writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[0], HSCX_MASK, 0x0); - writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[1], HSCX_MASK, 0x0); - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -static void -release_io_s0box(struct IsdnCardState *cs) -{ - release_region(cs->hw.teles3.cfg_reg, 8); -} - -static int -S0Box_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - u_long flags; - - switch (mt) { - case CARD_RESET: - break; - case CARD_RELEASE: - release_io_s0box(cs); - break; - case CARD_INIT: - spin_lock_irqsave(&cs->lock, flags); - inithscxisac(cs, 3); - spin_unlock_irqrestore(&cs->lock, flags); - break; - case CARD_TEST: - break; - } - return (0); -} - -int setup_s0box(struct IsdnCard *card) -{ - struct IsdnCardState *cs = card->cs; - char tmp[64]; - - strcpy(tmp, s0box_revision); - printk(KERN_INFO "HiSax: S0Box IO driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_S0BOX) - return (0); - - cs->hw.teles3.cfg_reg = card->para[1]; - cs->hw.teles3.hscx[0] = -0x20; - cs->hw.teles3.hscx[1] = 0x0; - cs->hw.teles3.isac = 0x20; - cs->hw.teles3.isacfifo = cs->hw.teles3.isac + 0x3e; - cs->hw.teles3.hscxfifo[0] = cs->hw.teles3.hscx[0] + 0x3e; - cs->hw.teles3.hscxfifo[1] = cs->hw.teles3.hscx[1] + 0x3e; - cs->irq = card->para[0]; - if (!request_region(cs->hw.teles3.cfg_reg, 8, "S0Box parallel I/O")) { - printk(KERN_WARNING "HiSax: S0Box ports %x-%x already in use\n", - cs->hw.teles3.cfg_reg, - cs->hw.teles3.cfg_reg + 7); - return 0; - } - printk(KERN_INFO "HiSax: S0Box config irq:%d isac:0x%x cfg:0x%x\n", - cs->irq, - cs->hw.teles3.isac, cs->hw.teles3.cfg_reg); - printk(KERN_INFO "HiSax: hscx A:0x%x hscx B:0x%x\n", - cs->hw.teles3.hscx[0], cs->hw.teles3.hscx[1]); - setup_isac(cs); - cs->readisac = &ReadISAC; - cs->writeisac = &WriteISAC; - cs->readisacfifo = &ReadISACfifo; - cs->writeisacfifo = &WriteISACfifo; - cs->BC_Read_Reg = &ReadHSCX; - cs->BC_Write_Reg = &WriteHSCX; - cs->BC_Send_Data = &hscx_fill_fifo; - cs->cardmsg = &S0Box_card_msg; - cs->irq_func = &s0box_interrupt; - ISACVersion(cs, "S0Box:"); - if (HscxVersion(cs, "S0Box:")) { - printk(KERN_WARNING - "S0Box: wrong HSCX versions check IO address\n"); - release_io_s0box(cs); - return (0); - } - return (1); -} diff --git a/drivers/isdn/hisax/saphir.c b/drivers/isdn/hisax/saphir.c deleted file mode 100644 index db906cb37a3f..000000000000 --- a/drivers/isdn/hisax/saphir.c +++ /dev/null @@ -1,296 +0,0 @@ -/* $Id: saphir.c,v 1.10.2.4 2004/01/13 23:48:39 keil Exp $ - * - * low level stuff for HST Saphir 1 - * - * Author Karsten Keil - * Copyright by Karsten Keil <keil@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * Thanks to HST High Soft Tech GmbH - * - */ - -#include <linux/init.h> -#include "hisax.h" -#include "isac.h" -#include "hscx.h" -#include "isdnl1.h" - -static char *saphir_rev = "$Revision: 1.10.2.4 $"; - -#define byteout(addr, val) outb(val, addr) -#define bytein(addr) inb(addr) - -#define ISAC_DATA 0 -#define HSCX_DATA 1 -#define ADDRESS_REG 2 -#define IRQ_REG 3 -#define SPARE_REG 4 -#define RESET_REG 5 - -static inline u_char -readreg(unsigned int ale, unsigned int adr, u_char off) -{ - register u_char ret; - - byteout(ale, off); - ret = bytein(adr); - return (ret); -} - -static inline void -readfifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size) -{ - byteout(ale, off); - insb(adr, data, size); -} - - -static inline void -writereg(unsigned int ale, unsigned int adr, u_char off, u_char data) -{ - byteout(ale, off); - byteout(adr, data); -} - -static inline void -writefifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size) -{ - byteout(ale, off); - outsb(adr, data, size); -} - -/* Interface functions */ - -static u_char -ReadISAC(struct IsdnCardState *cs, u_char offset) -{ - return (readreg(cs->hw.saphir.ale, cs->hw.saphir.isac, offset)); -} - -static void -WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value) -{ - writereg(cs->hw.saphir.ale, cs->hw.saphir.isac, offset, value); -} - -static void -ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - readfifo(cs->hw.saphir.ale, cs->hw.saphir.isac, 0, data, size); -} - -static void -WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - writefifo(cs->hw.saphir.ale, cs->hw.saphir.isac, 0, data, size); -} - -static u_char -ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset) -{ - return (readreg(cs->hw.saphir.ale, cs->hw.saphir.hscx, - offset + (hscx ? 0x40 : 0))); -} - -static void -WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) -{ - writereg(cs->hw.saphir.ale, cs->hw.saphir.hscx, - offset + (hscx ? 0x40 : 0), value); -} - -#define READHSCX(cs, nr, reg) readreg(cs->hw.saphir.ale, \ - cs->hw.saphir.hscx, reg + (nr ? 0x40 : 0)) -#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.saphir.ale, \ - cs->hw.saphir.hscx, reg + (nr ? 0x40 : 0), data) - -#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.saphir.ale, \ - cs->hw.saphir.hscx, (nr ? 0x40 : 0), ptr, cnt) - -#define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.saphir.ale, \ - cs->hw.saphir.hscx, (nr ? 0x40 : 0), ptr, cnt) - -#include "hscx_irq.c" - -static irqreturn_t -saphir_interrupt(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - u_char val; - u_long flags; - - spin_lock_irqsave(&cs->lock, flags); - val = readreg(cs->hw.saphir.ale, cs->hw.saphir.hscx, HSCX_ISTA + 0x40); -Start_HSCX: - if (val) - hscx_int_main(cs, val); - val = readreg(cs->hw.saphir.ale, cs->hw.saphir.isac, ISAC_ISTA); -Start_ISAC: - if (val) - isac_interrupt(cs, val); - val = readreg(cs->hw.saphir.ale, cs->hw.saphir.hscx, HSCX_ISTA + 0x40); - if (val) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "HSCX IntStat after IntRoutine"); - goto Start_HSCX; - } - val = readreg(cs->hw.saphir.ale, cs->hw.saphir.isac, ISAC_ISTA); - if (val) { - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "ISAC IntStat after IntRoutine"); - goto Start_ISAC; - } - /* Watchdog */ - if (cs->hw.saphir.timer.function) - mod_timer(&cs->hw.saphir.timer, jiffies + 1 * HZ); - else - printk(KERN_WARNING "saphir: Spurious timer!\n"); - writereg(cs->hw.saphir.ale, cs->hw.saphir.hscx, HSCX_MASK, 0xFF); - writereg(cs->hw.saphir.ale, cs->hw.saphir.hscx, HSCX_MASK + 0x40, 0xFF); - writereg(cs->hw.saphir.ale, cs->hw.saphir.isac, ISAC_MASK, 0xFF); - writereg(cs->hw.saphir.ale, cs->hw.saphir.isac, ISAC_MASK, 0); - writereg(cs->hw.saphir.ale, cs->hw.saphir.hscx, HSCX_MASK, 0); - writereg(cs->hw.saphir.ale, cs->hw.saphir.hscx, HSCX_MASK + 0x40, 0); - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -static void -SaphirWatchDog(struct timer_list *t) -{ - struct IsdnCardState *cs = from_timer(cs, t, hw.saphir.timer); - u_long flags; - - spin_lock_irqsave(&cs->lock, flags); - /* 5 sec WatchDog, so read at least every 4 sec */ - cs->readisac(cs, ISAC_RBCH); - spin_unlock_irqrestore(&cs->lock, flags); - mod_timer(&cs->hw.saphir.timer, jiffies + 1 * HZ); -} - -static void -release_io_saphir(struct IsdnCardState *cs) -{ - byteout(cs->hw.saphir.cfg_reg + IRQ_REG, 0xff); - del_timer(&cs->hw.saphir.timer); - cs->hw.saphir.timer.function = NULL; - if (cs->hw.saphir.cfg_reg) - release_region(cs->hw.saphir.cfg_reg, 6); -} - -static int -saphir_reset(struct IsdnCardState *cs) -{ - u_char irq_val; - - switch (cs->irq) { - case 5: irq_val = 0; - break; - case 3: irq_val = 1; - break; - case 11: - irq_val = 2; - break; - case 12: - irq_val = 3; - break; - case 15: - irq_val = 4; - break; - default: - printk(KERN_WARNING "HiSax: saphir wrong IRQ %d\n", - cs->irq); - return (1); - } - byteout(cs->hw.saphir.cfg_reg + IRQ_REG, irq_val); - byteout(cs->hw.saphir.cfg_reg + RESET_REG, 1); - mdelay(10); - byteout(cs->hw.saphir.cfg_reg + RESET_REG, 0); - mdelay(10); - byteout(cs->hw.saphir.cfg_reg + IRQ_REG, irq_val); - byteout(cs->hw.saphir.cfg_reg + SPARE_REG, 0x02); - return (0); -} - -static int -saphir_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - u_long flags; - - switch (mt) { - case CARD_RESET: - spin_lock_irqsave(&cs->lock, flags); - saphir_reset(cs); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_RELEASE: - release_io_saphir(cs); - return (0); - case CARD_INIT: - spin_lock_irqsave(&cs->lock, flags); - inithscxisac(cs, 3); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_TEST: - return (0); - } - return (0); -} - - -int setup_saphir(struct IsdnCard *card) -{ - struct IsdnCardState *cs = card->cs; - char tmp[64]; - - strcpy(tmp, saphir_rev); - printk(KERN_INFO "HiSax: HST Saphir driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_HSTSAPHIR) - return (0); - - /* IO-Ports */ - cs->hw.saphir.cfg_reg = card->para[1]; - cs->hw.saphir.isac = card->para[1] + ISAC_DATA; - cs->hw.saphir.hscx = card->para[1] + HSCX_DATA; - cs->hw.saphir.ale = card->para[1] + ADDRESS_REG; - cs->irq = card->para[0]; - if (!request_region(cs->hw.saphir.cfg_reg, 6, "saphir")) { - printk(KERN_WARNING - "HiSax: HST Saphir config port %x-%x already in use\n", - cs->hw.saphir.cfg_reg, - cs->hw.saphir.cfg_reg + 5); - return (0); - } - - printk(KERN_INFO "HiSax: HST Saphir config irq:%d io:0x%X\n", - cs->irq, cs->hw.saphir.cfg_reg); - - setup_isac(cs); - timer_setup(&cs->hw.saphir.timer, SaphirWatchDog, 0); - cs->hw.saphir.timer.expires = jiffies + 4 * HZ; - add_timer(&cs->hw.saphir.timer); - if (saphir_reset(cs)) { - release_io_saphir(cs); - return (0); - } - cs->readisac = &ReadISAC; - cs->writeisac = &WriteISAC; - cs->readisacfifo = &ReadISACfifo; - cs->writeisacfifo = &WriteISACfifo; - cs->BC_Read_Reg = &ReadHSCX; - cs->BC_Write_Reg = &WriteHSCX; - cs->BC_Send_Data = &hscx_fill_fifo; - cs->cardmsg = &saphir_card_msg; - cs->irq_func = &saphir_interrupt; - ISACVersion(cs, "saphir:"); - if (HscxVersion(cs, "saphir:")) { - printk(KERN_WARNING - "saphir: wrong HSCX versions check IO address\n"); - release_io_saphir(cs); - return (0); - } - return (1); -} diff --git a/drivers/isdn/hisax/sedlbauer.c b/drivers/isdn/hisax/sedlbauer.c deleted file mode 100644 index c0b97b893495..000000000000 --- a/drivers/isdn/hisax/sedlbauer.c +++ /dev/null @@ -1,873 +0,0 @@ -/* $Id: sedlbauer.c,v 1.34.2.6 2004/01/24 20:47:24 keil Exp $ - * - * low level stuff for Sedlbauer cards - * includes support for the Sedlbauer speed star (speed star II), - * support for the Sedlbauer speed fax+, - * support for the Sedlbauer ISDN-Controller PC/104 and - * support for the Sedlbauer speed pci - * derived from the original file asuscom.c from Karsten Keil - * - * Author Marcus Niemann - * Copyright by Marcus Niemann <niemann@www-bib.fh-bielefeld.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * Thanks to Karsten Keil - * Sedlbauer AG for informations - * Edgar Toernig - * - */ - -/* Supported cards: - * Card: Chip: Configuration: Comment: - * --------------------------------------------------------------------- - * Speed Card ISAC_HSCX DIP-SWITCH - * Speed Win ISAC_HSCX ISAPNP - * Speed Fax+ ISAC_ISAR ISAPNP Full analog support - * Speed Star ISAC_HSCX CARDMGR - * Speed Win2 IPAC ISAPNP - * ISDN PC/104 IPAC DIP-SWITCH - * Speed Star2 IPAC CARDMGR - * Speed PCI IPAC PCI PNP - * Speed Fax+ ISAC_ISAR PCI PNP Full analog support - * - * Important: - * For the sedlbauer speed fax+ to work properly you have to download - * the firmware onto the card. - * For example: hisaxctrl <DriverID> 9 ISAR.BIN - */ - -#include <linux/init.h> -#include "hisax.h" -#include "isac.h" -#include "ipac.h" -#include "hscx.h" -#include "isar.h" -#include "isdnl1.h" -#include <linux/pci.h> -#include <linux/isapnp.h> - -static const char *Sedlbauer_revision = "$Revision: 1.34.2.6 $"; - -static const char *Sedlbauer_Types[] = -{"None", "speed card/win", "speed star", "speed fax+", - "speed win II / ISDN PC/104", "speed star II", "speed pci", - "speed fax+ pyramid", "speed fax+ pci", "HST Saphir III"}; - -#define PCI_SUBVENDOR_SPEEDFAX_PYRAMID 0x51 -#define PCI_SUBVENDOR_HST_SAPHIR3 0x52 -#define PCI_SUBVENDOR_SEDLBAUER_PCI 0x53 -#define PCI_SUBVENDOR_SPEEDFAX_PCI 0x54 -#define PCI_SUB_ID_SEDLBAUER 0x01 - -#define SEDL_SPEED_CARD_WIN 1 -#define SEDL_SPEED_STAR 2 -#define SEDL_SPEED_FAX 3 -#define SEDL_SPEED_WIN2_PC104 4 -#define SEDL_SPEED_STAR2 5 -#define SEDL_SPEED_PCI 6 -#define SEDL_SPEEDFAX_PYRAMID 7 -#define SEDL_SPEEDFAX_PCI 8 -#define HST_SAPHIR3 9 - -#define SEDL_CHIP_TEST 0 -#define SEDL_CHIP_ISAC_HSCX 1 -#define SEDL_CHIP_ISAC_ISAR 2 -#define SEDL_CHIP_IPAC 3 - -#define SEDL_BUS_ISA 1 -#define SEDL_BUS_PCI 2 -#define SEDL_BUS_PCMCIA 3 - -#define byteout(addr, val) outb(val, addr) -#define bytein(addr) inb(addr) - -#define SEDL_HSCX_ISA_RESET_ON 0 -#define SEDL_HSCX_ISA_RESET_OFF 1 -#define SEDL_HSCX_ISA_ISAC 2 -#define SEDL_HSCX_ISA_HSCX 3 -#define SEDL_HSCX_ISA_ADR 4 - -#define SEDL_HSCX_PCMCIA_RESET 0 -#define SEDL_HSCX_PCMCIA_ISAC 1 -#define SEDL_HSCX_PCMCIA_HSCX 2 -#define SEDL_HSCX_PCMCIA_ADR 4 - -#define SEDL_ISAR_ISA_ISAC 4 -#define SEDL_ISAR_ISA_ISAR 6 -#define SEDL_ISAR_ISA_ADR 8 -#define SEDL_ISAR_ISA_ISAR_RESET_ON 10 -#define SEDL_ISAR_ISA_ISAR_RESET_OFF 12 - -#define SEDL_IPAC_ANY_ADR 0 -#define SEDL_IPAC_ANY_IPAC 2 - -#define SEDL_IPAC_PCI_BASE 0 -#define SEDL_IPAC_PCI_ADR 0xc0 -#define SEDL_IPAC_PCI_IPAC 0xc8 -#define SEDL_ISAR_PCI_ADR 0xc8 -#define SEDL_ISAR_PCI_ISAC 0xd0 -#define SEDL_ISAR_PCI_ISAR 0xe0 -#define SEDL_ISAR_PCI_ISAR_RESET_ON 0x01 -#define SEDL_ISAR_PCI_ISAR_RESET_OFF 0x18 -#define SEDL_ISAR_PCI_LED1 0x08 -#define SEDL_ISAR_PCI_LED2 0x10 - -#define SEDL_RESET 0x3 /* same as DOS driver */ - -static inline u_char -readreg(unsigned int ale, unsigned int adr, u_char off) -{ - register u_char ret; - - byteout(ale, off); - ret = bytein(adr); - return (ret); -} - -static inline void -readfifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size) -{ - byteout(ale, off); - insb(adr, data, size); -} - - -static inline void -writereg(unsigned int ale, unsigned int adr, u_char off, u_char data) -{ - byteout(ale, off); - byteout(adr, data); -} - -static inline void -writefifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size) -{ - byteout(ale, off); - outsb(adr, data, size); -} - -/* Interface functions */ - -static u_char -ReadISAC(struct IsdnCardState *cs, u_char offset) -{ - return (readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, offset)); -} - -static void -WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value) -{ - writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, offset, value); -} - -static void -ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - readfifo(cs->hw.sedl.adr, cs->hw.sedl.isac, 0, data, size); -} - -static void -WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - writefifo(cs->hw.sedl.adr, cs->hw.sedl.isac, 0, data, size); -} - -static u_char -ReadISAC_IPAC(struct IsdnCardState *cs, u_char offset) -{ - return (readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, offset | 0x80)); -} - -static void -WriteISAC_IPAC(struct IsdnCardState *cs, u_char offset, u_char value) -{ - writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, offset | 0x80, value); -} - -static void -ReadISACfifo_IPAC(struct IsdnCardState *cs, u_char *data, int size) -{ - readfifo(cs->hw.sedl.adr, cs->hw.sedl.isac, 0x80, data, size); -} - -static void -WriteISACfifo_IPAC(struct IsdnCardState *cs, u_char *data, int size) -{ - writefifo(cs->hw.sedl.adr, cs->hw.sedl.isac, 0x80, data, size); -} - -static u_char -ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset) -{ - return (readreg(cs->hw.sedl.adr, - cs->hw.sedl.hscx, offset + (hscx ? 0x40 : 0))); -} - -static void -WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) -{ - writereg(cs->hw.sedl.adr, - cs->hw.sedl.hscx, offset + (hscx ? 0x40 : 0), value); -} - -/* ISAR access routines - * mode = 0 access with IRQ on - * mode = 1 access with IRQ off - * mode = 2 access with IRQ off and using last offset - */ - -static u_char -ReadISAR(struct IsdnCardState *cs, int mode, u_char offset) -{ - if (mode == 0) - return (readreg(cs->hw.sedl.adr, cs->hw.sedl.hscx, offset)); - else if (mode == 1) - byteout(cs->hw.sedl.adr, offset); - return (bytein(cs->hw.sedl.hscx)); -} - -static void -WriteISAR(struct IsdnCardState *cs, int mode, u_char offset, u_char value) -{ - if (mode == 0) - writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, offset, value); - else { - if (mode == 1) - byteout(cs->hw.sedl.adr, offset); - byteout(cs->hw.sedl.hscx, value); - } -} - -/* - * fast interrupt HSCX stuff goes here - */ - -#define READHSCX(cs, nr, reg) readreg(cs->hw.sedl.adr, \ - cs->hw.sedl.hscx, reg + (nr ? 0x40 : 0)) -#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.sedl.adr, \ - cs->hw.sedl.hscx, reg + (nr ? 0x40 : 0), data) - -#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.sedl.adr, \ - cs->hw.sedl.hscx, (nr ? 0x40 : 0), ptr, cnt) - -#define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.sedl.adr, \ - cs->hw.sedl.hscx, (nr ? 0x40 : 0), ptr, cnt) - -#include "hscx_irq.c" - -static irqreturn_t -sedlbauer_interrupt(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - u_char val; - u_long flags; - - spin_lock_irqsave(&cs->lock, flags); - if ((cs->hw.sedl.bus == SEDL_BUS_PCMCIA) && (*cs->busy_flag == 1)) { - /* The card tends to generate interrupts while being removed - causing us to just crash the kernel. bad. */ - spin_unlock_irqrestore(&cs->lock, flags); - printk(KERN_WARNING "Sedlbauer: card not available!\n"); - return IRQ_NONE; - } - - val = readreg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_ISTA + 0x40); -Start_HSCX: - if (val) - hscx_int_main(cs, val); - val = readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_ISTA); -Start_ISAC: - if (val) - isac_interrupt(cs, val); - val = readreg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_ISTA + 0x40); - if (val) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "HSCX IntStat after IntRoutine"); - goto Start_HSCX; - } - val = readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_ISTA); - if (val) { - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "ISAC IntStat after IntRoutine"); - goto Start_ISAC; - } - writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_MASK, 0xFF); - writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_MASK + 0x40, 0xFF); - writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_MASK, 0xFF); - writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_MASK, 0x0); - writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_MASK, 0x0); - writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_MASK + 0x40, 0x0); - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -static irqreturn_t -sedlbauer_interrupt_ipac(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - u_char ista, val, icnt = 5; - u_long flags; - - spin_lock_irqsave(&cs->lock, flags); - ista = readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_ISTA); -Start_IPAC: - if (cs->debug & L1_DEB_IPAC) - debugl1(cs, "IPAC ISTA %02X", ista); - if (ista & 0x0f) { - val = readreg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_ISTA + 0x40); - if (ista & 0x01) - val |= 0x01; - if (ista & 0x04) - val |= 0x02; - if (ista & 0x08) - val |= 0x04; - if (val) - hscx_int_main(cs, val); - } - if (ista & 0x20) { - val = 0xfe & readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_ISTA | 0x80); - if (val) { - isac_interrupt(cs, val); - } - } - if (ista & 0x10) { - val = 0x01; - isac_interrupt(cs, val); - } - ista = readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_ISTA); - if ((ista & 0x3f) && icnt) { - icnt--; - goto Start_IPAC; - } - if (!icnt) - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "Sedlbauer IRQ LOOP"); - writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_MASK, 0xFF); - writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_MASK, 0xC0); - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -static irqreturn_t -sedlbauer_interrupt_isar(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - u_char val; - int cnt = 5; - u_long flags; - - spin_lock_irqsave(&cs->lock, flags); - val = readreg(cs->hw.sedl.adr, cs->hw.sedl.hscx, ISAR_IRQBIT); -Start_ISAR: - if (val & ISAR_IRQSTA) - isar_int_main(cs); - val = readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_ISTA); -Start_ISAC: - if (val) - isac_interrupt(cs, val); - val = readreg(cs->hw.sedl.adr, cs->hw.sedl.hscx, ISAR_IRQBIT); - if ((val & ISAR_IRQSTA) && --cnt) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "ISAR IntStat after IntRoutine"); - goto Start_ISAR; - } - val = readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_ISTA); - if (val && --cnt) { - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "ISAC IntStat after IntRoutine"); - goto Start_ISAC; - } - if (!cnt) - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "Sedlbauer IRQ LOOP"); - - writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, ISAR_IRQBIT, 0); - writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_MASK, 0xFF); - writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_MASK, 0x0); - writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, ISAR_IRQBIT, ISAR_IRQMSK); - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -static void -release_io_sedlbauer(struct IsdnCardState *cs) -{ - int bytecnt = 8; - - if (cs->subtyp == SEDL_SPEED_FAX) { - bytecnt = 16; - } else if (cs->hw.sedl.bus == SEDL_BUS_PCI) { - bytecnt = 256; - } - if (cs->hw.sedl.cfg_reg) - release_region(cs->hw.sedl.cfg_reg, bytecnt); -} - -static void -reset_sedlbauer(struct IsdnCardState *cs) -{ - printk(KERN_INFO "Sedlbauer: resetting card\n"); - - if (!((cs->hw.sedl.bus == SEDL_BUS_PCMCIA) && - (cs->hw.sedl.chip == SEDL_CHIP_ISAC_HSCX))) { - if (cs->hw.sedl.chip == SEDL_CHIP_IPAC) { - writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_POTA2, 0x20); - mdelay(2); - writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_POTA2, 0x0); - mdelay(10); - writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_CONF, 0x0); - writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_ACFG, 0xff); - writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_AOE, 0x0); - writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_MASK, 0xc0); - writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_PCFG, 0x12); - } else if ((cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) && - (cs->hw.sedl.bus == SEDL_BUS_PCI)) { - byteout(cs->hw.sedl.cfg_reg + 3, cs->hw.sedl.reset_on); - mdelay(2); - byteout(cs->hw.sedl.cfg_reg + 3, cs->hw.sedl.reset_off); - mdelay(10); - } else { - byteout(cs->hw.sedl.reset_on, SEDL_RESET); /* Reset On */ - mdelay(2); - byteout(cs->hw.sedl.reset_off, 0); /* Reset Off */ - mdelay(10); - } - } -} - -static int -Sedl_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - u_long flags; - - switch (mt) { - case CARD_RESET: - spin_lock_irqsave(&cs->lock, flags); - reset_sedlbauer(cs); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_RELEASE: - if (cs->hw.sedl.bus == SEDL_BUS_PCI) - /* disable all IRQ */ - byteout(cs->hw.sedl.cfg_reg + 5, 0); - if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) { - spin_lock_irqsave(&cs->lock, flags); - writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, - ISAR_IRQBIT, 0); - writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, - ISAC_MASK, 0xFF); - reset_sedlbauer(cs); - writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, - ISAR_IRQBIT, 0); - writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, - ISAC_MASK, 0xFF); - spin_unlock_irqrestore(&cs->lock, flags); - } - release_io_sedlbauer(cs); - return (0); - case CARD_INIT: - spin_lock_irqsave(&cs->lock, flags); - if (cs->hw.sedl.bus == SEDL_BUS_PCI) - /* enable all IRQ */ - byteout(cs->hw.sedl.cfg_reg + 5, 0x02); - reset_sedlbauer(cs); - if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) { - clear_pending_isac_ints(cs); - writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, - ISAR_IRQBIT, 0); - initisac(cs); - initisar(cs); - /* Reenable all IRQ */ - cs->writeisac(cs, ISAC_MASK, 0); - /* RESET Receiver and Transmitter */ - cs->writeisac(cs, ISAC_CMDR, 0x41); - } else { - inithscxisac(cs, 3); - } - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_TEST: - return (0); - case MDL_INFO_CONN: - if (cs->subtyp != SEDL_SPEEDFAX_PYRAMID) - return (0); - spin_lock_irqsave(&cs->lock, flags); - if ((long) arg) - cs->hw.sedl.reset_off &= ~SEDL_ISAR_PCI_LED2; - else - cs->hw.sedl.reset_off &= ~SEDL_ISAR_PCI_LED1; - byteout(cs->hw.sedl.cfg_reg + 3, cs->hw.sedl.reset_off); - spin_unlock_irqrestore(&cs->lock, flags); - break; - case MDL_INFO_REL: - if (cs->subtyp != SEDL_SPEEDFAX_PYRAMID) - return (0); - spin_lock_irqsave(&cs->lock, flags); - if ((long) arg) - cs->hw.sedl.reset_off |= SEDL_ISAR_PCI_LED2; - else - cs->hw.sedl.reset_off |= SEDL_ISAR_PCI_LED1; - byteout(cs->hw.sedl.cfg_reg + 3, cs->hw.sedl.reset_off); - spin_unlock_irqrestore(&cs->lock, flags); - break; - } - return (0); -} - -#ifdef __ISAPNP__ -static struct isapnp_device_id sedl_ids[] = { - { ISAPNP_VENDOR('S', 'A', 'G'), ISAPNP_FUNCTION(0x01), - ISAPNP_VENDOR('S', 'A', 'G'), ISAPNP_FUNCTION(0x01), - (unsigned long) "Speed win" }, - { ISAPNP_VENDOR('S', 'A', 'G'), ISAPNP_FUNCTION(0x02), - ISAPNP_VENDOR('S', 'A', 'G'), ISAPNP_FUNCTION(0x02), - (unsigned long) "Speed Fax+" }, - { 0, } -}; - -static struct isapnp_device_id *ipid = &sedl_ids[0]; -static struct pnp_card *pnp_c = NULL; - -static int setup_sedlbauer_isapnp(struct IsdnCard *card, int *bytecnt) -{ - struct IsdnCardState *cs = card->cs; - struct pnp_dev *pnp_d; - - if (!isapnp_present()) - return -1; - - while (ipid->card_vendor) { - if ((pnp_c = pnp_find_card(ipid->card_vendor, - ipid->card_device, pnp_c))) { - pnp_d = NULL; - if ((pnp_d = pnp_find_dev(pnp_c, - ipid->vendor, ipid->function, pnp_d))) { - int err; - - printk(KERN_INFO "HiSax: %s detected\n", - (char *)ipid->driver_data); - pnp_disable_dev(pnp_d); - err = pnp_activate_dev(pnp_d); - if (err < 0) { - printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n", - __func__, err); - return (0); - } - card->para[1] = pnp_port_start(pnp_d, 0); - card->para[0] = pnp_irq(pnp_d, 0); - - if (card->para[0] == -1 || !card->para[1]) { - printk(KERN_ERR "Sedlbauer PnP:some resources are missing %ld/%lx\n", - card->para[0], card->para[1]); - pnp_disable_dev(pnp_d); - return (0); - } - cs->hw.sedl.cfg_reg = card->para[1]; - cs->irq = card->para[0]; - if (ipid->function == ISAPNP_FUNCTION(0x2)) { - cs->subtyp = SEDL_SPEED_FAX; - cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR; - *bytecnt = 16; - } else { - cs->subtyp = SEDL_SPEED_CARD_WIN; - cs->hw.sedl.chip = SEDL_CHIP_TEST; - } - - return (1); - } else { - printk(KERN_ERR "Sedlbauer PnP: PnP error card found, no device\n"); - return (0); - } - } - ipid++; - pnp_c = NULL; - } - - printk(KERN_INFO "Sedlbauer PnP: no ISAPnP card found\n"); - return -1; -} -#else - -static int setup_sedlbauer_isapnp(struct IsdnCard *card, int *bytecnt) -{ - return -1; -} -#endif /* __ISAPNP__ */ - -#ifdef CONFIG_PCI -static struct pci_dev *dev_sedl = NULL; - -static int setup_sedlbauer_pci(struct IsdnCard *card) -{ - struct IsdnCardState *cs = card->cs; - u16 sub_vendor_id, sub_id; - - if ((dev_sedl = hisax_find_pci_device(PCI_VENDOR_ID_TIGERJET, - PCI_DEVICE_ID_TIGERJET_100, dev_sedl))) { - if (pci_enable_device(dev_sedl)) - return (0); - cs->irq = dev_sedl->irq; - if (!cs->irq) { - printk(KERN_WARNING "Sedlbauer: No IRQ for PCI card found\n"); - return (0); - } - cs->hw.sedl.cfg_reg = pci_resource_start(dev_sedl, 0); - } else { - printk(KERN_WARNING "Sedlbauer: No PCI card found\n"); - return (0); - } - cs->irq_flags |= IRQF_SHARED; - cs->hw.sedl.bus = SEDL_BUS_PCI; - sub_vendor_id = dev_sedl->subsystem_vendor; - sub_id = dev_sedl->subsystem_device; - printk(KERN_INFO "Sedlbauer: PCI subvendor:%x subid %x\n", - sub_vendor_id, sub_id); - printk(KERN_INFO "Sedlbauer: PCI base adr %#x\n", - cs->hw.sedl.cfg_reg); - if (sub_id != PCI_SUB_ID_SEDLBAUER) { - printk(KERN_ERR "Sedlbauer: unknown sub id %#x\n", sub_id); - return (0); - } - if (sub_vendor_id == PCI_SUBVENDOR_SPEEDFAX_PYRAMID) { - cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR; - cs->subtyp = SEDL_SPEEDFAX_PYRAMID; - } else if (sub_vendor_id == PCI_SUBVENDOR_SPEEDFAX_PCI) { - cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR; - cs->subtyp = SEDL_SPEEDFAX_PCI; - } else if (sub_vendor_id == PCI_SUBVENDOR_HST_SAPHIR3) { - cs->hw.sedl.chip = SEDL_CHIP_IPAC; - cs->subtyp = HST_SAPHIR3; - } else if (sub_vendor_id == PCI_SUBVENDOR_SEDLBAUER_PCI) { - cs->hw.sedl.chip = SEDL_CHIP_IPAC; - cs->subtyp = SEDL_SPEED_PCI; - } else { - printk(KERN_ERR "Sedlbauer: unknown sub vendor id %#x\n", - sub_vendor_id); - return (0); - } - - cs->hw.sedl.reset_on = SEDL_ISAR_PCI_ISAR_RESET_ON; - cs->hw.sedl.reset_off = SEDL_ISAR_PCI_ISAR_RESET_OFF; - byteout(cs->hw.sedl.cfg_reg, 0xff); - byteout(cs->hw.sedl.cfg_reg, 0x00); - byteout(cs->hw.sedl.cfg_reg + 2, 0xdd); - byteout(cs->hw.sedl.cfg_reg + 5, 0); /* disable all IRQ */ - byteout(cs->hw.sedl.cfg_reg + 3, cs->hw.sedl.reset_on); - mdelay(2); - byteout(cs->hw.sedl.cfg_reg + 3, cs->hw.sedl.reset_off); - mdelay(10); - - return (1); -} - -#else - -static int setup_sedlbauer_pci(struct IsdnCard *card) -{ - return (1); -} - -#endif /* CONFIG_PCI */ - -int setup_sedlbauer(struct IsdnCard *card) -{ - int bytecnt = 8, ver, val, rc; - struct IsdnCardState *cs = card->cs; - char tmp[64]; - - strcpy(tmp, Sedlbauer_revision); - printk(KERN_INFO "HiSax: Sedlbauer driver Rev. %s\n", HiSax_getrev(tmp)); - - if (cs->typ == ISDN_CTYPE_SEDLBAUER) { - cs->subtyp = SEDL_SPEED_CARD_WIN; - cs->hw.sedl.bus = SEDL_BUS_ISA; - cs->hw.sedl.chip = SEDL_CHIP_TEST; - } else if (cs->typ == ISDN_CTYPE_SEDLBAUER_PCMCIA) { - cs->subtyp = SEDL_SPEED_STAR; - cs->hw.sedl.bus = SEDL_BUS_PCMCIA; - cs->hw.sedl.chip = SEDL_CHIP_TEST; - } else if (cs->typ == ISDN_CTYPE_SEDLBAUER_FAX) { - cs->subtyp = SEDL_SPEED_FAX; - cs->hw.sedl.bus = SEDL_BUS_ISA; - cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR; - } else - return (0); - - bytecnt = 8; - if (card->para[1]) { - cs->hw.sedl.cfg_reg = card->para[1]; - cs->irq = card->para[0]; - if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) { - bytecnt = 16; - } - } else { - rc = setup_sedlbauer_isapnp(card, &bytecnt); - if (!rc) - return (0); - if (rc > 0) - goto ready; - - /* Probe for Sedlbauer speed pci */ - rc = setup_sedlbauer_pci(card); - if (!rc) - return (0); - - bytecnt = 256; - } - -ready: - - /* In case of the sedlbauer pcmcia card, this region is in use, - * reserved for us by the card manager. So we do not check it - * here, it would fail. - */ - if (cs->hw.sedl.bus != SEDL_BUS_PCMCIA && - !request_region(cs->hw.sedl.cfg_reg, bytecnt, "sedlbauer isdn")) { - printk(KERN_WARNING - "HiSax: %s config port %x-%x already in use\n", - CardType[card->typ], - cs->hw.sedl.cfg_reg, - cs->hw.sedl.cfg_reg + bytecnt); - return (0); - } - - printk(KERN_INFO - "Sedlbauer: defined at 0x%x-0x%x IRQ %d\n", - cs->hw.sedl.cfg_reg, - cs->hw.sedl.cfg_reg + bytecnt, - cs->irq); - - cs->BC_Read_Reg = &ReadHSCX; - cs->BC_Write_Reg = &WriteHSCX; - cs->BC_Send_Data = &hscx_fill_fifo; - cs->cardmsg = &Sedl_card_msg; - -/* - * testing ISA and PCMCIA Cards for IPAC, default is ISAC - * do not test for PCI card, because ports are different - * and PCI card uses only IPAC (for the moment) - */ - if (cs->hw.sedl.bus != SEDL_BUS_PCI) { - val = readreg(cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_ADR, - cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC, IPAC_ID); - printk(KERN_DEBUG "Sedlbauer: testing IPAC version %x\n", val); - if ((val == 1) || (val == 2)) { - /* IPAC */ - cs->subtyp = SEDL_SPEED_WIN2_PC104; - if (cs->hw.sedl.bus == SEDL_BUS_PCMCIA) { - cs->subtyp = SEDL_SPEED_STAR2; - } - cs->hw.sedl.chip = SEDL_CHIP_IPAC; - } else { - /* ISAC_HSCX oder ISAC_ISAR */ - if (cs->hw.sedl.chip == SEDL_CHIP_TEST) { - cs->hw.sedl.chip = SEDL_CHIP_ISAC_HSCX; - } - } - } - -/* - * hw.sedl.chip is now properly set - */ - printk(KERN_INFO "Sedlbauer: %s detected\n", - Sedlbauer_Types[cs->subtyp]); - - setup_isac(cs); - if (cs->hw.sedl.chip == SEDL_CHIP_IPAC) { - if (cs->hw.sedl.bus == SEDL_BUS_PCI) { - cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_ADR; - cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_IPAC; - cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_IPAC; - } else { - cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_ADR; - cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC; - cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC; - } - test_and_set_bit(HW_IPAC, &cs->HW_Flags); - cs->readisac = &ReadISAC_IPAC; - cs->writeisac = &WriteISAC_IPAC; - cs->readisacfifo = &ReadISACfifo_IPAC; - cs->writeisacfifo = &WriteISACfifo_IPAC; - cs->irq_func = &sedlbauer_interrupt_ipac; - val = readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_ID); - printk(KERN_INFO "Sedlbauer: IPAC version %x\n", val); - } else { - /* ISAC_HSCX oder ISAC_ISAR */ - cs->readisac = &ReadISAC; - cs->writeisac = &WriteISAC; - cs->readisacfifo = &ReadISACfifo; - cs->writeisacfifo = &WriteISACfifo; - if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) { - if (cs->hw.sedl.bus == SEDL_BUS_PCI) { - cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + - SEDL_ISAR_PCI_ADR; - cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + - SEDL_ISAR_PCI_ISAC; - cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + - SEDL_ISAR_PCI_ISAR; - } else { - cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + - SEDL_ISAR_ISA_ADR; - cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + - SEDL_ISAR_ISA_ISAC; - cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + - SEDL_ISAR_ISA_ISAR; - cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg + - SEDL_ISAR_ISA_ISAR_RESET_ON; - cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + - SEDL_ISAR_ISA_ISAR_RESET_OFF; - } - cs->bcs[0].hw.isar.reg = &cs->hw.sedl.isar; - cs->bcs[1].hw.isar.reg = &cs->hw.sedl.isar; - test_and_set_bit(HW_ISAR, &cs->HW_Flags); - cs->irq_func = &sedlbauer_interrupt_isar; - cs->auxcmd = &isar_auxcmd; - ISACVersion(cs, "Sedlbauer:"); - cs->BC_Read_Reg = &ReadISAR; - cs->BC_Write_Reg = &WriteISAR; - cs->BC_Send_Data = &isar_fill_fifo; - bytecnt = 3; - while (bytecnt) { - ver = ISARVersion(cs, "Sedlbauer:"); - if (ver < 0) - printk(KERN_WARNING - "Sedlbauer: wrong ISAR version (ret = %d)\n", ver); - else - break; - reset_sedlbauer(cs); - bytecnt--; - } - if (!bytecnt) { - release_io_sedlbauer(cs); - return (0); - } - } else { - if (cs->hw.sedl.bus == SEDL_BUS_PCMCIA) { - cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_ADR; - cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_ISAC; - cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_HSCX; - cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_RESET; - cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_RESET; - cs->irq_flags |= IRQF_SHARED; - } else { - cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_ADR; - cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_ISAC; - cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_HSCX; - cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_RESET_ON; - cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_RESET_OFF; - } - cs->irq_func = &sedlbauer_interrupt; - ISACVersion(cs, "Sedlbauer:"); - - if (HscxVersion(cs, "Sedlbauer:")) { - printk(KERN_WARNING - "Sedlbauer: wrong HSCX versions check IO address\n"); - release_io_sedlbauer(cs); - return (0); - } - } - } - return (1); -} diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c deleted file mode 100644 index 92ef62d4caf4..000000000000 --- a/drivers/isdn/hisax/sedlbauer_cs.c +++ /dev/null @@ -1,209 +0,0 @@ -/*====================================================================== - - A Sedlbauer PCMCIA client driver - - This driver is for the Sedlbauer Speed Star and Speed Star II, - which are ISDN PCMCIA Cards. - - The contents of this file are subject to the Mozilla Public - License Version 1.1 (the "License"); you may not use this file - except in compliance with the License. You may obtain a copy of - the License at http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS - IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - implied. See the License for the specific language governing - rights and limitations under the License. - - The initial developer of the original code is David A. Hinds - <dahinds@users.sourceforge.net>. Portions created by David A. Hinds - are Copyright (C) 1999 David A. Hinds. All Rights Reserved. - - Modifications from dummy_cs.c are Copyright (C) 1999-2001 Marcus Niemann - <maniemann@users.sourceforge.net>. All Rights Reserved. - - Alternatively, the contents of this file may be used under the - terms of the GNU General Public License version 2 (the "GPL"), in - which case the provisions of the GPL are applicable instead of the - above. If you wish to allow the use of your version of this file - only under the terms of the GPL and not to allow others to use - your version of this file under the MPL, indicate your decision - by deleting the provisions above and replace them with the notice - and other provisions required by the GPL. If you do not delete - the provisions above, a recipient may use your version of this - file under either the MPL or the GPL. - - ======================================================================*/ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/ptrace.h> -#include <linux/slab.h> -#include <linux/string.h> -#include <linux/timer.h> -#include <linux/ioport.h> -#include <asm/io.h> - -#include <pcmcia/cistpl.h> -#include <pcmcia/cisreg.h> -#include <pcmcia/ds.h> -#include "hisax_cfg.h" - -MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Sedlbauer cards"); -MODULE_AUTHOR("Marcus Niemann"); -MODULE_LICENSE("Dual MPL/GPL"); - - -/*====================================================================*/ - -/* Parameters that can be set with 'insmod' */ - -static int protocol = 2; /* EURO-ISDN Default */ -module_param(protocol, int, 0); - -static int sedlbauer_config(struct pcmcia_device *link); -static void sedlbauer_release(struct pcmcia_device *link); - -static void sedlbauer_detach(struct pcmcia_device *p_dev); - -typedef struct local_info_t { - struct pcmcia_device *p_dev; - int stop; - int cardnr; -} local_info_t; - -static int sedlbauer_probe(struct pcmcia_device *link) -{ - local_info_t *local; - - dev_dbg(&link->dev, "sedlbauer_attach()\n"); - - /* Allocate space for private device-specific data */ - local = kzalloc(sizeof(local_info_t), GFP_KERNEL); - if (!local) return -ENOMEM; - local->cardnr = -1; - - local->p_dev = link; - link->priv = local; - - return sedlbauer_config(link); -} /* sedlbauer_attach */ - -static void sedlbauer_detach(struct pcmcia_device *link) -{ - dev_dbg(&link->dev, "sedlbauer_detach(0x%p)\n", link); - - ((local_info_t *)link->priv)->stop = 1; - sedlbauer_release(link); - - /* This points to the parent local_info_t struct */ - kfree(link->priv); -} /* sedlbauer_detach */ - -static int sedlbauer_config_check(struct pcmcia_device *p_dev, void *priv_data) -{ - if (p_dev->config_index == 0) - return -EINVAL; - - p_dev->io_lines = 3; - return pcmcia_request_io(p_dev); -} - -static int sedlbauer_config(struct pcmcia_device *link) -{ - int ret; - IsdnCard_t icard; - - dev_dbg(&link->dev, "sedlbauer_config(0x%p)\n", link); - - link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_CHECK_VCC | - CONF_AUTO_SET_VPP | CONF_AUTO_AUDIO | CONF_AUTO_SET_IO; - - ret = pcmcia_loop_config(link, sedlbauer_config_check, NULL); - if (ret) - goto failed; - - ret = pcmcia_enable_device(link); - if (ret) - goto failed; - - icard.para[0] = link->irq; - icard.para[1] = link->resource[0]->start; - icard.protocol = protocol; - icard.typ = ISDN_CTYPE_SEDLBAUER_PCMCIA; - - ret = hisax_init_pcmcia(link, - &(((local_info_t *)link->priv)->stop), &icard); - if (ret < 0) { - printk(KERN_ERR "sedlbauer_cs: failed to initialize SEDLBAUER PCMCIA %d with %pR\n", - ret, link->resource[0]); - sedlbauer_release(link); - return -ENODEV; - } else - ((local_info_t *)link->priv)->cardnr = ret; - - return 0; - -failed: - sedlbauer_release(link); - return -ENODEV; - -} /* sedlbauer_config */ - -static void sedlbauer_release(struct pcmcia_device *link) -{ - local_info_t *local = link->priv; - dev_dbg(&link->dev, "sedlbauer_release(0x%p)\n", link); - - if (local) { - if (local->cardnr >= 0) { - /* no unregister function with hisax */ - HiSax_closecard(local->cardnr); - } - } - - pcmcia_disable_device(link); -} /* sedlbauer_release */ - -static int sedlbauer_suspend(struct pcmcia_device *link) -{ - local_info_t *dev = link->priv; - - dev->stop = 1; - - return 0; -} - -static int sedlbauer_resume(struct pcmcia_device *link) -{ - local_info_t *dev = link->priv; - - dev->stop = 0; - - return 0; -} - - -static const struct pcmcia_device_id sedlbauer_ids[] = { - PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "speed star II", "V 3.1", 0x81fb79f5, 0xf3612e1d, 0x6b95c78a), - PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "ISDN-Adapter", "4D67", 0x81fb79f5, 0xe4e9bc12, 0x397b7e90), - PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "ISDN-Adapter", "4D98", 0x81fb79f5, 0xe4e9bc12, 0x2e5c7fce), - PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "ISDN-Adapter", " (C) 93-94 VK", 0x81fb79f5, 0xe4e9bc12, 0x8db143fe), - PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "ISDN-Adapter", " (c) 93-95 VK", 0x81fb79f5, 0xe4e9bc12, 0xb391ab4c), - PCMCIA_DEVICE_PROD_ID12("HST High Soft Tech GmbH", "Saphir II B", 0xd79e0b84, 0x21d083ae), -/* PCMCIA_DEVICE_PROD_ID1234("SEDLBAUER", 0x81fb79f5), */ /* too generic*/ - PCMCIA_DEVICE_NULL -}; -MODULE_DEVICE_TABLE(pcmcia, sedlbauer_ids); - -static struct pcmcia_driver sedlbauer_driver = { - .owner = THIS_MODULE, - .name = "sedlbauer_cs", - .probe = sedlbauer_probe, - .remove = sedlbauer_detach, - .id_table = sedlbauer_ids, - .suspend = sedlbauer_suspend, - .resume = sedlbauer_resume, -}; -module_pcmcia_driver(sedlbauer_driver); diff --git a/drivers/isdn/hisax/sportster.c b/drivers/isdn/hisax/sportster.c deleted file mode 100644 index 18cee6360d0a..000000000000 --- a/drivers/isdn/hisax/sportster.c +++ /dev/null @@ -1,267 +0,0 @@ -/* $Id: sportster.c,v 1.16.2.4 2004/01/13 23:48:39 keil Exp $ - * - * low level stuff for USR Sportster internal TA - * - * Author Karsten Keil - * Copyright by Karsten Keil <keil@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * Thanks to Christian "naddy" Weisgerber (3Com, US Robotics) for documentation - * - * - */ -#include <linux/init.h> -#include "hisax.h" -#include "isac.h" -#include "hscx.h" -#include "isdnl1.h" - -static const char *sportster_revision = "$Revision: 1.16.2.4 $"; - -#define byteout(addr, val) outb(val, addr) -#define bytein(addr) inb(addr) - -#define SPORTSTER_ISAC 0xC000 -#define SPORTSTER_HSCXA 0x0000 -#define SPORTSTER_HSCXB 0x4000 -#define SPORTSTER_RES_IRQ 0x8000 -#define SPORTSTER_RESET 0x80 -#define SPORTSTER_INTE 0x40 - -static inline int -calc_off(unsigned int base, unsigned int off) -{ - return (base + ((off & 0xfc) << 8) + ((off & 3) << 1)); -} - -static inline void -read_fifo(unsigned int adr, u_char *data, int size) -{ - insb(adr, data, size); -} - -static void -write_fifo(unsigned int adr, u_char *data, int size) -{ - outsb(adr, data, size); -} - -/* Interface functions */ - -static u_char -ReadISAC(struct IsdnCardState *cs, u_char offset) -{ - return (bytein(calc_off(cs->hw.spt.isac, offset))); -} - -static void -WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value) -{ - byteout(calc_off(cs->hw.spt.isac, offset), value); -} - -static void -ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - read_fifo(cs->hw.spt.isac, data, size); -} - -static void -WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - write_fifo(cs->hw.spt.isac, data, size); -} - -static u_char -ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset) -{ - return (bytein(calc_off(cs->hw.spt.hscx[hscx], offset))); -} - -static void -WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) -{ - byteout(calc_off(cs->hw.spt.hscx[hscx], offset), value); -} - -/* - * fast interrupt HSCX stuff goes here - */ - -#define READHSCX(cs, nr, reg) bytein(calc_off(cs->hw.spt.hscx[nr], reg)) -#define WRITEHSCX(cs, nr, reg, data) byteout(calc_off(cs->hw.spt.hscx[nr], reg), data) -#define READHSCXFIFO(cs, nr, ptr, cnt) read_fifo(cs->hw.spt.hscx[nr], ptr, cnt) -#define WRITEHSCXFIFO(cs, nr, ptr, cnt) write_fifo(cs->hw.spt.hscx[nr], ptr, cnt) - -#include "hscx_irq.c" - -static irqreturn_t -sportster_interrupt(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - u_char val; - u_long flags; - - spin_lock_irqsave(&cs->lock, flags); - val = READHSCX(cs, 1, HSCX_ISTA); -Start_HSCX: - if (val) - hscx_int_main(cs, val); - val = ReadISAC(cs, ISAC_ISTA); -Start_ISAC: - if (val) - isac_interrupt(cs, val); - val = READHSCX(cs, 1, HSCX_ISTA); - if (val) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "HSCX IntStat after IntRoutine"); - goto Start_HSCX; - } - val = ReadISAC(cs, ISAC_ISTA); - if (val) { - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "ISAC IntStat after IntRoutine"); - goto Start_ISAC; - } - /* get a new irq impulse if there any pending */ - bytein(cs->hw.spt.cfg_reg + SPORTSTER_RES_IRQ + 1); - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -static void -release_io_sportster(struct IsdnCardState *cs) -{ - int i, adr; - - byteout(cs->hw.spt.cfg_reg + SPORTSTER_RES_IRQ, 0); - for (i = 0; i < 64; i++) { - adr = cs->hw.spt.cfg_reg + i * 1024; - release_region(adr, 8); - } -} - -static void -reset_sportster(struct IsdnCardState *cs) -{ - cs->hw.spt.res_irq |= SPORTSTER_RESET; /* Reset On */ - byteout(cs->hw.spt.cfg_reg + SPORTSTER_RES_IRQ, cs->hw.spt.res_irq); - mdelay(10); - cs->hw.spt.res_irq &= ~SPORTSTER_RESET; /* Reset Off */ - byteout(cs->hw.spt.cfg_reg + SPORTSTER_RES_IRQ, cs->hw.spt.res_irq); - mdelay(10); -} - -static int -Sportster_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - u_long flags; - - switch (mt) { - case CARD_RESET: - spin_lock_irqsave(&cs->lock, flags); - reset_sportster(cs); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_RELEASE: - release_io_sportster(cs); - return (0); - case CARD_INIT: - spin_lock_irqsave(&cs->lock, flags); - reset_sportster(cs); - inithscxisac(cs, 1); - cs->hw.spt.res_irq |= SPORTSTER_INTE; /* IRQ On */ - byteout(cs->hw.spt.cfg_reg + SPORTSTER_RES_IRQ, cs->hw.spt.res_irq); - inithscxisac(cs, 2); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_TEST: - return (0); - } - return (0); -} - -static int get_io_range(struct IsdnCardState *cs) -{ - int i, j, adr; - - for (i = 0; i < 64; i++) { - adr = cs->hw.spt.cfg_reg + i * 1024; - if (!request_region(adr, 8, "sportster")) { - printk(KERN_WARNING "HiSax: USR Sportster config port " - "%x-%x already in use\n", - adr, adr + 8); - break; - } - } - if (i == 64) - return (1); - else { - for (j = 0; j < i; j++) { - adr = cs->hw.spt.cfg_reg + j * 1024; - release_region(adr, 8); - } - return (0); - } -} - -int setup_sportster(struct IsdnCard *card) -{ - struct IsdnCardState *cs = card->cs; - char tmp[64]; - - strcpy(tmp, sportster_revision); - printk(KERN_INFO "HiSax: USR Sportster driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_SPORTSTER) - return (0); - - cs->hw.spt.cfg_reg = card->para[1]; - cs->irq = card->para[0]; - if (!get_io_range(cs)) - return (0); - cs->hw.spt.isac = cs->hw.spt.cfg_reg + SPORTSTER_ISAC; - cs->hw.spt.hscx[0] = cs->hw.spt.cfg_reg + SPORTSTER_HSCXA; - cs->hw.spt.hscx[1] = cs->hw.spt.cfg_reg + SPORTSTER_HSCXB; - - switch (cs->irq) { - case 5: cs->hw.spt.res_irq = 1; - break; - case 7: cs->hw.spt.res_irq = 2; - break; - case 10:cs->hw.spt.res_irq = 3; - break; - case 11:cs->hw.spt.res_irq = 4; - break; - case 12:cs->hw.spt.res_irq = 5; - break; - case 14:cs->hw.spt.res_irq = 6; - break; - case 15:cs->hw.spt.res_irq = 7; - break; - default:release_io_sportster(cs); - printk(KERN_WARNING "Sportster: wrong IRQ\n"); - return (0); - } - printk(KERN_INFO "HiSax: USR Sportster config irq:%d cfg:0x%X\n", - cs->irq, cs->hw.spt.cfg_reg); - setup_isac(cs); - cs->readisac = &ReadISAC; - cs->writeisac = &WriteISAC; - cs->readisacfifo = &ReadISACfifo; - cs->writeisacfifo = &WriteISACfifo; - cs->BC_Read_Reg = &ReadHSCX; - cs->BC_Write_Reg = &WriteHSCX; - cs->BC_Send_Data = &hscx_fill_fifo; - cs->cardmsg = &Sportster_card_msg; - cs->irq_func = &sportster_interrupt; - ISACVersion(cs, "Sportster:"); - if (HscxVersion(cs, "Sportster:")) { - printk(KERN_WARNING - "Sportster: wrong HSCX versions check IO address\n"); - release_io_sportster(cs); - return (0); - } - return (1); -} diff --git a/drivers/isdn/hisax/st5481.h b/drivers/isdn/hisax/st5481.h deleted file mode 100644 index b421b86ca7da..000000000000 --- a/drivers/isdn/hisax/st5481.h +++ /dev/null @@ -1,529 +0,0 @@ -/* - * Driver for ST5481 USB ISDN modem - * - * Author Frode Isaksen - * Copyright 2001 by Frode Isaksen <fisaksen@bewan.com> - * 2001 by Kai Germaschewski <kai.germaschewski@gmx.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#ifndef _ST5481_H_ -#define _ST5481_H_ - - -// USB IDs, the Product Id is in the range 0x4810-0x481F - -#define ST_VENDOR_ID 0x0483 -#define ST5481_PRODUCT_ID 0x4810 -#define ST5481_PRODUCT_ID_MASK 0xFFF0 - -// ST5481 endpoints when using alternative setting 3 (2B+D). -// To get the endpoint address, OR with 0x80 for IN endpoints. - -#define EP_CTRL 0x00U /* Control endpoint */ -#define EP_INT 0x01U /* Interrupt endpoint */ -#define EP_B1_OUT 0x02U /* B1 channel out */ -#define EP_B1_IN 0x03U /* B1 channel in */ -#define EP_B2_OUT 0x04U /* B2 channel out */ -#define EP_B2_IN 0x05U /* B2 channel in */ -#define EP_D_OUT 0x06U /* D channel out */ -#define EP_D_IN 0x07U /* D channel in */ - -// Number of isochronous packets. With 20 packets we get -// 50 interrupts/sec for each endpoint. - -#define NUM_ISO_PACKETS_D 20 -#define NUM_ISO_PACKETS_B 20 - -// Size of each isochronous packet. -// In outgoing direction we need to match ISDN data rates: -// D: 2 bytes / msec -> 16 kbit / s -// B: 16 bytes / msec -> 64 kbit / s -#define SIZE_ISO_PACKETS_D_IN 16 -#define SIZE_ISO_PACKETS_D_OUT 2 -#define SIZE_ISO_PACKETS_B_IN 32 -#define SIZE_ISO_PACKETS_B_OUT 8 - -// If we overrun/underrun, we send one packet with +/- 2 bytes -#define B_FLOW_ADJUST 2 - -// Registers that are written using vendor specific device request -// on endpoint 0. - -#define LBA 0x02 /* S loopback */ -#define SET_DEFAULT 0x06 /* Soft reset */ -#define LBB 0x1D /* S maintenance loopback */ -#define STT 0x1e /* S force transmission signals */ -#define SDA_MIN 0x20 /* SDA-sin minimal value */ -#define SDA_MAX 0x21 /* SDA-sin maximal value */ -#define SDELAY_VALUE 0x22 /* Delay between Tx and Rx clock */ -#define IN_D_COUNTER 0x36 /* D receive channel fifo counter */ -#define OUT_D_COUNTER 0x37 /* D transmit channel fifo counter */ -#define IN_B1_COUNTER 0x38 /* B1 receive channel fifo counter */ -#define OUT_B1_COUNTER 0x39 /* B1 transmit channel fifo counter */ -#define IN_B2_COUNTER 0x3a /* B2 receive channel fifo counter */ -#define OUT_B2_COUNTER 0x3b /* B2 transmit channel fifo counter */ -#define FFCTRL_IN_D 0x3C /* D receive channel fifo threshold low */ -#define FFCTRH_IN_D 0x3D /* D receive channel fifo threshold high */ -#define FFCTRL_OUT_D 0x3E /* D transmit channel fifo threshold low */ -#define FFCTRH_OUT_D 0x3F /* D transmit channel fifo threshold high */ -#define FFCTRL_IN_B1 0x40 /* B1 receive channel fifo threshold low */ -#define FFCTRH_IN_B1 0x41 /* B1 receive channel fifo threshold high */ -#define FFCTRL_OUT_B1 0x42 /* B1 transmit channel fifo threshold low */ -#define FFCTRH_OUT_B1 0x43 /* B1 transmit channel fifo threshold high */ -#define FFCTRL_IN_B2 0x44 /* B2 receive channel fifo threshold low */ -#define FFCTRH_IN_B2 0x45 /* B2 receive channel fifo threshold high */ -#define FFCTRL_OUT_B2 0x46 /* B2 transmit channel fifo threshold low */ -#define FFCTRH_OUT_B2 0x47 /* B2 transmit channel fifo threshold high */ -#define MPMSK 0x4A /* Multi purpose interrupt MASK register */ -#define FFMSK_D 0x4c /* D fifo interrupt MASK register */ -#define FFMSK_B1 0x4e /* B1 fifo interrupt MASK register */ -#define FFMSK_B2 0x50 /* B2 fifo interrupt MASK register */ -#define GPIO_DIR 0x52 /* GPIO pins direction registers */ -#define GPIO_OUT 0x53 /* GPIO pins output register */ -#define GPIO_IN 0x54 /* GPIO pins input register */ -#define TXCI 0x56 /* CI command to be transmitted */ - - -// Format of the interrupt packet received on endpoint 1: -// -// +--------+--------+--------+--------+--------+--------+ -// !MPINT !FFINT_D !FFINT_B1!FFINT_B2!CCIST !GPIO_INT! -// +--------+--------+--------+--------+--------+--------+ - -// Offsets in the interrupt packet - -#define MPINT 0 -#define FFINT_D 1 -#define FFINT_B1 2 -#define FFINT_B2 3 -#define CCIST 4 -#define GPIO_INT 5 -#define INT_PKT_SIZE 6 - -// MPINT -#define LSD_INT 0x80 /* S line activity detected */ -#define RXCI_INT 0x40 /* Indicate primitive arrived */ -#define DEN_INT 0x20 /* Signal enabling data out of D Tx fifo */ -#define DCOLL_INT 0x10 /* D channel collision */ -#define AMIVN_INT 0x04 /* AMI violation number reached 2 */ -#define INFOI_INT 0x04 /* INFOi changed */ -#define DRXON_INT 0x02 /* Reception channel active */ -#define GPCHG_INT 0x01 /* GPIO pin value changed */ - -// FFINT_x -#define IN_OVERRUN 0x80 /* In fifo overrun */ -#define OUT_UNDERRUN 0x40 /* Out fifo underrun */ -#define IN_UP 0x20 /* In fifo thresholdh up-crossed */ -#define IN_DOWN 0x10 /* In fifo thresholdl down-crossed */ -#define OUT_UP 0x08 /* Out fifo thresholdh up-crossed */ -#define OUT_DOWN 0x04 /* Out fifo thresholdl down-crossed */ -#define IN_COUNTER_ZEROED 0x02 /* In down-counter reached 0 */ -#define OUT_COUNTER_ZEROED 0x01 /* Out down-counter reached 0 */ - -#define ANY_REC_INT (IN_OVERRUN + IN_UP + IN_DOWN + IN_COUNTER_ZEROED) -#define ANY_XMIT_INT (OUT_UNDERRUN + OUT_UP + OUT_DOWN + OUT_COUNTER_ZEROED) - - -// Level 1 commands that are sent using the TXCI device request -#define ST5481_CMD_DR 0x0 /* Deactivation Request */ -#define ST5481_CMD_RES 0x1 /* state machine RESet */ -#define ST5481_CMD_TM1 0x2 /* Test Mode 1 */ -#define ST5481_CMD_TM2 0x3 /* Test Mode 2 */ -#define ST5481_CMD_PUP 0x7 /* Power UP */ -#define ST5481_CMD_AR8 0x8 /* Activation Request class 1 */ -#define ST5481_CMD_AR10 0x9 /* Activation Request class 2 */ -#define ST5481_CMD_ARL 0xA /* Activation Request Loopback */ -#define ST5481_CMD_PDN 0xF /* Power DoWn */ - -// Turn on/off the LEDs using the GPIO device request. -// To use the B LEDs, number_of_leds must be set to 4 -#define B1_LED 0x10U -#define B2_LED 0x20U -#define GREEN_LED 0x40U -#define RED_LED 0x80U - -// D channel out states -enum { - ST_DOUT_NONE, - - ST_DOUT_SHORT_INIT, - ST_DOUT_SHORT_WAIT_DEN, - - ST_DOUT_LONG_INIT, - ST_DOUT_LONG_WAIT_DEN, - ST_DOUT_NORMAL, - - ST_DOUT_WAIT_FOR_UNDERRUN, - ST_DOUT_WAIT_FOR_NOT_BUSY, - ST_DOUT_WAIT_FOR_STOP, - ST_DOUT_WAIT_FOR_RESET, -}; - -#define DOUT_STATE_COUNT (ST_DOUT_WAIT_FOR_RESET + 1) - -// D channel out events -enum { - EV_DOUT_START_XMIT, - EV_DOUT_COMPLETE, - EV_DOUT_DEN, - EV_DOUT_RESETED, - EV_DOUT_STOPPED, - EV_DOUT_COLL, - EV_DOUT_UNDERRUN, -}; - -#define DOUT_EVENT_COUNT (EV_DOUT_UNDERRUN + 1) - -// ---------------------------------------------------------------------- - -enum { - ST_L1_F3, - ST_L1_F4, - ST_L1_F6, - ST_L1_F7, - ST_L1_F8, -}; - -#define L1_STATE_COUNT (ST_L1_F8 + 1) - -// The first 16 entries match the Level 1 indications that -// are found at offset 4 (CCIST) in the interrupt packet - -enum { - EV_IND_DP, // 0000 Deactivation Pending - EV_IND_1, // 0001 - EV_IND_2, // 0010 - EV_IND_3, // 0011 - EV_IND_RSY, // 0100 ReSYnchronizing - EV_IND_5, // 0101 - EV_IND_6, // 0110 - EV_IND_7, // 0111 - EV_IND_AP, // 1000 Activation Pending - EV_IND_9, // 1001 - EV_IND_10, // 1010 - EV_IND_11, // 1011 - EV_IND_AI8, // 1100 Activation Indication class 8 - EV_IND_AI10,// 1101 Activation Indication class 10 - EV_IND_AIL, // 1110 Activation Indication Loopback - EV_IND_DI, // 1111 Deactivation Indication - EV_PH_ACTIVATE_REQ, - EV_PH_DEACTIVATE_REQ, - EV_TIMER3, -}; - -#define L1_EVENT_COUNT (EV_TIMER3 + 1) - -#define ERR(format, arg...) \ - printk(KERN_ERR "%s:%s: " format "\n" , __FILE__, __func__ , ## arg) - -#define WARNING(format, arg...) \ - printk(KERN_WARNING "%s:%s: " format "\n" , __FILE__, __func__ , ## arg) - -#define INFO(format, arg...) \ - printk(KERN_INFO "%s:%s: " format "\n" , __FILE__, __func__ , ## arg) - -#include <linux/isdn/hdlc.h> -#include "fsm.h" -#include "hisax_if.h" -#include <linux/skbuff.h> - -/* ====================================================================== - * FIFO handling - */ - -/* Generic FIFO structure */ -struct fifo { - u_char r, w, count, size; - spinlock_t lock; -}; - -/* - * Init an FIFO - */ -static inline void fifo_init(struct fifo *fifo, int size) -{ - fifo->r = fifo->w = fifo->count = 0; - fifo->size = size; - spin_lock_init(&fifo->lock); -} - -/* - * Add an entry to the FIFO - */ -static inline int fifo_add(struct fifo *fifo) -{ - unsigned long flags; - int index; - - if (!fifo) { - return -1; - } - - spin_lock_irqsave(&fifo->lock, flags); - if (fifo->count == fifo->size) { - // FIFO full - index = -1; - } else { - // Return index where to get the next data to add to the FIFO - index = fifo->w++ & (fifo->size - 1); - fifo->count++; - } - spin_unlock_irqrestore(&fifo->lock, flags); - return index; -} - -/* - * Remove an entry from the FIFO with the index returned. - */ -static inline int fifo_remove(struct fifo *fifo) -{ - unsigned long flags; - int index; - - if (!fifo) { - return -1; - } - - spin_lock_irqsave(&fifo->lock, flags); - if (!fifo->count) { - // FIFO empty - index = -1; - } else { - // Return index where to get the next data from the FIFO - index = fifo->r++ & (fifo->size - 1); - fifo->count--; - } - spin_unlock_irqrestore(&fifo->lock, flags); - - return index; -} - -/* ====================================================================== - * control pipe - */ -typedef void (*ctrl_complete_t)(void *); - -typedef struct ctrl_msg { - struct usb_ctrlrequest dr; - ctrl_complete_t complete; - void *context; -} ctrl_msg; - -/* FIFO of ctrl messages waiting to be sent */ -#define MAX_EP0_MSG 16 -struct ctrl_msg_fifo { - struct fifo f; - struct ctrl_msg data[MAX_EP0_MSG]; -}; - -#define MAX_DFRAME_LEN_L1 300 -#define HSCX_BUFMAX 4096 - -struct st5481_ctrl { - struct ctrl_msg_fifo msg_fifo; - unsigned long busy; - struct urb *urb; -}; - -struct st5481_intr { - // struct evt_fifo evt_fifo; - struct urb *urb; -}; - -struct st5481_d_out { - struct isdnhdlc_vars hdlc_state; - struct urb *urb[2]; /* double buffering */ - unsigned long busy; - struct sk_buff *tx_skb; - struct FsmInst fsm; -}; - -struct st5481_b_out { - struct isdnhdlc_vars hdlc_state; - struct urb *urb[2]; /* double buffering */ - u_char flow_event; - u_long busy; - struct sk_buff *tx_skb; -}; - -struct st5481_in { - struct isdnhdlc_vars hdlc_state; - struct urb *urb[2]; /* double buffering */ - int mode; - int bufsize; - unsigned int num_packets; - unsigned int packet_size; - unsigned char ep, counter; - unsigned char *rcvbuf; - struct st5481_adapter *adapter; - struct hisax_if *hisax_if; -}; - -int st5481_setup_in(struct st5481_in *in); -void st5481_release_in(struct st5481_in *in); -void st5481_in_mode(struct st5481_in *in, int mode); - -struct st5481_bcs { - struct hisax_b_if b_if; - struct st5481_adapter *adapter; - struct st5481_in b_in; - struct st5481_b_out b_out; - int channel; - int mode; -}; - -struct st5481_adapter { - int number_of_leds; - struct usb_device *usb_dev; - struct hisax_d_if hisax_d_if; - - struct st5481_ctrl ctrl; - struct st5481_intr intr; - struct st5481_in d_in; - struct st5481_d_out d_out; - - unsigned char leds; - unsigned int led_counter; - - unsigned long event; - - struct FsmInst l1m; - struct FsmTimer timer; - - struct st5481_bcs bcs[2]; -}; - -#define TIMER3_VALUE 7000 - -/* ====================================================================== - * - */ - -/* - * Submit an URB with error reporting. This is a macro so - * the __func__ returns the caller function name. - */ -#define SUBMIT_URB(urb, mem_flags) \ - ({ \ - int status; \ - if ((status = usb_submit_urb(urb, mem_flags)) < 0) { \ - WARNING("usb_submit_urb failed,status=%d", status); \ - } \ - status; \ - }) - -/* - * USB double buffering, return the URB index (0 or 1). - */ -static inline int get_buf_nr(struct urb *urbs[], struct urb *urb) -{ - return (urbs[0] == urb ? 0 : 1); -} - -/* ---------------------------------------------------------------------- */ - -/* B Channel */ - -int st5481_setup_b(struct st5481_bcs *bcs); -void st5481_release_b(struct st5481_bcs *bcs); -void st5481_d_l2l1(struct hisax_if *hisax_d_if, int pr, void *arg); - -/* D Channel */ - -int st5481_setup_d(struct st5481_adapter *adapter); -void st5481_release_d(struct st5481_adapter *adapter); -void st5481_b_l2l1(struct hisax_if *b_if, int pr, void *arg); -int st5481_d_init(void); -void st5481_d_exit(void); - -/* USB */ -void st5481_ph_command(struct st5481_adapter *adapter, unsigned int command); -int st5481_setup_isocpipes(struct urb *urb[2], struct usb_device *dev, - unsigned int pipe, int num_packets, - int packet_size, int buf_size, - usb_complete_t complete, void *context); -void st5481_release_isocpipes(struct urb *urb[2]); - -void st5481_usb_pipe_reset(struct st5481_adapter *adapter, - u_char pipe, ctrl_complete_t complete, void *context); -void st5481_usb_device_ctrl_msg(struct st5481_adapter *adapter, - u8 request, u16 value, - ctrl_complete_t complete, void *context); -int st5481_setup_usb(struct st5481_adapter *adapter); -void st5481_release_usb(struct st5481_adapter *adapter); -void st5481_start(struct st5481_adapter *adapter); -void st5481_stop(struct st5481_adapter *adapter); - -// ---------------------------------------------------------------------- -// debugging macros - -#define __debug_variable st5481_debug -#include "hisax_debug.h" - -extern int st5481_debug; - -#ifdef CONFIG_HISAX_DEBUG - -#define DBG_ISO_PACKET(level, urb) \ - if (level & __debug_variable) dump_iso_packet(__func__, urb) - -static void __attribute__((unused)) -dump_iso_packet(const char *name, struct urb *urb) -{ - int i, j; - int len, ofs; - u_char *data; - - printk(KERN_DEBUG "%s: packets=%d,errors=%d\n", - name, urb->number_of_packets, urb->error_count); - for (i = 0; i < urb->number_of_packets; ++i) { - if (urb->pipe & USB_DIR_IN) { - len = urb->iso_frame_desc[i].actual_length; - } else { - len = urb->iso_frame_desc[i].length; - } - ofs = urb->iso_frame_desc[i].offset; - printk(KERN_DEBUG "len=%.2d,ofs=%.3d ", len, ofs); - if (len) { - data = urb->transfer_buffer + ofs; - for (j = 0; j < len; j++) { - printk("%.2x", data[j]); - } - } - printk("\n"); - } -} - -static inline const char *ST5481_CMD_string(int evt) -{ - static char s[16]; - - switch (evt) { - case ST5481_CMD_DR: return "DR"; - case ST5481_CMD_RES: return "RES"; - case ST5481_CMD_TM1: return "TM1"; - case ST5481_CMD_TM2: return "TM2"; - case ST5481_CMD_PUP: return "PUP"; - case ST5481_CMD_AR8: return "AR8"; - case ST5481_CMD_AR10: return "AR10"; - case ST5481_CMD_ARL: return "ARL"; - case ST5481_CMD_PDN: return "PDN"; - } - - sprintf(s, "0x%x", evt); - return s; -} - -#else - -#define DBG_ISO_PACKET(level, urb) do {} while (0) - -#endif - - - -#endif diff --git a/drivers/isdn/hisax/st5481_b.c b/drivers/isdn/hisax/st5481_b.c deleted file mode 100644 index f64a36007800..000000000000 --- a/drivers/isdn/hisax/st5481_b.c +++ /dev/null @@ -1,380 +0,0 @@ -/* - * Driver for ST5481 USB ISDN modem - * - * Author Frode Isaksen - * Copyright 2001 by Frode Isaksen <fisaksen@bewan.com> - * 2001 by Kai Germaschewski <kai.germaschewski@gmx.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#include <linux/init.h> -#include <linux/gfp.h> -#include <linux/usb.h> -#include <linux/netdevice.h> -#include <linux/bitrev.h> -#include "st5481.h" - -static inline void B_L1L2(struct st5481_bcs *bcs, int pr, void *arg) -{ - struct hisax_if *ifc = (struct hisax_if *) &bcs->b_if; - - ifc->l1l2(ifc, pr, arg); -} - -/* - * Encode and transmit next frame. - */ -static void usb_b_out(struct st5481_bcs *bcs, int buf_nr) -{ - struct st5481_b_out *b_out = &bcs->b_out; - struct st5481_adapter *adapter = bcs->adapter; - struct urb *urb; - unsigned int packet_size, offset; - int len, buf_size, bytes_sent; - int i; - struct sk_buff *skb; - - if (test_and_set_bit(buf_nr, &b_out->busy)) { - DBG(4, "ep %d urb %d busy", (bcs->channel + 1) * 2, buf_nr); - return; - } - urb = b_out->urb[buf_nr]; - - // Adjust isoc buffer size according to flow state - if (b_out->flow_event & (OUT_DOWN | OUT_UNDERRUN)) { - buf_size = NUM_ISO_PACKETS_B * SIZE_ISO_PACKETS_B_OUT + B_FLOW_ADJUST; - packet_size = SIZE_ISO_PACKETS_B_OUT + B_FLOW_ADJUST; - DBG(4, "B%d,adjust flow,add %d bytes", bcs->channel + 1, B_FLOW_ADJUST); - } else if (b_out->flow_event & OUT_UP) { - buf_size = NUM_ISO_PACKETS_B * SIZE_ISO_PACKETS_B_OUT - B_FLOW_ADJUST; - packet_size = SIZE_ISO_PACKETS_B_OUT - B_FLOW_ADJUST; - DBG(4, "B%d,adjust flow,remove %d bytes", bcs->channel + 1, B_FLOW_ADJUST); - } else { - buf_size = NUM_ISO_PACKETS_B * SIZE_ISO_PACKETS_B_OUT; - packet_size = 8; - } - b_out->flow_event = 0; - - len = 0; - while (len < buf_size) { - if ((skb = b_out->tx_skb)) { - DBG_SKB(0x100, skb); - DBG(4, "B%d,len=%d", bcs->channel + 1, skb->len); - - if (bcs->mode == L1_MODE_TRANS) { - bytes_sent = buf_size - len; - if (skb->len < bytes_sent) - bytes_sent = skb->len; - { /* swap tx bytes to get hearable audio data */ - register unsigned char *src = skb->data; - register unsigned char *dest = urb->transfer_buffer + len; - register unsigned int count; - for (count = 0; count < bytes_sent; count++) - *dest++ = bitrev8(*src++); - } - len += bytes_sent; - } else { - len += isdnhdlc_encode(&b_out->hdlc_state, - skb->data, skb->len, &bytes_sent, - urb->transfer_buffer + len, buf_size-len); - } - - skb_pull(skb, bytes_sent); - - if (!skb->len) { - // Frame sent - b_out->tx_skb = NULL; - B_L1L2(bcs, PH_DATA | CONFIRM, (void *)(unsigned long) skb->truesize); - dev_kfree_skb_any(skb); - -/* if (!(bcs->tx_skb = skb_dequeue(&bcs->sq))) { */ -/* st5481B_sched_event(bcs, B_XMTBUFREADY); */ -/* } */ - } - } else { - if (bcs->mode == L1_MODE_TRANS) { - memset(urb->transfer_buffer + len, 0xff, buf_size-len); - len = buf_size; - } else { - // Send flags - len += isdnhdlc_encode(&b_out->hdlc_state, - NULL, 0, &bytes_sent, - urb->transfer_buffer + len, buf_size-len); - } - } - } - - // Prepare the URB - for (i = 0, offset = 0; offset < len; i++) { - urb->iso_frame_desc[i].offset = offset; - urb->iso_frame_desc[i].length = packet_size; - offset += packet_size; - packet_size = SIZE_ISO_PACKETS_B_OUT; - } - urb->transfer_buffer_length = len; - urb->number_of_packets = i; - urb->dev = adapter->usb_dev; - - DBG_ISO_PACKET(0x200, urb); - - SUBMIT_URB(urb, GFP_NOIO); -} - -/* - * Start transferring (flags or data) on the B channel, since - * FIFO counters has been set to a non-zero value. - */ -static void st5481B_start_xfer(void *context) -{ - struct st5481_bcs *bcs = context; - - DBG(4, "B%d", bcs->channel + 1); - - // Start transmitting (flags or data) on B channel - - usb_b_out(bcs, 0); - usb_b_out(bcs, 1); -} - -/* - * If the adapter has only 2 LEDs, the green - * LED will blink with a rate depending - * on the number of channels opened. - */ -static void led_blink(struct st5481_adapter *adapter) -{ - u_char leds = adapter->leds; - - // 50 frames/sec for each channel - if (++adapter->led_counter % 50) { - return; - } - - if (adapter->led_counter % 100) { - leds |= GREEN_LED; - } else { - leds &= ~GREEN_LED; - } - - st5481_usb_device_ctrl_msg(adapter, GPIO_OUT, leds, NULL, NULL); -} - -static void usb_b_out_complete(struct urb *urb) -{ - struct st5481_bcs *bcs = urb->context; - struct st5481_b_out *b_out = &bcs->b_out; - struct st5481_adapter *adapter = bcs->adapter; - int buf_nr; - - buf_nr = get_buf_nr(b_out->urb, urb); - test_and_clear_bit(buf_nr, &b_out->busy); - - if (unlikely(urb->status < 0)) { - switch (urb->status) { - case -ENOENT: - case -ESHUTDOWN: - case -ECONNRESET: - DBG(4, "urb killed status %d", urb->status); - return; // Give up - default: - WARNING("urb status %d", urb->status); - if (b_out->busy == 0) { - st5481_usb_pipe_reset(adapter, (bcs->channel + 1) * 2 | USB_DIR_OUT, NULL, NULL); - } - break; - } - } - - usb_b_out(bcs, buf_nr); - - if (adapter->number_of_leds == 2) - led_blink(adapter); -} - -/* - * Start or stop the transfer on the B channel. - */ -static void st5481B_mode(struct st5481_bcs *bcs, int mode) -{ - struct st5481_b_out *b_out = &bcs->b_out; - struct st5481_adapter *adapter = bcs->adapter; - - DBG(4, "B%d,mode=%d", bcs->channel + 1, mode); - - if (bcs->mode == mode) - return; - - bcs->mode = mode; - - // Cancel all USB transfers on this B channel - usb_unlink_urb(b_out->urb[0]); - usb_unlink_urb(b_out->urb[1]); - b_out->busy = 0; - - st5481_in_mode(&bcs->b_in, mode); - if (bcs->mode != L1_MODE_NULL) { - // Open the B channel - if (bcs->mode != L1_MODE_TRANS) { - u32 features = HDLC_BITREVERSE; - if (bcs->mode == L1_MODE_HDLC_56K) - features |= HDLC_56KBIT; - isdnhdlc_out_init(&b_out->hdlc_state, features); - } - st5481_usb_pipe_reset(adapter, (bcs->channel + 1) * 2, NULL, NULL); - - // Enable B channel interrupts - st5481_usb_device_ctrl_msg(adapter, FFMSK_B1 + (bcs->channel * 2), - OUT_UP + OUT_DOWN + OUT_UNDERRUN, NULL, NULL); - - // Enable B channel FIFOs - st5481_usb_device_ctrl_msg(adapter, OUT_B1_COUNTER+(bcs->channel * 2), 32, st5481B_start_xfer, bcs); - if (adapter->number_of_leds == 4) { - if (bcs->channel == 0) { - adapter->leds |= B1_LED; - } else { - adapter->leds |= B2_LED; - } - } - } else { - // Disable B channel interrupts - st5481_usb_device_ctrl_msg(adapter, FFMSK_B1+(bcs->channel * 2), 0, NULL, NULL); - - // Disable B channel FIFOs - st5481_usb_device_ctrl_msg(adapter, OUT_B1_COUNTER+(bcs->channel * 2), 0, NULL, NULL); - - if (adapter->number_of_leds == 4) { - if (bcs->channel == 0) { - adapter->leds &= ~B1_LED; - } else { - adapter->leds &= ~B2_LED; - } - } else { - st5481_usb_device_ctrl_msg(adapter, GPIO_OUT, adapter->leds, NULL, NULL); - } - if (b_out->tx_skb) { - dev_kfree_skb_any(b_out->tx_skb); - b_out->tx_skb = NULL; - } - - } -} - -static int st5481_setup_b_out(struct st5481_bcs *bcs) -{ - struct usb_device *dev = bcs->adapter->usb_dev; - struct usb_interface *intf; - struct usb_host_interface *altsetting = NULL; - struct usb_host_endpoint *endpoint; - struct st5481_b_out *b_out = &bcs->b_out; - - DBG(4, ""); - - intf = usb_ifnum_to_if(dev, 0); - if (intf) - altsetting = usb_altnum_to_altsetting(intf, 3); - if (!altsetting) - return -ENXIO; - - // Allocate URBs and buffers for the B channel out - endpoint = &altsetting->endpoint[EP_B1_OUT - 1 + bcs->channel * 2]; - - DBG(4, "endpoint address=%02x,packet size=%d", - endpoint->desc.bEndpointAddress, le16_to_cpu(endpoint->desc.wMaxPacketSize)); - - // Allocate memory for 8000bytes/sec + extra bytes if underrun - return st5481_setup_isocpipes(b_out->urb, dev, - usb_sndisocpipe(dev, endpoint->desc.bEndpointAddress), - NUM_ISO_PACKETS_B, SIZE_ISO_PACKETS_B_OUT, - NUM_ISO_PACKETS_B * SIZE_ISO_PACKETS_B_OUT + B_FLOW_ADJUST, - usb_b_out_complete, bcs); -} - -static void st5481_release_b_out(struct st5481_bcs *bcs) -{ - struct st5481_b_out *b_out = &bcs->b_out; - - DBG(4, ""); - - st5481_release_isocpipes(b_out->urb); -} - -int st5481_setup_b(struct st5481_bcs *bcs) -{ - int retval; - - DBG(4, ""); - - retval = st5481_setup_b_out(bcs); - if (retval) - goto err; - bcs->b_in.bufsize = HSCX_BUFMAX; - bcs->b_in.num_packets = NUM_ISO_PACKETS_B; - bcs->b_in.packet_size = SIZE_ISO_PACKETS_B_IN; - bcs->b_in.ep = (bcs->channel ? EP_B2_IN : EP_B1_IN) | USB_DIR_IN; - bcs->b_in.counter = bcs->channel ? IN_B2_COUNTER : IN_B1_COUNTER; - bcs->b_in.adapter = bcs->adapter; - bcs->b_in.hisax_if = &bcs->b_if.ifc; - retval = st5481_setup_in(&bcs->b_in); - if (retval) - goto err_b_out; - - - return 0; - -err_b_out: - st5481_release_b_out(bcs); -err: - return retval; -} - -/* - * Release buffers and URBs for the B channels - */ -void st5481_release_b(struct st5481_bcs *bcs) -{ - DBG(4, ""); - - st5481_release_in(&bcs->b_in); - st5481_release_b_out(bcs); -} - -/* - * st5481_b_l2l1 is the entry point for upper layer routines that want to - * transmit on the B channel. PH_DATA | REQUEST is a normal packet that - * we either start transmitting (if idle) or queue (if busy). - * PH_PULL | REQUEST can be called to request a callback message - * (PH_PULL | CONFIRM) - * once the link is idle. After a "pull" callback, the upper layer - * routines can use PH_PULL | INDICATION to send data. - */ -void st5481_b_l2l1(struct hisax_if *ifc, int pr, void *arg) -{ - struct st5481_bcs *bcs = ifc->priv; - struct sk_buff *skb = arg; - long mode; - - DBG(4, ""); - - switch (pr) { - case PH_DATA | REQUEST: - BUG_ON(bcs->b_out.tx_skb); - bcs->b_out.tx_skb = skb; - break; - case PH_ACTIVATE | REQUEST: - mode = (long) arg; - DBG(4, "B%d,PH_ACTIVATE_REQUEST %ld", bcs->channel + 1, mode); - st5481B_mode(bcs, mode); - B_L1L2(bcs, PH_ACTIVATE | INDICATION, NULL); - break; - case PH_DEACTIVATE | REQUEST: - DBG(4, "B%d,PH_DEACTIVATE_REQUEST", bcs->channel + 1); - st5481B_mode(bcs, L1_MODE_NULL); - B_L1L2(bcs, PH_DEACTIVATE | INDICATION, NULL); - break; - default: - WARNING("pr %#x\n", pr); - } -} diff --git a/drivers/isdn/hisax/st5481_d.c b/drivers/isdn/hisax/st5481_d.c deleted file mode 100644 index e88c5c71fca7..000000000000 --- a/drivers/isdn/hisax/st5481_d.c +++ /dev/null @@ -1,780 +0,0 @@ -/* - * Driver for ST5481 USB ISDN modem - * - * Author Frode Isaksen - * Copyright 2001 by Frode Isaksen <fisaksen@bewan.com> - * 2001 by Kai Germaschewski <kai.germaschewski@gmx.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#include <linux/init.h> -#include <linux/gfp.h> -#include <linux/usb.h> -#include <linux/netdevice.h> -#include "st5481.h" - -static void ph_connect(struct st5481_adapter *adapter); -static void ph_disconnect(struct st5481_adapter *adapter); - -static struct Fsm l1fsm; - -static char *strL1State[] = -{ - "ST_L1_F3", - "ST_L1_F4", - "ST_L1_F6", - "ST_L1_F7", - "ST_L1_F8", -}; - -static char *strL1Event[] = -{ - "EV_IND_DP", - "EV_IND_1", - "EV_IND_2", - "EV_IND_3", - "EV_IND_RSY", - "EV_IND_5", - "EV_IND_6", - "EV_IND_7", - "EV_IND_AP", - "EV_IND_9", - "EV_IND_10", - "EV_IND_11", - "EV_IND_AI8", - "EV_IND_AI10", - "EV_IND_AIL", - "EV_IND_DI", - "EV_PH_ACTIVATE_REQ", - "EV_PH_DEACTIVATE_REQ", - "EV_TIMER3", -}; - -static inline void D_L1L2(struct st5481_adapter *adapter, int pr, void *arg) -{ - struct hisax_if *ifc = (struct hisax_if *) &adapter->hisax_d_if; - - ifc->l1l2(ifc, pr, arg); -} - -static void -l1_go_f3(struct FsmInst *fi, int event, void *arg) -{ - struct st5481_adapter *adapter = fi->userdata; - - if (fi->state == ST_L1_F7) - ph_disconnect(adapter); - - FsmChangeState(fi, ST_L1_F3); - D_L1L2(adapter, PH_DEACTIVATE | INDICATION, NULL); -} - -static void -l1_go_f6(struct FsmInst *fi, int event, void *arg) -{ - struct st5481_adapter *adapter = fi->userdata; - - if (fi->state == ST_L1_F7) - ph_disconnect(adapter); - - FsmChangeState(fi, ST_L1_F6); -} - -static void -l1_go_f7(struct FsmInst *fi, int event, void *arg) -{ - struct st5481_adapter *adapter = fi->userdata; - - FsmDelTimer(&adapter->timer, 0); - ph_connect(adapter); - FsmChangeState(fi, ST_L1_F7); - D_L1L2(adapter, PH_ACTIVATE | INDICATION, NULL); -} - -static void -l1_go_f8(struct FsmInst *fi, int event, void *arg) -{ - struct st5481_adapter *adapter = fi->userdata; - - if (fi->state == ST_L1_F7) - ph_disconnect(adapter); - - FsmChangeState(fi, ST_L1_F8); -} - -static void -l1_timer3(struct FsmInst *fi, int event, void *arg) -{ - struct st5481_adapter *adapter = fi->userdata; - - st5481_ph_command(adapter, ST5481_CMD_DR); - FsmChangeState(fi, ST_L1_F3); - D_L1L2(adapter, PH_DEACTIVATE | INDICATION, NULL); -} - -static void -l1_ignore(struct FsmInst *fi, int event, void *arg) -{ -} - -static void -l1_activate(struct FsmInst *fi, int event, void *arg) -{ - struct st5481_adapter *adapter = fi->userdata; - - st5481_ph_command(adapter, ST5481_CMD_DR); - st5481_ph_command(adapter, ST5481_CMD_PUP); - FsmRestartTimer(&adapter->timer, TIMER3_VALUE, EV_TIMER3, NULL, 2); - st5481_ph_command(adapter, ST5481_CMD_AR8); - FsmChangeState(fi, ST_L1_F4); -} - -static struct FsmNode L1FnList[] __initdata = -{ - {ST_L1_F3, EV_IND_DP, l1_ignore}, - {ST_L1_F3, EV_IND_AP, l1_go_f6}, - {ST_L1_F3, EV_IND_AI8, l1_go_f7}, - {ST_L1_F3, EV_IND_AI10, l1_go_f7}, - {ST_L1_F3, EV_PH_ACTIVATE_REQ, l1_activate}, - - {ST_L1_F4, EV_TIMER3, l1_timer3}, - {ST_L1_F4, EV_IND_DP, l1_go_f3}, - {ST_L1_F4, EV_IND_AP, l1_go_f6}, - {ST_L1_F4, EV_IND_AI8, l1_go_f7}, - {ST_L1_F4, EV_IND_AI10, l1_go_f7}, - - {ST_L1_F6, EV_TIMER3, l1_timer3}, - {ST_L1_F6, EV_IND_DP, l1_go_f3}, - {ST_L1_F6, EV_IND_AP, l1_ignore}, - {ST_L1_F6, EV_IND_AI8, l1_go_f7}, - {ST_L1_F6, EV_IND_AI10, l1_go_f7}, - {ST_L1_F7, EV_IND_RSY, l1_go_f8}, - - {ST_L1_F7, EV_IND_DP, l1_go_f3}, - {ST_L1_F7, EV_IND_AP, l1_go_f6}, - {ST_L1_F7, EV_IND_AI8, l1_ignore}, - {ST_L1_F7, EV_IND_AI10, l1_ignore}, - {ST_L1_F7, EV_IND_RSY, l1_go_f8}, - - {ST_L1_F8, EV_TIMER3, l1_timer3}, - {ST_L1_F8, EV_IND_DP, l1_go_f3}, - {ST_L1_F8, EV_IND_AP, l1_go_f6}, - {ST_L1_F8, EV_IND_AI8, l1_go_f8}, - {ST_L1_F8, EV_IND_AI10, l1_go_f8}, - {ST_L1_F8, EV_IND_RSY, l1_ignore}, -}; - -static __printf(2, 3) - void l1m_debug(struct FsmInst *fi, char *fmt, ...) -{ - va_list args; - char buf[256]; - - va_start(args, fmt); - vsnprintf(buf, sizeof(buf), fmt, args); - DBG(8, "%s", buf); - va_end(args); -} - -/* ====================================================================== - * D-Channel out - */ - -/* - D OUT state machine: - ==================== - - Transmit short frame (< 16 bytes of encoded data): - - L1 FRAME D_OUT_STATE USB D CHANNEL - -------- ----------- --- --------- - - FIXME - - -> [xx..xx] SHORT_INIT -> [7Exx..xxC1C27EFF] - SHORT_WAIT_DEN <> OUT_D_COUNTER=16 - - END_OF_SHORT <- DEN_EVENT -> 7Exx - xxxx - xxxx - xxxx - xxxx - xxxx - C1C1 - 7EFF - WAIT_FOR_RESET_IDLE <- D_UNDERRUN <- (8ms) - IDLE <> Reset pipe - - - - Transmit long frame (>= 16 bytes of encoded data): - - L1 FRAME D_OUT_STATE USB D CHANNEL - -------- ----------- --- --------- - - -> [xx...xx] IDLE - WAIT_FOR_STOP <> OUT_D_COUNTER=0 - WAIT_FOR_RESET <> Reset pipe - STOP - INIT_LONG_FRAME -> [7Exx..xx] - WAIT_DEN <> OUT_D_COUNTER=16 - OUT_NORMAL <- DEN_EVENT -> 7Exx - END_OF_FRAME_BUSY -> [xxxx] xxxx - END_OF_FRAME_NOT_BUSY -> [xxxx] xxxx - -> [xxxx] xxxx - -> [C1C2] xxxx - -> [7EFF] xxxx - xxxx - xxxx - .... - xxxx - C1C2 - 7EFF - <- D_UNDERRUN <- (> 8ms) - WAIT_FOR_STOP <> OUT_D_COUNTER=0 - WAIT_FOR_RESET <> Reset pipe - STOP - -*/ - -static struct Fsm dout_fsm; - -static char *strDoutState[] = -{ - "ST_DOUT_NONE", - - "ST_DOUT_SHORT_INIT", - "ST_DOUT_SHORT_WAIT_DEN", - - "ST_DOUT_LONG_INIT", - "ST_DOUT_LONG_WAIT_DEN", - "ST_DOUT_NORMAL", - - "ST_DOUT_WAIT_FOR_UNDERRUN", - "ST_DOUT_WAIT_FOR_NOT_BUSY", - "ST_DOUT_WAIT_FOR_STOP", - "ST_DOUT_WAIT_FOR_RESET", -}; - -static char *strDoutEvent[] = -{ - "EV_DOUT_START_XMIT", - "EV_DOUT_COMPLETE", - "EV_DOUT_DEN", - "EV_DOUT_RESETED", - "EV_DOUT_STOPPED", - "EV_DOUT_COLL", - "EV_DOUT_UNDERRUN", -}; - -static __printf(2, 3) - void dout_debug(struct FsmInst *fi, char *fmt, ...) -{ - va_list args; - char buf[256]; - - va_start(args, fmt); - vsnprintf(buf, sizeof(buf), fmt, args); - DBG(0x2, "%s", buf); - va_end(args); -} - -static void dout_stop_event(void *context) -{ - struct st5481_adapter *adapter = context; - - FsmEvent(&adapter->d_out.fsm, EV_DOUT_STOPPED, NULL); -} - -/* - * Start the transfer of a D channel frame. - */ -static void usb_d_out(struct st5481_adapter *adapter, int buf_nr) -{ - struct st5481_d_out *d_out = &adapter->d_out; - struct urb *urb; - unsigned int num_packets, packet_offset; - int len, buf_size, bytes_sent; - struct sk_buff *skb; - struct usb_iso_packet_descriptor *desc; - - if (d_out->fsm.state != ST_DOUT_NORMAL) - return; - - if (test_and_set_bit(buf_nr, &d_out->busy)) { - DBG(2, "ep %d urb %d busy %#lx", EP_D_OUT, buf_nr, d_out->busy); - return; - } - urb = d_out->urb[buf_nr]; - - skb = d_out->tx_skb; - - buf_size = NUM_ISO_PACKETS_D * SIZE_ISO_PACKETS_D_OUT; - - if (skb) { - len = isdnhdlc_encode(&d_out->hdlc_state, - skb->data, skb->len, &bytes_sent, - urb->transfer_buffer, buf_size); - skb_pull(skb, bytes_sent); - } else { - // Send flags or idle - len = isdnhdlc_encode(&d_out->hdlc_state, - NULL, 0, &bytes_sent, - urb->transfer_buffer, buf_size); - } - - if (len < buf_size) { - FsmChangeState(&d_out->fsm, ST_DOUT_WAIT_FOR_UNDERRUN); - } - if (skb && !skb->len) { - d_out->tx_skb = NULL; - D_L1L2(adapter, PH_DATA | CONFIRM, NULL); - dev_kfree_skb_any(skb); - } - - // Prepare the URB - urb->transfer_buffer_length = len; - num_packets = 0; - packet_offset = 0; - while (packet_offset < len) { - desc = &urb->iso_frame_desc[num_packets]; - desc->offset = packet_offset; - desc->length = SIZE_ISO_PACKETS_D_OUT; - if (len - packet_offset < desc->length) - desc->length = len - packet_offset; - num_packets++; - packet_offset += desc->length; - } - urb->number_of_packets = num_packets; - - // Prepare the URB - urb->dev = adapter->usb_dev; - // Need to transmit the next buffer 2ms after the DEN_EVENT - urb->transfer_flags = 0; - urb->start_frame = usb_get_current_frame_number(adapter->usb_dev) + 2; - - DBG_ISO_PACKET(0x20, urb); - - if (usb_submit_urb(urb, GFP_KERNEL) < 0) { - // There is another URB queued up - urb->transfer_flags = URB_ISO_ASAP; - SUBMIT_URB(urb, GFP_KERNEL); - } -} - -static void fifo_reseted(void *context) -{ - struct st5481_adapter *adapter = context; - - FsmEvent(&adapter->d_out.fsm, EV_DOUT_RESETED, NULL); -} - -static void usb_d_out_complete(struct urb *urb) -{ - struct st5481_adapter *adapter = urb->context; - struct st5481_d_out *d_out = &adapter->d_out; - long buf_nr; - - DBG(2, ""); - - buf_nr = get_buf_nr(d_out->urb, urb); - test_and_clear_bit(buf_nr, &d_out->busy); - - if (unlikely(urb->status < 0)) { - switch (urb->status) { - case -ENOENT: - case -ESHUTDOWN: - case -ECONNRESET: - DBG(1, "urb killed status %d", urb->status); - break; - default: - WARNING("urb status %d", urb->status); - if (d_out->busy == 0) { - st5481_usb_pipe_reset(adapter, EP_D_OUT | USB_DIR_OUT, fifo_reseted, adapter); - } - break; - } - return; // Give up - } - - FsmEvent(&adapter->d_out.fsm, EV_DOUT_COMPLETE, (void *) buf_nr); -} - -/* ====================================================================== */ - -static void dout_start_xmit(struct FsmInst *fsm, int event, void *arg) -{ - // FIXME unify? - struct st5481_adapter *adapter = fsm->userdata; - struct st5481_d_out *d_out = &adapter->d_out; - struct urb *urb; - int len, bytes_sent; - struct sk_buff *skb; - int buf_nr = 0; - - skb = d_out->tx_skb; - - DBG(2, "len=%d", skb->len); - - isdnhdlc_out_init(&d_out->hdlc_state, HDLC_DCHANNEL | HDLC_BITREVERSE); - - if (test_and_set_bit(buf_nr, &d_out->busy)) { - WARNING("ep %d urb %d busy %#lx", EP_D_OUT, buf_nr, d_out->busy); - return; - } - urb = d_out->urb[buf_nr]; - - DBG_SKB(0x10, skb); - len = isdnhdlc_encode(&d_out->hdlc_state, - skb->data, skb->len, &bytes_sent, - urb->transfer_buffer, 16); - skb_pull(skb, bytes_sent); - - if (len < 16) - FsmChangeState(&d_out->fsm, ST_DOUT_SHORT_INIT); - else - FsmChangeState(&d_out->fsm, ST_DOUT_LONG_INIT); - - if (skb->len == 0) { - d_out->tx_skb = NULL; - D_L1L2(adapter, PH_DATA | CONFIRM, NULL); - dev_kfree_skb_any(skb); - } - -// Prepare the URB - urb->transfer_buffer_length = len; - - urb->iso_frame_desc[0].offset = 0; - urb->iso_frame_desc[0].length = len; - urb->number_of_packets = 1; - - // Prepare the URB - urb->dev = adapter->usb_dev; - urb->transfer_flags = URB_ISO_ASAP; - - DBG_ISO_PACKET(0x20, urb); - SUBMIT_URB(urb, GFP_KERNEL); -} - -static void dout_short_fifo(struct FsmInst *fsm, int event, void *arg) -{ - struct st5481_adapter *adapter = fsm->userdata; - struct st5481_d_out *d_out = &adapter->d_out; - - FsmChangeState(&d_out->fsm, ST_DOUT_SHORT_WAIT_DEN); - st5481_usb_device_ctrl_msg(adapter, OUT_D_COUNTER, 16, NULL, NULL); -} - -static void dout_end_short_frame(struct FsmInst *fsm, int event, void *arg) -{ - struct st5481_adapter *adapter = fsm->userdata; - struct st5481_d_out *d_out = &adapter->d_out; - - FsmChangeState(&d_out->fsm, ST_DOUT_WAIT_FOR_UNDERRUN); -} - -static void dout_long_enable_fifo(struct FsmInst *fsm, int event, void *arg) -{ - struct st5481_adapter *adapter = fsm->userdata; - struct st5481_d_out *d_out = &adapter->d_out; - - st5481_usb_device_ctrl_msg(adapter, OUT_D_COUNTER, 16, NULL, NULL); - FsmChangeState(&d_out->fsm, ST_DOUT_LONG_WAIT_DEN); -} - -static void dout_long_den(struct FsmInst *fsm, int event, void *arg) -{ - struct st5481_adapter *adapter = fsm->userdata; - struct st5481_d_out *d_out = &adapter->d_out; - - FsmChangeState(&d_out->fsm, ST_DOUT_NORMAL); - usb_d_out(adapter, 0); - usb_d_out(adapter, 1); -} - -static void dout_reset(struct FsmInst *fsm, int event, void *arg) -{ - struct st5481_adapter *adapter = fsm->userdata; - struct st5481_d_out *d_out = &adapter->d_out; - - FsmChangeState(&d_out->fsm, ST_DOUT_WAIT_FOR_RESET); - st5481_usb_pipe_reset(adapter, EP_D_OUT | USB_DIR_OUT, fifo_reseted, adapter); -} - -static void dout_stop(struct FsmInst *fsm, int event, void *arg) -{ - struct st5481_adapter *adapter = fsm->userdata; - struct st5481_d_out *d_out = &adapter->d_out; - - FsmChangeState(&d_out->fsm, ST_DOUT_WAIT_FOR_STOP); - st5481_usb_device_ctrl_msg(adapter, OUT_D_COUNTER, 0, dout_stop_event, adapter); -} - -static void dout_underrun(struct FsmInst *fsm, int event, void *arg) -{ - struct st5481_adapter *adapter = fsm->userdata; - struct st5481_d_out *d_out = &adapter->d_out; - - if (test_bit(0, &d_out->busy) || test_bit(1, &d_out->busy)) { - FsmChangeState(&d_out->fsm, ST_DOUT_WAIT_FOR_NOT_BUSY); - } else { - dout_stop(fsm, event, arg); - } -} - -static void dout_check_busy(struct FsmInst *fsm, int event, void *arg) -{ - struct st5481_adapter *adapter = fsm->userdata; - struct st5481_d_out *d_out = &adapter->d_out; - - if (!test_bit(0, &d_out->busy) && !test_bit(1, &d_out->busy)) - dout_stop(fsm, event, arg); -} - -static void dout_reseted(struct FsmInst *fsm, int event, void *arg) -{ - struct st5481_adapter *adapter = fsm->userdata; - struct st5481_d_out *d_out = &adapter->d_out; - - FsmChangeState(&d_out->fsm, ST_DOUT_NONE); - // FIXME locking - if (d_out->tx_skb) - FsmEvent(&d_out->fsm, EV_DOUT_START_XMIT, NULL); -} - -static void dout_complete(struct FsmInst *fsm, int event, void *arg) -{ - struct st5481_adapter *adapter = fsm->userdata; - long buf_nr = (long) arg; - - usb_d_out(adapter, buf_nr); -} - -static void dout_ignore(struct FsmInst *fsm, int event, void *arg) -{ -} - -static struct FsmNode DoutFnList[] __initdata = -{ - {ST_DOUT_NONE, EV_DOUT_START_XMIT, dout_start_xmit}, - - {ST_DOUT_SHORT_INIT, EV_DOUT_COMPLETE, dout_short_fifo}, - - {ST_DOUT_SHORT_WAIT_DEN, EV_DOUT_DEN, dout_end_short_frame}, - {ST_DOUT_SHORT_WAIT_DEN, EV_DOUT_UNDERRUN, dout_underrun}, - - {ST_DOUT_LONG_INIT, EV_DOUT_COMPLETE, dout_long_enable_fifo}, - - {ST_DOUT_LONG_WAIT_DEN, EV_DOUT_DEN, dout_long_den}, - {ST_DOUT_LONG_WAIT_DEN, EV_DOUT_UNDERRUN, dout_underrun}, - - {ST_DOUT_NORMAL, EV_DOUT_UNDERRUN, dout_underrun}, - {ST_DOUT_NORMAL, EV_DOUT_COMPLETE, dout_complete}, - - {ST_DOUT_WAIT_FOR_UNDERRUN, EV_DOUT_UNDERRUN, dout_underrun}, - {ST_DOUT_WAIT_FOR_UNDERRUN, EV_DOUT_COMPLETE, dout_ignore}, - - {ST_DOUT_WAIT_FOR_NOT_BUSY, EV_DOUT_COMPLETE, dout_check_busy}, - - {ST_DOUT_WAIT_FOR_STOP, EV_DOUT_STOPPED, dout_reset}, - - {ST_DOUT_WAIT_FOR_RESET, EV_DOUT_RESETED, dout_reseted}, -}; - -void st5481_d_l2l1(struct hisax_if *hisax_d_if, int pr, void *arg) -{ - struct st5481_adapter *adapter = hisax_d_if->priv; - struct sk_buff *skb = arg; - - switch (pr) { - case PH_ACTIVATE | REQUEST: - FsmEvent(&adapter->l1m, EV_PH_ACTIVATE_REQ, NULL); - break; - case PH_DEACTIVATE | REQUEST: - FsmEvent(&adapter->l1m, EV_PH_DEACTIVATE_REQ, NULL); - break; - case PH_DATA | REQUEST: - DBG(2, "PH_DATA REQUEST len %d", skb->len); - BUG_ON(adapter->d_out.tx_skb); - adapter->d_out.tx_skb = skb; - FsmEvent(&adapter->d_out.fsm, EV_DOUT_START_XMIT, NULL); - break; - default: - WARNING("pr %#x\n", pr); - break; - } -} - -/* ====================================================================== - */ - -/* - * Start receiving on the D channel since entered state F7. - */ -static void ph_connect(struct st5481_adapter *adapter) -{ - struct st5481_d_out *d_out = &adapter->d_out; - struct st5481_in *d_in = &adapter->d_in; - - DBG(8, ""); - - FsmChangeState(&d_out->fsm, ST_DOUT_NONE); - - // st5481_usb_device_ctrl_msg(adapter, FFMSK_D, OUT_UNDERRUN, NULL, NULL); - st5481_usb_device_ctrl_msg(adapter, FFMSK_D, 0xfc, NULL, NULL); - st5481_in_mode(d_in, L1_MODE_HDLC); - -#ifdef LOOPBACK - // Turn loopback on (data sent on B and D looped back) - st5481_usb_device_ctrl_msg(cs, LBB, 0x04, NULL, NULL); -#endif - - st5481_usb_pipe_reset(adapter, EP_D_OUT | USB_DIR_OUT, NULL, NULL); - - // Turn on the green LED to tell that we are in state F7 - adapter->leds |= GREEN_LED; - st5481_usb_device_ctrl_msg(adapter, GPIO_OUT, adapter->leds, NULL, NULL); -} - -/* - * Stop receiving on the D channel since not in state F7. - */ -static void ph_disconnect(struct st5481_adapter *adapter) -{ - DBG(8, ""); - - st5481_in_mode(&adapter->d_in, L1_MODE_NULL); - - // Turn off the green LED to tell that we left state F7 - adapter->leds &= ~GREEN_LED; - st5481_usb_device_ctrl_msg(adapter, GPIO_OUT, adapter->leds, NULL, NULL); -} - -static int st5481_setup_d_out(struct st5481_adapter *adapter) -{ - struct usb_device *dev = adapter->usb_dev; - struct usb_interface *intf; - struct usb_host_interface *altsetting = NULL; - struct usb_host_endpoint *endpoint; - struct st5481_d_out *d_out = &adapter->d_out; - - DBG(2, ""); - - intf = usb_ifnum_to_if(dev, 0); - if (intf) - altsetting = usb_altnum_to_altsetting(intf, 3); - if (!altsetting) - return -ENXIO; - - // Allocate URBs and buffers for the D channel out - endpoint = &altsetting->endpoint[EP_D_OUT-1]; - - DBG(2, "endpoint address=%02x,packet size=%d", - endpoint->desc.bEndpointAddress, le16_to_cpu(endpoint->desc.wMaxPacketSize)); - - return st5481_setup_isocpipes(d_out->urb, dev, - usb_sndisocpipe(dev, endpoint->desc.bEndpointAddress), - NUM_ISO_PACKETS_D, SIZE_ISO_PACKETS_D_OUT, - NUM_ISO_PACKETS_D * SIZE_ISO_PACKETS_D_OUT, - usb_d_out_complete, adapter); -} - -static void st5481_release_d_out(struct st5481_adapter *adapter) -{ - struct st5481_d_out *d_out = &adapter->d_out; - - DBG(2, ""); - - st5481_release_isocpipes(d_out->urb); -} - -int st5481_setup_d(struct st5481_adapter *adapter) -{ - int retval; - - DBG(2, ""); - - retval = st5481_setup_d_out(adapter); - if (retval) - goto err; - adapter->d_in.bufsize = MAX_DFRAME_LEN_L1; - adapter->d_in.num_packets = NUM_ISO_PACKETS_D; - adapter->d_in.packet_size = SIZE_ISO_PACKETS_D_IN; - adapter->d_in.ep = EP_D_IN | USB_DIR_IN; - adapter->d_in.counter = IN_D_COUNTER; - adapter->d_in.adapter = adapter; - adapter->d_in.hisax_if = &adapter->hisax_d_if.ifc; - retval = st5481_setup_in(&adapter->d_in); - if (retval) - goto err_d_out; - - adapter->l1m.fsm = &l1fsm; - adapter->l1m.state = ST_L1_F3; - adapter->l1m.debug = st5481_debug & 0x100; - adapter->l1m.userdata = adapter; - adapter->l1m.printdebug = l1m_debug; - FsmInitTimer(&adapter->l1m, &adapter->timer); - - adapter->d_out.fsm.fsm = &dout_fsm; - adapter->d_out.fsm.state = ST_DOUT_NONE; - adapter->d_out.fsm.debug = st5481_debug & 0x100; - adapter->d_out.fsm.userdata = adapter; - adapter->d_out.fsm.printdebug = dout_debug; - - return 0; - -err_d_out: - st5481_release_d_out(adapter); -err: - return retval; -} - -void st5481_release_d(struct st5481_adapter *adapter) -{ - DBG(2, ""); - - st5481_release_in(&adapter->d_in); - st5481_release_d_out(adapter); -} - -/* ====================================================================== - * init / exit - */ - -int __init st5481_d_init(void) -{ - int retval; - - l1fsm.state_count = L1_STATE_COUNT; - l1fsm.event_count = L1_EVENT_COUNT; - l1fsm.strEvent = strL1Event; - l1fsm.strState = strL1State; - retval = FsmNew(&l1fsm, L1FnList, ARRAY_SIZE(L1FnList)); - if (retval) - goto err; - - dout_fsm.state_count = DOUT_STATE_COUNT; - dout_fsm.event_count = DOUT_EVENT_COUNT; - dout_fsm.strEvent = strDoutEvent; - dout_fsm.strState = strDoutState; - retval = FsmNew(&dout_fsm, DoutFnList, ARRAY_SIZE(DoutFnList)); - if (retval) - goto err_l1; - - return 0; - -err_l1: - FsmFree(&l1fsm); -err: - return retval; -} - -// can't be __exit -void st5481_d_exit(void) -{ - FsmFree(&l1fsm); - FsmFree(&dout_fsm); -} diff --git a/drivers/isdn/hisax/st5481_init.c b/drivers/isdn/hisax/st5481_init.c deleted file mode 100644 index 54ef9e4f8cbc..000000000000 --- a/drivers/isdn/hisax/st5481_init.c +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Driver for ST5481 USB ISDN modem - * - * Author Frode Isaksen - * Copyright 2001 by Frode Isaksen <fisaksen@bewan.com> - * 2001 by Kai Germaschewski <kai.germaschewski@gmx.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -/* - * TODO: - * - * b layer1 delay? - * hotplug / unregister issues - * mod_inc/dec_use_count - * unify parts of d/b channel usb handling - * file header - * avoid copy to isoc buffer? - * improve usb delay? - * merge l1 state machines? - * clean up debug - */ - -#include <linux/module.h> -#include <linux/init.h> -#include <linux/usb.h> -#include <linux/slab.h> -#include "st5481.h" - -MODULE_DESCRIPTION("ISDN4Linux: driver for ST5481 USB ISDN adapter"); -MODULE_AUTHOR("Frode Isaksen"); -MODULE_LICENSE("GPL"); - -static int protocol = 2; /* EURO-ISDN Default */ -module_param(protocol, int, 0); - -static int number_of_leds = 2; /* 2 LEDs on the adpater default */ -module_param(number_of_leds, int, 0); - -#ifdef CONFIG_HISAX_DEBUG -static int debug = 0; -module_param(debug, int, 0); -#endif -int st5481_debug; - -/* ====================================================================== - * registration/deregistration with the USB layer - */ - -/* - * This function will be called when the adapter is plugged - * into the USB bus. - */ -static int probe_st5481(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct usb_device *dev = interface_to_usbdev(intf); - struct st5481_adapter *adapter; - struct hisax_b_if *b_if[2]; - int retval, i; - - printk(KERN_INFO "st541: found adapter VendorId %04x, ProductId %04x, LEDs %d\n", - le16_to_cpu(dev->descriptor.idVendor), - le16_to_cpu(dev->descriptor.idProduct), - number_of_leds); - - adapter = kzalloc(sizeof(struct st5481_adapter), GFP_KERNEL); - if (!adapter) - return -ENOMEM; - - adapter->number_of_leds = number_of_leds; - adapter->usb_dev = dev; - - adapter->hisax_d_if.owner = THIS_MODULE; - adapter->hisax_d_if.ifc.priv = adapter; - adapter->hisax_d_if.ifc.l2l1 = st5481_d_l2l1; - - for (i = 0; i < 2; i++) { - adapter->bcs[i].adapter = adapter; - adapter->bcs[i].channel = i; - adapter->bcs[i].b_if.ifc.priv = &adapter->bcs[i]; - adapter->bcs[i].b_if.ifc.l2l1 = st5481_b_l2l1; - } - - retval = st5481_setup_usb(adapter); - if (retval < 0) - goto err; - - retval = st5481_setup_d(adapter); - if (retval < 0) - goto err_usb; - - retval = st5481_setup_b(&adapter->bcs[0]); - if (retval < 0) - goto err_d; - - retval = st5481_setup_b(&adapter->bcs[1]); - if (retval < 0) - goto err_b; - - for (i = 0; i < 2; i++) - b_if[i] = &adapter->bcs[i].b_if; - - if (hisax_register(&adapter->hisax_d_if, b_if, "st5481_usb", - protocol) != 0) - goto err_b1; - - st5481_start(adapter); - - usb_set_intfdata(intf, adapter); - return 0; - -err_b1: - st5481_release_b(&adapter->bcs[1]); -err_b: - st5481_release_b(&adapter->bcs[0]); -err_d: - st5481_release_d(adapter); -err_usb: - st5481_release_usb(adapter); -err: - kfree(adapter); - return -EIO; -} - -/* - * This function will be called when the adapter is removed - * from the USB bus. - */ -static void disconnect_st5481(struct usb_interface *intf) -{ - struct st5481_adapter *adapter = usb_get_intfdata(intf); - - DBG(1, ""); - - usb_set_intfdata(intf, NULL); - if (!adapter) - return; - - st5481_stop(adapter); - st5481_release_b(&adapter->bcs[1]); - st5481_release_b(&adapter->bcs[0]); - st5481_release_d(adapter); - // we would actually better wait for completion of outstanding urbs - mdelay(2); - st5481_release_usb(adapter); - - hisax_unregister(&adapter->hisax_d_if); - - kfree(adapter); -} - -/* - * The last 4 bits in the Product Id is set with 4 pins on the chip. - */ -static struct usb_device_id st5481_ids[] = { - { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0x0) }, - { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0x1) }, - { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0x2) }, - { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0x3) }, - { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0x4) }, - { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0x5) }, - { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0x6) }, - { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0x7) }, - { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0x8) }, - { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0x9) }, - { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0xA) }, - { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0xB) }, - { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0xC) }, - { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0xD) }, - { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0xE) }, - { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0xF) }, - { } -}; -MODULE_DEVICE_TABLE(usb, st5481_ids); - -static struct usb_driver st5481_usb_driver = { - .name = "st5481_usb", - .probe = probe_st5481, - .disconnect = disconnect_st5481, - .id_table = st5481_ids, - .disable_hub_initiated_lpm = 1, -}; - -static int __init st5481_usb_init(void) -{ - int retval; - -#ifdef CONFIG_HISAX_DEBUG - st5481_debug = debug; -#endif - - printk(KERN_INFO "hisax_st5481: ST5481 USB ISDN driver $Revision: 2.4.2.3 $\n"); - - retval = st5481_d_init(); - if (retval < 0) - goto out; - - retval = usb_register(&st5481_usb_driver); - if (retval < 0) - goto out_d_exit; - - return 0; - -out_d_exit: - st5481_d_exit(); -out: - return retval; -} - -static void __exit st5481_usb_exit(void) -{ - usb_deregister(&st5481_usb_driver); - st5481_d_exit(); -} - -module_init(st5481_usb_init); -module_exit(st5481_usb_exit); diff --git a/drivers/isdn/hisax/st5481_usb.c b/drivers/isdn/hisax/st5481_usb.c deleted file mode 100644 index f207fda691c7..000000000000 --- a/drivers/isdn/hisax/st5481_usb.c +++ /dev/null @@ -1,659 +0,0 @@ -/* - * Driver for ST5481 USB ISDN modem - * - * Author Frode Isaksen - * Copyright 2001 by Frode Isaksen <fisaksen@bewan.com> - * 2001 by Kai Germaschewski <kai.germaschewski@gmx.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#include <linux/init.h> -#include <linux/usb.h> -#include <linux/slab.h> -#include "st5481.h" - -static int st5481_isoc_flatten(struct urb *urb); - -/* ====================================================================== - * control pipe - */ - -/* - * Send the next endpoint 0 request stored in the FIFO. - * Called either by the completion or by usb_ctrl_msg. - */ -static void usb_next_ctrl_msg(struct urb *urb, - struct st5481_adapter *adapter) -{ - struct st5481_ctrl *ctrl = &adapter->ctrl; - int r_index; - - if (test_and_set_bit(0, &ctrl->busy)) { - return; - } - - if ((r_index = fifo_remove(&ctrl->msg_fifo.f)) < 0) { - test_and_clear_bit(0, &ctrl->busy); - return; - } - urb->setup_packet = - (unsigned char *)&ctrl->msg_fifo.data[r_index]; - - DBG(1, "request=0x%02x,value=0x%04x,index=%x", - ((struct ctrl_msg *)urb->setup_packet)->dr.bRequest, - ((struct ctrl_msg *)urb->setup_packet)->dr.wValue, - ((struct ctrl_msg *)urb->setup_packet)->dr.wIndex); - - // Prepare the URB - urb->dev = adapter->usb_dev; - - SUBMIT_URB(urb, GFP_ATOMIC); -} - -/* - * Asynchronous endpoint 0 request (async version of usb_control_msg). - * The request will be queued up in a FIFO if the endpoint is busy. - */ -static void usb_ctrl_msg(struct st5481_adapter *adapter, - u8 request, u8 requesttype, u16 value, u16 index, - ctrl_complete_t complete, void *context) -{ - struct st5481_ctrl *ctrl = &adapter->ctrl; - int w_index; - struct ctrl_msg *ctrl_msg; - - if ((w_index = fifo_add(&ctrl->msg_fifo.f)) < 0) { - WARNING("control msg FIFO full"); - return; - } - ctrl_msg = &ctrl->msg_fifo.data[w_index]; - - ctrl_msg->dr.bRequestType = requesttype; - ctrl_msg->dr.bRequest = request; - ctrl_msg->dr.wValue = cpu_to_le16p(&value); - ctrl_msg->dr.wIndex = cpu_to_le16p(&index); - ctrl_msg->dr.wLength = 0; - ctrl_msg->complete = complete; - ctrl_msg->context = context; - - usb_next_ctrl_msg(ctrl->urb, adapter); -} - -/* - * Asynchronous endpoint 0 device request. - */ -void st5481_usb_device_ctrl_msg(struct st5481_adapter *adapter, - u8 request, u16 value, - ctrl_complete_t complete, void *context) -{ - usb_ctrl_msg(adapter, request, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, 0, complete, context); -} - -/* - * Asynchronous pipe reset (async version of usb_clear_halt). - */ -void st5481_usb_pipe_reset(struct st5481_adapter *adapter, - u_char pipe, - ctrl_complete_t complete, void *context) -{ - DBG(1, "pipe=%02x", pipe); - - usb_ctrl_msg(adapter, - USB_REQ_CLEAR_FEATURE, USB_DIR_OUT | USB_RECIP_ENDPOINT, - 0, pipe, complete, context); -} - - -/* - Physical level functions -*/ - -void st5481_ph_command(struct st5481_adapter *adapter, unsigned int command) -{ - DBG(8, "command=%s", ST5481_CMD_string(command)); - - st5481_usb_device_ctrl_msg(adapter, TXCI, command, NULL, NULL); -} - -/* - * The request on endpoint 0 has completed. - * Call the user provided completion routine and try - * to send the next request. - */ -static void usb_ctrl_complete(struct urb *urb) -{ - struct st5481_adapter *adapter = urb->context; - struct st5481_ctrl *ctrl = &adapter->ctrl; - struct ctrl_msg *ctrl_msg; - - if (unlikely(urb->status < 0)) { - switch (urb->status) { - case -ENOENT: - case -ESHUTDOWN: - case -ECONNRESET: - DBG(1, "urb killed status %d", urb->status); - return; // Give up - default: - WARNING("urb status %d", urb->status); - break; - } - } - - ctrl_msg = (struct ctrl_msg *)urb->setup_packet; - - if (ctrl_msg->dr.bRequest == USB_REQ_CLEAR_FEATURE) { - /* Special case handling for pipe reset */ - le16_to_cpus(&ctrl_msg->dr.wIndex); - usb_reset_endpoint(adapter->usb_dev, ctrl_msg->dr.wIndex); - } - - if (ctrl_msg->complete) - ctrl_msg->complete(ctrl_msg->context); - - clear_bit(0, &ctrl->busy); - - // Try to send next control message - usb_next_ctrl_msg(urb, adapter); - return; -} - -/* ====================================================================== - * interrupt pipe - */ - -/* - * The interrupt endpoint will be called when any - * of the 6 registers changes state (depending on masks). - * Decode the register values and schedule a private event. - * Called at interrupt. - */ -static void usb_int_complete(struct urb *urb) -{ - u8 *data = urb->transfer_buffer; - u8 irqbyte; - struct st5481_adapter *adapter = urb->context; - int j; - int status; - - switch (urb->status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - DBG(2, "urb shutting down with status: %d", urb->status); - return; - default: - WARNING("nonzero urb status received: %d", urb->status); - goto exit; - } - - - DBG_PACKET(2, data, INT_PKT_SIZE); - - if (urb->actual_length == 0) { - goto exit; - } - - irqbyte = data[MPINT]; - if (irqbyte & DEN_INT) - FsmEvent(&adapter->d_out.fsm, EV_DOUT_DEN, NULL); - - if (irqbyte & DCOLL_INT) - FsmEvent(&adapter->d_out.fsm, EV_DOUT_COLL, NULL); - - irqbyte = data[FFINT_D]; - if (irqbyte & OUT_UNDERRUN) - FsmEvent(&adapter->d_out.fsm, EV_DOUT_UNDERRUN, NULL); - - if (irqbyte & OUT_DOWN) - ;// printk("OUT_DOWN\n"); - - irqbyte = data[MPINT]; - if (irqbyte & RXCI_INT) - FsmEvent(&adapter->l1m, data[CCIST] & 0x0f, NULL); - - for (j = 0; j < 2; j++) - adapter->bcs[j].b_out.flow_event |= data[FFINT_B1 + j]; - - urb->actual_length = 0; - -exit: - status = usb_submit_urb(urb, GFP_ATOMIC); - if (status) - WARNING("usb_submit_urb failed with result %d", status); -} - -/* ====================================================================== - * initialization - */ - -int st5481_setup_usb(struct st5481_adapter *adapter) -{ - struct usb_device *dev = adapter->usb_dev; - struct st5481_ctrl *ctrl = &adapter->ctrl; - struct st5481_intr *intr = &adapter->intr; - struct usb_interface *intf; - struct usb_host_interface *altsetting = NULL; - struct usb_host_endpoint *endpoint; - int status; - struct urb *urb; - u8 *buf; - - DBG(2, ""); - - if ((status = usb_reset_configuration(dev)) < 0) { - WARNING("reset_configuration failed,status=%d", status); - return status; - } - - intf = usb_ifnum_to_if(dev, 0); - if (intf) - altsetting = usb_altnum_to_altsetting(intf, 3); - if (!altsetting) - return -ENXIO; - - // Check if the config is sane - if (altsetting->desc.bNumEndpoints != 7) { - WARNING("expecting 7 got %d endpoints!", altsetting->desc.bNumEndpoints); - return -EINVAL; - } - - // The descriptor is wrong for some early samples of the ST5481 chip - altsetting->endpoint[3].desc.wMaxPacketSize = cpu_to_le16(32); - altsetting->endpoint[4].desc.wMaxPacketSize = cpu_to_le16(32); - - // Use alternative setting 3 on interface 0 to have 2B+D - if ((status = usb_set_interface(dev, 0, 3)) < 0) { - WARNING("usb_set_interface failed,status=%d", status); - return status; - } - - // Allocate URB for control endpoint - urb = usb_alloc_urb(0, GFP_KERNEL); - if (!urb) { - return -ENOMEM; - } - ctrl->urb = urb; - - // Fill the control URB - usb_fill_control_urb(urb, dev, - usb_sndctrlpipe(dev, 0), - NULL, NULL, 0, usb_ctrl_complete, adapter); - - - fifo_init(&ctrl->msg_fifo.f, ARRAY_SIZE(ctrl->msg_fifo.data)); - - // Allocate URBs and buffers for interrupt endpoint - urb = usb_alloc_urb(0, GFP_KERNEL); - if (!urb) { - goto err1; - } - intr->urb = urb; - - buf = kmalloc(INT_PKT_SIZE, GFP_KERNEL); - if (!buf) { - goto err2; - } - - endpoint = &altsetting->endpoint[EP_INT-1]; - - // Fill the interrupt URB - usb_fill_int_urb(urb, dev, - usb_rcvintpipe(dev, endpoint->desc.bEndpointAddress), - buf, INT_PKT_SIZE, - usb_int_complete, adapter, - endpoint->desc.bInterval); - - return 0; -err2: - usb_free_urb(intr->urb); - intr->urb = NULL; -err1: - usb_free_urb(ctrl->urb); - ctrl->urb = NULL; - - return -ENOMEM; -} - -/* - * Release buffers and URBs for the interrupt and control - * endpoint. - */ -void st5481_release_usb(struct st5481_adapter *adapter) -{ - struct st5481_intr *intr = &adapter->intr; - struct st5481_ctrl *ctrl = &adapter->ctrl; - - DBG(1, ""); - - // Stop and free Control and Interrupt URBs - usb_kill_urb(ctrl->urb); - kfree(ctrl->urb->transfer_buffer); - usb_free_urb(ctrl->urb); - ctrl->urb = NULL; - - usb_kill_urb(intr->urb); - kfree(intr->urb->transfer_buffer); - usb_free_urb(intr->urb); - intr->urb = NULL; -} - -/* - * Initialize the adapter. - */ -void st5481_start(struct st5481_adapter *adapter) -{ - static const u8 init_cmd_table[] = { - SET_DEFAULT, 0, - STT, 0, - SDA_MIN, 0x0d, - SDA_MAX, 0x29, - SDELAY_VALUE, 0x14, - GPIO_DIR, 0x01, - GPIO_OUT, RED_LED, -// FFCTRL_OUT_D,4, -// FFCTRH_OUT_D,12, - FFCTRL_OUT_B1, 6, - FFCTRH_OUT_B1, 20, - FFCTRL_OUT_B2, 6, - FFCTRH_OUT_B2, 20, - MPMSK, RXCI_INT + DEN_INT + DCOLL_INT, - 0 - }; - struct st5481_intr *intr = &adapter->intr; - int i = 0; - u8 request, value; - - DBG(8, ""); - - adapter->leds = RED_LED; - - // Start receiving on the interrupt endpoint - SUBMIT_URB(intr->urb, GFP_KERNEL); - - while ((request = init_cmd_table[i++])) { - value = init_cmd_table[i++]; - st5481_usb_device_ctrl_msg(adapter, request, value, NULL, NULL); - } - st5481_ph_command(adapter, ST5481_CMD_PUP); -} - -/* - * Reset the adapter to default values. - */ -void st5481_stop(struct st5481_adapter *adapter) -{ - DBG(8, ""); - - st5481_usb_device_ctrl_msg(adapter, SET_DEFAULT, 0, NULL, NULL); -} - -/* ====================================================================== - * isochronous USB helpers - */ - -static void -fill_isoc_urb(struct urb *urb, struct usb_device *dev, - unsigned int pipe, void *buf, int num_packets, - int packet_size, usb_complete_t complete, - void *context) -{ - int k; - - usb_fill_int_urb(urb, dev, pipe, buf, num_packets * packet_size, - complete, context, 1); - - urb->number_of_packets = num_packets; - urb->transfer_flags = URB_ISO_ASAP; - for (k = 0; k < num_packets; k++) { - urb->iso_frame_desc[k].offset = packet_size * k; - urb->iso_frame_desc[k].length = packet_size; - urb->iso_frame_desc[k].actual_length = 0; - } -} - -int -st5481_setup_isocpipes(struct urb *urb[2], struct usb_device *dev, - unsigned int pipe, int num_packets, - int packet_size, int buf_size, - usb_complete_t complete, void *context) -{ - int j, retval; - unsigned char *buf; - - for (j = 0; j < 2; j++) { - retval = -ENOMEM; - urb[j] = usb_alloc_urb(num_packets, GFP_KERNEL); - if (!urb[j]) - goto err; - - // Allocate memory for 2000bytes/sec (16Kb/s) - buf = kmalloc(buf_size, GFP_KERNEL); - if (!buf) - goto err; - - // Fill the isochronous URB - fill_isoc_urb(urb[j], dev, pipe, buf, - num_packets, packet_size, complete, - context); - } - return 0; - -err: - for (j = 0; j < 2; j++) { - if (urb[j]) { - kfree(urb[j]->transfer_buffer); - urb[j]->transfer_buffer = NULL; - usb_free_urb(urb[j]); - urb[j] = NULL; - } - } - return retval; -} - -void st5481_release_isocpipes(struct urb *urb[2]) -{ - int j; - - for (j = 0; j < 2; j++) { - usb_kill_urb(urb[j]); - kfree(urb[j]->transfer_buffer); - usb_free_urb(urb[j]); - urb[j] = NULL; - } -} - -/* - * Decode frames received on the B/D channel. - * Note that this function will be called continuously - * with 64Kbit/s / 16Kbit/s of data and hence it will be - * called 50 times per second with 20 ISOC descriptors. - * Called at interrupt. - */ -static void usb_in_complete(struct urb *urb) -{ - struct st5481_in *in = urb->context; - unsigned char *ptr; - struct sk_buff *skb; - int len, count, status; - - if (unlikely(urb->status < 0)) { - switch (urb->status) { - case -ENOENT: - case -ESHUTDOWN: - case -ECONNRESET: - DBG(1, "urb killed status %d", urb->status); - return; // Give up - default: - WARNING("urb status %d", urb->status); - break; - } - } - - DBG_ISO_PACKET(0x80, urb); - - len = st5481_isoc_flatten(urb); - ptr = urb->transfer_buffer; - while (len > 0) { - if (in->mode == L1_MODE_TRANS) { - memcpy(in->rcvbuf, ptr, len); - status = len; - len = 0; - } else { - status = isdnhdlc_decode(&in->hdlc_state, ptr, len, &count, - in->rcvbuf, in->bufsize); - ptr += count; - len -= count; - } - - if (status > 0) { - // Good frame received - DBG(4, "count=%d", status); - DBG_PACKET(0x400, in->rcvbuf, status); - if (!(skb = dev_alloc_skb(status))) { - WARNING("receive out of memory\n"); - break; - } - skb_put_data(skb, in->rcvbuf, status); - in->hisax_if->l1l2(in->hisax_if, PH_DATA | INDICATION, skb); - } else if (status == -HDLC_CRC_ERROR) { - INFO("CRC error"); - } else if (status == -HDLC_FRAMING_ERROR) { - INFO("framing error"); - } else if (status == -HDLC_LENGTH_ERROR) { - INFO("length error"); - } - } - - // Prepare URB for next transfer - urb->dev = in->adapter->usb_dev; - urb->actual_length = 0; - - SUBMIT_URB(urb, GFP_ATOMIC); -} - -int st5481_setup_in(struct st5481_in *in) -{ - struct usb_device *dev = in->adapter->usb_dev; - int retval; - - DBG(4, ""); - - in->rcvbuf = kmalloc(in->bufsize, GFP_KERNEL); - retval = -ENOMEM; - if (!in->rcvbuf) - goto err; - - retval = st5481_setup_isocpipes(in->urb, dev, - usb_rcvisocpipe(dev, in->ep), - in->num_packets, in->packet_size, - in->num_packets * in->packet_size, - usb_in_complete, in); - if (retval) - goto err_free; - return 0; - -err_free: - kfree(in->rcvbuf); -err: - return retval; -} - -void st5481_release_in(struct st5481_in *in) -{ - DBG(2, ""); - - st5481_release_isocpipes(in->urb); -} - -/* - * Make the transfer_buffer contiguous by - * copying from the iso descriptors if necessary. - */ -static int st5481_isoc_flatten(struct urb *urb) -{ - struct usb_iso_packet_descriptor *pipd, *pend; - unsigned char *src, *dst; - unsigned int len; - - if (urb->status < 0) { - return urb->status; - } - for (pipd = &urb->iso_frame_desc[0], - pend = &urb->iso_frame_desc[urb->number_of_packets], - dst = urb->transfer_buffer; - pipd < pend; - pipd++) { - - if (pipd->status < 0) { - return (pipd->status); - } - - len = pipd->actual_length; - pipd->actual_length = 0; - src = urb->transfer_buffer + pipd->offset; - - if (src != dst) { - // Need to copy since isoc buffers not full - while (len--) { - *dst++ = *src++; - } - } else { - // No need to copy, just update destination buffer - dst += len; - } - } - // Return size of flattened buffer - return (dst - (unsigned char *)urb->transfer_buffer); -} - -static void st5481_start_rcv(void *context) -{ - struct st5481_in *in = context; - struct st5481_adapter *adapter = in->adapter; - - DBG(4, ""); - - in->urb[0]->dev = adapter->usb_dev; - SUBMIT_URB(in->urb[0], GFP_KERNEL); - - in->urb[1]->dev = adapter->usb_dev; - SUBMIT_URB(in->urb[1], GFP_KERNEL); -} - -void st5481_in_mode(struct st5481_in *in, int mode) -{ - if (in->mode == mode) - return; - - in->mode = mode; - - usb_unlink_urb(in->urb[0]); - usb_unlink_urb(in->urb[1]); - - if (in->mode != L1_MODE_NULL) { - if (in->mode != L1_MODE_TRANS) { - u32 features = HDLC_BITREVERSE; - - if (in->mode == L1_MODE_HDLC_56K) - features |= HDLC_56KBIT; - isdnhdlc_rcv_init(&in->hdlc_state, features); - } - st5481_usb_pipe_reset(in->adapter, in->ep, NULL, NULL); - st5481_usb_device_ctrl_msg(in->adapter, in->counter, - in->packet_size, - NULL, NULL); - st5481_start_rcv(in); - } else { - st5481_usb_device_ctrl_msg(in->adapter, in->counter, - 0, NULL, NULL); - } -} diff --git a/drivers/isdn/hisax/tei.c b/drivers/isdn/hisax/tei.c deleted file mode 100644 index 9195f9fd628f..000000000000 --- a/drivers/isdn/hisax/tei.c +++ /dev/null @@ -1,465 +0,0 @@ -/* $Id: tei.c,v 2.20.2.3 2004/01/13 14:31:26 keil Exp $ - * - * Author Karsten Keil - * based on the teles driver from Jan den Ouden - * Copyright by Karsten Keil <keil@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * For changes and modifications please read - * Documentation/isdn/HiSax.cert - * - * Thanks to Jan den Ouden - * Fritz Elfert - * - */ - -#include "hisax.h" -#include "isdnl2.h" -#include <linux/gfp.h> -#include <linux/init.h> -#include <linux/random.h> - -const char *tei_revision = "$Revision: 2.20.2.3 $"; - -#define ID_REQUEST 1 -#define ID_ASSIGNED 2 -#define ID_DENIED 3 -#define ID_CHK_REQ 4 -#define ID_CHK_RES 5 -#define ID_REMOVE 6 -#define ID_VERIFY 7 - -#define TEI_ENTITY_ID 0xf - -static struct Fsm teifsm; - -void tei_handler(struct PStack *st, u_char pr, struct sk_buff *skb); - -enum { - ST_TEI_NOP, - ST_TEI_IDREQ, - ST_TEI_IDVERIFY, -}; - -#define TEI_STATE_COUNT (ST_TEI_IDVERIFY + 1) - -static char *strTeiState[] = -{ - "ST_TEI_NOP", - "ST_TEI_IDREQ", - "ST_TEI_IDVERIFY", -}; - -enum { - EV_IDREQ, - EV_ASSIGN, - EV_DENIED, - EV_CHKREQ, - EV_REMOVE, - EV_VERIFY, - EV_T202, -}; - -#define TEI_EVENT_COUNT (EV_T202 + 1) - -static char *strTeiEvent[] = -{ - "EV_IDREQ", - "EV_ASSIGN", - "EV_DENIED", - "EV_CHKREQ", - "EV_REMOVE", - "EV_VERIFY", - "EV_T202", -}; - -static unsigned int -random_ri(void) -{ - unsigned int x; - - get_random_bytes(&x, sizeof(x)); - return (x & 0xffff); -} - -static struct PStack * -findtei(struct PStack *st, int tei) -{ - struct PStack *ptr = *(st->l1.stlistp); - - if (tei == 127) - return (NULL); - - while (ptr) - if (ptr->l2.tei == tei) - return (ptr); - else - ptr = ptr->next; - return (NULL); -} - -static void -put_tei_msg(struct PStack *st, u_char m_id, unsigned int ri, u_char tei) -{ - struct sk_buff *skb; - u_char *bp; - - if (!(skb = alloc_skb(8, GFP_ATOMIC))) { - printk(KERN_WARNING "HiSax: No skb for TEI manager\n"); - return; - } - bp = skb_put(skb, 3); - bp[0] = (TEI_SAPI << 2); - bp[1] = (GROUP_TEI << 1) | 0x1; - bp[2] = UI; - bp = skb_put(skb, 5); - bp[0] = TEI_ENTITY_ID; - bp[1] = ri >> 8; - bp[2] = ri & 0xff; - bp[3] = m_id; - bp[4] = (tei << 1) | 1; - st->l2.l2l1(st, PH_DATA | REQUEST, skb); -} - -static void -tei_id_request(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - if (st->l2.tei != -1) { - st->ma.tei_m.printdebug(&st->ma.tei_m, - "assign request for already assigned tei %d", - st->l2.tei); - return; - } - st->ma.ri = random_ri(); - if (st->ma.debug) - st->ma.tei_m.printdebug(&st->ma.tei_m, - "assign request ri %d", st->ma.ri); - put_tei_msg(st, ID_REQUEST, st->ma.ri, 127); - FsmChangeState(&st->ma.tei_m, ST_TEI_IDREQ); - FsmAddTimer(&st->ma.t202, st->ma.T202, EV_T202, NULL, 1); - st->ma.N202 = 3; -} - -static void -tei_id_assign(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *ost, *st = fi->userdata; - struct sk_buff *skb = arg; - struct IsdnCardState *cs; - int ri, tei; - - ri = ((unsigned int) skb->data[1] << 8) + skb->data[2]; - tei = skb->data[4] >> 1; - if (st->ma.debug) - st->ma.tei_m.printdebug(&st->ma.tei_m, - "identity assign ri %d tei %d", ri, tei); - if ((ost = findtei(st, tei))) { /* same tei is in use */ - if (ri != ost->ma.ri) { - st->ma.tei_m.printdebug(&st->ma.tei_m, - "possible duplicate assignment tei %d", tei); - ost->l2.l2tei(ost, MDL_ERROR | RESPONSE, NULL); - } - } else if (ri == st->ma.ri) { - FsmDelTimer(&st->ma.t202, 1); - FsmChangeState(&st->ma.tei_m, ST_TEI_NOP); - st->l3.l3l2(st, MDL_ASSIGN | REQUEST, (void *) (long) tei); - cs = (struct IsdnCardState *) st->l1.hardware; - cs->cardmsg(cs, MDL_ASSIGN | REQUEST, NULL); - } -} - -static void -tei_id_test_dup(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *ost, *st = fi->userdata; - struct sk_buff *skb = arg; - int tei, ri; - - ri = ((unsigned int) skb->data[1] << 8) + skb->data[2]; - tei = skb->data[4] >> 1; - if (st->ma.debug) - st->ma.tei_m.printdebug(&st->ma.tei_m, - "foreign identity assign ri %d tei %d", ri, tei); - if ((ost = findtei(st, tei))) { /* same tei is in use */ - if (ri != ost->ma.ri) { /* and it wasn't our request */ - st->ma.tei_m.printdebug(&st->ma.tei_m, - "possible duplicate assignment tei %d", tei); - FsmEvent(&ost->ma.tei_m, EV_VERIFY, NULL); - } - } -} - -static void -tei_id_denied(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - struct sk_buff *skb = arg; - int ri, tei; - - ri = ((unsigned int) skb->data[1] << 8) + skb->data[2]; - tei = skb->data[4] >> 1; - if (st->ma.debug) - st->ma.tei_m.printdebug(&st->ma.tei_m, - "identity denied ri %d tei %d", ri, tei); -} - -static void -tei_id_chk_req(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - struct sk_buff *skb = arg; - int tei; - - tei = skb->data[4] >> 1; - if (st->ma.debug) - st->ma.tei_m.printdebug(&st->ma.tei_m, - "identity check req tei %d", tei); - if ((st->l2.tei != -1) && ((tei == GROUP_TEI) || (tei == st->l2.tei))) { - FsmDelTimer(&st->ma.t202, 4); - FsmChangeState(&st->ma.tei_m, ST_TEI_NOP); - put_tei_msg(st, ID_CHK_RES, random_ri(), st->l2.tei); - } -} - -static void -tei_id_remove(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - struct sk_buff *skb = arg; - struct IsdnCardState *cs; - int tei; - - tei = skb->data[4] >> 1; - if (st->ma.debug) - st->ma.tei_m.printdebug(&st->ma.tei_m, - "identity remove tei %d", tei); - if ((st->l2.tei != -1) && ((tei == GROUP_TEI) || (tei == st->l2.tei))) { - FsmDelTimer(&st->ma.t202, 5); - FsmChangeState(&st->ma.tei_m, ST_TEI_NOP); - st->l3.l3l2(st, MDL_REMOVE | REQUEST, NULL); - cs = (struct IsdnCardState *) st->l1.hardware; - cs->cardmsg(cs, MDL_REMOVE | REQUEST, NULL); - } -} - -static void -tei_id_verify(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - - if (st->ma.debug) - st->ma.tei_m.printdebug(&st->ma.tei_m, - "id verify request for tei %d", st->l2.tei); - put_tei_msg(st, ID_VERIFY, 0, st->l2.tei); - FsmChangeState(&st->ma.tei_m, ST_TEI_IDVERIFY); - FsmAddTimer(&st->ma.t202, st->ma.T202, EV_T202, NULL, 2); - st->ma.N202 = 2; -} - -static void -tei_id_req_tout(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - struct IsdnCardState *cs; - - if (--st->ma.N202) { - st->ma.ri = random_ri(); - if (st->ma.debug) - st->ma.tei_m.printdebug(&st->ma.tei_m, - "assign req(%d) ri %d", 4 - st->ma.N202, - st->ma.ri); - put_tei_msg(st, ID_REQUEST, st->ma.ri, 127); - FsmAddTimer(&st->ma.t202, st->ma.T202, EV_T202, NULL, 3); - } else { - st->ma.tei_m.printdebug(&st->ma.tei_m, "assign req failed"); - st->l3.l3l2(st, MDL_ERROR | RESPONSE, NULL); - cs = (struct IsdnCardState *) st->l1.hardware; - cs->cardmsg(cs, MDL_REMOVE | REQUEST, NULL); - FsmChangeState(fi, ST_TEI_NOP); - } -} - -static void -tei_id_ver_tout(struct FsmInst *fi, int event, void *arg) -{ - struct PStack *st = fi->userdata; - struct IsdnCardState *cs; - - if (--st->ma.N202) { - if (st->ma.debug) - st->ma.tei_m.printdebug(&st->ma.tei_m, - "id verify req(%d) for tei %d", - 3 - st->ma.N202, st->l2.tei); - put_tei_msg(st, ID_VERIFY, 0, st->l2.tei); - FsmAddTimer(&st->ma.t202, st->ma.T202, EV_T202, NULL, 4); - } else { - st->ma.tei_m.printdebug(&st->ma.tei_m, - "verify req for tei %d failed", st->l2.tei); - st->l3.l3l2(st, MDL_REMOVE | REQUEST, NULL); - cs = (struct IsdnCardState *) st->l1.hardware; - cs->cardmsg(cs, MDL_REMOVE | REQUEST, NULL); - FsmChangeState(fi, ST_TEI_NOP); - } -} - -static void -tei_l1l2(struct PStack *st, int pr, void *arg) -{ - struct sk_buff *skb = arg; - int mt; - - if (test_bit(FLG_FIXED_TEI, &st->l2.flag)) { - dev_kfree_skb(skb); - return; - } - - if (pr == (PH_DATA | INDICATION)) { - if (skb->len < 3) { - st->ma.tei_m.printdebug(&st->ma.tei_m, - "short mgr frame %ld/3", skb->len); - } else if ((skb->data[0] != ((TEI_SAPI << 2) | 2)) || - (skb->data[1] != ((GROUP_TEI << 1) | 1))) { - st->ma.tei_m.printdebug(&st->ma.tei_m, - "wrong mgr sapi/tei %x/%x", - skb->data[0], skb->data[1]); - } else if ((skb->data[2] & 0xef) != UI) { - st->ma.tei_m.printdebug(&st->ma.tei_m, - "mgr frame is not ui %x", skb->data[2]); - } else { - skb_pull(skb, 3); - if (skb->len < 5) { - st->ma.tei_m.printdebug(&st->ma.tei_m, - "short mgr frame %ld/5", skb->len); - } else if (skb->data[0] != TEI_ENTITY_ID) { - /* wrong management entity identifier, ignore */ - st->ma.tei_m.printdebug(&st->ma.tei_m, - "tei handler wrong entity id %x", - skb->data[0]); - } else { - mt = skb->data[3]; - if (mt == ID_ASSIGNED) - FsmEvent(&st->ma.tei_m, EV_ASSIGN, skb); - else if (mt == ID_DENIED) - FsmEvent(&st->ma.tei_m, EV_DENIED, skb); - else if (mt == ID_CHK_REQ) - FsmEvent(&st->ma.tei_m, EV_CHKREQ, skb); - else if (mt == ID_REMOVE) - FsmEvent(&st->ma.tei_m, EV_REMOVE, skb); - else { - st->ma.tei_m.printdebug(&st->ma.tei_m, - "tei handler wrong mt %x\n", mt); - } - } - } - } else { - st->ma.tei_m.printdebug(&st->ma.tei_m, - "tei handler wrong pr %x\n", pr); - } - dev_kfree_skb(skb); -} - -static void -tei_l2tei(struct PStack *st, int pr, void *arg) -{ - struct IsdnCardState *cs; - - if (test_bit(FLG_FIXED_TEI, &st->l2.flag)) { - if (pr == (MDL_ASSIGN | INDICATION)) { - if (st->ma.debug) - st->ma.tei_m.printdebug(&st->ma.tei_m, - "fixed assign tei %d", st->l2.tei); - st->l3.l3l2(st, MDL_ASSIGN | REQUEST, (void *) (long) st->l2.tei); - cs = (struct IsdnCardState *) st->l1.hardware; - cs->cardmsg(cs, MDL_ASSIGN | REQUEST, NULL); - } - return; - } - switch (pr) { - case (MDL_ASSIGN | INDICATION): - FsmEvent(&st->ma.tei_m, EV_IDREQ, arg); - break; - case (MDL_ERROR | REQUEST): - FsmEvent(&st->ma.tei_m, EV_VERIFY, arg); - break; - default: - break; - } -} - -static void -tei_debug(struct FsmInst *fi, char *fmt, ...) -{ - va_list args; - struct PStack *st = fi->userdata; - - va_start(args, fmt); - VHiSax_putstatus(st->l1.hardware, "tei ", fmt, args); - va_end(args); -} - -void -setstack_tei(struct PStack *st) -{ - st->l2.l2tei = tei_l2tei; - st->ma.T202 = 2000; /* T202 2000 milliseconds */ - st->l1.l1tei = tei_l1l2; - st->ma.debug = 1; - st->ma.tei_m.fsm = &teifsm; - st->ma.tei_m.state = ST_TEI_NOP; - st->ma.tei_m.debug = 1; - st->ma.tei_m.userdata = st; - st->ma.tei_m.userint = 0; - st->ma.tei_m.printdebug = tei_debug; - FsmInitTimer(&st->ma.tei_m, &st->ma.t202); -} - -void -init_tei(struct IsdnCardState *cs, int protocol) -{ -} - -void -release_tei(struct IsdnCardState *cs) -{ - struct PStack *st = cs->stlist; - - while (st) { - FsmDelTimer(&st->ma.t202, 1); - st = st->next; - } -} - -static struct FsmNode TeiFnList[] __initdata = -{ - {ST_TEI_NOP, EV_IDREQ, tei_id_request}, - {ST_TEI_NOP, EV_ASSIGN, tei_id_test_dup}, - {ST_TEI_NOP, EV_VERIFY, tei_id_verify}, - {ST_TEI_NOP, EV_REMOVE, tei_id_remove}, - {ST_TEI_NOP, EV_CHKREQ, tei_id_chk_req}, - {ST_TEI_IDREQ, EV_T202, tei_id_req_tout}, - {ST_TEI_IDREQ, EV_ASSIGN, tei_id_assign}, - {ST_TEI_IDREQ, EV_DENIED, tei_id_denied}, - {ST_TEI_IDVERIFY, EV_T202, tei_id_ver_tout}, - {ST_TEI_IDVERIFY, EV_REMOVE, tei_id_remove}, - {ST_TEI_IDVERIFY, EV_CHKREQ, tei_id_chk_req}, -}; - -int __init -TeiNew(void) -{ - teifsm.state_count = TEI_STATE_COUNT; - teifsm.event_count = TEI_EVENT_COUNT; - teifsm.strEvent = strTeiEvent; - teifsm.strState = strTeiState; - return FsmNew(&teifsm, TeiFnList, ARRAY_SIZE(TeiFnList)); -} - -void -TeiFree(void) -{ - FsmFree(&teifsm); -} diff --git a/drivers/isdn/hisax/teleint.c b/drivers/isdn/hisax/teleint.c deleted file mode 100644 index 247aa33076b1..000000000000 --- a/drivers/isdn/hisax/teleint.c +++ /dev/null @@ -1,334 +0,0 @@ -/* $Id: teleint.c,v 1.16.2.5 2004/01/19 15:31:50 keil Exp $ - * - * low level stuff for TeleInt isdn cards - * - * Author Karsten Keil - * Copyright by Karsten Keil <keil@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/init.h> -#include "hisax.h" -#include "isac.h" -#include "hfc_2bs0.h" -#include "isdnl1.h" - -static const char *TeleInt_revision = "$Revision: 1.16.2.5 $"; - -#define byteout(addr, val) outb(val, addr) -#define bytein(addr) inb(addr) - -static inline u_char -readreg(unsigned int ale, unsigned int adr, u_char off) -{ - register u_char ret; - int max_delay = 2000; - - byteout(ale, off); - ret = HFC_BUSY & bytein(ale); - while (ret && --max_delay) - ret = HFC_BUSY & bytein(ale); - if (!max_delay) { - printk(KERN_WARNING "TeleInt Busy not inactive\n"); - return (0); - } - ret = bytein(adr); - return (ret); -} - -static inline void -readfifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size) -{ - register u_char ret; - register int max_delay = 20000; - register int i; - - byteout(ale, off); - for (i = 0; i < size; i++) { - ret = HFC_BUSY & bytein(ale); - while (ret && --max_delay) - ret = HFC_BUSY & bytein(ale); - if (!max_delay) { - printk(KERN_WARNING "TeleInt Busy not inactive\n"); - return; - } - data[i] = bytein(adr); - } -} - - -static inline void -writereg(unsigned int ale, unsigned int adr, u_char off, u_char data) -{ - register u_char ret; - int max_delay = 2000; - - byteout(ale, off); - ret = HFC_BUSY & bytein(ale); - while (ret && --max_delay) - ret = HFC_BUSY & bytein(ale); - if (!max_delay) { - printk(KERN_WARNING "TeleInt Busy not inactive\n"); - return; - } - byteout(adr, data); -} - -static inline void -writefifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size) -{ - register u_char ret; - register int max_delay = 20000; - register int i; - - byteout(ale, off); - for (i = 0; i < size; i++) { - ret = HFC_BUSY & bytein(ale); - while (ret && --max_delay) - ret = HFC_BUSY & bytein(ale); - if (!max_delay) { - printk(KERN_WARNING "TeleInt Busy not inactive\n"); - return; - } - byteout(adr, data[i]); - } -} - -/* Interface functions */ - -static u_char -ReadISAC(struct IsdnCardState *cs, u_char offset) -{ - cs->hw.hfc.cip = offset; - return (readreg(cs->hw.hfc.addr | 1, cs->hw.hfc.addr, offset)); -} - -static void -WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value) -{ - cs->hw.hfc.cip = offset; - writereg(cs->hw.hfc.addr | 1, cs->hw.hfc.addr, offset, value); -} - -static void -ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - cs->hw.hfc.cip = 0; - readfifo(cs->hw.hfc.addr | 1, cs->hw.hfc.addr, 0, data, size); -} - -static void -WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - cs->hw.hfc.cip = 0; - writefifo(cs->hw.hfc.addr | 1, cs->hw.hfc.addr, 0, data, size); -} - -static u_char -ReadHFC(struct IsdnCardState *cs, int data, u_char reg) -{ - register u_char ret; - - if (data) { - cs->hw.hfc.cip = reg; - byteout(cs->hw.hfc.addr | 1, reg); - ret = bytein(cs->hw.hfc.addr); - if (cs->debug & L1_DEB_HSCX_FIFO && (data != 2)) - debugl1(cs, "hfc RD %02x %02x", reg, ret); - } else - ret = bytein(cs->hw.hfc.addr | 1); - return (ret); -} - -static void -WriteHFC(struct IsdnCardState *cs, int data, u_char reg, u_char value) -{ - byteout(cs->hw.hfc.addr | 1, reg); - cs->hw.hfc.cip = reg; - if (data) - byteout(cs->hw.hfc.addr, value); - if (cs->debug & L1_DEB_HSCX_FIFO && (data != 2)) - debugl1(cs, "hfc W%c %02x %02x", data ? 'D' : 'C', reg, value); -} - -static irqreturn_t -TeleInt_interrupt(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - u_char val; - u_long flags; - - spin_lock_irqsave(&cs->lock, flags); - val = readreg(cs->hw.hfc.addr | 1, cs->hw.hfc.addr, ISAC_ISTA); -Start_ISAC: - if (val) - isac_interrupt(cs, val); - val = readreg(cs->hw.hfc.addr | 1, cs->hw.hfc.addr, ISAC_ISTA); - if (val) { - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "ISAC IntStat after IntRoutine"); - goto Start_ISAC; - } - writereg(cs->hw.hfc.addr | 1, cs->hw.hfc.addr, ISAC_MASK, 0xFF); - writereg(cs->hw.hfc.addr | 1, cs->hw.hfc.addr, ISAC_MASK, 0x0); - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -static void -TeleInt_Timer(struct timer_list *t) -{ - struct IsdnCardState *cs = from_timer(cs, t, hw.hfc.timer); - int stat = 0; - u_long flags; - - spin_lock_irqsave(&cs->lock, flags); - if (cs->bcs[0].mode) { - stat |= 1; - main_irq_hfc(&cs->bcs[0]); - } - if (cs->bcs[1].mode) { - stat |= 2; - main_irq_hfc(&cs->bcs[1]); - } - spin_unlock_irqrestore(&cs->lock, flags); - stat = HZ / 100; - if (!stat) - stat = 1; - cs->hw.hfc.timer.expires = jiffies + stat; - add_timer(&cs->hw.hfc.timer); -} - -static void -release_io_TeleInt(struct IsdnCardState *cs) -{ - del_timer(&cs->hw.hfc.timer); - releasehfc(cs); - if (cs->hw.hfc.addr) - release_region(cs->hw.hfc.addr, 2); -} - -static void -reset_TeleInt(struct IsdnCardState *cs) -{ - printk(KERN_INFO "TeleInt: resetting card\n"); - cs->hw.hfc.cirm |= HFC_RESET; - byteout(cs->hw.hfc.addr | 1, cs->hw.hfc.cirm); /* Reset On */ - mdelay(10); - cs->hw.hfc.cirm &= ~HFC_RESET; - byteout(cs->hw.hfc.addr | 1, cs->hw.hfc.cirm); /* Reset Off */ - mdelay(10); -} - -static int -TeleInt_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - u_long flags; - int delay; - - switch (mt) { - case CARD_RESET: - spin_lock_irqsave(&cs->lock, flags); - reset_TeleInt(cs); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_RELEASE: - release_io_TeleInt(cs); - return (0); - case CARD_INIT: - spin_lock_irqsave(&cs->lock, flags); - reset_TeleInt(cs); - inithfc(cs); - clear_pending_isac_ints(cs); - initisac(cs); - /* Reenable all IRQ */ - cs->writeisac(cs, ISAC_MASK, 0); - cs->writeisac(cs, ISAC_CMDR, 0x41); - spin_unlock_irqrestore(&cs->lock, flags); - delay = HZ / 100; - if (!delay) - delay = 1; - cs->hw.hfc.timer.expires = jiffies + delay; - add_timer(&cs->hw.hfc.timer); - return (0); - case CARD_TEST: - return (0); - } - return (0); -} - -int setup_TeleInt(struct IsdnCard *card) -{ - struct IsdnCardState *cs = card->cs; - char tmp[64]; - - strcpy(tmp, TeleInt_revision); - printk(KERN_INFO "HiSax: TeleInt driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_TELEINT) - return (0); - - cs->hw.hfc.addr = card->para[1] & 0x3fe; - cs->irq = card->para[0]; - cs->hw.hfc.cirm = HFC_CIRM; - cs->hw.hfc.isac_spcr = 0x00; - cs->hw.hfc.cip = 0; - cs->hw.hfc.ctmt = HFC_CTMT | HFC_CLTIMER; - cs->bcs[0].hw.hfc.send = NULL; - cs->bcs[1].hw.hfc.send = NULL; - cs->hw.hfc.fifosize = 7 * 1024 + 512; - timer_setup(&cs->hw.hfc.timer, TeleInt_Timer, 0); - if (!request_region(cs->hw.hfc.addr, 2, "TeleInt isdn")) { - printk(KERN_WARNING - "HiSax: TeleInt config port %x-%x already in use\n", - cs->hw.hfc.addr, - cs->hw.hfc.addr + 2); - return (0); - } - /* HW IO = IO */ - byteout(cs->hw.hfc.addr, cs->hw.hfc.addr & 0xff); - byteout(cs->hw.hfc.addr | 1, ((cs->hw.hfc.addr & 0x300) >> 8) | 0x54); - switch (cs->irq) { - case 3: - cs->hw.hfc.cirm |= HFC_INTA; - break; - case 4: - cs->hw.hfc.cirm |= HFC_INTB; - break; - case 5: - cs->hw.hfc.cirm |= HFC_INTC; - break; - case 7: - cs->hw.hfc.cirm |= HFC_INTD; - break; - case 10: - cs->hw.hfc.cirm |= HFC_INTE; - break; - case 11: - cs->hw.hfc.cirm |= HFC_INTF; - break; - default: - printk(KERN_WARNING "TeleInt: wrong IRQ\n"); - release_io_TeleInt(cs); - return (0); - } - byteout(cs->hw.hfc.addr | 1, cs->hw.hfc.cirm); - byteout(cs->hw.hfc.addr | 1, cs->hw.hfc.ctmt); - - printk(KERN_INFO "TeleInt: defined at 0x%x IRQ %d\n", - cs->hw.hfc.addr, cs->irq); - - setup_isac(cs); - cs->readisac = &ReadISAC; - cs->writeisac = &WriteISAC; - cs->readisacfifo = &ReadISACfifo; - cs->writeisacfifo = &WriteISACfifo; - cs->BC_Read_Reg = &ReadHFC; - cs->BC_Write_Reg = &WriteHFC; - cs->cardmsg = &TeleInt_card_msg; - cs->irq_func = &TeleInt_interrupt; - ISACVersion(cs, "TeleInt:"); - return (1); -} diff --git a/drivers/isdn/hisax/teles0.c b/drivers/isdn/hisax/teles0.c deleted file mode 100644 index ce9eabdd2f6e..000000000000 --- a/drivers/isdn/hisax/teles0.c +++ /dev/null @@ -1,364 +0,0 @@ -/* $Id: teles0.c,v 2.15.2.4 2004/01/13 23:48:39 keil Exp $ - * - * low level stuff for Teles Memory IO isdn cards - * - * Author Karsten Keil - * based on the teles driver from Jan den Ouden - * Copyright by Karsten Keil <keil@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * Thanks to Jan den Ouden - * Fritz Elfert - * Beat Doebeli - * - */ - -#include <linux/init.h> -#include "hisax.h" -#include "isdnl1.h" -#include "isac.h" -#include "hscx.h" - -static const char *teles0_revision = "$Revision: 2.15.2.4 $"; - -#define TELES_IOMEM_SIZE 0x400 -#define byteout(addr, val) outb(val, addr) -#define bytein(addr) inb(addr) - -static inline u_char -readisac(void __iomem *adr, u_char off) -{ - return readb(adr + ((off & 1) ? 0x2ff : 0x100) + off); -} - -static inline void -writeisac(void __iomem *adr, u_char off, u_char data) -{ - writeb(data, adr + ((off & 1) ? 0x2ff : 0x100) + off); mb(); -} - - -static inline u_char -readhscx(void __iomem *adr, int hscx, u_char off) -{ - return readb(adr + (hscx ? 0x1c0 : 0x180) + - ((off & 1) ? 0x1ff : 0) + off); -} - -static inline void -writehscx(void __iomem *adr, int hscx, u_char off, u_char data) -{ - writeb(data, adr + (hscx ? 0x1c0 : 0x180) + - ((off & 1) ? 0x1ff : 0) + off); mb(); -} - -static inline void -read_fifo_isac(void __iomem *adr, u_char *data, int size) -{ - register int i; - register u_char __iomem *ad = adr + 0x100; - for (i = 0; i < size; i++) - data[i] = readb(ad); -} - -static inline void -write_fifo_isac(void __iomem *adr, u_char *data, int size) -{ - register int i; - register u_char __iomem *ad = adr + 0x100; - for (i = 0; i < size; i++) { - writeb(data[i], ad); mb(); - } -} - -static inline void -read_fifo_hscx(void __iomem *adr, int hscx, u_char *data, int size) -{ - register int i; - register u_char __iomem *ad = adr + (hscx ? 0x1c0 : 0x180); - for (i = 0; i < size; i++) - data[i] = readb(ad); -} - -static inline void -write_fifo_hscx(void __iomem *adr, int hscx, u_char *data, int size) -{ - int i; - register u_char __iomem *ad = adr + (hscx ? 0x1c0 : 0x180); - for (i = 0; i < size; i++) { - writeb(data[i], ad); mb(); - } -} - -/* Interface functions */ - -static u_char -ReadISAC(struct IsdnCardState *cs, u_char offset) -{ - return (readisac(cs->hw.teles0.membase, offset)); -} - -static void -WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value) -{ - writeisac(cs->hw.teles0.membase, offset, value); -} - -static void -ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - read_fifo_isac(cs->hw.teles0.membase, data, size); -} - -static void -WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - write_fifo_isac(cs->hw.teles0.membase, data, size); -} - -static u_char -ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset) -{ - return (readhscx(cs->hw.teles0.membase, hscx, offset)); -} - -static void -WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) -{ - writehscx(cs->hw.teles0.membase, hscx, offset, value); -} - -/* - * fast interrupt HSCX stuff goes here - */ - -#define READHSCX(cs, nr, reg) readhscx(cs->hw.teles0.membase, nr, reg) -#define WRITEHSCX(cs, nr, reg, data) writehscx(cs->hw.teles0.membase, nr, reg, data) -#define READHSCXFIFO(cs, nr, ptr, cnt) read_fifo_hscx(cs->hw.teles0.membase, nr, ptr, cnt) -#define WRITEHSCXFIFO(cs, nr, ptr, cnt) write_fifo_hscx(cs->hw.teles0.membase, nr, ptr, cnt) - -#include "hscx_irq.c" - -static irqreturn_t -teles0_interrupt(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - u_char val; - u_long flags; - int count = 0; - - spin_lock_irqsave(&cs->lock, flags); - val = readhscx(cs->hw.teles0.membase, 1, HSCX_ISTA); -Start_HSCX: - if (val) - hscx_int_main(cs, val); - val = readisac(cs->hw.teles0.membase, ISAC_ISTA); -Start_ISAC: - if (val) - isac_interrupt(cs, val); - count++; - val = readhscx(cs->hw.teles0.membase, 1, HSCX_ISTA); - if (val && count < 5) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "HSCX IntStat after IntRoutine"); - goto Start_HSCX; - } - val = readisac(cs->hw.teles0.membase, ISAC_ISTA); - if (val && count < 5) { - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "ISAC IntStat after IntRoutine"); - goto Start_ISAC; - } - writehscx(cs->hw.teles0.membase, 0, HSCX_MASK, 0xFF); - writehscx(cs->hw.teles0.membase, 1, HSCX_MASK, 0xFF); - writeisac(cs->hw.teles0.membase, ISAC_MASK, 0xFF); - writeisac(cs->hw.teles0.membase, ISAC_MASK, 0x0); - writehscx(cs->hw.teles0.membase, 0, HSCX_MASK, 0x0); - writehscx(cs->hw.teles0.membase, 1, HSCX_MASK, 0x0); - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -static void -release_io_teles0(struct IsdnCardState *cs) -{ - if (cs->hw.teles0.cfg_reg) - release_region(cs->hw.teles0.cfg_reg, 8); - iounmap(cs->hw.teles0.membase); - release_mem_region(cs->hw.teles0.phymem, TELES_IOMEM_SIZE); -} - -static int -reset_teles0(struct IsdnCardState *cs) -{ - u_char cfval; - - if (cs->hw.teles0.cfg_reg) { - switch (cs->irq) { - case 2: - case 9: - cfval = 0x00; - break; - case 3: - cfval = 0x02; - break; - case 4: - cfval = 0x04; - break; - case 5: - cfval = 0x06; - break; - case 10: - cfval = 0x08; - break; - case 11: - cfval = 0x0A; - break; - case 12: - cfval = 0x0C; - break; - case 15: - cfval = 0x0E; - break; - default: - return (1); - } - cfval |= ((cs->hw.teles0.phymem >> 9) & 0xF0); - byteout(cs->hw.teles0.cfg_reg + 4, cfval); - HZDELAY(HZ / 10 + 1); - byteout(cs->hw.teles0.cfg_reg + 4, cfval | 1); - HZDELAY(HZ / 10 + 1); - } - writeb(0, cs->hw.teles0.membase + 0x80); mb(); - HZDELAY(HZ / 5 + 1); - writeb(1, cs->hw.teles0.membase + 0x80); mb(); - HZDELAY(HZ / 5 + 1); - return (0); -} - -static int -Teles_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - u_long flags; - - switch (mt) { - case CARD_RESET: - spin_lock_irqsave(&cs->lock, flags); - reset_teles0(cs); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_RELEASE: - release_io_teles0(cs); - return (0); - case CARD_INIT: - spin_lock_irqsave(&cs->lock, flags); - inithscxisac(cs, 3); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_TEST: - return (0); - } - return (0); -} - -int setup_teles0(struct IsdnCard *card) -{ - u_char val; - struct IsdnCardState *cs = card->cs; - char tmp[64]; - - strcpy(tmp, teles0_revision); - printk(KERN_INFO "HiSax: Teles 8.0/16.0 driver Rev. %s\n", HiSax_getrev(tmp)); - if ((cs->typ != ISDN_CTYPE_16_0) && (cs->typ != ISDN_CTYPE_8_0)) - return (0); - - if (cs->typ == ISDN_CTYPE_16_0) - cs->hw.teles0.cfg_reg = card->para[2]; - else /* 8.0 */ - cs->hw.teles0.cfg_reg = 0; - - if (card->para[1] < 0x10000) { - card->para[1] <<= 4; - printk(KERN_INFO - "Teles0: membase configured DOSish, assuming 0x%lx\n", - (unsigned long) card->para[1]); - } - cs->irq = card->para[0]; - if (cs->hw.teles0.cfg_reg) { - if (!request_region(cs->hw.teles0.cfg_reg, 8, "teles cfg")) { - printk(KERN_WARNING - "HiSax: %s config port %x-%x already in use\n", - CardType[card->typ], - cs->hw.teles0.cfg_reg, - cs->hw.teles0.cfg_reg + 8); - return (0); - } - } - if (cs->hw.teles0.cfg_reg) { - if ((val = bytein(cs->hw.teles0.cfg_reg + 0)) != 0x51) { - printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n", - cs->hw.teles0.cfg_reg + 0, val); - release_region(cs->hw.teles0.cfg_reg, 8); - return (0); - } - if ((val = bytein(cs->hw.teles0.cfg_reg + 1)) != 0x93) { - printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n", - cs->hw.teles0.cfg_reg + 1, val); - release_region(cs->hw.teles0.cfg_reg, 8); - return (0); - } - val = bytein(cs->hw.teles0.cfg_reg + 2); /* 0x1e=without AB - * 0x1f=with AB - * 0x1c 16.3 ??? - */ - if (val != 0x1e && val != 0x1f) { - printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n", - cs->hw.teles0.cfg_reg + 2, val); - release_region(cs->hw.teles0.cfg_reg, 8); - return (0); - } - } - /* 16.0 and 8.0 designed for IOM1 */ - test_and_set_bit(HW_IOM1, &cs->HW_Flags); - cs->hw.teles0.phymem = card->para[1]; - if (!request_mem_region(cs->hw.teles0.phymem, TELES_IOMEM_SIZE, "teles iomem")) { - printk(KERN_WARNING - "HiSax: %s memory region %lx-%lx already in use\n", - CardType[card->typ], - cs->hw.teles0.phymem, - cs->hw.teles0.phymem + TELES_IOMEM_SIZE); - if (cs->hw.teles0.cfg_reg) - release_region(cs->hw.teles0.cfg_reg, 8); - return (0); - } - cs->hw.teles0.membase = ioremap(cs->hw.teles0.phymem, TELES_IOMEM_SIZE); - printk(KERN_INFO - "HiSax: %s config irq:%d mem:%p cfg:0x%X\n", - CardType[cs->typ], cs->irq, - cs->hw.teles0.membase, cs->hw.teles0.cfg_reg); - if (reset_teles0(cs)) { - printk(KERN_WARNING "Teles0: wrong IRQ\n"); - release_io_teles0(cs); - return (0); - } - setup_isac(cs); - cs->readisac = &ReadISAC; - cs->writeisac = &WriteISAC; - cs->readisacfifo = &ReadISACfifo; - cs->writeisacfifo = &WriteISACfifo; - cs->BC_Read_Reg = &ReadHSCX; - cs->BC_Write_Reg = &WriteHSCX; - cs->BC_Send_Data = &hscx_fill_fifo; - cs->cardmsg = &Teles_card_msg; - cs->irq_func = &teles0_interrupt; - ISACVersion(cs, "Teles0:"); - if (HscxVersion(cs, "Teles0:")) { - printk(KERN_WARNING - "Teles0: wrong HSCX versions check IO/MEM addresses\n"); - release_io_teles0(cs); - return (0); - } - return (1); -} diff --git a/drivers/isdn/hisax/teles3.c b/drivers/isdn/hisax/teles3.c deleted file mode 100644 index 1eef693f04f0..000000000000 --- a/drivers/isdn/hisax/teles3.c +++ /dev/null @@ -1,498 +0,0 @@ -/* $Id: teles3.c,v 2.19.2.4 2004/01/13 23:48:39 keil Exp $ - * - * low level stuff for Teles 16.3 & PNP isdn cards - * - * Author Karsten Keil - * Copyright by Karsten Keil <keil@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * Thanks to Jan den Ouden - * Fritz Elfert - * Beat Doebeli - * - */ -#include <linux/init.h> -#include <linux/isapnp.h> -#include "hisax.h" -#include "isac.h" -#include "hscx.h" -#include "isdnl1.h" - -static const char *teles3_revision = "$Revision: 2.19.2.4 $"; - -#define byteout(addr, val) outb(val, addr) -#define bytein(addr) inb(addr) - -static inline u_char -readreg(unsigned int adr, u_char off) -{ - return (bytein(adr + off)); -} - -static inline void -writereg(unsigned int adr, u_char off, u_char data) -{ - byteout(adr + off, data); -} - - -static inline void -read_fifo(unsigned int adr, u_char *data, int size) -{ - insb(adr, data, size); -} - -static void -write_fifo(unsigned int adr, u_char *data, int size) -{ - outsb(adr, data, size); -} - -/* Interface functions */ - -static u_char -ReadISAC(struct IsdnCardState *cs, u_char offset) -{ - return (readreg(cs->hw.teles3.isac, offset)); -} - -static void -WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value) -{ - writereg(cs->hw.teles3.isac, offset, value); -} - -static void -ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - read_fifo(cs->hw.teles3.isacfifo, data, size); -} - -static void -WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - write_fifo(cs->hw.teles3.isacfifo, data, size); -} - -static u_char -ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset) -{ - return (readreg(cs->hw.teles3.hscx[hscx], offset)); -} - -static void -WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) -{ - writereg(cs->hw.teles3.hscx[hscx], offset, value); -} - -/* - * fast interrupt HSCX stuff goes here - */ - -#define READHSCX(cs, nr, reg) readreg(cs->hw.teles3.hscx[nr], reg) -#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.teles3.hscx[nr], reg, data) -#define READHSCXFIFO(cs, nr, ptr, cnt) read_fifo(cs->hw.teles3.hscxfifo[nr], ptr, cnt) -#define WRITEHSCXFIFO(cs, nr, ptr, cnt) write_fifo(cs->hw.teles3.hscxfifo[nr], ptr, cnt) - -#include "hscx_irq.c" - -static irqreturn_t -teles3_interrupt(int intno, void *dev_id) -{ -#define MAXCOUNT 5 - struct IsdnCardState *cs = dev_id; - u_char val; - u_long flags; - int count = 0; - - spin_lock_irqsave(&cs->lock, flags); - val = readreg(cs->hw.teles3.hscx[1], HSCX_ISTA); -Start_HSCX: - if (val) - hscx_int_main(cs, val); - val = readreg(cs->hw.teles3.isac, ISAC_ISTA); -Start_ISAC: - if (val) - isac_interrupt(cs, val); - count++; - val = readreg(cs->hw.teles3.hscx[1], HSCX_ISTA); - if (val && count < MAXCOUNT) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "HSCX IntStat after IntRoutine"); - goto Start_HSCX; - } - val = readreg(cs->hw.teles3.isac, ISAC_ISTA); - if (val && count < MAXCOUNT) { - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "ISAC IntStat after IntRoutine"); - goto Start_ISAC; - } - if (count >= MAXCOUNT) - printk(KERN_WARNING "Teles3: more than %d loops in teles3_interrupt\n", count); - writereg(cs->hw.teles3.hscx[0], HSCX_MASK, 0xFF); - writereg(cs->hw.teles3.hscx[1], HSCX_MASK, 0xFF); - writereg(cs->hw.teles3.isac, ISAC_MASK, 0xFF); - writereg(cs->hw.teles3.isac, ISAC_MASK, 0x0); - writereg(cs->hw.teles3.hscx[0], HSCX_MASK, 0x0); - writereg(cs->hw.teles3.hscx[1], HSCX_MASK, 0x0); - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -static inline void -release_ioregs(struct IsdnCardState *cs, int mask) -{ - if (mask & 1) - release_region(cs->hw.teles3.isac + 32, 32); - if (mask & 2) - release_region(cs->hw.teles3.hscx[0] + 32, 32); - if (mask & 4) - release_region(cs->hw.teles3.hscx[1] + 32, 32); -} - -static void -release_io_teles3(struct IsdnCardState *cs) -{ - if (cs->typ == ISDN_CTYPE_TELESPCMCIA) { - release_region(cs->hw.teles3.hscx[1], 96); - } else { - if (cs->hw.teles3.cfg_reg) { - if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) { - release_region(cs->hw.teles3.cfg_reg, 1); - } else { - release_region(cs->hw.teles3.cfg_reg, 8); - } - } - release_ioregs(cs, 0x7); - } -} - -static int -reset_teles3(struct IsdnCardState *cs) -{ - u_char irqcfg; - - if (cs->typ != ISDN_CTYPE_TELESPCMCIA) { - if ((cs->hw.teles3.cfg_reg) && (cs->typ != ISDN_CTYPE_COMPAQ_ISA)) { - switch (cs->irq) { - case 2: - case 9: - irqcfg = 0x00; - break; - case 3: - irqcfg = 0x02; - break; - case 4: - irqcfg = 0x04; - break; - case 5: - irqcfg = 0x06; - break; - case 10: - irqcfg = 0x08; - break; - case 11: - irqcfg = 0x0A; - break; - case 12: - irqcfg = 0x0C; - break; - case 15: - irqcfg = 0x0E; - break; - default: - return (1); - } - byteout(cs->hw.teles3.cfg_reg + 4, irqcfg); - HZDELAY(HZ / 10 + 1); - byteout(cs->hw.teles3.cfg_reg + 4, irqcfg | 1); - HZDELAY(HZ / 10 + 1); - } else if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) { - byteout(cs->hw.teles3.cfg_reg, 0xff); - HZDELAY(2); - byteout(cs->hw.teles3.cfg_reg, 0x00); - HZDELAY(2); - } else { - /* Reset off for 16.3 PnP , thanks to Georg Acher */ - byteout(cs->hw.teles3.isac + 0x3c, 0); - HZDELAY(2); - byteout(cs->hw.teles3.isac + 0x3c, 1); - HZDELAY(2); - } - } - return (0); -} - -static int -Teles_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - u_long flags; - - switch (mt) { - case CARD_RESET: - spin_lock_irqsave(&cs->lock, flags); - reset_teles3(cs); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_RELEASE: - release_io_teles3(cs); - return (0); - case CARD_INIT: - spin_lock_irqsave(&cs->lock, flags); - inithscxisac(cs, 3); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_TEST: - return (0); - } - return (0); -} - -#ifdef __ISAPNP__ - -static struct isapnp_device_id teles_ids[] = { - { ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x2110), - ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x2110), - (unsigned long) "Teles 16.3 PnP" }, - { ISAPNP_VENDOR('C', 'T', 'X'), ISAPNP_FUNCTION(0x0), - ISAPNP_VENDOR('C', 'T', 'X'), ISAPNP_FUNCTION(0x0), - (unsigned long) "Creatix 16.3 PnP" }, - { ISAPNP_VENDOR('C', 'P', 'Q'), ISAPNP_FUNCTION(0x1002), - ISAPNP_VENDOR('C', 'P', 'Q'), ISAPNP_FUNCTION(0x1002), - (unsigned long) "Compaq ISDN S0" }, - { 0, } -}; - -static struct isapnp_device_id *ipid = &teles_ids[0]; -static struct pnp_card *pnp_c = NULL; -#endif - -int setup_teles3(struct IsdnCard *card) -{ - u_char val; - struct IsdnCardState *cs = card->cs; - char tmp[64]; - - strcpy(tmp, teles3_revision); - printk(KERN_INFO "HiSax: Teles IO driver Rev. %s\n", HiSax_getrev(tmp)); - if ((cs->typ != ISDN_CTYPE_16_3) && (cs->typ != ISDN_CTYPE_PNP) - && (cs->typ != ISDN_CTYPE_TELESPCMCIA) && (cs->typ != ISDN_CTYPE_COMPAQ_ISA)) - return (0); - -#ifdef __ISAPNP__ - if (!card->para[1] && isapnp_present()) { - struct pnp_dev *pnp_d; - while (ipid->card_vendor) { - if ((pnp_c = pnp_find_card(ipid->card_vendor, - ipid->card_device, pnp_c))) { - pnp_d = NULL; - if ((pnp_d = pnp_find_dev(pnp_c, - ipid->vendor, ipid->function, pnp_d))) { - int err; - - printk(KERN_INFO "HiSax: %s detected\n", - (char *)ipid->driver_data); - pnp_disable_dev(pnp_d); - err = pnp_activate_dev(pnp_d); - if (err < 0) { - printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n", - __func__, err); - return (0); - } - card->para[3] = pnp_port_start(pnp_d, 2); - card->para[2] = pnp_port_start(pnp_d, 1); - card->para[1] = pnp_port_start(pnp_d, 0); - card->para[0] = pnp_irq(pnp_d, 0); - if (card->para[0] == -1 || !card->para[1] || !card->para[2]) { - printk(KERN_ERR "Teles PnP:some resources are missing %ld/%lx/%lx\n", - card->para[0], card->para[1], card->para[2]); - pnp_disable_dev(pnp_d); - return (0); - } - break; - } else { - printk(KERN_ERR "Teles PnP: PnP error card found, no device\n"); - } - } - ipid++; - pnp_c = NULL; - } - if (!ipid->card_vendor) { - printk(KERN_INFO "Teles PnP: no ISAPnP card found\n"); - return (0); - } - } -#endif - if (cs->typ == ISDN_CTYPE_16_3) { - cs->hw.teles3.cfg_reg = card->para[1]; - switch (cs->hw.teles3.cfg_reg) { - case 0x180: - case 0x280: - case 0x380: - cs->hw.teles3.cfg_reg |= 0xc00; - break; - } - cs->hw.teles3.isac = cs->hw.teles3.cfg_reg - 0x420; - cs->hw.teles3.hscx[0] = cs->hw.teles3.cfg_reg - 0xc20; - cs->hw.teles3.hscx[1] = cs->hw.teles3.cfg_reg - 0x820; - } else if (cs->typ == ISDN_CTYPE_TELESPCMCIA) { - cs->hw.teles3.cfg_reg = 0; - cs->hw.teles3.hscx[0] = card->para[1] - 0x20; - cs->hw.teles3.hscx[1] = card->para[1]; - cs->hw.teles3.isac = card->para[1] + 0x20; - } else if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) { - cs->hw.teles3.cfg_reg = card->para[3]; - cs->hw.teles3.isac = card->para[2] - 32; - cs->hw.teles3.hscx[0] = card->para[1] - 32; - cs->hw.teles3.hscx[1] = card->para[1]; - } else { /* PNP */ - cs->hw.teles3.cfg_reg = 0; - cs->hw.teles3.isac = card->para[1] - 32; - cs->hw.teles3.hscx[0] = card->para[2] - 32; - cs->hw.teles3.hscx[1] = card->para[2]; - } - cs->irq = card->para[0]; - cs->hw.teles3.isacfifo = cs->hw.teles3.isac + 0x3e; - cs->hw.teles3.hscxfifo[0] = cs->hw.teles3.hscx[0] + 0x3e; - cs->hw.teles3.hscxfifo[1] = cs->hw.teles3.hscx[1] + 0x3e; - if (cs->typ == ISDN_CTYPE_TELESPCMCIA) { - if (!request_region(cs->hw.teles3.hscx[1], 96, "HiSax Teles PCMCIA")) { - printk(KERN_WARNING - "HiSax: %s ports %x-%x already in use\n", - CardType[cs->typ], - cs->hw.teles3.hscx[1], - cs->hw.teles3.hscx[1] + 96); - return (0); - } - cs->irq_flags |= IRQF_SHARED; /* cardbus can share */ - } else { - if (cs->hw.teles3.cfg_reg) { - if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) { - if (!request_region(cs->hw.teles3.cfg_reg, 1, "teles3 cfg")) { - printk(KERN_WARNING - "HiSax: %s config port %x already in use\n", - CardType[card->typ], - cs->hw.teles3.cfg_reg); - return (0); - } - } else { - if (!request_region(cs->hw.teles3.cfg_reg, 8, "teles3 cfg")) { - printk(KERN_WARNING - "HiSax: %s config port %x-%x already in use\n", - CardType[card->typ], - cs->hw.teles3.cfg_reg, - cs->hw.teles3.cfg_reg + 8); - return (0); - } - } - } - if (!request_region(cs->hw.teles3.isac + 32, 32, "HiSax isac")) { - printk(KERN_WARNING - "HiSax: %s isac ports %x-%x already in use\n", - CardType[cs->typ], - cs->hw.teles3.isac + 32, - cs->hw.teles3.isac + 64); - if (cs->hw.teles3.cfg_reg) { - if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) { - release_region(cs->hw.teles3.cfg_reg, 1); - } else { - release_region(cs->hw.teles3.cfg_reg, 8); - } - } - return (0); - } - if (!request_region(cs->hw.teles3.hscx[0] + 32, 32, "HiSax hscx A")) { - printk(KERN_WARNING - "HiSax: %s hscx A ports %x-%x already in use\n", - CardType[cs->typ], - cs->hw.teles3.hscx[0] + 32, - cs->hw.teles3.hscx[0] + 64); - if (cs->hw.teles3.cfg_reg) { - if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) { - release_region(cs->hw.teles3.cfg_reg, 1); - } else { - release_region(cs->hw.teles3.cfg_reg, 8); - } - } - release_ioregs(cs, 1); - return (0); - } - if (!request_region(cs->hw.teles3.hscx[1] + 32, 32, "HiSax hscx B")) { - printk(KERN_WARNING - "HiSax: %s hscx B ports %x-%x already in use\n", - CardType[cs->typ], - cs->hw.teles3.hscx[1] + 32, - cs->hw.teles3.hscx[1] + 64); - if (cs->hw.teles3.cfg_reg) { - if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) { - release_region(cs->hw.teles3.cfg_reg, 1); - } else { - release_region(cs->hw.teles3.cfg_reg, 8); - } - } - release_ioregs(cs, 3); - return (0); - } - } - if ((cs->hw.teles3.cfg_reg) && (cs->typ != ISDN_CTYPE_COMPAQ_ISA)) { - if ((val = bytein(cs->hw.teles3.cfg_reg + 0)) != 0x51) { - printk(KERN_WARNING "Teles: 16.3 Byte at %x is %x\n", - cs->hw.teles3.cfg_reg + 0, val); - release_io_teles3(cs); - return (0); - } - if ((val = bytein(cs->hw.teles3.cfg_reg + 1)) != 0x93) { - printk(KERN_WARNING "Teles: 16.3 Byte at %x is %x\n", - cs->hw.teles3.cfg_reg + 1, val); - release_io_teles3(cs); - return (0); - } - val = bytein(cs->hw.teles3.cfg_reg + 2);/* 0x1e=without AB - * 0x1f=with AB - * 0x1c 16.3 ??? - * 0x39 16.3 1.1 - * 0x38 16.3 1.3 - * 0x46 16.3 with AB + Video (Teles-Vision) - */ - if (val != 0x46 && val != 0x39 && val != 0x38 && val != 0x1c && val != 0x1e && val != 0x1f) { - printk(KERN_WARNING "Teles: 16.3 Byte at %x is %x\n", - cs->hw.teles3.cfg_reg + 2, val); - release_io_teles3(cs); - return (0); - } - } - printk(KERN_INFO - "HiSax: %s config irq:%d isac:0x%X cfg:0x%X\n", - CardType[cs->typ], cs->irq, - cs->hw.teles3.isac + 32, cs->hw.teles3.cfg_reg); - printk(KERN_INFO - "HiSax: hscx A:0x%X hscx B:0x%X\n", - cs->hw.teles3.hscx[0] + 32, cs->hw.teles3.hscx[1] + 32); - - setup_isac(cs); - if (reset_teles3(cs)) { - printk(KERN_WARNING "Teles3: wrong IRQ\n"); - release_io_teles3(cs); - return (0); - } - cs->readisac = &ReadISAC; - cs->writeisac = &WriteISAC; - cs->readisacfifo = &ReadISACfifo; - cs->writeisacfifo = &WriteISACfifo; - cs->BC_Read_Reg = &ReadHSCX; - cs->BC_Write_Reg = &WriteHSCX; - cs->BC_Send_Data = &hscx_fill_fifo; - cs->cardmsg = &Teles_card_msg; - cs->irq_func = &teles3_interrupt; - ISACVersion(cs, "Teles3:"); - if (HscxVersion(cs, "Teles3:")) { - printk(KERN_WARNING - "Teles3: wrong HSCX versions check IO address\n"); - release_io_teles3(cs); - return (0); - } - return (1); -} diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c deleted file mode 100644 index bcc37e955622..000000000000 --- a/drivers/isdn/hisax/teles_cs.c +++ /dev/null @@ -1,201 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* $Id: teles_cs.c,v 1.1.2.2 2004/01/25 15:07:06 keil Exp $ */ -/*====================================================================== - - A teles S0 PCMCIA client driver - - Based on skeleton by David Hinds, dhinds@allegro.stanford.edu - Written by Christof Petig, christof.petig@wtal.de - - Also inspired by ELSA PCMCIA driver - by Klaus Lichtenwalder <Lichtenwalder@ACM.org> - - Extensions to new hisax_pcmcia by Karsten Keil - - minor changes to be compatible with kernel 2.4.x - by Jan.Schubert@GMX.li - - ======================================================================*/ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/ptrace.h> -#include <linux/slab.h> -#include <linux/string.h> -#include <linux/timer.h> -#include <linux/ioport.h> -#include <asm/io.h> - -#include <pcmcia/cistpl.h> -#include <pcmcia/cisreg.h> -#include <pcmcia/ds.h> -#include "hisax_cfg.h" - -MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Teles PCMCIA cards"); -MODULE_AUTHOR("Christof Petig, christof.petig@wtal.de, Karsten Keil, kkeil@suse.de"); -MODULE_LICENSE("GPL"); - - -/*====================================================================*/ - -/* Parameters that can be set with 'insmod' */ - -static int protocol = 2; /* EURO-ISDN Default */ -module_param(protocol, int, 0); - -static int teles_cs_config(struct pcmcia_device *link); -static void teles_cs_release(struct pcmcia_device *link); -static void teles_detach(struct pcmcia_device *p_dev); - -typedef struct local_info_t { - struct pcmcia_device *p_dev; - int busy; - int cardnr; -} local_info_t; - -static int teles_probe(struct pcmcia_device *link) -{ - local_info_t *local; - - dev_dbg(&link->dev, "teles_attach()\n"); - - /* Allocate space for private device-specific data */ - local = kzalloc(sizeof(local_info_t), GFP_KERNEL); - if (!local) return -ENOMEM; - local->cardnr = -1; - - local->p_dev = link; - link->priv = local; - - link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; - - return teles_cs_config(link); -} /* teles_attach */ - -static void teles_detach(struct pcmcia_device *link) -{ - local_info_t *info = link->priv; - - dev_dbg(&link->dev, "teles_detach(0x%p)\n", link); - - info->busy = 1; - teles_cs_release(link); - - kfree(info); -} /* teles_detach */ - -static int teles_cs_configcheck(struct pcmcia_device *p_dev, void *priv_data) -{ - int j; - - p_dev->io_lines = 5; - p_dev->resource[0]->end = 96; - p_dev->resource[0]->flags &= IO_DATA_PATH_WIDTH; - p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; - - if ((p_dev->resource[0]->end) && p_dev->resource[0]->start) { - printk(KERN_INFO "(teles_cs: looks like the 96 model)\n"); - if (!pcmcia_request_io(p_dev)) - return 0; - } else { - printk(KERN_INFO "(teles_cs: looks like the 97 model)\n"); - for (j = 0x2f0; j > 0x100; j -= 0x10) { - p_dev->resource[0]->start = j; - if (!pcmcia_request_io(p_dev)) - return 0; - } - } - return -ENODEV; -} - -static int teles_cs_config(struct pcmcia_device *link) -{ - int i; - IsdnCard_t icard; - - dev_dbg(&link->dev, "teles_config(0x%p)\n", link); - - i = pcmcia_loop_config(link, teles_cs_configcheck, NULL); - if (i != 0) - goto cs_failed; - - if (!link->irq) - goto cs_failed; - - i = pcmcia_enable_device(link); - if (i != 0) - goto cs_failed; - - icard.para[0] = link->irq; - icard.para[1] = link->resource[0]->start; - icard.protocol = protocol; - icard.typ = ISDN_CTYPE_TELESPCMCIA; - - i = hisax_init_pcmcia(link, &(((local_info_t *)link->priv)->busy), &icard); - if (i < 0) { - printk(KERN_ERR "teles_cs: failed to initialize Teles PCMCIA %d at i/o %#x\n", - i, (unsigned int) link->resource[0]->start); - teles_cs_release(link); - return -ENODEV; - } - - ((local_info_t *)link->priv)->cardnr = i; - return 0; - -cs_failed: - teles_cs_release(link); - return -ENODEV; -} /* teles_cs_config */ - -static void teles_cs_release(struct pcmcia_device *link) -{ - local_info_t *local = link->priv; - - dev_dbg(&link->dev, "teles_cs_release(0x%p)\n", link); - - if (local) { - if (local->cardnr >= 0) { - /* no unregister function with hisax */ - HiSax_closecard(local->cardnr); - } - } - - pcmcia_disable_device(link); -} /* teles_cs_release */ - -static int teles_suspend(struct pcmcia_device *link) -{ - local_info_t *dev = link->priv; - - dev->busy = 1; - - return 0; -} - -static int teles_resume(struct pcmcia_device *link) -{ - local_info_t *dev = link->priv; - - dev->busy = 0; - - return 0; -} - - -static const struct pcmcia_device_id teles_ids[] = { - PCMCIA_DEVICE_PROD_ID12("TELES", "S0/PC", 0x67b50eae, 0xe9e70119), - PCMCIA_DEVICE_NULL, -}; -MODULE_DEVICE_TABLE(pcmcia, teles_ids); - -static struct pcmcia_driver teles_cs_driver = { - .owner = THIS_MODULE, - .name = "teles_cs", - .probe = teles_probe, - .remove = teles_detach, - .id_table = teles_ids, - .suspend = teles_suspend, - .resume = teles_resume, -}; -module_pcmcia_driver(teles_cs_driver); diff --git a/drivers/isdn/hisax/telespci.c b/drivers/isdn/hisax/telespci.c deleted file mode 100644 index 33eeb4602c7e..000000000000 --- a/drivers/isdn/hisax/telespci.c +++ /dev/null @@ -1,349 +0,0 @@ -/* $Id: telespci.c,v 2.23.2.3 2004/01/13 14:31:26 keil Exp $ - * - * low level stuff for Teles PCI isdn cards - * - * Author Ton van Rosmalen - * Karsten Keil - * Copyright by Ton van Rosmalen - * by Karsten Keil <keil@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/init.h> -#include "hisax.h" -#include "isac.h" -#include "hscx.h" -#include "isdnl1.h" -#include <linux/pci.h> - -static const char *telespci_revision = "$Revision: 2.23.2.3 $"; - -#define ZORAN_PO_RQ_PEN 0x02000000 -#define ZORAN_PO_WR 0x00800000 -#define ZORAN_PO_GID0 0x00000000 -#define ZORAN_PO_GID1 0x00100000 -#define ZORAN_PO_GREG0 0x00000000 -#define ZORAN_PO_GREG1 0x00010000 -#define ZORAN_PO_DMASK 0xFF - -#define WRITE_ADDR_ISAC (ZORAN_PO_WR | ZORAN_PO_GID0 | ZORAN_PO_GREG0) -#define READ_DATA_ISAC (ZORAN_PO_GID0 | ZORAN_PO_GREG1) -#define WRITE_DATA_ISAC (ZORAN_PO_WR | ZORAN_PO_GID0 | ZORAN_PO_GREG1) -#define WRITE_ADDR_HSCX (ZORAN_PO_WR | ZORAN_PO_GID1 | ZORAN_PO_GREG0) -#define READ_DATA_HSCX (ZORAN_PO_GID1 | ZORAN_PO_GREG1) -#define WRITE_DATA_HSCX (ZORAN_PO_WR | ZORAN_PO_GID1 | ZORAN_PO_GREG1) - -#define ZORAN_WAIT_NOBUSY do { \ - portdata = readl(adr + 0x200); \ - } while (portdata & ZORAN_PO_RQ_PEN) - -static inline u_char -readisac(void __iomem *adr, u_char off) -{ - register unsigned int portdata; - - ZORAN_WAIT_NOBUSY; - - /* set address for ISAC */ - writel(WRITE_ADDR_ISAC | off, adr + 0x200); - ZORAN_WAIT_NOBUSY; - - /* read data from ISAC */ - writel(READ_DATA_ISAC, adr + 0x200); - ZORAN_WAIT_NOBUSY; - return ((u_char)(portdata & ZORAN_PO_DMASK)); -} - -static inline void -writeisac(void __iomem *adr, u_char off, u_char data) -{ - register unsigned int portdata; - - ZORAN_WAIT_NOBUSY; - - /* set address for ISAC */ - writel(WRITE_ADDR_ISAC | off, adr + 0x200); - ZORAN_WAIT_NOBUSY; - - /* write data to ISAC */ - writel(WRITE_DATA_ISAC | data, adr + 0x200); - ZORAN_WAIT_NOBUSY; -} - -static inline u_char -readhscx(void __iomem *adr, int hscx, u_char off) -{ - register unsigned int portdata; - - ZORAN_WAIT_NOBUSY; - /* set address for HSCX */ - writel(WRITE_ADDR_HSCX | ((hscx ? 0x40 : 0) + off), adr + 0x200); - ZORAN_WAIT_NOBUSY; - - /* read data from HSCX */ - writel(READ_DATA_HSCX, adr + 0x200); - ZORAN_WAIT_NOBUSY; - return ((u_char)(portdata & ZORAN_PO_DMASK)); -} - -static inline void -writehscx(void __iomem *adr, int hscx, u_char off, u_char data) -{ - register unsigned int portdata; - - ZORAN_WAIT_NOBUSY; - /* set address for HSCX */ - writel(WRITE_ADDR_HSCX | ((hscx ? 0x40 : 0) + off), adr + 0x200); - ZORAN_WAIT_NOBUSY; - - /* write data to HSCX */ - writel(WRITE_DATA_HSCX | data, adr + 0x200); - ZORAN_WAIT_NOBUSY; -} - -static inline void -read_fifo_isac(void __iomem *adr, u_char *data, int size) -{ - register unsigned int portdata; - register int i; - - ZORAN_WAIT_NOBUSY; - /* read data from ISAC */ - for (i = 0; i < size; i++) { - /* set address for ISAC fifo */ - writel(WRITE_ADDR_ISAC | 0x1E, adr + 0x200); - ZORAN_WAIT_NOBUSY; - writel(READ_DATA_ISAC, adr + 0x200); - ZORAN_WAIT_NOBUSY; - data[i] = (u_char)(portdata & ZORAN_PO_DMASK); - } -} - -static void -write_fifo_isac(void __iomem *adr, u_char *data, int size) -{ - register unsigned int portdata; - register int i; - - ZORAN_WAIT_NOBUSY; - /* write data to ISAC */ - for (i = 0; i < size; i++) { - /* set address for ISAC fifo */ - writel(WRITE_ADDR_ISAC | 0x1E, adr + 0x200); - ZORAN_WAIT_NOBUSY; - writel(WRITE_DATA_ISAC | data[i], adr + 0x200); - ZORAN_WAIT_NOBUSY; - } -} - -static inline void -read_fifo_hscx(void __iomem *adr, int hscx, u_char *data, int size) -{ - register unsigned int portdata; - register int i; - - ZORAN_WAIT_NOBUSY; - /* read data from HSCX */ - for (i = 0; i < size; i++) { - /* set address for HSCX fifo */ - writel(WRITE_ADDR_HSCX | (hscx ? 0x5F : 0x1F), adr + 0x200); - ZORAN_WAIT_NOBUSY; - writel(READ_DATA_HSCX, adr + 0x200); - ZORAN_WAIT_NOBUSY; - data[i] = (u_char) (portdata & ZORAN_PO_DMASK); - } -} - -static inline void -write_fifo_hscx(void __iomem *adr, int hscx, u_char *data, int size) -{ - unsigned int portdata; - register int i; - - ZORAN_WAIT_NOBUSY; - /* write data to HSCX */ - for (i = 0; i < size; i++) { - /* set address for HSCX fifo */ - writel(WRITE_ADDR_HSCX | (hscx ? 0x5F : 0x1F), adr + 0x200); - ZORAN_WAIT_NOBUSY; - writel(WRITE_DATA_HSCX | data[i], adr + 0x200); - ZORAN_WAIT_NOBUSY; - udelay(10); - } -} - -/* Interface functions */ - -static u_char -ReadISAC(struct IsdnCardState *cs, u_char offset) -{ - return (readisac(cs->hw.teles0.membase, offset)); -} - -static void -WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value) -{ - writeisac(cs->hw.teles0.membase, offset, value); -} - -static void -ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - read_fifo_isac(cs->hw.teles0.membase, data, size); -} - -static void -WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - write_fifo_isac(cs->hw.teles0.membase, data, size); -} - -static u_char -ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset) -{ - return (readhscx(cs->hw.teles0.membase, hscx, offset)); -} - -static void -WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) -{ - writehscx(cs->hw.teles0.membase, hscx, offset, value); -} - -/* - * fast interrupt HSCX stuff goes here - */ - -#define READHSCX(cs, nr, reg) readhscx(cs->hw.teles0.membase, nr, reg) -#define WRITEHSCX(cs, nr, reg, data) writehscx(cs->hw.teles0.membase, nr, reg, data) -#define READHSCXFIFO(cs, nr, ptr, cnt) read_fifo_hscx(cs->hw.teles0.membase, nr, ptr, cnt) -#define WRITEHSCXFIFO(cs, nr, ptr, cnt) write_fifo_hscx(cs->hw.teles0.membase, nr, ptr, cnt) - -#include "hscx_irq.c" - -static irqreturn_t -telespci_interrupt(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - u_char hval, ival; - u_long flags; - - spin_lock_irqsave(&cs->lock, flags); - hval = readhscx(cs->hw.teles0.membase, 1, HSCX_ISTA); - if (hval) - hscx_int_main(cs, hval); - ival = readisac(cs->hw.teles0.membase, ISAC_ISTA); - if ((hval | ival) == 0) { - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_NONE; - } - if (ival) - isac_interrupt(cs, ival); - /* Clear interrupt register for Zoran PCI controller */ - writel(0x70000000, cs->hw.teles0.membase + 0x3C); - - writehscx(cs->hw.teles0.membase, 0, HSCX_MASK, 0xFF); - writehscx(cs->hw.teles0.membase, 1, HSCX_MASK, 0xFF); - writeisac(cs->hw.teles0.membase, ISAC_MASK, 0xFF); - writeisac(cs->hw.teles0.membase, ISAC_MASK, 0x0); - writehscx(cs->hw.teles0.membase, 0, HSCX_MASK, 0x0); - writehscx(cs->hw.teles0.membase, 1, HSCX_MASK, 0x0); - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -static void -release_io_telespci(struct IsdnCardState *cs) -{ - iounmap(cs->hw.teles0.membase); -} - -static int -TelesPCI_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - u_long flags; - - switch (mt) { - case CARD_RESET: - return (0); - case CARD_RELEASE: - release_io_telespci(cs); - return (0); - case CARD_INIT: - spin_lock_irqsave(&cs->lock, flags); - inithscxisac(cs, 3); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_TEST: - return (0); - } - return (0); -} - -static struct pci_dev *dev_tel = NULL; - -int setup_telespci(struct IsdnCard *card) -{ - struct IsdnCardState *cs = card->cs; - char tmp[64]; - - strcpy(tmp, telespci_revision); - printk(KERN_INFO "HiSax: Teles/PCI driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_TELESPCI) - return (0); - - if ((dev_tel = hisax_find_pci_device(PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36120, dev_tel))) { - if (pci_enable_device(dev_tel)) - return (0); - cs->irq = dev_tel->irq; - if (!cs->irq) { - printk(KERN_WARNING "Teles: No IRQ for PCI card found\n"); - return (0); - } - cs->hw.teles0.membase = ioremap(pci_resource_start(dev_tel, 0), - PAGE_SIZE); - printk(KERN_INFO "Found: Zoran, base-address: 0x%llx, irq: 0x%x\n", - (unsigned long long)pci_resource_start(dev_tel, 0), - dev_tel->irq); - } else { - printk(KERN_WARNING "TelesPCI: No PCI card found\n"); - return (0); - } - - /* Initialize Zoran PCI controller */ - writel(0x00000000, cs->hw.teles0.membase + 0x28); - writel(0x01000000, cs->hw.teles0.membase + 0x28); - writel(0x01000000, cs->hw.teles0.membase + 0x28); - writel(0x7BFFFFFF, cs->hw.teles0.membase + 0x2C); - writel(0x70000000, cs->hw.teles0.membase + 0x3C); - writel(0x61000000, cs->hw.teles0.membase + 0x40); - /* writel(0x00800000, cs->hw.teles0.membase + 0x200); */ - - printk(KERN_INFO - "HiSax: Teles PCI config irq:%d mem:%p\n", - cs->irq, - cs->hw.teles0.membase); - - setup_isac(cs); - cs->readisac = &ReadISAC; - cs->writeisac = &WriteISAC; - cs->readisacfifo = &ReadISACfifo; - cs->writeisacfifo = &WriteISACfifo; - cs->BC_Read_Reg = &ReadHSCX; - cs->BC_Write_Reg = &WriteHSCX; - cs->BC_Send_Data = &hscx_fill_fifo; - cs->cardmsg = &TelesPCI_card_msg; - cs->irq_func = &telespci_interrupt; - cs->irq_flags |= IRQF_SHARED; - ISACVersion(cs, "TelesPCI:"); - if (HscxVersion(cs, "TelesPCI:")) { - printk(KERN_WARNING - "TelesPCI: wrong HSCX versions check IO/MEM addresses\n"); - release_io_telespci(cs); - return (0); - } - return (1); -} diff --git a/drivers/isdn/hisax/w6692.c b/drivers/isdn/hisax/w6692.c deleted file mode 100644 index 36eefaa3a7d9..000000000000 --- a/drivers/isdn/hisax/w6692.c +++ /dev/null @@ -1,1085 +0,0 @@ -/* $Id: w6692.c,v 1.18.2.4 2004/02/11 13:21:34 keil Exp $ - * - * Winbond W6692 specific routines - * - * Author Petr Novak - * Copyright by Petr Novak <petr.novak@i.cz> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#include <linux/init.h> -#include "hisax.h" -#include "w6692.h" -#include "isdnl1.h" -#include <linux/interrupt.h> -#include <linux/pci.h> -#include <linux/slab.h> - -/* table entry in the PCI devices list */ -typedef struct { - int vendor_id; - int device_id; - char *vendor_name; - char *card_name; -} PCI_ENTRY; - -static const PCI_ENTRY id_list[] = -{ - {PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_6692, "Winbond", "W6692"}, - {PCI_VENDOR_ID_DYNALINK, PCI_DEVICE_ID_DYNALINK_IS64PH, "Dynalink/AsusCom", "IS64PH"}, - {0, 0, "U.S.Robotics", "ISDN PCI Card TA"} -}; - -#define W6692_SV_USR 0x16ec -#define W6692_SD_USR 0x3409 -#define W6692_WINBOND 0 -#define W6692_DYNALINK 1 -#define W6692_USR 2 - -static const char *w6692_revision = "$Revision: 1.18.2.4 $"; - -#define DBUSY_TIMER_VALUE 80 - -static char *W6692Ver[] = -{"W6692 V00", "W6692 V01", "W6692 V10", - "W6692 V11"}; - -static void -W6692Version(struct IsdnCardState *cs, char *s) -{ - int val; - - val = cs->readW6692(cs, W_D_RBCH); - printk(KERN_INFO "%s Winbond W6692 version (%x): %s\n", s, val, W6692Ver[(val >> 6) & 3]); -} - -static void -ph_command(struct IsdnCardState *cs, unsigned int command) -{ - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "ph_command %x", command); - cs->writeisac(cs, W_CIX, command); -} - - -static void -W6692_new_ph(struct IsdnCardState *cs) -{ - switch (cs->dc.w6692.ph_state) { - case (W_L1CMD_RST): - ph_command(cs, W_L1CMD_DRC); - l1_msg(cs, HW_RESET | INDICATION, NULL); - /* fall through */ - case (W_L1IND_CD): - l1_msg(cs, HW_DEACTIVATE | CONFIRM, NULL); - break; - case (W_L1IND_DRD): - l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL); - break; - case (W_L1IND_CE): - l1_msg(cs, HW_POWERUP | CONFIRM, NULL); - break; - case (W_L1IND_LD): - l1_msg(cs, HW_RSYNC | INDICATION, NULL); - break; - case (W_L1IND_ARD): - l1_msg(cs, HW_INFO2 | INDICATION, NULL); - break; - case (W_L1IND_AI8): - l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL); - break; - case (W_L1IND_AI10): - l1_msg(cs, HW_INFO4_P10 | INDICATION, NULL); - break; - default: - break; - } -} - -static void -W6692_bh(struct work_struct *work) -{ - struct IsdnCardState *cs = - container_of(work, struct IsdnCardState, tqueue); - struct PStack *stptr; - - if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) { - if (cs->debug) - debugl1(cs, "D-Channel Busy cleared"); - stptr = cs->stlist; - while (stptr != NULL) { - stptr->l1.l1l2(stptr, PH_PAUSE | CONFIRM, NULL); - stptr = stptr->next; - } - } - if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) - W6692_new_ph(cs); - if (test_and_clear_bit(D_RCVBUFREADY, &cs->event)) - DChannel_proc_rcv(cs); - if (test_and_clear_bit(D_XMTBUFREADY, &cs->event)) - DChannel_proc_xmt(cs); -/* - if (test_and_clear_bit(D_RX_MON1, &cs->event)) - arcofi_fsm(cs, ARCOFI_RX_END, NULL); - if (test_and_clear_bit(D_TX_MON1, &cs->event)) - arcofi_fsm(cs, ARCOFI_TX_END, NULL); -*/ -} - -static void -W6692_empty_fifo(struct IsdnCardState *cs, int count) -{ - u_char *ptr; - - if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO)) - debugl1(cs, "W6692_empty_fifo"); - - if ((cs->rcvidx + count) >= MAX_DFRAME_LEN_L1) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "W6692_empty_fifo overrun %d", - cs->rcvidx + count); - cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_RACK); - cs->rcvidx = 0; - return; - } - ptr = cs->rcvbuf + cs->rcvidx; - cs->rcvidx += count; - cs->readW6692fifo(cs, ptr, count); - cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_RACK); - if (cs->debug & L1_DEB_ISAC_FIFO) { - char *t = cs->dlog; - - t += sprintf(t, "W6692_empty_fifo cnt %d", count); - QuickHex(t, ptr, count); - debugl1(cs, "%s", cs->dlog); - } -} - -static void -W6692_fill_fifo(struct IsdnCardState *cs) -{ - int count, more; - u_char *ptr; - - if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO)) - debugl1(cs, "W6692_fill_fifo"); - - if (!cs->tx_skb) - return; - - count = cs->tx_skb->len; - if (count <= 0) - return; - - more = 0; - if (count > W_D_FIFO_THRESH) { - more = !0; - count = W_D_FIFO_THRESH; - } - ptr = cs->tx_skb->data; - skb_pull(cs->tx_skb, count); - cs->tx_cnt += count; - cs->writeW6692fifo(cs, ptr, count); - cs->writeW6692(cs, W_D_CMDR, more ? W_D_CMDR_XMS : (W_D_CMDR_XMS | W_D_CMDR_XME)); - if (test_and_set_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) { - debugl1(cs, "W6692_fill_fifo dbusytimer running"); - del_timer(&cs->dbusytimer); - } - cs->dbusytimer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ) / 1000); - add_timer(&cs->dbusytimer); - if (cs->debug & L1_DEB_ISAC_FIFO) { - char *t = cs->dlog; - - t += sprintf(t, "W6692_fill_fifo cnt %d", count); - QuickHex(t, ptr, count); - debugl1(cs, "%s", cs->dlog); - } -} - -static void -W6692B_empty_fifo(struct BCState *bcs, int count) -{ - u_char *ptr; - struct IsdnCardState *cs = bcs->cs; - - if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) - debugl1(cs, "W6692B_empty_fifo"); - - if (bcs->hw.w6692.rcvidx + count > HSCX_BUFMAX) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "W6692B_empty_fifo: incoming packet too large"); - cs->BC_Write_Reg(cs, bcs->channel, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT); - bcs->hw.w6692.rcvidx = 0; - return; - } - ptr = bcs->hw.w6692.rcvbuf + bcs->hw.w6692.rcvidx; - bcs->hw.w6692.rcvidx += count; - READW6692BFIFO(cs, bcs->channel, ptr, count); - cs->BC_Write_Reg(cs, bcs->channel, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT); - if (cs->debug & L1_DEB_HSCX_FIFO) { - char *t = bcs->blog; - - t += sprintf(t, "W6692B_empty_fifo %c cnt %d", - bcs->channel + '1', count); - QuickHex(t, ptr, count); - debugl1(cs, "%s", bcs->blog); - } -} - -static void -W6692B_fill_fifo(struct BCState *bcs) -{ - struct IsdnCardState *cs = bcs->cs; - int more, count; - u_char *ptr; - - if (!bcs->tx_skb) - return; - if (bcs->tx_skb->len <= 0) - return; - - more = (bcs->mode == L1_MODE_TRANS) ? 1 : 0; - if (bcs->tx_skb->len > W_B_FIFO_THRESH) { - more = 1; - count = W_B_FIFO_THRESH; - } else - count = bcs->tx_skb->len; - - if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) - debugl1(cs, "W6692B_fill_fifo%s%d", (more ? " " : " last "), count); - - ptr = bcs->tx_skb->data; - skb_pull(bcs->tx_skb, count); - bcs->tx_cnt -= count; - bcs->hw.w6692.count += count; - WRITEW6692BFIFO(cs, bcs->channel, ptr, count); - cs->BC_Write_Reg(cs, bcs->channel, W_B_CMDR, W_B_CMDR_RACT | W_B_CMDR_XMS | (more ? 0 : W_B_CMDR_XME)); - if (cs->debug & L1_DEB_HSCX_FIFO) { - char *t = bcs->blog; - - t += sprintf(t, "W6692B_fill_fifo %c cnt %d", - bcs->channel + '1', count); - QuickHex(t, ptr, count); - debugl1(cs, "%s", bcs->blog); - } -} - -static void -W6692B_interrupt(struct IsdnCardState *cs, u_char bchan) -{ - u_char val; - u_char r; - struct BCState *bcs; - struct sk_buff *skb; - int count; - - bcs = (cs->bcs->channel == bchan) ? cs->bcs : (cs->bcs + 1); - val = cs->BC_Read_Reg(cs, bchan, W_B_EXIR); - debugl1(cs, "W6692B chan %d B_EXIR 0x%02X", bchan, val); - - if (!test_bit(BC_FLG_INIT, &bcs->Flag)) { - debugl1(cs, "W6692B not INIT yet"); - return; - } - if (val & W_B_EXI_RME) { /* RME */ - r = cs->BC_Read_Reg(cs, bchan, W_B_STAR); - if (r & (W_B_STAR_RDOV | W_B_STAR_CRCE | W_B_STAR_RMB)) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "W6692 B STAR %x", r); - if ((r & W_B_STAR_RDOV) && bcs->mode) - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "W6692 B RDOV mode=%d", - bcs->mode); - if (r & W_B_STAR_CRCE) - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "W6692 B CRC error"); - cs->BC_Write_Reg(cs, bchan, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RRST | W_B_CMDR_RACT); - } else { - count = cs->BC_Read_Reg(cs, bchan, W_B_RBCL) & (W_B_FIFO_THRESH - 1); - if (count == 0) - count = W_B_FIFO_THRESH; - W6692B_empty_fifo(bcs, count); - if ((count = bcs->hw.w6692.rcvidx) > 0) { - if (cs->debug & L1_DEB_HSCX_FIFO) - debugl1(cs, "W6692 Bchan Frame %d", count); - if (!(skb = dev_alloc_skb(count))) - printk(KERN_WARNING "W6692: Bchan receive out of memory\n"); - else { - skb_put_data(skb, - bcs->hw.w6692.rcvbuf, - count); - skb_queue_tail(&bcs->rqueue, skb); - } - } - } - bcs->hw.w6692.rcvidx = 0; - schedule_event(bcs, B_RCVBUFREADY); - } - if (val & W_B_EXI_RMR) { /* RMR */ - W6692B_empty_fifo(bcs, W_B_FIFO_THRESH); - r = cs->BC_Read_Reg(cs, bchan, W_B_STAR); - if (r & W_B_STAR_RDOV) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "W6692 B RDOV(RMR) mode=%d", bcs->mode); - cs->BC_Write_Reg(cs, bchan, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RRST | W_B_CMDR_RACT); - if (bcs->mode != L1_MODE_TRANS) - bcs->hw.w6692.rcvidx = 0; - } - if (bcs->mode == L1_MODE_TRANS) { - /* receive audio data */ - if (!(skb = dev_alloc_skb(W_B_FIFO_THRESH))) - printk(KERN_WARNING "HiSax: receive out of memory\n"); - else { - skb_put_data(skb, bcs->hw.w6692.rcvbuf, - W_B_FIFO_THRESH); - skb_queue_tail(&bcs->rqueue, skb); - } - bcs->hw.w6692.rcvidx = 0; - schedule_event(bcs, B_RCVBUFREADY); - } - } - if (val & W_B_EXI_XDUN) { /* XDUN */ - cs->BC_Write_Reg(cs, bchan, W_B_CMDR, W_B_CMDR_XRST | W_B_CMDR_RACT); - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "W6692 B EXIR %x Lost TX", val); - if (bcs->mode == 1) - W6692B_fill_fifo(bcs); - else { - /* Here we lost an TX interrupt, so - * restart transmitting the whole frame. - */ - if (bcs->tx_skb) { - skb_push(bcs->tx_skb, bcs->hw.w6692.count); - bcs->tx_cnt += bcs->hw.w6692.count; - bcs->hw.w6692.count = 0; - } - } - return; - } - if (val & W_B_EXI_XFR) { /* XFR */ - r = cs->BC_Read_Reg(cs, bchan, W_B_STAR); - if (r & W_B_STAR_XDOW) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "W6692 B STAR %x XDOW", r); - cs->BC_Write_Reg(cs, bchan, W_B_CMDR, W_B_CMDR_XRST | W_B_CMDR_RACT); - if (bcs->tx_skb && (bcs->mode != 1)) { - skb_push(bcs->tx_skb, bcs->hw.w6692.count); - bcs->tx_cnt += bcs->hw.w6692.count; - bcs->hw.w6692.count = 0; - } - } - if (bcs->tx_skb) { - if (bcs->tx_skb->len) { - W6692B_fill_fifo(bcs); - return; - } else { - if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) && - (PACKET_NOACK != bcs->tx_skb->pkt_type)) { - u_long flags; - spin_lock_irqsave(&bcs->aclock, flags); - bcs->ackcnt += bcs->hw.w6692.count; - spin_unlock_irqrestore(&bcs->aclock, flags); - schedule_event(bcs, B_ACKPENDING); - } - dev_kfree_skb_irq(bcs->tx_skb); - bcs->hw.w6692.count = 0; - bcs->tx_skb = NULL; - } - } - if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) { - bcs->hw.w6692.count = 0; - test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); - W6692B_fill_fifo(bcs); - } else { - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - schedule_event(bcs, B_XMTBUFREADY); - } - } -} - -static irqreturn_t -W6692_interrupt(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - u_char val, exval, v1; - struct sk_buff *skb; - u_int count; - u_long flags; - int icnt = 5; - - spin_lock_irqsave(&cs->lock, flags); - val = cs->readW6692(cs, W_ISTA); - if (!val) { - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_NONE; - } -StartW6692: - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "W6692 ISTA %x", val); - - if (val & W_INT_D_RME) { /* RME */ - exval = cs->readW6692(cs, W_D_RSTA); - if (exval & (W_D_RSTA_RDOV | W_D_RSTA_CRCE | W_D_RSTA_RMB)) { - if (exval & W_D_RSTA_RDOV) - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "W6692 RDOV"); - if (exval & W_D_RSTA_CRCE) - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "W6692 D-channel CRC error"); - if (exval & W_D_RSTA_RMB) - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "W6692 D-channel ABORT"); - cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_RACK | W_D_CMDR_RRST); - } else { - count = cs->readW6692(cs, W_D_RBCL) & (W_D_FIFO_THRESH - 1); - if (count == 0) - count = W_D_FIFO_THRESH; - W6692_empty_fifo(cs, count); - if ((count = cs->rcvidx) > 0) { - cs->rcvidx = 0; - if (!(skb = alloc_skb(count, GFP_ATOMIC))) - printk(KERN_WARNING "HiSax: D receive out of memory\n"); - else { - skb_put_data(skb, cs->rcvbuf, count); - skb_queue_tail(&cs->rq, skb); - } - } - } - cs->rcvidx = 0; - schedule_event(cs, D_RCVBUFREADY); - } - if (val & W_INT_D_RMR) { /* RMR */ - W6692_empty_fifo(cs, W_D_FIFO_THRESH); - } - if (val & W_INT_D_XFR) { /* XFR */ - if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) - del_timer(&cs->dbusytimer); - if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags)) - schedule_event(cs, D_CLEARBUSY); - if (cs->tx_skb) { - if (cs->tx_skb->len) { - W6692_fill_fifo(cs); - goto afterXFR; - } else { - dev_kfree_skb_irq(cs->tx_skb); - cs->tx_cnt = 0; - cs->tx_skb = NULL; - } - } - if ((cs->tx_skb = skb_dequeue(&cs->sq))) { - cs->tx_cnt = 0; - W6692_fill_fifo(cs); - } else - schedule_event(cs, D_XMTBUFREADY); - } -afterXFR: - if (val & (W_INT_XINT0 | W_INT_XINT1)) { /* XINT0/1 - never */ - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "W6692 spurious XINT!"); - } - if (val & W_INT_D_EXI) { /* EXI */ - exval = cs->readW6692(cs, W_D_EXIR); - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "W6692 D_EXIR %02x", exval); - if (exval & (W_D_EXI_XDUN | W_D_EXI_XCOL)) { /* Transmit underrun/collision */ - debugl1(cs, "W6692 D-chan underrun/collision"); - printk(KERN_WARNING "HiSax: W6692 XDUN/XCOL\n"); - if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) - del_timer(&cs->dbusytimer); - if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags)) - schedule_event(cs, D_CLEARBUSY); - if (cs->tx_skb) { /* Restart frame */ - skb_push(cs->tx_skb, cs->tx_cnt); - cs->tx_cnt = 0; - W6692_fill_fifo(cs); - } else { - printk(KERN_WARNING "HiSax: W6692 XDUN/XCOL no skb\n"); - debugl1(cs, "W6692 XDUN/XCOL no skb"); - cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_XRST); - } - } - if (exval & W_D_EXI_RDOV) { /* RDOV */ - debugl1(cs, "W6692 D-channel RDOV"); - printk(KERN_WARNING "HiSax: W6692 D-RDOV\n"); - cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_RRST); - } - if (exval & W_D_EXI_TIN2) { /* TIN2 - never */ - debugl1(cs, "W6692 spurious TIN2 interrupt"); - } - if (exval & W_D_EXI_MOC) { /* MOC - not supported */ - debugl1(cs, "W6692 spurious MOC interrupt"); - v1 = cs->readW6692(cs, W_MOSR); - debugl1(cs, "W6692 MOSR %02x", v1); - } - if (exval & W_D_EXI_ISC) { /* ISC - Level1 change */ - v1 = cs->readW6692(cs, W_CIR); - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "W6692 ISC CIR=0x%02X", v1); - if (v1 & W_CIR_ICC) { - cs->dc.w6692.ph_state = v1 & W_CIR_COD_MASK; - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "ph_state_change %x", cs->dc.w6692.ph_state); - schedule_event(cs, D_L1STATECHANGE); - } - if (v1 & W_CIR_SCC) { - v1 = cs->readW6692(cs, W_SQR); - debugl1(cs, "W6692 SCC SQR=0x%02X", v1); - } - } - if (exval & W_D_EXI_WEXP) { - debugl1(cs, "W6692 spurious WEXP interrupt!"); - } - if (exval & W_D_EXI_TEXP) { - debugl1(cs, "W6692 spurious TEXP interrupt!"); - } - } - if (val & W_INT_B1_EXI) { - debugl1(cs, "W6692 B channel 1 interrupt"); - W6692B_interrupt(cs, 0); - } - if (val & W_INT_B2_EXI) { - debugl1(cs, "W6692 B channel 2 interrupt"); - W6692B_interrupt(cs, 1); - } - val = cs->readW6692(cs, W_ISTA); - if (val && icnt) { - icnt--; - goto StartW6692; - } - if (!icnt) { - printk(KERN_WARNING "W6692 IRQ LOOP\n"); - cs->writeW6692(cs, W_IMASK, 0xff); - } - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -static void -W6692_l1hw(struct PStack *st, int pr, void *arg) -{ - struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware; - struct sk_buff *skb = arg; - u_long flags; - int val; - - switch (pr) { - case (PH_DATA | REQUEST): - if (cs->debug & DEB_DLOG_HEX) - LogFrame(cs, skb->data, skb->len); - if (cs->debug & DEB_DLOG_VERBOSE) - dlogframe(cs, skb, 0); - spin_lock_irqsave(&cs->lock, flags); - if (cs->tx_skb) { - skb_queue_tail(&cs->sq, skb); -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - Logl2Frame(cs, skb, "PH_DATA Queued", 0); -#endif - } else { - cs->tx_skb = skb; - cs->tx_cnt = 0; -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - Logl2Frame(cs, skb, "PH_DATA", 0); -#endif - W6692_fill_fifo(cs); - } - spin_unlock_irqrestore(&cs->lock, flags); - break; - case (PH_PULL | INDICATION): - spin_lock_irqsave(&cs->lock, flags); - if (cs->tx_skb) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, " l2l1 tx_skb exist this shouldn't happen"); - skb_queue_tail(&cs->sq, skb); - spin_unlock_irqrestore(&cs->lock, flags); - break; - } - if (cs->debug & DEB_DLOG_HEX) - LogFrame(cs, skb->data, skb->len); - if (cs->debug & DEB_DLOG_VERBOSE) - dlogframe(cs, skb, 0); - cs->tx_skb = skb; - cs->tx_cnt = 0; -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - Logl2Frame(cs, skb, "PH_DATA_PULLED", 0); -#endif - W6692_fill_fifo(cs); - spin_unlock_irqrestore(&cs->lock, flags); - break; - case (PH_PULL | REQUEST): -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - debugl1(cs, "-> PH_REQUEST_PULL"); -#endif - if (!cs->tx_skb) { - test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); - } else - test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - break; - case (HW_RESET | REQUEST): - spin_lock_irqsave(&cs->lock, flags); - if (cs->dc.w6692.ph_state == W_L1IND_DRD) { - ph_command(cs, W_L1CMD_ECK); - spin_unlock_irqrestore(&cs->lock, flags); - } else { - ph_command(cs, W_L1CMD_RST); - cs->dc.w6692.ph_state = W_L1CMD_RST; - spin_unlock_irqrestore(&cs->lock, flags); - W6692_new_ph(cs); - } - break; - case (HW_ENABLE | REQUEST): - spin_lock_irqsave(&cs->lock, flags); - ph_command(cs, W_L1CMD_ECK); - spin_unlock_irqrestore(&cs->lock, flags); - break; - case (HW_INFO3 | REQUEST): - spin_lock_irqsave(&cs->lock, flags); - ph_command(cs, W_L1CMD_AR8); - spin_unlock_irqrestore(&cs->lock, flags); - break; - case (HW_TESTLOOP | REQUEST): - val = 0; - if (1 & (long) arg) - val |= 0x0c; - if (2 & (long) arg) - val |= 0x3; - /* !!! not implemented yet */ - break; - case (HW_DEACTIVATE | RESPONSE): - skb_queue_purge(&cs->rq); - skb_queue_purge(&cs->sq); - if (cs->tx_skb) { - dev_kfree_skb_any(cs->tx_skb); - cs->tx_skb = NULL; - } - if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) - del_timer(&cs->dbusytimer); - if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags)) - schedule_event(cs, D_CLEARBUSY); - break; - default: - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "W6692_l1hw unknown %04x", pr); - break; - } -} - -static void -setstack_W6692(struct PStack *st, struct IsdnCardState *cs) -{ - st->l1.l1hw = W6692_l1hw; -} - -static void -DC_Close_W6692(struct IsdnCardState *cs) -{ -} - -static void -dbusy_timer_handler(struct timer_list *t) -{ - struct IsdnCardState *cs = from_timer(cs, t, dbusytimer); - struct PStack *stptr; - int rbch, star; - u_long flags; - - spin_lock_irqsave(&cs->lock, flags); - if (test_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) { - rbch = cs->readW6692(cs, W_D_RBCH); - star = cs->readW6692(cs, W_D_STAR); - if (cs->debug) - debugl1(cs, "D-Channel Busy D_RBCH %02x D_STAR %02x", - rbch, star); - if (star & W_D_STAR_XBZ) { /* D-Channel Busy */ - test_and_set_bit(FLG_L1_DBUSY, &cs->HW_Flags); - stptr = cs->stlist; - while (stptr != NULL) { - stptr->l1.l1l2(stptr, PH_PAUSE | INDICATION, NULL); - stptr = stptr->next; - } - } else { - /* discard frame; reset transceiver */ - test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags); - if (cs->tx_skb) { - dev_kfree_skb_any(cs->tx_skb); - cs->tx_cnt = 0; - cs->tx_skb = NULL; - } else { - printk(KERN_WARNING "HiSax: W6692 D-Channel Busy no skb\n"); - debugl1(cs, "D-Channel Busy no skb"); - } - cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_XRST); /* Transmitter reset */ - spin_unlock_irqrestore(&cs->lock, flags); - cs->irq_func(cs->irq, cs); - return; - } - } - spin_unlock_irqrestore(&cs->lock, flags); -} - -static void -W6692Bmode(struct BCState *bcs, int mode, int bchan) -{ - struct IsdnCardState *cs = bcs->cs; - - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "w6692 %c mode %d ichan %d", - '1' + bchan, mode, bchan); - bcs->mode = mode; - bcs->channel = bchan; - bcs->hw.w6692.bchan = bchan; - - switch (mode) { - case (L1_MODE_NULL): - cs->BC_Write_Reg(cs, bchan, W_B_MODE, 0); - break; - case (L1_MODE_TRANS): - cs->BC_Write_Reg(cs, bchan, W_B_MODE, W_B_MODE_MMS); - break; - case (L1_MODE_HDLC): - cs->BC_Write_Reg(cs, bchan, W_B_MODE, W_B_MODE_ITF); - cs->BC_Write_Reg(cs, bchan, W_B_ADM1, 0xff); - cs->BC_Write_Reg(cs, bchan, W_B_ADM2, 0xff); - break; - } - if (mode) - cs->BC_Write_Reg(cs, bchan, W_B_CMDR, W_B_CMDR_RRST | - W_B_CMDR_RACT | W_B_CMDR_XRST); - cs->BC_Write_Reg(cs, bchan, W_B_EXIM, 0x00); -} - -static void -W6692_l2l1(struct PStack *st, int pr, void *arg) -{ - struct sk_buff *skb = arg; - struct BCState *bcs = st->l1.bcs; - u_long flags; - - switch (pr) { - case (PH_DATA | REQUEST): - spin_lock_irqsave(&bcs->cs->lock, flags); - if (bcs->tx_skb) { - skb_queue_tail(&bcs->squeue, skb); - } else { - bcs->tx_skb = skb; - test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); - bcs->hw.w6692.count = 0; - bcs->cs->BC_Send_Data(bcs); - } - spin_unlock_irqrestore(&bcs->cs->lock, flags); - break; - case (PH_PULL | INDICATION): - if (bcs->tx_skb) { - printk(KERN_WARNING "W6692_l2l1: this shouldn't happen\n"); - break; - } - spin_lock_irqsave(&bcs->cs->lock, flags); - test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); - bcs->tx_skb = skb; - bcs->hw.w6692.count = 0; - bcs->cs->BC_Send_Data(bcs); - spin_unlock_irqrestore(&bcs->cs->lock, flags); - break; - case (PH_PULL | REQUEST): - if (!bcs->tx_skb) { - test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); - } else - test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - break; - case (PH_ACTIVATE | REQUEST): - spin_lock_irqsave(&bcs->cs->lock, flags); - test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag); - W6692Bmode(bcs, st->l1.mode, st->l1.bc); - spin_unlock_irqrestore(&bcs->cs->lock, flags); - l1_msg_b(st, pr, arg); - break; - case (PH_DEACTIVATE | REQUEST): - l1_msg_b(st, pr, arg); - break; - case (PH_DEACTIVATE | CONFIRM): - spin_lock_irqsave(&bcs->cs->lock, flags); - test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag); - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - W6692Bmode(bcs, 0, st->l1.bc); - spin_unlock_irqrestore(&bcs->cs->lock, flags); - st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL); - break; - } -} - -static void -close_w6692state(struct BCState *bcs) -{ - W6692Bmode(bcs, 0, bcs->channel); - if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) { - kfree(bcs->hw.w6692.rcvbuf); - bcs->hw.w6692.rcvbuf = NULL; - kfree(bcs->blog); - bcs->blog = NULL; - skb_queue_purge(&bcs->rqueue); - skb_queue_purge(&bcs->squeue); - if (bcs->tx_skb) { - dev_kfree_skb_any(bcs->tx_skb); - bcs->tx_skb = NULL; - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - } - } -} - -static int -open_w6692state(struct IsdnCardState *cs, struct BCState *bcs) -{ - if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { - if (!(bcs->hw.w6692.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) { - printk(KERN_WARNING - "HiSax: No memory for w6692.rcvbuf\n"); - test_and_clear_bit(BC_FLG_INIT, &bcs->Flag); - return (1); - } - if (!(bcs->blog = kmalloc(MAX_BLOG_SPACE, GFP_ATOMIC))) { - printk(KERN_WARNING - "HiSax: No memory for bcs->blog\n"); - test_and_clear_bit(BC_FLG_INIT, &bcs->Flag); - kfree(bcs->hw.w6692.rcvbuf); - bcs->hw.w6692.rcvbuf = NULL; - return (2); - } - skb_queue_head_init(&bcs->rqueue); - skb_queue_head_init(&bcs->squeue); - } - bcs->tx_skb = NULL; - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - bcs->event = 0; - bcs->hw.w6692.rcvidx = 0; - bcs->tx_cnt = 0; - return (0); -} - -static int -setstack_w6692(struct PStack *st, struct BCState *bcs) -{ - bcs->channel = st->l1.bc; - if (open_w6692state(st->l1.hardware, bcs)) - return (-1); - st->l1.bcs = bcs; - st->l2.l2l1 = W6692_l2l1; - setstack_manager(st); - bcs->st = st; - setstack_l1_B(st); - return (0); -} - -static void resetW6692(struct IsdnCardState *cs) -{ - cs->writeW6692(cs, W_D_CTL, W_D_CTL_SRST); - mdelay(10); - cs->writeW6692(cs, W_D_CTL, 0x00); - mdelay(10); - cs->writeW6692(cs, W_IMASK, 0xff); - cs->writeW6692(cs, W_D_SAM, 0xff); - cs->writeW6692(cs, W_D_TAM, 0xff); - cs->writeW6692(cs, W_D_EXIM, 0x00); - cs->writeW6692(cs, W_D_MODE, W_D_MODE_RACT); - cs->writeW6692(cs, W_IMASK, 0x18); - if (cs->subtyp == W6692_USR) { - /* seems that USR implemented some power control features - * Pin 79 is connected to the oscilator circuit so we - * have to handle it here - */ - cs->writeW6692(cs, W_PCTL, 0x80); - cs->writeW6692(cs, W_XDATA, 0x00); - } -} - -static void initW6692(struct IsdnCardState *cs, int part) -{ - if (part & 1) { - cs->setstack_d = setstack_W6692; - cs->DC_Close = DC_Close_W6692; - timer_setup(&cs->dbusytimer, dbusy_timer_handler, 0); - resetW6692(cs); - ph_command(cs, W_L1CMD_RST); - cs->dc.w6692.ph_state = W_L1CMD_RST; - W6692_new_ph(cs); - ph_command(cs, W_L1CMD_ECK); - - cs->bcs[0].BC_SetStack = setstack_w6692; - cs->bcs[1].BC_SetStack = setstack_w6692; - cs->bcs[0].BC_Close = close_w6692state; - cs->bcs[1].BC_Close = close_w6692state; - W6692Bmode(cs->bcs, 0, 0); - W6692Bmode(cs->bcs + 1, 0, 0); - } - if (part & 2) { - /* Reenable all IRQ */ - cs->writeW6692(cs, W_IMASK, 0x18); - cs->writeW6692(cs, W_D_EXIM, 0x00); - cs->BC_Write_Reg(cs, 0, W_B_EXIM, 0x00); - cs->BC_Write_Reg(cs, 1, W_B_EXIM, 0x00); - /* Reset D-chan receiver and transmitter */ - cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_RRST | W_D_CMDR_XRST); - } -} - -/* Interface functions */ - -static u_char -ReadW6692(struct IsdnCardState *cs, u_char offset) -{ - return (inb(cs->hw.w6692.iobase + offset)); -} - -static void -WriteW6692(struct IsdnCardState *cs, u_char offset, u_char value) -{ - outb(value, cs->hw.w6692.iobase + offset); -} - -static void -ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - insb(cs->hw.w6692.iobase + W_D_RFIFO, data, size); -} - -static void -WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - outsb(cs->hw.w6692.iobase + W_D_XFIFO, data, size); -} - -static u_char -ReadW6692B(struct IsdnCardState *cs, int bchan, u_char offset) -{ - return (inb(cs->hw.w6692.iobase + (bchan ? 0x40 : 0) + offset)); -} - -static void -WriteW6692B(struct IsdnCardState *cs, int bchan, u_char offset, u_char value) -{ - outb(value, cs->hw.w6692.iobase + (bchan ? 0x40 : 0) + offset); -} - -static int -w6692_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - switch (mt) { - case CARD_RESET: - resetW6692(cs); - return (0); - case CARD_RELEASE: - cs->writeW6692(cs, W_IMASK, 0xff); - release_region(cs->hw.w6692.iobase, 256); - if (cs->subtyp == W6692_USR) { - cs->writeW6692(cs, W_XDATA, 0x04); - } - return (0); - case CARD_INIT: - initW6692(cs, 3); - return (0); - case CARD_TEST: - return (0); - } - return (0); -} - -static int id_idx; - -static struct pci_dev *dev_w6692 = NULL; - -int setup_w6692(struct IsdnCard *card) -{ - struct IsdnCardState *cs = card->cs; - char tmp[64]; - u_char found = 0; - u_char pci_irq = 0; - u_int pci_ioaddr = 0; - - strcpy(tmp, w6692_revision); - printk(KERN_INFO "HiSax: W6692 driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_W6692) - return (0); - - while (id_list[id_idx].vendor_id) { - dev_w6692 = hisax_find_pci_device(id_list[id_idx].vendor_id, - id_list[id_idx].device_id, - dev_w6692); - if (dev_w6692) { - if (pci_enable_device(dev_w6692)) - continue; - cs->subtyp = id_idx; - break; - } - id_idx++; - } - if (dev_w6692) { - found = 1; - pci_irq = dev_w6692->irq; - /* I think address 0 is allways the configuration area */ - /* and address 1 is the real IO space KKe 03.09.99 */ - pci_ioaddr = pci_resource_start(dev_w6692, 1); - /* USR ISDN PCI card TA need some special handling */ - if (cs->subtyp == W6692_WINBOND) { - if ((W6692_SV_USR == dev_w6692->subsystem_vendor) && - (W6692_SD_USR == dev_w6692->subsystem_device)) { - cs->subtyp = W6692_USR; - } - } - } - if (!found) { - printk(KERN_WARNING "W6692: No PCI card found\n"); - return (0); - } - cs->irq = pci_irq; - if (!cs->irq) { - printk(KERN_WARNING "W6692: No IRQ for PCI card found\n"); - return (0); - } - if (!pci_ioaddr) { - printk(KERN_WARNING "W6692: NO I/O Base Address found\n"); - return (0); - } - cs->hw.w6692.iobase = pci_ioaddr; - printk(KERN_INFO "Found: %s %s, I/O base: 0x%x, irq: %d\n", - id_list[cs->subtyp].vendor_name, id_list[cs->subtyp].card_name, - pci_ioaddr, pci_irq); - if (!request_region(cs->hw.w6692.iobase, 256, id_list[cs->subtyp].card_name)) { - printk(KERN_WARNING - "HiSax: %s I/O ports %x-%x already in use\n", - id_list[cs->subtyp].card_name, - cs->hw.w6692.iobase, - cs->hw.w6692.iobase + 255); - return (0); - } - - printk(KERN_INFO - "HiSax: %s config irq:%d I/O:%x\n", - id_list[cs->subtyp].card_name, cs->irq, - cs->hw.w6692.iobase); - - INIT_WORK(&cs->tqueue, W6692_bh); - cs->readW6692 = &ReadW6692; - cs->writeW6692 = &WriteW6692; - cs->readisacfifo = &ReadISACfifo; - cs->writeisacfifo = &WriteISACfifo; - cs->BC_Read_Reg = &ReadW6692B; - cs->BC_Write_Reg = &WriteW6692B; - cs->BC_Send_Data = &W6692B_fill_fifo; - cs->cardmsg = &w6692_card_msg; - cs->irq_func = &W6692_interrupt; - cs->irq_flags |= IRQF_SHARED; - W6692Version(cs, "W6692:"); - printk(KERN_INFO "W6692 ISTA=0x%X\n", ReadW6692(cs, W_ISTA)); - printk(KERN_INFO "W6692 IMASK=0x%X\n", ReadW6692(cs, W_IMASK)); - printk(KERN_INFO "W6692 D_EXIR=0x%X\n", ReadW6692(cs, W_D_EXIR)); - printk(KERN_INFO "W6692 D_EXIM=0x%X\n", ReadW6692(cs, W_D_EXIM)); - printk(KERN_INFO "W6692 D_RSTA=0x%X\n", ReadW6692(cs, W_D_RSTA)); - return (1); -} diff --git a/drivers/isdn/hisax/w6692.h b/drivers/isdn/hisax/w6692.h deleted file mode 100644 index 024b04d33e43..000000000000 --- a/drivers/isdn/hisax/w6692.h +++ /dev/null @@ -1,184 +0,0 @@ -/* $Id: w6692.h,v 1.4.2.2 2004/01/12 22:52:29 keil Exp $ - * - * Winbond W6692 specific defines - * - * Author Petr Novak - * Copyright by Petr Novak <petr.novak@i.cz> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -/* map W6692 functions to ISAC functions */ -#define readW6692 readisac -#define writeW6692 writeisac -#define readW6692fifo readisacfifo -#define writeW6692fifo writeisacfifo - -/* B-channel FIFO read/write routines */ - -#define READW6692BFIFO(cs, bchan, ptr, count) \ - insb(cs->hw.w6692.iobase + W_B_RFIFO + (bchan ? 0x40 : 0), ptr, count) - -#define WRITEW6692BFIFO(cs, bchan, ptr, count) \ - outsb(cs->hw.w6692.iobase + W_B_XFIFO + (bchan ? 0x40 : 0), ptr, count) - -/* Specifications of W6692 registers */ - -#define W_D_RFIFO 0x00 /* R */ -#define W_D_XFIFO 0x04 /* W */ -#define W_D_CMDR 0x08 /* W */ -#define W_D_MODE 0x0c /* R/W */ -#define W_D_TIMR 0x10 /* R/W */ -#define W_ISTA 0x14 /* R_clr */ -#define W_IMASK 0x18 /* R/W */ -#define W_D_EXIR 0x1c /* R_clr */ -#define W_D_EXIM 0x20 /* R/W */ -#define W_D_STAR 0x24 /* R */ -#define W_D_RSTA 0x28 /* R */ -#define W_D_SAM 0x2c /* R/W */ -#define W_D_SAP1 0x30 /* R/W */ -#define W_D_SAP2 0x34 /* R/W */ -#define W_D_TAM 0x38 /* R/W */ -#define W_D_TEI1 0x3c /* R/W */ -#define W_D_TEI2 0x40 /* R/W */ -#define W_D_RBCH 0x44 /* R */ -#define W_D_RBCL 0x48 /* R */ -#define W_TIMR2 0x4c /* W */ -#define W_L1_RC 0x50 /* R/W */ -#define W_D_CTL 0x54 /* R/W */ -#define W_CIR 0x58 /* R */ -#define W_CIX 0x5c /* W */ -#define W_SQR 0x60 /* R */ -#define W_SQX 0x64 /* W */ -#define W_PCTL 0x68 /* R/W */ -#define W_MOR 0x6c /* R */ -#define W_MOX 0x70 /* R/W */ -#define W_MOSR 0x74 /* R_clr */ -#define W_MOCR 0x78 /* R/W */ -#define W_GCR 0x7c /* R/W */ - -#define W_B_RFIFO 0x80 /* R */ -#define W_B_XFIFO 0x84 /* W */ -#define W_B_CMDR 0x88 /* W */ -#define W_B_MODE 0x8c /* R/W */ -#define W_B_EXIR 0x90 /* R_clr */ -#define W_B_EXIM 0x94 /* R/W */ -#define W_B_STAR 0x98 /* R */ -#define W_B_ADM1 0x9c /* R/W */ -#define W_B_ADM2 0xa0 /* R/W */ -#define W_B_ADR1 0xa4 /* R/W */ -#define W_B_ADR2 0xa8 /* R/W */ -#define W_B_RBCL 0xac /* R */ -#define W_B_RBCH 0xb0 /* R */ - -#define W_XADDR 0xf4 /* R/W */ -#define W_XDATA 0xf8 /* R/W */ -#define W_EPCTL 0xfc /* W */ - -/* W6692 register bits */ - -#define W_D_CMDR_XRST 0x01 -#define W_D_CMDR_XME 0x02 -#define W_D_CMDR_XMS 0x08 -#define W_D_CMDR_STT 0x10 -#define W_D_CMDR_RRST 0x40 -#define W_D_CMDR_RACK 0x80 - -#define W_D_MODE_RLP 0x01 -#define W_D_MODE_DLP 0x02 -#define W_D_MODE_MFD 0x04 -#define W_D_MODE_TEE 0x08 -#define W_D_MODE_TMS 0x10 -#define W_D_MODE_RACT 0x40 -#define W_D_MODE_MMS 0x80 - -#define W_INT_B2_EXI 0x01 -#define W_INT_B1_EXI 0x02 -#define W_INT_D_EXI 0x04 -#define W_INT_XINT0 0x08 -#define W_INT_XINT1 0x10 -#define W_INT_D_XFR 0x20 -#define W_INT_D_RME 0x40 -#define W_INT_D_RMR 0x80 - -#define W_D_EXI_WEXP 0x01 -#define W_D_EXI_TEXP 0x02 -#define W_D_EXI_ISC 0x04 -#define W_D_EXI_MOC 0x08 -#define W_D_EXI_TIN2 0x10 -#define W_D_EXI_XCOL 0x20 -#define W_D_EXI_XDUN 0x40 -#define W_D_EXI_RDOV 0x80 - -#define W_D_STAR_DRDY 0x10 -#define W_D_STAR_XBZ 0x20 -#define W_D_STAR_XDOW 0x80 - -#define W_D_RSTA_RMB 0x10 -#define W_D_RSTA_CRCE 0x20 -#define W_D_RSTA_RDOV 0x40 - -#define W_D_CTL_SRST 0x20 - -#define W_CIR_SCC 0x80 -#define W_CIR_ICC 0x40 -#define W_CIR_COD_MASK 0x0f - -#define W_B_CMDR_XRST 0x01 -#define W_B_CMDR_XME 0x02 -#define W_B_CMDR_XMS 0x04 -#define W_B_CMDR_RACT 0x20 -#define W_B_CMDR_RRST 0x40 -#define W_B_CMDR_RACK 0x80 - -#define W_B_MODE_FTS0 0x01 -#define W_B_MODE_FTS1 0x02 -#define W_B_MODE_SW56 0x04 -#define W_B_MODE_BSW0 0x08 -#define W_B_MODE_BSW1 0x10 -#define W_B_MODE_EPCM 0x20 -#define W_B_MODE_ITF 0x40 -#define W_B_MODE_MMS 0x80 - -#define W_B_EXI_XDUN 0x01 -#define W_B_EXI_XFR 0x02 -#define W_B_EXI_RDOV 0x10 -#define W_B_EXI_RME 0x20 -#define W_B_EXI_RMR 0x40 - -#define W_B_STAR_XBZ 0x01 -#define W_B_STAR_XDOW 0x04 -#define W_B_STAR_RMB 0x10 -#define W_B_STAR_CRCE 0x20 -#define W_B_STAR_RDOV 0x40 - -#define W_B_RBCH_LOV 0x20 - -/* W6692 Layer1 commands */ - -#define W_L1CMD_ECK 0x00 -#define W_L1CMD_RST 0x01 -#define W_L1CMD_SCP 0x04 -#define W_L1CMD_SSP 0x02 -#define W_L1CMD_AR8 0x08 -#define W_L1CMD_AR10 0x09 -#define W_L1CMD_EAL 0x0a -#define W_L1CMD_DRC 0x0f - -/* W6692 Layer1 indications */ - -#define W_L1IND_CE 0x07 -#define W_L1IND_DRD 0x00 -#define W_L1IND_LD 0x04 -#define W_L1IND_ARD 0x08 -#define W_L1IND_TI 0x0a -#define W_L1IND_ATI 0x0b -#define W_L1IND_AI8 0x0c -#define W_L1IND_AI10 0x0d -#define W_L1IND_CD 0x0f - -/* FIFO thresholds */ -#define W_D_FIFO_THRESH 64 -#define W_B_FIFO_THRESH 64 diff --git a/drivers/isdn/i4l/Kconfig b/drivers/isdn/i4l/Kconfig index caa1b52f06f7..cacde8de38a3 100644 --- a/drivers/isdn/i4l/Kconfig +++ b/drivers/isdn/i4l/Kconfig @@ -122,8 +122,6 @@ endmenu comment "ISDN4Linux hardware drivers" -source "drivers/isdn/hisax/Kconfig" - # end ISDN_I4L endif |