diff options
104 files changed, 0 insertions, 56236 deletions
diff --git a/Documentation/isdn/HiSax.cert b/Documentation/isdn/HiSax.cert deleted file mode 100644 index f2a6fcb8efee..000000000000 --- a/Documentation/isdn/HiSax.cert +++ /dev/null @@ -1,96 +0,0 @@ ------BEGIN PGP SIGNED MESSAGE----- - -First: - - HiSax 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 of the License, 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. - -However, if you wish to modify the HiSax sources, please note the following: - -HiSax has passed the ITU approval test suite with ELSA Quickstep ISDN cards -and Eicon Technology Diva 2.01 PCI card. -The certification is only valid for the combination of the tested software -version and the tested hardware. Any changes to the HiSax source code may -therefore affect the certification. - -Additional ITU approval tests have been carried out for all generic cards -using Colognechip single chip solutions HFC-S PCI A for PCI cards as well -as HFC-S USB based USB ISDN ta adapters. -These tests included all layers 1-3 and as well all functional tests for -the layer 1. Because all hardware based on these chips are complete ISDN -solutions in one chip all cards and USB-TAs using these chips are to be -regarded as approved for those tests. Some additional electrical tests -of the layer 1 which are independent of the driver and related to a -special hardware used will be regarded as approved if at least one -solution has been tested including those electrical tests. So if cards -or tas have been completely approved for any other os, the approval -for those electrical tests is valid for linux, too. -Please send any questions regarding this drivers or approval abouts to -werner@isdn-development.de -Additional information and the type approval documents will be found -shortly on the Colognechip website www.colognechip.com - -If you change the main files of the HiSax ISDN stack, the certification will -become invalid. Because in most countries it is illegal to connect -unapproved ISDN equipment to the public network, I have to guarantee that -changes in HiSax do not affect the certification. - -In order to make a valid certification apparent to the user, I have built in -some validation checks that are made during the make process. The HiSax main -files are protected by md5 checksums and the md5sum file is pgp signed by -myself: - -KeyID 1024/FF992F6D 1997/01/16 Karsten Keil <kkeil@suse.de> -Key fingerprint = 92 6B F7 58 EE 86 28 C8 C4 1A E6 DC 39 89 F2 AA - -Only if the checksums are OK, and the signature of the file -"drivers/isdn/hisax/md5sums.asc" match, is the certification valid; a -message confirming this is then displayed during the hisax init process. - -The affected files are: - -drivers/isdn/hisax/isac.c -drivers/isdn/hisax/isdnl1.c -drivers/isdn/hisax/isdnl2.c -drivers/isdn/hisax/isdnl3.c -drivers/isdn/hisax/tei.c -drivers/isdn/hisax/callc.c -drivers/isdn/hisax/l3dss1.c -drivers/isdn/hisax/l3_1tr6.c -drivers/isdn/hisax/cert.c -drivers/isdn/hisax/elsa.c -drivers/isdn/hisax/diva.c -drivers/isdn/hisax/hfc_pci.c - -Please send any changes, bugfixes and patches to me rather than implementing -them directly into the HiSax sources. - -This does not reduce your rights granted by the GNU General Public License. -If you wish to change the sources, go ahead; but note that then the -certification is invalid even if you use one of the approved cards. - -Here are the certification registration numbers for ELSA Quickstep cards: -German D133361J CETECOM ICT Services GmbH 0682 -European D133362J CETECOM ICT Services GmbH 0682 - - -Karsten Keil -keil@isdn4linux.de - ------BEGIN PGP SIGNATURE----- -Version: 2.6.3i -Charset: noconv - -iQCVAwUBOFAwqTpxHvX/mS9tAQFI2QP9GLDK2iy/KBhwReE3F7LeO+tVhffTVZ3a -20q5/z/WcIg/pnH0uTkl2UgDXBFXYl45zJyDGNpAposIFmT+Edd14o7Vj1w/BBdn -Y+5rBmJf+gyBu61da5d6bv0lpymwRa/um+ri+ilYnZ/XPfg5JKhdjGSBCJuJAElM -d2jFbTrsMYw= -=LNf9 ------END PGP SIGNATURE----- diff --git a/Documentation/isdn/README.HiSax b/Documentation/isdn/README.HiSax deleted file mode 100644 index b1a573cf4472..000000000000 --- a/Documentation/isdn/README.HiSax +++ /dev/null @@ -1,659 +0,0 @@ -HiSax is a Linux hardware-level driver for passive ISDN cards with Siemens -chipset (ISAC_S 2085/2086/2186, HSCX SAB 82525). It is based on the Teles -driver from Jan den Ouden. -It is meant to be used with isdn4linux, an ISDN link-level module for Linux -written by Fritz Elfert. - - 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 of the License, 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. - - -Supported cards ---------------- - -Teles 8.0/16.0/16.3 and compatible ones -Teles 16.3c -Teles S0/PCMCIA -Teles PCI -Teles S0Box -Creatix S0Box -Creatix PnP S0 -Compaq ISDN S0 ISA card -AVM A1 (Fritz, Teledat 150) -AVM Fritz PCMCIA -AVM Fritz PnP -AVM Fritz PCI -ELSA Microlink PCC-16, PCF, PCF-Pro, PCC-8 -ELSA Quickstep 1000 -ELSA Quickstep 1000PCI -ELSA Quickstep 3000 (same settings as QS1000) -ELSA Quickstep 3000PCI -ELSA PCMCIA -ITK ix1-micro Rev.2 -Eicon Diva 2.0 ISA and PCI (S0 and U interface, no PRO version) -Eicon Diva 2.01 ISA and PCI -Eicon Diva 2.02 PCI -Eicon Diva Piccola -ASUSCOM NETWORK INC. ISDNLink 128K PC adapter (order code I-IN100-ST-D) -Dynalink IS64PH (OEM version of ASUSCOM NETWORK INC. ISDNLink 128K adapter) -PCBIT-DP (OEM version of ASUSCOM NETWORK INC. ISDNLink) -HFC-2BS0 based cards (TeleInt SA1) -Sedlbauer Speed Card (Speed Win, Teledat 100, PCI, Fax+) -Sedlbauer Speed Star/Speed Star2 (PCMCIA) -Sedlbauer ISDN-Controller PC/104 -USR Sportster internal TA (compatible Stollmann tina-pp V3) -USR internal TA PCI -ith Kommunikationstechnik GmbH MIC 16 ISA card -Traverse Technologie NETjet PCI S0 card and NETspider U card -Ovislink ISDN sc100-p card (NETjet driver) -Dr. Neuhaus Niccy PnP/PCI -Siemens I-Surf 1.0 -Siemens I-Surf 2.0 (with IPAC, try type 12 asuscom) -ACER P10 -HST Saphir -Berkom Telekom A4T -Scitel Quadro -Gazel ISDN cards -HFC-PCI based cards -Winbond W6692 based cards -HFC-S+, HFC-SP/PCMCIA cards -formula-n enternow -Gerdes Power ISDN - -Note: PCF, PCF-Pro: up to now, only the ISDN part is supported - PCC-8: not tested yet - Eicon.Diehl Diva U interface not tested - -If you know other passive cards with the Siemens chipset, please let me know. -You can combine any card, if there is no conflict between the resources -(io, mem, irq). - - -Configuring the driver ----------------------- - -The HiSax driver can either be built directly into the kernel or as a module. -It can be configured using the command line feature while loading the kernel -with LILO or LOADLIN or, if built as a module, using insmod/modprobe with -parameters. -There is also some config needed before you compile the kernel and/or -modules. It is included in the normal "make [menu]config" target at the -kernel. Don't forget it, especially to select the right D-channel protocol. - -Please note: In older versions of the HiSax driver, all PnP cards -needed to be configured with isapnp and worked only with the HiSax -driver used as a module. - -In the current version, HiSax will automatically use the in-kernel -ISAPnP support, provided you selected it during kernel configuration -(CONFIG_ISAPNP), if you don't give the io=, irq= command line parameters. - -The affected card types are: 4,7,12,14,19,27-30 - -a) when built as a module -------------------------- - -insmod/modprobe hisax.o \ - io=iobase irq=IRQ mem=membase type=card_type \ - protocol=D_channel_protocol id=idstring - -or, if several cards are installed: - -insmod/modprobe hisax.o \ - io=iobase1,iobase2,... irq=IRQ1,IRQ2,... mem=membase1,membase2,... \ - type=card_type1,card_type2,... \ - protocol=D_channel_protocol1,D_channel_protocol2,... \ - id=idstring1%idstring2 ... - -where "iobaseN" represents the I/O base address of the Nth card, "membaseN" -the memory base address of the Nth card, etc. - -The reason for the delimiter "%" being used in the idstrings is that "," -won't work with the current modules package. - -The parameters may be specified in any order. For example, the "io" -parameter may precede the "irq" parameter, or vice versa. If several -cards are installed, the ordering within the comma separated parameter -lists must of course be consistent. - -Only parameters applicable to the card type need to be specified. For -example, the Teles 16.3 card is not memory-mapped, so the "mem" -parameter may be omitted for this card. Sometimes it may be necessary -to specify a dummy parameter, however. This is the case when there is -a card of a different type later in the list that needs a parameter -which the preceding card does not. For instance, if a Teles 16.0 card -is listed after a Teles 16.3 card, a dummy memory base parameter of 0 -must be specified for the 16.3. Instead of a dummy value, the parameter -can also be skipped by simply omitting the value. For example: -mem=,0xd0000. See example 6 below. - -The parameter for the D-Channel protocol may be omitted if you selected the -correct one during kernel config. Valid values are "1" for German 1TR6, -"2" for EDSS1 (Euro ISDN), "3" for leased lines (no D-Channel) and "4" -for US NI1. -With US NI1 you have to include your SPID into the MSN setting in the form -<MSN>:<SPID> for example (your phonenumber is 1234 your SPID 5678): -AT&E1234:5678 on ttyI interfaces -isdnctrl eaz ippp0 1234:5678 on network devices - -The Creatix/Teles PnP cards use io1= and io2= instead of io= for specifying -the I/O addresses of the ISAC and HSCX chips, respectively. - -Card types: - - Type Required parameters (in addition to type and protocol) - - 1 Teles 16.0 irq, mem, io - 2 Teles 8.0 irq, mem - 3 Teles 16.3 (non PnP) irq, io - 4 Creatix/Teles PnP irq, io0 (ISAC), io1 (HSCX) - 5 AVM A1 (Fritz) irq, io - 6 ELSA PCC/PCF cards io or nothing for autodetect (the iobase is - required only if you have more than one ELSA - card in your PC) - 7 ELSA Quickstep 1000 irq, io (from isapnp setup) - 8 Teles 16.3 PCMCIA irq, io - 9 ITK ix1-micro Rev.2 irq, io - 10 ELSA PCMCIA irq, io (set with card manager) - 11 Eicon.Diehl Diva ISA PnP irq, io - 11 Eicon.Diehl Diva PCI no parameter - 12 ASUS COM ISDNLink irq, io (from isapnp setup) - 13 HFC-2BS0 based cards irq, io - 14 Teles 16.3c PnP irq, io - 15 Sedlbauer Speed Card irq, io - 15 Sedlbauer PC/104 irq, io - 15 Sedlbauer Speed PCI no parameter - 16 USR Sportster internal irq, io - 17 MIC card irq, io - 18 ELSA Quickstep 1000PCI no parameter - 19 Compaq ISDN S0 ISA card irq, io0, io1, io (from isapnp setup io=IO2) - 20 NETjet PCI card no parameter - 21 Teles PCI no parameter - 22 Sedlbauer Speed Star (PCMCIA) irq, io (set with card manager) - 24 Dr. Neuhaus Niccy PnP irq, io0, io1 (from isapnp setup) - 24 Dr. Neuhaus Niccy PCI no parameter - 25 Teles S0Box irq, io (of the used lpt port) - 26 AVM A1 PCMCIA (Fritz!) irq, io (set with card manager) - 27 AVM PnP (Fritz!PnP) irq, io (from isapnp setup) - 27 AVM PCI (Fritz!PCI) no parameter - 28 Sedlbauer Speed Fax+ irq, io (from isapnp setup) - 29 Siemens I-Surf 1.0 irq, io, memory (from isapnp setup) - 30 ACER P10 irq, io (from isapnp setup) - 31 HST Saphir irq, io - 32 Telekom A4T none - 33 Scitel Quadro subcontroller (4*S0, subctrl 1...4) - 34 Gazel ISDN cards (ISA) irq,io - 34 Gazel ISDN cards (PCI) none - 35 HFC 2BDS0 PCI none - 36 W6692 based PCI cards none - 37 HFC 2BDS0 S+, SP irq,io - 38 NETspider U PCI card none - 39 HFC 2BDS0 SP/PCMCIA irq,io (set with cardmgr) - 40 hotplug interface - 41 Formula-n enter:now PCI none - -At the moment IRQ sharing is only possible with PCI cards. Please make sure -that your IRQ is free and enabled for ISA use. - - -Examples for module loading - -1. Teles 16.3, Euro ISDN, I/O base 280 hex, IRQ 10 - modprobe hisax type=3 protocol=2 io=0x280 irq=10 - -2. Teles 16.0, 1TR6 ISDN, I/O base d80 hex, IRQ 5, Memory d0000 hex - modprobe hisax protocol=1 type=1 io=0xd80 mem=0xd0000 irq=5 - -3. Fritzcard, Euro ISDN, I/O base 340 hex, IRQ 10 and ELSA PCF, Euro ISDN - modprobe hisax type=5,6 protocol=2,2 io=0x340 irq=10 id=Fritz%Elsa - -4. Any ELSA PCC/PCF card, Euro ISDN - modprobe hisax type=6 protocol=2 - -5. Teles 16.3 PnP, Euro ISDN, with isapnp configured - isapnp config: (INT 0 (IRQ 10 (MODE +E))) - (IO 0 (BASE 0x0580)) - (IO 1 (BASE 0x0180)) - modprobe hisax type=4 protocol=2 irq=10 io0=0x580 io1=0x180 - - In the current version of HiSax, you can instead simply use - - modprobe hisax type=4 protocol=2 - - if you configured your kernel for ISAPnP. Don't run isapnp in - this case! - -6. Teles 16.3, Euro ISDN, I/O base 280 hex, IRQ 12 and - Teles 16.0, 1TR6, IRQ 5, Memory d0000 hex - modprobe hisax type=3,1 protocol=2,1 io=0x280 mem=0,0xd0000 - - Please note the dummy 0 memory address for the Teles 16.3, used as a - placeholder as described above, in the last example. - -7. Teles PCMCIA, Euro ISDN, I/O base 180 hex, IRQ 15 (default values) - modprobe hisax type=8 protocol=2 io=0x180 irq=15 - - -b) using LILO/LOADLIN, with the driver compiled directly into the kernel ------------------------------------------------------------------------- - -hisax=typ1,dp1,pa_1,pb_1,pc_1[,typ2,dp2,pa_2 ... \ - typn,dpn,pa_n,pb_n,pc_n][,idstring1[,idstring2,...,idstringn]] - -where - typ1 = type of 1st card (default depends on kernel settings) - dp1 = D-Channel protocol of 1st card. 1=1TR6, 2=EDSS1, 3=leased - pa_1 = 1st parameter (depending on the type of the card) - pb_1 = 2nd parameter ( " " " " " " " ) - pc_1 = 3rd parameter ( " " " " " " " ) - - typ2,dp2,pa_2,pb_2,pc_2 = Parameters of the second card (defaults: none) - typn,dpn,pa_n,pb_n,pc_n = Parameters of the n'th card (up to 16 cards are - supported) - - idstring = Driver ID for accessing the particular card with utility - programs and for identification when using a line monitor - (default: "HiSax") - - Note: the ID string must start with an alphabetical character! - -Card types: - -type - 1 Teles 16.0 pa=irq pb=membase pc=iobase - 2 Teles 8.0 pa=irq pb=membase - 3 Teles 16.3 pa=irq pb=iobase - 4 Creatix/Teles PNP ONLY WORKS AS A MODULE ! - 5 AVM A1 (Fritz) pa=irq pb=iobase - 6 ELSA PCC/PCF cards pa=iobase or nothing for autodetect - 7 ELSA Quickstep 1000 ONLY WORKS AS A MODULE ! - 8 Teles S0 PCMCIA pa=irq pb=iobase - 9 ITK ix1-micro Rev.2 pa=irq pb=iobase - 10 ELSA PCMCIA pa=irq, pb=io (set with card manager) - 11 Eicon.Diehl Diva ISAPnP ONLY WORKS AS A MODULE ! - 11 Eicon.Diehl Diva PCI no parameter - 12 ASUS COM ISDNLink ONLY WORKS AS A MODULE ! - 13 HFC-2BS0 based cards pa=irq pb=io - 14 Teles 16.3c PnP ONLY WORKS AS A MODULE ! - 15 Sedlbauer Speed Card pa=irq pb=io (Speed Win only as module !) - 15 Sedlbauer PC/104 pa=irq pb=io - 15 Sedlbauer Speed PCI no parameter - 16 USR Sportster internal pa=irq pb=io - 17 MIC card pa=irq pb=io - 18 ELSA Quickstep 1000PCI no parameter - 19 Compaq ISDN S0 ISA card ONLY WORKS AS A MODULE ! - 20 NETjet PCI card no parameter - 21 Teles PCI no parameter - 22 Sedlbauer Speed Star (PCMCIA) pa=irq, pb=io (set with card manager) - 24 Dr. Neuhaus Niccy PnP ONLY WORKS AS A MODULE ! - 24 Dr. Neuhaus Niccy PCI no parameter - 25 Teles S0Box pa=irq, pb=io (of the used lpt port) - 26 AVM A1 PCMCIA (Fritz!) pa=irq, pb=io (set with card manager) - 27 AVM PnP (Fritz!PnP) ONLY WORKS AS A MODULE ! - 27 AVM PCI (Fritz!PCI) no parameter - 28 Sedlbauer Speed Fax+ ONLY WORKS AS A MODULE ! - 29 Siemens I-Surf 1.0 ONLY WORKS AS A MODULE ! - 30 ACER P10 ONLY WORKS AS A MODULE ! - 31 HST Saphir pa=irq, pb=io - 32 Telekom A4T no parameter - 33 Scitel Quadro subcontroller (4*S0, subctrl 1...4) - 34 Gazel ISDN cards (ISA) pa=irq, pb=io - 34 Gazel ISDN cards (PCI) no parameter - 35 HFC 2BDS0 PCI no parameter - 36 W6692 based PCI cards none - 37 HFC 2BDS0 S+,SP/PCMCIA ONLY WORKS AS A MODULE ! - 38 NETspider U PCI card none - 39 HFC 2BDS0 SP/PCMCIA ONLY WORKS AS A MODULE ! - 40 hotplug interface ONLY WORKS AS A MODULE ! - 41 Formula-n enter:now PCI none - -Running the driver ------------------- - -When you insmod isdn.o and hisax.o (or with the in-kernel version, during -boot time), a few lines should appear in your syslog. Look for something like: - -Apr 13 21:01:59 kke01 kernel: HiSax: Driver for Siemens chip set ISDN cards -Apr 13 21:01:59 kke01 kernel: HiSax: Version 2.9 -Apr 13 21:01:59 kke01 kernel: HiSax: Revisions 1.14/1.9/1.10/1.25/1.8 -Apr 13 21:01:59 kke01 kernel: HiSax: Total 1 card defined -Apr 13 21:01:59 kke01 kernel: HiSax: Card 1 Protocol EDSS1 Id=HiSax1 (0) -Apr 13 21:01:59 kke01 kernel: HiSax: Elsa driver Rev. 1.13 -... -Apr 13 21:01:59 kke01 kernel: Elsa: PCF-Pro found at 0x360 Rev.:C IRQ 10 -Apr 13 21:01:59 kke01 kernel: Elsa: timer OK; resetting card -Apr 13 21:01:59 kke01 kernel: Elsa: HSCX version A: V2.1 B: V2.1 -Apr 13 21:01:59 kke01 kernel: Elsa: ISAC 2086/2186 V1.1 -... -Apr 13 21:01:59 kke01 kernel: HiSax: DSS1 Rev. 1.14 -Apr 13 21:01:59 kke01 kernel: HiSax: 2 channels added - -This means that the card is ready for use. -Cabling problems or line-downs are not detected, and only some ELSA cards can -detect the S0 power. - -Remember that, according to the new strategy for accessing low-level drivers -from within isdn4linux, you should also define a driver ID while doing -insmod: Simply append hisax_id=<SomeString> to the insmod command line. This -string MUST NOT start with a digit or a small 'x'! - -At this point you can run a 'cat /dev/isdnctrl0' and view debugging messages. - -At the moment, debugging messages are enabled with the hisaxctrl tool: - - hisaxctrl <DriverId> DebugCmd <debugging_flags> - -<DriverId> default is HiSax, if you didn't specify one. - -DebugCmd is 1 for generic debugging - 11 for layer 1 development debugging - 13 for layer 3 development debugging - -where <debugging_flags> is the integer sum of the following debugging -options you wish enabled: - -With DebugCmd set to 1: - - 0x0001 Link-level <--> hardware-level communication - 0x0002 Top state machine - 0x0004 D-Channel Frames for isdnlog - 0x0008 D-Channel Q.921 - 0x0010 B-Channel X.75 - 0x0020 D-Channel l2 - 0x0040 B-Channel l2 - 0x0080 D-Channel link state debugging - 0x0100 B-Channel link state debugging - 0x0200 TEI debug - 0x0400 LOCK debug in callc.c - 0x0800 More paranoid debug in callc.c (not for normal use) - 0x1000 D-Channel l1 state debugging - 0x2000 B-Channel l1 state debugging - -With DebugCmd set to 11: - - 0x0001 Warnings (default: on) - 0x0002 IRQ status - 0x0004 ISAC - 0x0008 ISAC FIFO - 0x0010 HSCX - 0x0020 HSCX FIFO (attention: full B-Channel output!) - 0x0040 D-Channel LAPD frame types - 0x0080 IPAC debug - 0x0100 HFC receive debug - 0x0200 ISAC monitor debug - 0x0400 D-Channel frames for isdnlog (set with 1 0x4 too) - 0x0800 D-Channel message verbose - -With DebugCmd set to 13: - - 1 Warnings (default: on) - 2 l3 protocol descriptor errors - 4 l3 state machine - 8 charge info debugging (1TR6) - -For example, 'hisaxctrl HiSax 1 0x3ff' enables full generic debugging. - -Because of some obscure problems with some switch equipment, the delay -between the CONNECT message and sending the first data on the B-channel is now -configurable with - -hisaxctrl <DriverId> 2 <delay> -<delay> in ms Value between 50 and 800 ms is recommended. - -Downloading Firmware --------------------- -At the moment, the Sedlbauer speed fax+ is the only card, which -needs to download firmware. -The firmware is downloaded with the hisaxctrl tool: - - hisaxctrl <DriverId> 9 <firmware_filename> - -<DriverId> default is HiSax, if you didn't specify one, - -where <firmware_filename> is the filename of the firmware file. - -For example, 'hisaxctrl HiSax 9 ISAR.BIN' downloads the firmware for -ISAR based cards (like the Sedlbauer speed fax+). - -Warning -------- -HiSax is a work in progress and may crash your machine. -For certification look at HiSax.cert file. - -Limitations ------------ -At this time, HiSax only works on Euro ISDN lines and German 1TR6 lines. -For leased lines see appendix. - -Bugs ----- -If you find any, please let me know. - - -Thanks ------- -Special thanks to: - - Emil Stephan for the name HiSax which is a mix of HSCX and ISAC. - - Fritz Elfert, Jan den Ouden, Michael Hipp, Michael Wein, - Andreas Kool, Pekka Sarnila, Sim Yskes, Johan Myrre'en, - Klaus-Peter Nischke (ITK AG), Christof Petig, Werner Fehn (ELSA GmbH), - Volker Schmidt - Edgar Toernig and Marcus Niemann for the Sedlbauer driver - Stephan von Krawczynski - Juergen Quade for the Leased Line part - Klaus Lichtenwalder (Klaus.Lichtenwalder@WebForum.DE), for ELSA PCMCIA support - Enrik Berkhan (enrik@starfleet.inka.de) for S0BOX specific stuff - Ton van Rosmalen for Teles PCI - Petr Novak <petr.novak@i.cz> for Winbond W6692 support - Werner Cornelius <werner@isdn4linux.de> for HFC-PCI, HFC-S(+/P) and supplementary services support - and more people who are hunting bugs. (If I forgot somebody, please - send me a mail). - - Firma ELSA GmbH - Firma Eicon.Diehl GmbH - Firma Dynalink NL - Firma ASUSCOM NETWORK INC. Taiwan - Firma S.u.S.E - Firma ith Kommunikationstechnik GmbH - Firma Traverse Technologie Australia - Firma Medusa GmbH (www.medusa.de). - Firma Quant-X Austria for sponsoring a DEC Alpha board+CPU - Firma Cologne Chip Designs GmbH - - My girl friend and partner in life Ute for her patience with me. - - -Enjoy, - -Karsten Keil -keil@isdn4linux.de - - -Appendix: Teles PCMCIA driver ------------------------------ - -See - http://www.linux.no/teles_cs.txt -for instructions. - -Appendix: Linux and ISDN-leased lines -------------------------------------- - -Original from Juergen Quade, new version KKe. - -Attention NEW VERSION, the old leased line syntax won't work !!! - -You can use HiSax to connect your Linux-Box via an ISDN leased line -to e.g. the Internet: - -1. Build a kernel which includes the HiSax driver either as a module - or as part of the kernel. - cd /usr/src/linux - make menuconfig - <ISDN subsystem - ISDN support -- HiSax> - make clean; make zImage; make modules; make modules_install -2. Install the new kernel - cp /usr/src/linux/arch/x86/boot/zImage /etc/kernel/linux.isdn - vi /etc/lilo.conf - <add new kernel in the bootable image section> - lilo -3. in case the hisax driver is a "fixed" part of the kernel, configure - the driver with lilo: - vi /etc/lilo.conf - <add HiSax driver parameter in the global section (see below)> - lilo - Your lilo.conf _might_ look like the following: - - # LILO configuration-file - # global section - # teles 16.0 on IRQ=5, MEM=0xd8000, PORT=0xd80 - append="hisax=1,3,5,0xd8000,0xd80,HiSax" - # teles 16.3 (non pnp) on IRQ=15, PORT=0xd80 - # append="hisax=3,3,5,0xd8000,0xd80,HiSax" - boot=/dev/sda - compact # faster, but won't work on all systems. - linear - read-only - prompt - timeout=100 - vga = normal # force sane state - # Linux bootable partition config begins - image = /etc/kernel/linux.isdn - root = /dev/sda1 - label = linux.isdn - # - image = /etc/kernel/linux-2.0.30 - root = /dev/sda1 - label = linux.secure - - In the line starting with "append" you have to adapt the parameters - according to your card (see above in this file) - -3. boot the new linux.isdn kernel -4. start the ISDN subsystem: - a) load - if necessary - the modules (depends, whether you compiled - the ISDN driver as module or not) - According to the type of card you have to specify the necessary - driver parameter (irq, io, mem, type, protocol). - For the leased line the protocol is "3". See the table above for - the parameters, which you have to specify depending on your card. - b) configure i4l - /sbin/isdnctrl addif isdn0 - # EAZ 1 -- B1 channel 2 --B2 channel - /sbin/isdnctrl eaz isdn0 1 - /sbin/isdnctrl secure isdn0 on - /sbin/isdnctrl huptimeout isdn0 0 - /sbin/isdnctrl l2_prot isdn0 hdlc - # Attention you must not set an outgoing number !!! This won't work !!! - # The incoming number is LEASED0 for the first card, LEASED1 for the - # second and so on. - /sbin/isdnctrl addphone isdn0 in LEASED0 - # Here is no need to bind the channel. - c) in case the remote partner is a CISCO: - /sbin/isdnctrl encap isdn0 cisco-h - d) configure the interface - /sbin/ifconfig isdn0 ${LOCAL_IP} pointopoint ${REMOTE_IP} - e) set the routes - /sbin/route add -host ${REMOTE_IP} isdn0 - /sbin/route add default gw ${REMOTE_IP} - f) switch the card into leased mode for each used B-channel - /sbin/hisaxctrl HiSax 5 1 - -Remarks: -a) Use state of the art isdn4k-utils - -Here an example script: -#!/bin/sh -# Start/Stop ISDN leased line connection - -I4L_AS_MODULE=yes -I4L_REMOTE_IS_CISCO=no -I4L_MODULE_PARAMS="type=16 io=0x268 irq=7 " -I4L_DEBUG=no -I4L_LEASED_128K=yes -LOCAL_IP=192.168.1.1 -REMOTE_IP=192.168.2.1 - -case "$1" in - start) - echo "Starting ISDN ..." - if [ ${I4L_AS_MODULE} = "yes" ]; then - echo "loading modules..." - /sbin/modprobe hisax ${I4L_MODULE_PARAMS} - fi - # configure interface - /sbin/isdnctrl addif isdn0 - /sbin/isdnctrl secure isdn0 on - if [ ${I4L_DEBUG} = "yes" ]; then - /sbin/isdnctrl verbose 7 - /sbin/hisaxctrl HiSax 1 0xffff - /sbin/hisaxctrl HiSax 11 0xff - cat /dev/isdnctrl >/tmp/lea.log & - fi - if [ ${I4L_REMOTE_IS_CISCO} = "yes" ]; then - /sbin/isdnctrl encap isdn0 cisco-h - fi - /sbin/isdnctrl huptimeout isdn0 0 - # B-CHANNEL 1 - /sbin/isdnctrl eaz isdn0 1 - /sbin/isdnctrl l2_prot isdn0 hdlc - # 1. card - /sbin/isdnctrl addphone isdn0 in LEASED0 - if [ ${I4L_LEASED_128K} = "yes" ]; then - /sbin/isdnctrl addslave isdn0 isdn0s - /sbin/isdnctrl secure isdn0s on - /sbin/isdnctrl huptimeout isdn0s 0 - # B-CHANNEL 2 - /sbin/isdnctrl eaz isdn0s 2 - /sbin/isdnctrl l2_prot isdn0s hdlc - # 1. card - /sbin/isdnctrl addphone isdn0s in LEASED0 - if [ ${I4L_REMOTE_IS_CISCO} = "yes" ]; then - /sbin/isdnctrl encap isdn0s cisco-h - fi - fi - /sbin/isdnctrl dialmode isdn0 manual - # configure tcp/ip - /sbin/ifconfig isdn0 ${LOCAL_IP} pointopoint ${REMOTE_IP} - /sbin/route add -host ${REMOTE_IP} isdn0 - /sbin/route add default gw ${REMOTE_IP} - # switch to leased mode - # B-CHANNEL 1 - /sbin/hisaxctrl HiSax 5 1 - if [ ${I4L_LEASED_128K} = "yes" ]; then - # B-CHANNEL 2 - sleep 10; /* Wait for master */ - /sbin/hisaxctrl HiSax 5 2 - fi - ;; - stop) - /sbin/ifconfig isdn0 down - /sbin/isdnctrl delif isdn0 - if [ ${I4L_DEBUG} = "yes" ]; then - killall cat - fi - if [ ${I4L_AS_MODULE} = "yes" ]; then - /sbin/rmmod hisax - /sbin/rmmod isdn - /sbin/rmmod ppp - /sbin/rmmod slhc - fi - ;; - *) - echo "Usage: $0 {start|stop}" - exit 1 -esac -exit 0 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 |