* Re: [PATCH net-deletions] net: remove ISDN subsystem and Bluetooth CMTP
2026-04-21 2:21 [PATCH net-deletions] net: remove ISDN subsystem and Bluetooth CMTP Jakub Kicinski
2026-04-21 6:03 ` Greg KH
2026-04-21 13:47 ` Stephen Hemminger
@ 2026-04-21 13:55 ` Luiz Augusto von Dentz
2026-04-21 17:12 ` Randy Dunlap
2 siblings, 1 reply; 5+ messages in thread
From: Luiz Augusto von Dentz @ 2026-04-21 13:55 UTC (permalink / raw)
To: Jakub Kicinski
Cc: davem, netdev, edumazet, pabeni, andrew+netdev, horms, corbet,
skhan, marcel, mchehab+huawei, jani.nikula, gregkh, demarchi,
rdunlap, justonli, ivecera, jonathan.cameron, kees,
marco.crivellari, ferr.lambarginio, nihaal, mingo, tglx, linmq006,
linux-doc, linux-bluetooth
Hi Jakub,
On Mon, Apr 20, 2026 at 10:21 PM Jakub Kicinski <kuba@kernel.org> wrote:
>
> Remove the ISDN (mISDN, CAPI) subsystem and Bluetooth CMTP protocol
> from the kernel tree.
>
> ISDN is a pretty old technology and it's unclear whether anyone still
> uses it. I went over the last few years of git history and all the
> commits are either tree-wide conversions or syzbot/static analyzer
> fixes.
>
> When we discussed removal in the past IIRC there were some concerns
> about ISDN still being used in parts of Germany. Unfortunately, the
> code base is quite old, none of the current maintainers are familiar
> with it and AI tools will have a field day finding bugs here.
>
> Delete this code and preserve it in an out-of-tree repository
> for any remaining users:
> https://github.com/linux-netdev/mod-orphan
>
> UAPI constants AF_ISDN/PF_ISDN and the SELinux isdn_socket class
> are preserved for ABI stability, but the rest of uAPI is removed.
>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> ---
> CC: corbet@lwn.net
> CC: skhan@linuxfoundation.org
> CC: marcel@holtmann.org
> CC: luiz.dentz@gmail.com
> CC: mchehab+huawei@kernel.org
> CC: jani.nikula@intel.com
> CC: gregkh@linuxfoundation.org
> CC: demarchi@kernel.org
> CC: rdunlap@infradead.org
> CC: justonli@chromium.org
> CC: ivecera@redhat.com
> CC: jonathan.cameron@huawei.com
> CC: kees@kernel.org
> CC: marco.crivellari@suse.com
> CC: ferr.lambarginio@gmail.com
> CC: nihaal@cse.iitm.ac.in
> CC: mingo@kernel.org
> CC: tglx@kernel.org
> CC: linmq006@gmail.com
> CC: linux-doc@vger.kernel.org
> CC: linux-bluetooth@vger.kernel.org
> ---
> MAINTAINERS | 19 -
> Documentation/isdn/credits.rst | 73 -
> Documentation/isdn/index.rst | 14 -
> Documentation/isdn/interface_capi.rst | 336 --
> Documentation/isdn/m_isdn.rst | 9 -
> Documentation/subsystem-apis.rst | 1 -
> drivers/Kconfig | 2 -
> drivers/isdn/Kconfig | 27 -
> drivers/isdn/capi/Kconfig | 32 -
> drivers/isdn/hardware/mISDN/Kconfig | 98 -
> drivers/isdn/mISDN/Kconfig | 48 -
> net/bluetooth/Kconfig | 3 -
> net/bluetooth/cmtp/Kconfig | 12 -
> drivers/Makefile | 1 -
> drivers/isdn/Makefile | 8 -
> drivers/isdn/capi/Makefile | 6 -
> drivers/isdn/hardware/Makefile | 6 -
> drivers/isdn/hardware/mISDN/Makefile | 19 -
> drivers/isdn/mISDN/Makefile | 14 -
> net/bluetooth/Makefile | 1 -
> net/bluetooth/cmtp/Makefile | 8 -
> drivers/isdn/capi/kcapi.h | 182 -
> drivers/isdn/hardware/mISDN/hfc_multi.h | 1236 -----
> drivers/isdn/hardware/mISDN/hfc_multi_8xx.h | 167 -
> drivers/isdn/hardware/mISDN/hfc_pci.h | 214 -
> drivers/isdn/hardware/mISDN/hfcsusb.h | 425 --
> drivers/isdn/hardware/mISDN/iohelper.h | 96 -
> drivers/isdn/hardware/mISDN/ipac.h | 393 --
> drivers/isdn/hardware/mISDN/isar.h | 256 -
> drivers/isdn/hardware/mISDN/isdnhdlc.h | 69 -
> drivers/isdn/hardware/mISDN/netjet.h | 44 -
> drivers/isdn/hardware/mISDN/w6692.h | 177 -
> drivers/isdn/mISDN/core.h | 69 -
> drivers/isdn/mISDN/dsp.h | 277 -
> drivers/isdn/mISDN/dsp_biquad.h | 51 -
> drivers/isdn/mISDN/dsp_ecdis.h | 96 -
> drivers/isdn/mISDN/dsp_hwec.h | 10 -
> drivers/isdn/mISDN/fsm.h | 58 -
> drivers/isdn/mISDN/l1oip.h | 92 -
> drivers/isdn/mISDN/layer1.h | 16 -
> drivers/isdn/mISDN/layer2.h | 131 -
> include/linux/isdn/capilli.h | 95 -
> include/linux/isdn/capiutil.h | 60 -
> include/linux/kernelcapi.h | 45 -
> include/linux/mISDNdsp.h | 40 -
> include/linux/mISDNhw.h | 192 -
> include/linux/mISDNif.h | 603 --
> include/uapi/linux/capi.h | 134 -
> include/uapi/linux/isdn/capicmd.h | 117 -
> include/uapi/linux/kernelcapi.h | 48 -
> net/bluetooth/cmtp/cmtp.h | 129 -
> drivers/isdn/capi/capi.c | 1435 -----
> drivers/isdn/capi/capiutil.c | 677 ---
> drivers/isdn/capi/kcapi.c | 933 ----
> drivers/isdn/capi/kcapi_proc.c | 231 -
> drivers/isdn/hardware/mISDN/avmfritz.c | 1164 ----
> drivers/isdn/hardware/mISDN/hfcmulti.c | 5540 -------------------
> drivers/isdn/hardware/mISDN/hfcpci.c | 2360 --------
> drivers/isdn/hardware/mISDN/hfcsusb.c | 2157 --------
> drivers/isdn/hardware/mISDN/isdnhdlc.c | 617 ---
> drivers/isdn/hardware/mISDN/mISDNinfineon.c | 1168 ----
> drivers/isdn/hardware/mISDN/mISDNipac.c | 1636 ------
> drivers/isdn/hardware/mISDN/mISDNisar.c | 1694 ------
> drivers/isdn/hardware/mISDN/netjet.c | 1154 ----
> drivers/isdn/hardware/mISDN/speedfax.c | 520 --
> drivers/isdn/hardware/mISDN/w6692.c | 1417 -----
> drivers/isdn/mISDN/clock.c | 197 -
> drivers/isdn/mISDN/core.c | 400 --
> drivers/isdn/mISDN/dsp_audio.c | 421 --
> drivers/isdn/mISDN/dsp_blowfish.c | 667 ---
> drivers/isdn/mISDN/dsp_cmx.c | 1949 -------
> drivers/isdn/mISDN/dsp_core.c | 1227 ----
> drivers/isdn/mISDN/dsp_dtmf.c | 313 --
> drivers/isdn/mISDN/dsp_hwec.c | 122 -
> drivers/isdn/mISDN/dsp_pipeline.c | 300 -
> drivers/isdn/mISDN/dsp_tones.c | 550 --
> drivers/isdn/mISDN/fsm.c | 176 -
> drivers/isdn/mISDN/hwchannel.c | 516 --
> drivers/isdn/mISDN/l1oip_codec.c | 358 --
> drivers/isdn/mISDN/l1oip_core.c | 1505 -----
> drivers/isdn/mISDN/layer1.c | 415 --
> drivers/isdn/mISDN/layer2.c | 2266 --------
> drivers/isdn/mISDN/socket.c | 825 ---
> drivers/isdn/mISDN/stack.c | 654 ---
> drivers/isdn/mISDN/tei.c | 1416 -----
> drivers/isdn/mISDN/timerdev.c | 295 -
> net/bluetooth/cmtp/capi.c | 579 --
> net/bluetooth/cmtp/core.c | 519 --
> net/bluetooth/cmtp/sock.c | 271 -
> CREDITS | 5 +
> 90 files changed, 5 insertions(+), 44903 deletions(-)
> delete mode 100644 Documentation/isdn/credits.rst
> delete mode 100644 Documentation/isdn/index.rst
> delete mode 100644 Documentation/isdn/interface_capi.rst
> delete mode 100644 Documentation/isdn/m_isdn.rst
> delete mode 100644 drivers/isdn/Kconfig
> delete mode 100644 drivers/isdn/capi/Kconfig
> delete mode 100644 drivers/isdn/hardware/mISDN/Kconfig
> delete mode 100644 drivers/isdn/mISDN/Kconfig
> delete mode 100644 net/bluetooth/cmtp/Kconfig
> delete mode 100644 drivers/isdn/Makefile
> delete mode 100644 drivers/isdn/capi/Makefile
> delete mode 100644 drivers/isdn/hardware/Makefile
> delete mode 100644 drivers/isdn/hardware/mISDN/Makefile
> delete mode 100644 drivers/isdn/mISDN/Makefile
> delete mode 100644 net/bluetooth/cmtp/Makefile
> delete mode 100644 drivers/isdn/capi/kcapi.h
> delete mode 100644 drivers/isdn/hardware/mISDN/hfc_multi.h
> delete mode 100644 drivers/isdn/hardware/mISDN/hfc_multi_8xx.h
> delete mode 100644 drivers/isdn/hardware/mISDN/hfc_pci.h
> delete mode 100644 drivers/isdn/hardware/mISDN/hfcsusb.h
> delete mode 100644 drivers/isdn/hardware/mISDN/iohelper.h
> delete mode 100644 drivers/isdn/hardware/mISDN/ipac.h
> delete mode 100644 drivers/isdn/hardware/mISDN/isar.h
> delete mode 100644 drivers/isdn/hardware/mISDN/isdnhdlc.h
> delete mode 100644 drivers/isdn/hardware/mISDN/netjet.h
> delete mode 100644 drivers/isdn/hardware/mISDN/w6692.h
> delete mode 100644 drivers/isdn/mISDN/core.h
> delete mode 100644 drivers/isdn/mISDN/dsp.h
> delete mode 100644 drivers/isdn/mISDN/dsp_biquad.h
> delete mode 100644 drivers/isdn/mISDN/dsp_ecdis.h
> delete mode 100644 drivers/isdn/mISDN/dsp_hwec.h
> delete mode 100644 drivers/isdn/mISDN/fsm.h
> delete mode 100644 drivers/isdn/mISDN/l1oip.h
> delete mode 100644 drivers/isdn/mISDN/layer1.h
> delete mode 100644 drivers/isdn/mISDN/layer2.h
> delete mode 100644 include/linux/isdn/capilli.h
> delete mode 100644 include/linux/isdn/capiutil.h
> delete mode 100644 include/linux/kernelcapi.h
> delete mode 100644 include/linux/mISDNdsp.h
> delete mode 100644 include/linux/mISDNhw.h
> delete mode 100644 include/linux/mISDNif.h
> delete mode 100644 include/uapi/linux/capi.h
> delete mode 100644 include/uapi/linux/isdn/capicmd.h
> delete mode 100644 include/uapi/linux/kernelcapi.h
> delete mode 100644 net/bluetooth/cmtp/cmtp.h
> delete mode 100644 drivers/isdn/capi/capi.c
> delete mode 100644 drivers/isdn/capi/capiutil.c
> delete mode 100644 drivers/isdn/capi/kcapi.c
> delete mode 100644 drivers/isdn/capi/kcapi_proc.c
> delete mode 100644 drivers/isdn/hardware/mISDN/avmfritz.c
> delete mode 100644 drivers/isdn/hardware/mISDN/hfcmulti.c
> delete mode 100644 drivers/isdn/hardware/mISDN/hfcpci.c
> delete mode 100644 drivers/isdn/hardware/mISDN/hfcsusb.c
> delete mode 100644 drivers/isdn/hardware/mISDN/isdnhdlc.c
> delete mode 100644 drivers/isdn/hardware/mISDN/mISDNinfineon.c
> delete mode 100644 drivers/isdn/hardware/mISDN/mISDNipac.c
> delete mode 100644 drivers/isdn/hardware/mISDN/mISDNisar.c
> delete mode 100644 drivers/isdn/hardware/mISDN/netjet.c
> delete mode 100644 drivers/isdn/hardware/mISDN/speedfax.c
> delete mode 100644 drivers/isdn/hardware/mISDN/w6692.c
> delete mode 100644 drivers/isdn/mISDN/clock.c
> delete mode 100644 drivers/isdn/mISDN/core.c
> delete mode 100644 drivers/isdn/mISDN/dsp_audio.c
> delete mode 100644 drivers/isdn/mISDN/dsp_blowfish.c
> delete mode 100644 drivers/isdn/mISDN/dsp_cmx.c
> delete mode 100644 drivers/isdn/mISDN/dsp_core.c
> delete mode 100644 drivers/isdn/mISDN/dsp_dtmf.c
> delete mode 100644 drivers/isdn/mISDN/dsp_hwec.c
> delete mode 100644 drivers/isdn/mISDN/dsp_pipeline.c
> delete mode 100644 drivers/isdn/mISDN/dsp_tones.c
> delete mode 100644 drivers/isdn/mISDN/fsm.c
> delete mode 100644 drivers/isdn/mISDN/hwchannel.c
> delete mode 100644 drivers/isdn/mISDN/l1oip_codec.c
> delete mode 100644 drivers/isdn/mISDN/l1oip_core.c
> delete mode 100644 drivers/isdn/mISDN/layer1.c
> delete mode 100644 drivers/isdn/mISDN/layer2.c
> delete mode 100644 drivers/isdn/mISDN/socket.c
> delete mode 100644 drivers/isdn/mISDN/stack.c
> delete mode 100644 drivers/isdn/mISDN/tei.c
> delete mode 100644 drivers/isdn/mISDN/timerdev.c
> delete mode 100644 net/bluetooth/cmtp/capi.c
> delete mode 100644 net/bluetooth/cmtp/core.c
> delete mode 100644 net/bluetooth/cmtp/sock.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 6eb1a3ec60f1..cfcf422dd40a 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -13560,25 +13560,6 @@ S: Supported
> T: git git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending.git master
> F: drivers/infiniband/ulp/isert
>
> -ISDN/CMTP OVER BLUETOOTH
> -L: netdev@vger.kernel.org
> -S: Orphan
> -W: http://www.isdn4linux.de
> -F: Documentation/isdn/
> -F: drivers/isdn/capi/
> -F: include/linux/isdn/
> -F: include/uapi/linux/isdn/
> -F: net/bluetooth/cmtp/
> -
> -ISDN/mISDN SUBSYSTEM
> -L: netdev@vger.kernel.org
> -S: Orphan
> -W: http://www.isdn4linux.de
> -F: drivers/isdn/Kconfig
> -F: drivers/isdn/Makefile
> -F: drivers/isdn/hardware/
> -F: drivers/isdn/mISDN/
> -
> ISL28022 HARDWARE MONITORING DRIVER
> M: Carsten Spieß <mail@carsten-spiess.de>
> L: linux-hwmon@vger.kernel.org
> diff --git a/Documentation/isdn/credits.rst b/Documentation/isdn/credits.rst
> deleted file mode 100644
> index 319323f2091f..000000000000
> --- a/Documentation/isdn/credits.rst
> +++ /dev/null
> @@ -1,73 +0,0 @@
> -=======
> -Credits
> -=======
> -
> -
> -I want to thank all who contributed to this project and especially to:
> -(in alphabetical order)
> -
> -Thomas Bogendörfer (tsbogend@bigbug.franken.de)
> - Tester, lots of bugfixes and hints.
> -
> -Alan Cox (alan@lxorguk.ukuu.org.uk)
> - For help getting into standard-kernel.
> -
> -Henner Eisen (eis@baty.hanse.de)
> - For X.25 implementation.
> -
> -Volker Götz (volker@oops.franken.de)
> - For contribution of man-pages, the imontty-tool and a perfect
> - maintaining of the mailing-list at hub-wue.
> -
> -Matthias Hessler (hessler@isdn4linux.de)
> - For creating and maintaining the FAQ.
> -
> -Bernhard Hailer (Bernhard.Hailer@lrz.uni-muenchen.de)
> - For creating the FAQ, and the leafsite HOWTO.
> -
> -Michael 'Ghandi' Herold (michael@abadonna.franken.de)
> - For contribution of the vbox answering machine.
> -
> -Michael Hipp (Michael.Hipp@student.uni-tuebingen.de)
> - For his Sync-PPP-code.
> -
> -Karsten Keil (keil@isdn4linux.de)
> - For adding 1TR6-support to the Teles-driver.
> - For the HiSax-driver.
> -
> -Michael Knigge (knick@cove.han.de)
> - For contributing the imon-tool
> -
> -Andreas Kool (akool@Kool.f.EUnet.de)
> - For contribution of the isdnlog/isdnrep-tool
> -
> -Pedro Roque Marques (roque@di.fc.ul.pt)
> - For lot of new ideas and the pcbit driver.
> -
> -Eberhard Mönkeberg (emoenke@gwdg.de)
> - For testing and help to get into kernel.
> -
> -Thomas Neumann (tn@ruhr.de)
> - For help with Cisco-SLARP and keepalive
> -
> -Jan den Ouden (denouden@groovin.xs4all.nl)
> - For contribution of the original teles-driver
> -
> -Carsten Paeth (calle@calle.in-berlin.de)
> - For the AVM-B1-CAPI2.0 driver
> -
> -Thomas Pfeiffer (pfeiffer@pds.de)
> - For V.110, extended T.70 and Hylafax extensions in isdn_tty.c
> -
> -Max Riegel (riegel@max.franken.de)
> - For making the ICN hardware-documentation and test-equipment available.
> -
> -Armin Schindler (mac@melware.de)
> - For the eicon active card driver.
> -
> -Gerhard 'Fido' Schneider (fido@wuff.mayn.de)
> - For heavy-duty-beta-testing with his BBS ;)
> -
> -Thomas Uhl (uhl@think.de)
> - For distributing the cards.
> - For pushing me to work ;-)
> diff --git a/Documentation/isdn/index.rst b/Documentation/isdn/index.rst
> deleted file mode 100644
> index d1125a16a746..000000000000
> --- a/Documentation/isdn/index.rst
> +++ /dev/null
> @@ -1,14 +0,0 @@
> -.. SPDX-License-Identifier: GPL-2.0
> -
> -====
> -ISDN
> -====
> -
> -.. toctree::
> - :maxdepth: 2
> -
> - interface_capi
> -
> - m_isdn
> -
> - credits
> diff --git a/Documentation/isdn/interface_capi.rst b/Documentation/isdn/interface_capi.rst
> deleted file mode 100644
> index 4d63b34b35cf..000000000000
> --- a/Documentation/isdn/interface_capi.rst
> +++ /dev/null
> @@ -1,336 +0,0 @@
> -=========================================
> -Kernel CAPI Interface to Hardware Drivers
> -=========================================
> -
> -1. Overview
> -===========
> -
> -From the CAPI 2.0 specification:
> -COMMON-ISDN-API (CAPI) is an application programming interface standard used
> -to access ISDN equipment connected to basic rate interfaces (BRI) and primary
> -rate interfaces (PRI).
> -
> -Kernel CAPI operates as a dispatching layer between CAPI applications and CAPI
> -hardware drivers. Hardware drivers register ISDN devices (controllers, in CAPI
> -lingo) with Kernel CAPI to indicate their readiness to provide their service
> -to CAPI applications. CAPI applications also register with Kernel CAPI,
> -requesting association with a CAPI device. Kernel CAPI then dispatches the
> -application registration to an available device, forwarding it to the
> -corresponding hardware driver. Kernel CAPI then forwards CAPI messages in both
> -directions between the application and the hardware driver.
> -
> -Format and semantics of CAPI messages are specified in the CAPI 2.0 standard.
> -This standard is freely available from https://www.capi.org.
> -
> -
> -2. Driver and Device Registration
> -=================================
> -
> -CAPI drivers must register each of the ISDN devices they control with Kernel
> -CAPI by calling the Kernel CAPI function attach_capi_ctr() with a pointer to a
> -struct capi_ctr before they can be used. This structure must be filled with
> -the names of the driver and controller, and a number of callback function
> -pointers which are subsequently used by Kernel CAPI for communicating with the
> -driver. The registration can be revoked by calling the function
> -detach_capi_ctr() with a pointer to the same struct capi_ctr.
> -
> -Before the device can be actually used, the driver must fill in the device
> -information fields 'manu', 'version', 'profile' and 'serial' in the capi_ctr
> -structure of the device, and signal its readiness by calling capi_ctr_ready().
> -From then on, Kernel CAPI may call the registered callback functions for the
> -device.
> -
> -If the device becomes unusable for any reason (shutdown, disconnect ...), the
> -driver has to call capi_ctr_down(). This will prevent further calls to the
> -callback functions by Kernel CAPI.
> -
> -
> -3. Application Registration and Communication
> -=============================================
> -
> -Kernel CAPI forwards registration requests from applications (calls to CAPI
> -operation CAPI_REGISTER) to an appropriate hardware driver by calling its
> -register_appl() callback function. A unique Application ID (ApplID, u16) is
> -allocated by Kernel CAPI and passed to register_appl() along with the
> -parameter structure provided by the application. This is analogous to the
> -open() operation on regular files or character devices.
> -
> -After a successful return from register_appl(), CAPI messages from the
> -application may be passed to the driver for the device via calls to the
> -send_message() callback function. Conversely, the driver may call Kernel
> -CAPI's capi_ctr_handle_message() function to pass a received CAPI message to
> -Kernel CAPI for forwarding to an application, specifying its ApplID.
> -
> -Deregistration requests (CAPI operation CAPI_RELEASE) from applications are
> -forwarded as calls to the release_appl() callback function, passing the same
> -ApplID as with register_appl(). After return from release_appl(), no CAPI
> -messages for that application may be passed to or from the device anymore.
> -
> -
> -4. Data Structures
> -==================
> -
> -4.1 struct capi_driver
> -----------------------
> -
> -This structure describes a Kernel CAPI driver itself. It is used in the
> -register_capi_driver() and unregister_capi_driver() functions, and contains
> -the following non-private fields, all to be set by the driver before calling
> -register_capi_driver():
> -
> -``char name[32]``
> - the name of the driver, as a zero-terminated ASCII string
> -``char revision[32]``
> - the revision number of the driver, as a zero-terminated ASCII string
> -
> -4.2 struct capi_ctr
> --------------------
> -
> -This structure describes an ISDN device (controller) handled by a Kernel CAPI
> -driver. After registration via the attach_capi_ctr() function it is passed to
> -all controller specific lower layer interface and callback functions to
> -identify the controller to operate on.
> -
> -It contains the following non-private fields:
> -
> -to be set by the driver before calling attach_capi_ctr():
> -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> -
> -``struct module *owner``
> - pointer to the driver module owning the device
> -
> -``void *driverdata``
> - an opaque pointer to driver specific data, not touched by Kernel CAPI
> -
> -``char name[32]``
> - the name of the controller, as a zero-terminated ASCII string
> -
> -``char *driver_name``
> - the name of the driver, as a zero-terminated ASCII string
> -
> -``int (*load_firmware)(struct capi_ctr *ctrlr, capiloaddata *ldata)``
> - (optional) pointer to a callback function for sending firmware and
> - configuration data to the device
> -
> - The function may return before the operation has completed.
> -
> - Completion must be signalled by a call to capi_ctr_ready().
> -
> - Return value: 0 on success, error code on error
> - Called in process context.
> -
> -``void (*reset_ctr)(struct capi_ctr *ctrlr)``
> - (optional) pointer to a callback function for stopping the device,
> - releasing all registered applications
> -
> - The function may return before the operation has completed.
> -
> - Completion must be signalled by a call to capi_ctr_down().
> -
> - Called in process context.
> -
> -``void (*register_appl)(struct capi_ctr *ctrlr, u16 applid, capi_register_params *rparam)``
> - pointers to callback function for registration of
> - applications with the device
> -
> - Calls to these functions are serialized by Kernel CAPI so that only
> - one call to any of them is active at any time.
> -
> -``void (*release_appl)(struct capi_ctr *ctrlr, u16 applid)``
> - pointers to callback functions deregistration of
> - applications with the device
> -
> - Calls to these functions are serialized by Kernel CAPI so that only
> - one call to any of them is active at any time.
> -
> -``u16 (*send_message)(struct capi_ctr *ctrlr, struct sk_buff *skb)``
> - pointer to a callback function for sending a CAPI message to the
> - device
> -
> - Return value: CAPI error code
> -
> - If the method returns 0 (CAPI_NOERROR) the driver has taken ownership
> - of the skb and the caller may no longer access it. If it returns a
> - non-zero (error) value then ownership of the skb returns to the caller
> - who may reuse or free it.
> -
> - The return value should only be used to signal problems with respect
> - to accepting or queueing the message. Errors occurring during the
> - actual processing of the message should be signaled with an
> - appropriate reply message.
> -
> - May be called in process or interrupt context.
> -
> - Calls to this function are not serialized by Kernel CAPI, ie. it must
> - be prepared to be re-entered.
> -
> -``char *(*procinfo)(struct capi_ctr *ctrlr)``
> - pointer to a callback function returning the entry for the device in
> - the CAPI controller info table, /proc/capi/controller
> -
> -Note:
> - Callback functions except send_message() are never called in interrupt
> - context.
> -
> -to be filled in before calling capi_ctr_ready():
> -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> -
> -``u8 manu[CAPI_MANUFACTURER_LEN]``
> - value to return for CAPI_GET_MANUFACTURER
> -
> -``capi_version version``
> - value to return for CAPI_GET_VERSION
> -
> -``capi_profile profile``
> - value to return for CAPI_GET_PROFILE
> -
> -``u8 serial[CAPI_SERIAL_LEN]``
> - value to return for CAPI_GET_SERIAL
> -
> -
> -4.3 SKBs
> ---------
> -
> -CAPI messages are passed between Kernel CAPI and the driver via send_message()
> -and capi_ctr_handle_message(), stored in the data portion of a socket buffer
> -(skb). Each skb contains a single CAPI message coded according to the CAPI 2.0
> -standard.
> -
> -For the data transfer messages, DATA_B3_REQ and DATA_B3_IND, the actual
> -payload data immediately follows the CAPI message itself within the same skb.
> -The Data and Data64 parameters are not used for processing. The Data64
> -parameter may be omitted by setting the length field of the CAPI message to 22
> -instead of 30.
> -
> -
> -4.4 The _cmsg Structure
> ------------------------
> -
> -(declared in <linux/isdn/capiutil.h>)
> -
> -The _cmsg structure stores the contents of a CAPI 2.0 message in an easily
> -accessible form. It contains members for all possible CAPI 2.0 parameters,
> -including subparameters of the Additional Info and B Protocol structured
> -parameters, with the following exceptions:
> -
> -* second Calling party number (CONNECT_IND)
> -
> -* Data64 (DATA_B3_REQ and DATA_B3_IND)
> -
> -* Sending complete (subparameter of Additional Info, CONNECT_REQ and INFO_REQ)
> -
> -* Global Configuration (subparameter of B Protocol, CONNECT_REQ, CONNECT_RESP
> - and SELECT_B_PROTOCOL_REQ)
> -
> -Only those parameters appearing in the message type currently being processed
> -are actually used. Unused members should be set to zero.
> -
> -Members are named after the CAPI 2.0 standard names of the parameters they
> -represent. See <linux/isdn/capiutil.h> for the exact spelling. Member data
> -types are:
> -
> -=========== =================================================================
> -u8 for CAPI parameters of type 'byte'
> -
> -u16 for CAPI parameters of type 'word'
> -
> -u32 for CAPI parameters of type 'dword'
> -
> -_cstruct for CAPI parameters of type 'struct'
> - The member is a pointer to a buffer containing the parameter in
> - CAPI encoding (length + content). It may also be NULL, which will
> - be taken to represent an empty (zero length) parameter.
> - Subparameters are stored in encoded form within the content part.
> -
> -_cmstruct alternative representation for CAPI parameters of type 'struct'
> - (used only for the 'Additional Info' and 'B Protocol' parameters)
> - The representation is a single byte containing one of the values:
> - CAPI_DEFAULT: The parameter is empty/absent.
> - CAPI_COMPOSE: The parameter is present.
> - Subparameter values are stored individually in the corresponding
> - _cmsg structure members.
> -=========== =================================================================
> -
> -
> -5. Lower Layer Interface Functions
> -==================================
> -
> -::
> -
> - int attach_capi_ctr(struct capi_ctr *ctrlr)
> - int detach_capi_ctr(struct capi_ctr *ctrlr)
> -
> -register/unregister a device (controller) with Kernel CAPI
> -
> -::
> -
> - void capi_ctr_ready(struct capi_ctr *ctrlr)
> - void capi_ctr_down(struct capi_ctr *ctrlr)
> -
> -signal controller ready/not ready
> -
> -::
> -
> - void capi_ctr_handle_message(struct capi_ctr * ctrlr, u16 applid,
> - struct sk_buff *skb)
> -
> -pass a received CAPI message to Kernel CAPI
> -for forwarding to the specified application
> -
> -
> -6. Helper Functions and Macros
> -==============================
> -
> -Macros to extract/set element values from/in a CAPI message header
> -(from <linux/isdn/capiutil.h>):
> -
> -====================== ============================= ====================
> -Get Macro Set Macro Element (Type)
> -====================== ============================= ====================
> -CAPIMSG_LEN(m) CAPIMSG_SETLEN(m, len) Total Length (u16)
> -CAPIMSG_APPID(m) CAPIMSG_SETAPPID(m, applid) ApplID (u16)
> -CAPIMSG_COMMAND(m) CAPIMSG_SETCOMMAND(m,cmd) Command (u8)
> -CAPIMSG_SUBCOMMAND(m) CAPIMSG_SETSUBCOMMAND(m, cmd) Subcommand (u8)
> -CAPIMSG_CMD(m) - Command*256
> - + Subcommand (u16)
> -CAPIMSG_MSGID(m) CAPIMSG_SETMSGID(m, msgid) Message Number (u16)
> -
> -CAPIMSG_CONTROL(m) CAPIMSG_SETCONTROL(m, contr) Controller/PLCI/NCCI
> - (u32)
> -CAPIMSG_DATALEN(m) CAPIMSG_SETDATALEN(m, len) Data Length (u16)
> -====================== ============================= ====================
> -
> -
> -Library functions for working with _cmsg structures
> -(from <linux/isdn/capiutil.h>):
> -
> -``char *capi_cmd2str(u8 Command, u8 Subcommand)``
> - Returns the CAPI 2.0 message name corresponding to the given command
> - and subcommand values, as a static ASCII string. The return value may
> - be NULL if the command/subcommand is not one of those defined in the
> - CAPI 2.0 standard.
> -
> -
> -7. Debugging
> -============
> -
> -The module kernelcapi has a module parameter showcapimsgs controlling some
> -debugging output produced by the module. It can only be set when the module is
> -loaded, via a parameter "showcapimsgs=<n>" to the modprobe command, either on
> -the command line or in the configuration file.
> -
> -If the lowest bit of showcapimsgs is set, kernelcapi logs controller and
> -application up and down events.
> -
> -In addition, every registered CAPI controller has an associated traceflag
> -parameter controlling how CAPI messages sent from and to the controller are
> -logged. The traceflag parameter is initialized with the value of the
> -showcapimsgs parameter when the controller is registered, but can later be
> -changed via the MANUFACTURER_REQ command KCAPI_CMD_TRACE.
> -
> -If the value of traceflag is non-zero, CAPI messages are logged.
> -DATA_B3 messages are only logged if the value of traceflag is > 2.
> -
> -If the lowest bit of traceflag is set, only the command/subcommand and message
> -length are logged. Otherwise, kernelcapi logs a readable representation of
> -the entire message.
> diff --git a/Documentation/isdn/m_isdn.rst b/Documentation/isdn/m_isdn.rst
> deleted file mode 100644
> index 5847a164287e..000000000000
> --- a/Documentation/isdn/m_isdn.rst
> +++ /dev/null
> @@ -1,9 +0,0 @@
> -============
> -mISDN Driver
> -============
> -
> -mISDN is a new modular ISDN driver, in the long term it should replace
> -the old I4L driver architecture for passive ISDN cards.
> -It was designed to allow a broad range of applications and interfaces
> -but only have the basic function in kernel, the interface to the user
> -space is based on sockets with a own address family AF_ISDN.
> diff --git a/Documentation/subsystem-apis.rst b/Documentation/subsystem-apis.rst
> index ff4fe8c936c8..b1ad48bb4001 100644
> --- a/Documentation/subsystem-apis.rst
> +++ b/Documentation/subsystem-apis.rst
> @@ -46,7 +46,6 @@ Networking interfaces
> networking/index
> netlabel/index
> infiniband/index
> - isdn/index
> mhi/index
>
> Storage interfaces
> diff --git a/drivers/Kconfig b/drivers/Kconfig
> index c0f1fb893ec0..f2bed2ddeb66 100644
> --- a/drivers/Kconfig
> +++ b/drivers/Kconfig
> @@ -61,8 +61,6 @@ source "drivers/macintosh/Kconfig"
>
> source "drivers/net/Kconfig"
>
> -source "drivers/isdn/Kconfig"
> -
> # input before char - char/joystick depends on it. As does USB.
>
> source "drivers/input/Kconfig"
> diff --git a/drivers/isdn/Kconfig b/drivers/isdn/Kconfig
> deleted file mode 100644
> index 6fd1b3f84a29..000000000000
> --- a/drivers/isdn/Kconfig
> +++ /dev/null
> @@ -1,27 +0,0 @@
> -# SPDX-License-Identifier: GPL-2.0-only
> -#
> -# ISDN device configuration
> -#
> -
> -menuconfig ISDN
> - bool "ISDN support"
> - depends on NET && NETDEVICES
> - help
> - ISDN ("Integrated Services Digital Network", called RNIS in France)
> - is a fully digital telephone service that can be used for voice and
> - data connections. If your computer is equipped with an ISDN
> - adapter you can use it to connect to your Internet service provider
> - (with SLIP or PPP) faster than via a conventional telephone modem
> - (though still much slower than with DSL) or to make and accept
> - voice calls (eg. turning your PC into a software answering machine
> - or PABX).
> -
> - Select this option if you want your kernel to support ISDN.
> -
> -if ISDN
> -
> -source "drivers/isdn/capi/Kconfig"
> -
> -source "drivers/isdn/mISDN/Kconfig"
> -
> -endif # ISDN
> diff --git a/drivers/isdn/capi/Kconfig b/drivers/isdn/capi/Kconfig
> deleted file mode 100644
> index fdb43a632215..000000000000
> --- a/drivers/isdn/capi/Kconfig
> +++ /dev/null
> @@ -1,32 +0,0 @@
> -# SPDX-License-Identifier: GPL-2.0-only
> -config ISDN_CAPI
> - def_bool ISDN && BT
> - help
> - This provides CAPI (the Common ISDN Application Programming
> - Interface) Version 2.0, a standard making it easy for programs to
> - access ISDN hardware in a device independent way. (For details see
> - <https://www.capi.org/>.) CAPI supports making and accepting voice
> - and data connections, controlling call options and protocols,
> - as well as ISDN supplementary services like call forwarding or
> - three-party conferences (if supported by the specific hardware
> - driver).
> -
> - This subsystem requires a hardware specific driver.
> - See CONFIG_BT_CMTP for the last remaining regular driver
> - in the kernel that uses the CAPI subsystem.
> -
> -config CAPI_TRACE
> - def_bool BT_CMTP
> - help
> - If you say Y here, the kernelcapi driver can make verbose traces
> - of CAPI messages. This feature can be enabled/disabled via IOCTL for
> - every controller (default disabled).
> -
> -config ISDN_CAPI_MIDDLEWARE
> - def_bool BT_CMTP && TTY
> - help
> - This option will enhance the capabilities of the /dev/capi20
> - interface. It will provide a means of moving a data connection,
> - established via the usual /dev/capi20 interface to a special tty
> - device. If you want to use pppd with pppdcapiplugin to dial up to
> - your ISP, say Y here.
> diff --git a/drivers/isdn/hardware/mISDN/Kconfig b/drivers/isdn/hardware/mISDN/Kconfig
> deleted file mode 100644
> index a35bff8a93f5..000000000000
> --- a/drivers/isdn/hardware/mISDN/Kconfig
> +++ /dev/null
> @@ -1,98 +0,0 @@
> -# SPDX-License-Identifier: GPL-2.0-only
> -#
> -# Hardware for mISDN
> -#
> -comment "mISDN hardware drivers"
> -
> -config MISDN_HFCPCI
> - tristate "Support for HFC PCI cards"
> - depends on MISDN
> - depends on PCI
> - help
> - Enable support for cards with Cologne Chip AG's
> - HFC PCI chip.
> -
> -config MISDN_HFCMULTI
> - tristate "Support for HFC multiport cards (HFC-4S/8S/E1)"
> - depends on (PCI || CPM1) && HAS_IOPORT
> - depends on MISDN
> - help
> - Enable support for cards with Cologne Chip AG's HFC multiport
> - chip. There are three types of chips that are quite similar,
> - but the interface is different:
> - * HFC-4S (4 S/T interfaces on one chip)
> - * HFC-8S (8 S/T interfaces on one chip)
> - * HFC-E1 (E1 interface for 2Mbit ISDN)
> -
> -config MISDN_HFCMULTI_8xx
> - bool "Support for XHFC embedded board in HFC multiport driver"
> - depends on MISDN
> - depends on MISDN_HFCMULTI
> - depends on CPM1
> - default CPM1
> - help
> - Enable support for the XHFC embedded solution from Speech Design.
> -
> -config MISDN_HFCUSB
> - tristate "Support for HFC-S USB based TAs"
> - depends on USB
> - help
> - Enable support for USB ISDN TAs with Cologne Chip AG's
> - HFC-S USB ISDN Controller
> -
> -config MISDN_AVMFRITZ
> - tristate "Support for AVM FRITZ!CARD PCI"
> - depends on MISDN
> - depends on PCI && HAS_IOPORT
> - select MISDN_IPAC
> - help
> - Enable support for AVMs FRITZ!CARD PCI cards
> -
> -config MISDN_SPEEDFAX
> - tristate "Support for Sedlbauer Speedfax+"
> - depends on MISDN
> - depends on PCI && HAS_IOPORT
> - select MISDN_IPAC
> - select MISDN_ISAR
> - help
> - Enable support for Sedlbauer Speedfax+.
> -
> -config MISDN_INFINEON
> - tristate "Support for cards with Infineon chipset"
> - depends on MISDN
> - depends on PCI && HAS_IOPORT
> - select MISDN_IPAC
> - help
> - Enable support for cards with ISAC + HSCX, IPAC or IPAC-SX
> - chip from Infineon (former manufacturer Siemens).
> -
> -config MISDN_W6692
> - tristate "Support for cards with Winbond 6692"
> - depends on MISDN
> - depends on PCI && HAS_IOPORT
> - help
> - Enable support for Winbond 6692 PCI chip based cards.
> -
> -config MISDN_NETJET
> - tristate "Support for NETJet cards"
> - depends on MISDN
> - depends on PCI && HAS_IOPORT
> - depends on TTY
> - select MISDN_IPAC
> - select MISDN_HDLC
> - help
> - Enable support for Traverse Technologies NETJet PCI cards.
> -
> -config MISDN_HDLC
> - tristate
> - select CRC_CCITT
> - select BITREVERSE
> -
> -config MISDN_IPAC
> - tristate
> - depends on MISDN
> -
> -config MISDN_ISAR
> - tristate
> - depends on MISDN
> -
> diff --git a/drivers/isdn/mISDN/Kconfig b/drivers/isdn/mISDN/Kconfig
> deleted file mode 100644
> index c9a53c222472..000000000000
> --- a/drivers/isdn/mISDN/Kconfig
> +++ /dev/null
> @@ -1,48 +0,0 @@
> -# SPDX-License-Identifier: GPL-2.0-only
> -#
> -# modularer ISDN driver
> -#
> -
> -menuconfig MISDN
> - tristate "Modular ISDN driver"
> - help
> - Enable support for the modular ISDN driver.
> -
> -if MISDN != n
> -
> -config MISDN_DSP
> - tristate "Digital Audio Processing of transparent data"
> - depends on MISDN
> - select BITREVERSE
> - help
> - Enable support for digital audio processing capability.
> -
> - This module may be used for special applications that require
> - cross connecting of bchannels, conferencing, dtmf decoding,
> - echo cancellation, tone generation, and Blowfish encryption and
> - decryption. It may use hardware features if available.
> -
> - E.g. it is required for PBX4Linux. Go to http://isdn.eversberg.eu
> - and get more information about this module and its usage.
> -
> - If unsure, say 'N'.
> -
> -config MISDN_L1OIP
> - tristate "ISDN over IP tunnel"
> - depends on MISDN
> - help
> - Enable support for ISDN over IP tunnel.
> -
> - It features:
> - - dynamic IP exchange, if one or both peers have dynamic IPs
> - - BRI (S0) and PRI (S2M) interface
> - - layer 1 control via network keepalive frames
> - - direct tunneling of physical interface via IP
> -
> - NOTE: This protocol is called 'Layer 1 over IP' and is not
> - compatible with ISDNoIP (Agfeo) or TDMoIP. Protocol description is
> - provided in the source code.
> -
> -source "drivers/isdn/hardware/mISDN/Kconfig"
> -
> -endif #MISDN
> diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig
> index 6b2b65a66700..ee6457d1a5ee 100644
> --- a/net/bluetooth/Kconfig
> +++ b/net/bluetooth/Kconfig
> @@ -33,7 +33,6 @@ menuconfig BT
> HCI Device drivers (Interface to the hardware)
> RFCOMM Module (RFCOMM Protocol)
> BNEP Module (Bluetooth Network Encapsulation Protocol)
> - CMTP Module (CAPI Message Transport Protocol)
> HIDP Module (Human Interface Device Protocol)
>
> Say Y here to compile Bluetooth support into the kernel or say M to
> @@ -58,8 +57,6 @@ source "net/bluetooth/rfcomm/Kconfig"
>
> source "net/bluetooth/bnep/Kconfig"
>
> -source "net/bluetooth/cmtp/Kconfig"
> -
> source "net/bluetooth/hidp/Kconfig"
>
> config BT_LE
> diff --git a/net/bluetooth/cmtp/Kconfig b/net/bluetooth/cmtp/Kconfig
> deleted file mode 100644
> index 34e923466236..000000000000
> --- a/net/bluetooth/cmtp/Kconfig
> +++ /dev/null
> @@ -1,12 +0,0 @@
> -# SPDX-License-Identifier: GPL-2.0-only
> -config BT_CMTP
> - tristate "CMTP protocol support (DEPRECATED)"
> - depends on BT_BREDR && ISDN_CAPI && DEPRECATED
> - help
> - CMTP (CAPI Message Transport Protocol) is a transport layer
> - for CAPI messages. CMTP is required for the Bluetooth Common
> - ISDN Access Profile.
> -
> - Say Y here to compile CMTP support into the kernel or say M to
> - compile it as module (cmtp).
> -
> diff --git a/drivers/Makefile b/drivers/Makefile
> index c902fe94f6e8..cc5fdb1ef79f 100644
> --- a/drivers/Makefile
> +++ b/drivers/Makefile
> @@ -123,7 +123,6 @@ obj-$(CONFIG_WATCHDOG) += watchdog/
> obj-$(CONFIG_MD) += md/
> obj-$(CONFIG_BT) += bluetooth/
> obj-$(CONFIG_ACCESSIBILITY) += accessibility/
> -obj-$(CONFIG_ISDN) += isdn/
> obj-$(CONFIG_EDAC) += edac/
> obj-$(CONFIG_EISA) += eisa/
> obj-$(CONFIG_PM_OPP) += opp/
> diff --git a/drivers/isdn/Makefile b/drivers/isdn/Makefile
> deleted file mode 100644
> index d14334f4007e..000000000000
> --- a/drivers/isdn/Makefile
> +++ /dev/null
> @@ -1,8 +0,0 @@
> -# SPDX-License-Identifier: GPL-2.0
> -# Makefile for the kernel ISDN subsystem and device drivers.
> -
> -# Object files in subdirectories
> -
> -obj-$(CONFIG_BT_CMTP) += capi/
> -obj-$(CONFIG_MISDN) += mISDN/
> -obj-$(CONFIG_ISDN) += hardware/
> diff --git a/drivers/isdn/capi/Makefile b/drivers/isdn/capi/Makefile
> deleted file mode 100644
> index 4fd3a4d7133f..000000000000
> --- a/drivers/isdn/capi/Makefile
> +++ /dev/null
> @@ -1,6 +0,0 @@
> -# SPDX-License-Identifier: GPL-2.0
> -# Makefile for the CAPI subsystem used by BT_CMTP
> -
> -obj-$(CONFIG_BT_CMTP) += kernelcapi.o
> -kernelcapi-y := kcapi.o capiutil.o capi.o
> -kernelcapi-$(CONFIG_PROC_FS) += kcapi_proc.o
> diff --git a/drivers/isdn/hardware/Makefile b/drivers/isdn/hardware/Makefile
> deleted file mode 100644
> index 96f9eb2e46ba..000000000000
> --- a/drivers/isdn/hardware/Makefile
> +++ /dev/null
> @@ -1,6 +0,0 @@
> -# SPDX-License-Identifier: GPL-2.0-only
> -# Makefile for the CAPI hardware drivers
> -
> -# Object files in subdirectories
> -
> -obj-$(CONFIG_MISDN) += mISDN/
> diff --git a/drivers/isdn/hardware/mISDN/Makefile b/drivers/isdn/hardware/mISDN/Makefile
> deleted file mode 100644
> index 3f50f8c4753f..000000000000
> --- a/drivers/isdn/hardware/mISDN/Makefile
> +++ /dev/null
> @@ -1,19 +0,0 @@
> -# SPDX-License-Identifier: GPL-2.0
> -#
> -# Makefile for the modular ISDN hardware drivers
> -#
> -#
> -
> -obj-$(CONFIG_MISDN_HFCPCI) += hfcpci.o
> -obj-$(CONFIG_MISDN_HFCMULTI) += hfcmulti.o
> -obj-$(CONFIG_MISDN_HFCUSB) += hfcsusb.o
> -obj-$(CONFIG_MISDN_AVMFRITZ) += avmfritz.o
> -obj-$(CONFIG_MISDN_SPEEDFAX) += speedfax.o
> -obj-$(CONFIG_MISDN_INFINEON) += mISDNinfineon.o
> -obj-$(CONFIG_MISDN_W6692) += w6692.o
> -obj-$(CONFIG_MISDN_NETJET) += netjet.o
> -# chip modules
> -obj-$(CONFIG_MISDN_IPAC) += mISDNipac.o
> -obj-$(CONFIG_MISDN_ISAR) += mISDNisar.o
> -
> -obj-$(CONFIG_MISDN_HDLC) += isdnhdlc.o
> diff --git a/drivers/isdn/mISDN/Makefile b/drivers/isdn/mISDN/Makefile
> deleted file mode 100644
> index f3b4b7fa85f8..000000000000
> --- a/drivers/isdn/mISDN/Makefile
> +++ /dev/null
> @@ -1,14 +0,0 @@
> -# SPDX-License-Identifier: GPL-2.0
> -#
> -# Makefile for the modular ISDN driver
> -#
> -
> -obj-$(CONFIG_MISDN) += mISDN_core.o
> -obj-$(CONFIG_MISDN_DSP) += mISDN_dsp.o
> -obj-$(CONFIG_MISDN_L1OIP) += l1oip.o
> -
> -# multi objects
> -
> -mISDN_core-objs := core.o fsm.o socket.o clock.o hwchannel.o stack.o layer1.o layer2.o tei.o timerdev.o
> -mISDN_dsp-objs := dsp_core.o dsp_cmx.o dsp_tones.o dsp_dtmf.o dsp_audio.o dsp_blowfish.o dsp_pipeline.o dsp_hwec.o
> -l1oip-objs := l1oip_core.o l1oip_codec.o
> diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile
> index a7eede7616d8..41049b280887 100644
> --- a/net/bluetooth/Makefile
> +++ b/net/bluetooth/Makefile
> @@ -6,7 +6,6 @@
> obj-$(CONFIG_BT) += bluetooth.o
> obj-$(CONFIG_BT_RFCOMM) += rfcomm/
> obj-$(CONFIG_BT_BNEP) += bnep/
> -obj-$(CONFIG_BT_CMTP) += cmtp/
> obj-$(CONFIG_BT_HIDP) += hidp/
> obj-$(CONFIG_BT_6LOWPAN) += bluetooth_6lowpan.o
>
> diff --git a/net/bluetooth/cmtp/Makefile b/net/bluetooth/cmtp/Makefile
> deleted file mode 100644
> index b2262ca97499..000000000000
> --- a/net/bluetooth/cmtp/Makefile
> +++ /dev/null
> @@ -1,8 +0,0 @@
> -# SPDX-License-Identifier: GPL-2.0-only
> -#
> -# Makefile for the Linux Bluetooth CMTP layer
> -#
> -
> -obj-$(CONFIG_BT_CMTP) += cmtp.o
> -
> -cmtp-objs := core.o sock.o capi.o
> diff --git a/drivers/isdn/capi/kcapi.h b/drivers/isdn/capi/kcapi.h
> deleted file mode 100644
> index 479623e1db2a..000000000000
> --- a/drivers/isdn/capi/kcapi.h
> +++ /dev/null
> @@ -1,182 +0,0 @@
> -/*
> - * Kernel CAPI 2.0 Module
> - *
> - * Copyright 1999 by Carsten Paeth <calle@calle.de>
> - * Copyright 2002 by Kai Germaschewski <kai@germaschewski.name>
> - *
> - * 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/spinlock.h>
> -#include <linux/list.h>
> -#include <linux/isdn/capilli.h>
> -
> -#ifdef KCAPI_DEBUG
> -#define DBG(format, arg...) do { \
> - printk(KERN_DEBUG "%s: " format "\n" , __func__ , ## arg); \
> - } while (0)
> -#else
> -#define DBG(format, arg...) /* */
> -#endif
> -
> -enum {
> - CAPI_CTR_DETACHED = 0,
> - CAPI_CTR_DETECTED = 1,
> - CAPI_CTR_LOADING = 2,
> - CAPI_CTR_RUNNING = 3,
> -};
> -
> -extern struct capi_ctr *capi_controller[CAPI_MAXCONTR];
> -extern struct mutex capi_controller_lock;
> -
> -extern struct capi20_appl *capi_applications[CAPI_MAXAPPL];
> -
> -void kcapi_proc_init(void);
> -void kcapi_proc_exit(void);
> -
> -struct capi20_appl {
> - u16 applid;
> - capi_register_params rparam;
> - void (*recv_message)(struct capi20_appl *ap, struct sk_buff *skb);
> - void *private;
> -
> - /* internal to kernelcapi.o */
> - unsigned long nrecvctlpkt;
> - unsigned long nrecvdatapkt;
> - unsigned long nsentctlpkt;
> - unsigned long nsentdatapkt;
> - struct mutex recv_mtx;
> - struct sk_buff_head recv_queue;
> - struct work_struct recv_work;
> - int release_in_progress;
> -};
> -
> -u16 capi20_isinstalled(void);
> -u16 capi20_register(struct capi20_appl *ap);
> -u16 capi20_release(struct capi20_appl *ap);
> -u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb);
> -u16 capi20_get_manufacturer(u32 contr, u8 buf[CAPI_MANUFACTURER_LEN]);
> -u16 capi20_get_version(u32 contr, struct capi_version *verp);
> -u16 capi20_get_serial(u32 contr, u8 serial[CAPI_SERIAL_LEN]);
> -u16 capi20_get_profile(u32 contr, struct capi_profile *profp);
> -int capi20_manufacturer(unsigned long cmd, void __user *data);
> -
> -#define CAPICTR_UP 0
> -#define CAPICTR_DOWN 1
> -
> -int kcapi_init(void);
> -void kcapi_exit(void);
> -
> -/*----- basic-type definitions -----*/
> -
> -typedef __u8 *_cstruct;
> -
> -typedef enum {
> - CAPI_COMPOSE,
> - CAPI_DEFAULT
> -} _cmstruct;
> -
> -/*
> - The _cmsg structure contains all possible CAPI 2.0 parameter.
> - All parameters are stored here first. The function CAPI_CMSG_2_MESSAGE
> - assembles the parameter and builds CAPI2.0 conform messages.
> - CAPI_MESSAGE_2_CMSG disassembles CAPI 2.0 messages and stores the
> - parameter in the _cmsg structure
> - */
> -
> -typedef struct {
> - /* Header */
> - __u16 ApplId;
> - __u8 Command;
> - __u8 Subcommand;
> - __u16 Messagenumber;
> -
> - /* Parameter */
> - union {
> - __u32 adrController;
> - __u32 adrPLCI;
> - __u32 adrNCCI;
> - } adr;
> -
> - _cmstruct AdditionalInfo;
> - _cstruct B1configuration;
> - __u16 B1protocol;
> - _cstruct B2configuration;
> - __u16 B2protocol;
> - _cstruct B3configuration;
> - __u16 B3protocol;
> - _cstruct BC;
> - _cstruct BChannelinformation;
> - _cmstruct BProtocol;
> - _cstruct CalledPartyNumber;
> - _cstruct CalledPartySubaddress;
> - _cstruct CallingPartyNumber;
> - _cstruct CallingPartySubaddress;
> - __u32 CIPmask;
> - __u32 CIPmask2;
> - __u16 CIPValue;
> - __u32 Class;
> - _cstruct ConnectedNumber;
> - _cstruct ConnectedSubaddress;
> - __u32 Data;
> - __u16 DataHandle;
> - __u16 DataLength;
> - _cstruct FacilityConfirmationParameter;
> - _cstruct Facilitydataarray;
> - _cstruct FacilityIndicationParameter;
> - _cstruct FacilityRequestParameter;
> - __u16 FacilitySelector;
> - __u16 Flags;
> - __u32 Function;
> - _cstruct HLC;
> - __u16 Info;
> - _cstruct InfoElement;
> - __u32 InfoMask;
> - __u16 InfoNumber;
> - _cstruct Keypadfacility;
> - _cstruct LLC;
> - _cstruct ManuData;
> - __u32 ManuID;
> - _cstruct NCPI;
> - __u16 Reason;
> - __u16 Reason_B3;
> - __u16 Reject;
> - _cstruct Useruserdata;
> -
> - /* intern */
> - unsigned l, p;
> - unsigned char *par;
> - __u8 *m;
> -
> - /* buffer to construct message */
> - __u8 buf[180];
> -
> -} _cmsg;
> -
> -/*-----------------------------------------------------------------------*/
> -
> -/*
> - * Debugging / Tracing functions
> - */
> -
> -char *capi_cmd2str(__u8 cmd, __u8 subcmd);
> -
> -typedef struct {
> - u_char *buf;
> - u_char *p;
> - size_t size;
> - size_t pos;
> -} _cdebbuf;
> -
> -#define CDEBUG_SIZE 1024
> -#define CDEBUG_GSIZE 4096
> -
> -void cdebbuf_free(_cdebbuf *cdb);
> -int cdebug_init(void);
> -void cdebug_exit(void);
> -
> -_cdebbuf *capi_message2str(__u8 *msg);
> diff --git a/drivers/isdn/hardware/mISDN/hfc_multi.h b/drivers/isdn/hardware/mISDN/hfc_multi.h
> deleted file mode 100644
> index 5acf826d913c..000000000000
> --- a/drivers/isdn/hardware/mISDN/hfc_multi.h
> +++ /dev/null
> @@ -1,1236 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0 */
> -/*
> - * see notice in hfc_multi.c
> - */
> -
> -#define DEBUG_HFCMULTI_FIFO 0x00010000
> -#define DEBUG_HFCMULTI_CRC 0x00020000
> -#define DEBUG_HFCMULTI_INIT 0x00040000
> -#define DEBUG_HFCMULTI_PLXSD 0x00080000
> -#define DEBUG_HFCMULTI_MODE 0x00100000
> -#define DEBUG_HFCMULTI_MSG 0x00200000
> -#define DEBUG_HFCMULTI_STATE 0x00400000
> -#define DEBUG_HFCMULTI_FILL 0x00800000
> -#define DEBUG_HFCMULTI_SYNC 0x01000000
> -#define DEBUG_HFCMULTI_DTMF 0x02000000
> -#define DEBUG_HFCMULTI_LOCK 0x80000000
> -
> -#define PCI_ENA_REGIO 0x01
> -#define PCI_ENA_MEMIO 0x02
> -
> -#define XHFC_IRQ 4 /* SIU_IRQ2 */
> -#define XHFC_MEMBASE 0xFE000000
> -#define XHFC_MEMSIZE 0x00001000
> -#define XHFC_OFFSET 0x00001000
> -#define PA_XHFC_A0 0x0020 /* PA10 */
> -#define PB_XHFC_IRQ1 0x00000100 /* PB23 */
> -#define PB_XHFC_IRQ2 0x00000200 /* PB22 */
> -#define PB_XHFC_IRQ3 0x00000400 /* PB21 */
> -#define PB_XHFC_IRQ4 0x00000800 /* PB20 */
> -
> -/*
> - * NOTE: some registers are assigned multiple times due to different modes
> - * also registers are assigned differen for HFC-4s/8s and HFC-E1
> - */
> -
> -/*
> - #define MAX_FRAME_SIZE 2048
> -*/
> -
> -struct hfc_chan {
> - struct dchannel *dch; /* link if channel is a D-channel */
> - struct bchannel *bch; /* link if channel is a B-channel */
> - int port; /* the interface port this */
> - /* channel is associated with */
> - int nt_timer; /* -1 if off, 0 if elapsed, >0 if running */
> - int los, ais, slip_tx, slip_rx, rdi; /* current alarms */
> - int jitter;
> - u_long cfg; /* port configuration */
> - int sync; /* sync state (used by E1) */
> - u_int protocol; /* current protocol */
> - int slot_tx; /* current pcm slot */
> - int bank_tx; /* current pcm bank */
> - int slot_rx;
> - int bank_rx;
> - int conf; /* conference setting of TX slot */
> - int txpending; /* if there is currently data in */
> - /* the FIFO 0=no, 1=yes, 2=splloop */
> - int Zfill; /* rx-fifo level on last hfcmulti_tx */
> - int rx_off; /* set to turn fifo receive off */
> - int coeff_count; /* curren coeff block */
> - s32 *coeff; /* memory pointer to 8 coeff blocks */
> -};
> -
> -
> -struct hfcm_hw {
> - u_char r_ctrl;
> - u_char r_irq_ctrl;
> - u_char r_cirm;
> - u_char r_ram_sz;
> - u_char r_pcm_md0;
> - u_char r_irqmsk_misc;
> - u_char r_dtmf;
> - u_char r_st_sync;
> - u_char r_sci_msk;
> - u_char r_tx0, r_tx1;
> - u_char a_st_ctrl0[8];
> - u_char r_bert_wd_md;
> - timer_t timer;
> -};
> -
> -
> -/* for each stack these flags are used (cfg) */
> -#define HFC_CFG_NONCAP_TX 1 /* S/T TX interface has less capacity */
> -#define HFC_CFG_DIS_ECHANNEL 2 /* disable E-channel processing */
> -#define HFC_CFG_REG_ECHANNEL 3 /* register E-channel */
> -#define HFC_CFG_OPTICAL 4 /* the E1 interface is optical */
> -#define HFC_CFG_REPORT_LOS 5 /* the card should report loss of signal */
> -#define HFC_CFG_REPORT_AIS 6 /* the card should report alarm ind. sign. */
> -#define HFC_CFG_REPORT_SLIP 7 /* the card should report bit slips */
> -#define HFC_CFG_REPORT_RDI 8 /* the card should report remote alarm */
> -#define HFC_CFG_DTMF 9 /* enable DTMF-detection */
> -#define HFC_CFG_CRC4 10 /* disable CRC-4 Multiframe mode, */
> -/* use double frame instead. */
> -
> -#define HFC_TYPE_E1 1 /* controller is HFC-E1 */
> -#define HFC_TYPE_4S 4 /* controller is HFC-4S */
> -#define HFC_TYPE_8S 8 /* controller is HFC-8S */
> -#define HFC_TYPE_XHFC 5 /* controller is XHFC */
> -
> -#define HFC_CHIP_EXRAM_128 0 /* external ram 128k */
> -#define HFC_CHIP_EXRAM_512 1 /* external ram 256k */
> -#define HFC_CHIP_REVISION0 2 /* old fifo handling */
> -#define HFC_CHIP_PCM_SLAVE 3 /* PCM is slave */
> -#define HFC_CHIP_PCM_MASTER 4 /* PCM is master */
> -#define HFC_CHIP_RX_SYNC 5 /* disable pll sync for pcm */
> -#define HFC_CHIP_DTMF 6 /* DTMF decoding is enabled */
> -#define HFC_CHIP_CONF 7 /* conference handling is enabled */
> -#define HFC_CHIP_ULAW 8 /* ULAW mode */
> -#define HFC_CHIP_CLOCK2 9 /* double clock mode */
> -#define HFC_CHIP_E1CLOCK_GET 10 /* always get clock from E1 interface */
> -#define HFC_CHIP_E1CLOCK_PUT 11 /* always put clock from E1 interface */
> -#define HFC_CHIP_WATCHDOG 12 /* whether we should send signals */
> -/* to the watchdog */
> -#define HFC_CHIP_B410P 13 /* whether we have a b410p with echocan in */
> -/* hw */
> -#define HFC_CHIP_PLXSD 14 /* whether we have a Speech-Design PLX */
> -#define HFC_CHIP_EMBSD 15 /* whether we have a SD Embedded board */
> -
> -#define HFC_IO_MODE_PCIMEM 0x00 /* normal memory mapped IO */
> -#define HFC_IO_MODE_REGIO 0x01 /* PCI io access */
> -#define HFC_IO_MODE_PLXSD 0x02 /* access HFC via PLX9030 */
> -#define HFC_IO_MODE_EMBSD 0x03 /* direct access */
> -
> -/* table entry in the PCI devices list */
> -struct hm_map {
> - char *vendor_name;
> - char *card_name;
> - int type;
> - int ports;
> - int clock2;
> - int leds;
> - int opticalsupport;
> - int dip_type;
> - int io_mode;
> - int irq;
> -};
> -
> -struct hfc_multi {
> - struct list_head list;
> - struct hm_map *mtyp;
> - int id;
> - int pcm; /* id of pcm bus */
> - int ctype; /* controller type */
> - int ports;
> -
> - u_int irq; /* irq used by card */
> - u_int irqcnt;
> - struct pci_dev *pci_dev;
> - int io_mode; /* selects mode */
> -#ifdef HFC_REGISTER_DEBUG
> - void (*HFC_outb)(struct hfc_multi *hc, u_char reg,
> - u_char val, const char *function, int line);
> - void (*HFC_outb_nodebug)(struct hfc_multi *hc, u_char reg,
> - u_char val, const char *function, int line);
> - u_char (*HFC_inb)(struct hfc_multi *hc, u_char reg,
> - const char *function, int line);
> - u_char (*HFC_inb_nodebug)(struct hfc_multi *hc, u_char reg,
> - const char *function, int line);
> - u_short (*HFC_inw)(struct hfc_multi *hc, u_char reg,
> - const char *function, int line);
> - u_short (*HFC_inw_nodebug)(struct hfc_multi *hc, u_char reg,
> - const char *function, int line);
> - void (*HFC_wait)(struct hfc_multi *hc,
> - const char *function, int line);
> - void (*HFC_wait_nodebug)(struct hfc_multi *hc,
> - const char *function, int line);
> -#else
> - void (*HFC_outb)(struct hfc_multi *hc, u_char reg,
> - u_char val);
> - void (*HFC_outb_nodebug)(struct hfc_multi *hc, u_char reg,
> - u_char val);
> - u_char (*HFC_inb)(struct hfc_multi *hc, u_char reg);
> - u_char (*HFC_inb_nodebug)(struct hfc_multi *hc, u_char reg);
> - u_short (*HFC_inw)(struct hfc_multi *hc, u_char reg);
> - u_short (*HFC_inw_nodebug)(struct hfc_multi *hc, u_char reg);
> - void (*HFC_wait)(struct hfc_multi *hc);
> - void (*HFC_wait_nodebug)(struct hfc_multi *hc);
> -#endif
> - void (*read_fifo)(struct hfc_multi *hc, u_char *data,
> - int len);
> - void (*write_fifo)(struct hfc_multi *hc, u_char *data,
> - int len);
> - u_long pci_origmembase, plx_origmembase;
> - void __iomem *pci_membase; /* PCI memory */
> - void __iomem *plx_membase; /* PLX memory */
> - u_long xhfc_origmembase;
> - u_char *xhfc_membase;
> - u_long *xhfc_memaddr, *xhfc_memdata;
> -#ifdef CONFIG_MISDN_HFCMULTI_8xx
> - struct immap *immap;
> -#endif
> - u_long pb_irqmsk; /* Portbit mask to check the IRQ line */
> - u_long pci_iobase; /* PCI IO */
> - struct hfcm_hw hw; /* remember data of write-only-registers */
> -
> - u_long chip; /* chip configuration */
> - int masterclk; /* port that provides master clock -1=off */
> - unsigned char silence;/* silence byte */
> - unsigned char silence_data[128];/* silence block */
> - int dtmf; /* flag that dtmf is currently in process */
> - int Flen; /* F-buffer size */
> - int Zlen; /* Z-buffer size (must be int for calculation)*/
> - int max_trans; /* maximum transparent fifo fill */
> - int Zmin; /* Z-buffer offset */
> - int DTMFbase; /* base address of DTMF coefficients */
> -
> - u_int slots; /* number of PCM slots */
> - u_int leds; /* type of leds */
> - u_long ledstate; /* save last state of leds */
> - int opticalsupport; /* has the e1 board */
> - /* an optical Interface */
> -
> - u_int bmask[32]; /* bitmask of bchannels for port */
> - u_char dnum[32]; /* array of used dchannel numbers for port */
> - u_char created[32]; /* what port is created */
> - u_int activity_tx; /* if there is data TX / RX */
> - u_int activity_rx; /* bitmask according to port number */
> - /* (will be cleared after */
> - /* showing led-states) */
> - u_int flash[8]; /* counter for flashing 8 leds on activity */
> -
> - u_long wdcount; /* every 500 ms we need to */
> - /* send the watchdog a signal */
> - u_char wdbyte; /* watchdog toggle byte */
> - int e1_state; /* keep track of last state */
> - int e1_getclock; /* if sync is retrieved from interface */
> - int syncronized; /* keep track of existing sync interface */
> - int e1_resync; /* resync jobs */
> -
> - spinlock_t lock; /* the lock */
> -
> - struct mISDNclock *iclock; /* isdn clock support */
> - int iclock_on;
> -
> - /*
> - * the channel index is counted from 0, regardless where the channel
> - * is located on the hfc-channel.
> - * the bch->channel is equvalent to the hfc-channel
> - */
> - struct hfc_chan chan[32];
> - signed char slot_owner[256]; /* owner channel of slot */
> -};
> -
> -/* PLX GPIOs */
> -#define PLX_GPIO4_DIR_BIT 13
> -#define PLX_GPIO4_BIT 14
> -#define PLX_GPIO5_DIR_BIT 16
> -#define PLX_GPIO5_BIT 17
> -#define PLX_GPIO6_DIR_BIT 19
> -#define PLX_GPIO6_BIT 20
> -#define PLX_GPIO7_DIR_BIT 22
> -#define PLX_GPIO7_BIT 23
> -#define PLX_GPIO8_DIR_BIT 25
> -#define PLX_GPIO8_BIT 26
> -
> -#define PLX_GPIO4 (1 << PLX_GPIO4_BIT)
> -#define PLX_GPIO5 (1 << PLX_GPIO5_BIT)
> -#define PLX_GPIO6 (1 << PLX_GPIO6_BIT)
> -#define PLX_GPIO7 (1 << PLX_GPIO7_BIT)
> -#define PLX_GPIO8 (1 << PLX_GPIO8_BIT)
> -
> -#define PLX_GPIO4_DIR (1 << PLX_GPIO4_DIR_BIT)
> -#define PLX_GPIO5_DIR (1 << PLX_GPIO5_DIR_BIT)
> -#define PLX_GPIO6_DIR (1 << PLX_GPIO6_DIR_BIT)
> -#define PLX_GPIO7_DIR (1 << PLX_GPIO7_DIR_BIT)
> -#define PLX_GPIO8_DIR (1 << PLX_GPIO8_DIR_BIT)
> -
> -#define PLX_TERM_ON PLX_GPIO7
> -#define PLX_SLAVE_EN_N PLX_GPIO5
> -#define PLX_MASTER_EN PLX_GPIO6
> -#define PLX_SYNC_O_EN PLX_GPIO4
> -#define PLX_DSP_RES_N PLX_GPIO8
> -/* GPIO4..8 Enable & Set to OUT, SLAVE_EN_N = 1 */
> -#define PLX_GPIOC_INIT (PLX_GPIO4_DIR | PLX_GPIO5_DIR | PLX_GPIO6_DIR \
> - | PLX_GPIO7_DIR | PLX_GPIO8_DIR | PLX_SLAVE_EN_N)
> -
> -/* PLX Interrupt Control/STATUS */
> -#define PLX_INTCSR_LINTI1_ENABLE 0x01
> -#define PLX_INTCSR_LINTI1_STATUS 0x04
> -#define PLX_INTCSR_LINTI2_ENABLE 0x08
> -#define PLX_INTCSR_LINTI2_STATUS 0x20
> -#define PLX_INTCSR_PCIINT_ENABLE 0x40
> -
> -/* PLX Registers */
> -#define PLX_INTCSR 0x4c
> -#define PLX_CNTRL 0x50
> -#define PLX_GPIOC 0x54
> -
> -
> -/*
> - * REGISTER SETTING FOR HFC-4S/8S AND HFC-E1
> - */
> -
> -/* write only registers */
> -#define R_CIRM 0x00
> -#define R_CTRL 0x01
> -#define R_BRG_PCM_CFG 0x02
> -#define R_RAM_ADDR0 0x08
> -#define R_RAM_ADDR1 0x09
> -#define R_RAM_ADDR2 0x0A
> -#define R_FIRST_FIFO 0x0B
> -#define R_RAM_SZ 0x0C
> -#define R_FIFO_MD 0x0D
> -#define R_INC_RES_FIFO 0x0E
> -#define R_FSM_IDX 0x0F
> -#define R_FIFO 0x0F
> -#define R_SLOT 0x10
> -#define R_IRQMSK_MISC 0x11
> -#define R_SCI_MSK 0x12
> -#define R_IRQ_CTRL 0x13
> -#define R_PCM_MD0 0x14
> -#define R_PCM_MD1 0x15
> -#define R_PCM_MD2 0x15
> -#define R_SH0H 0x15
> -#define R_SH1H 0x15
> -#define R_SH0L 0x15
> -#define R_SH1L 0x15
> -#define R_SL_SEL0 0x15
> -#define R_SL_SEL1 0x15
> -#define R_SL_SEL2 0x15
> -#define R_SL_SEL3 0x15
> -#define R_SL_SEL4 0x15
> -#define R_SL_SEL5 0x15
> -#define R_SL_SEL6 0x15
> -#define R_SL_SEL7 0x15
> -#define R_ST_SEL 0x16
> -#define R_ST_SYNC 0x17
> -#define R_CONF_EN 0x18
> -#define R_TI_WD 0x1A
> -#define R_BERT_WD_MD 0x1B
> -#define R_DTMF 0x1C
> -#define R_DTMF_N 0x1D
> -#define R_E1_WR_STA 0x20
> -#define R_E1_RD_STA 0x20
> -#define R_LOS0 0x22
> -#define R_LOS1 0x23
> -#define R_RX0 0x24
> -#define R_RX_FR0 0x25
> -#define R_RX_FR1 0x26
> -#define R_TX0 0x28
> -#define R_TX1 0x29
> -#define R_TX_FR0 0x2C
> -
> -#define R_TX_FR1 0x2D
> -#define R_TX_FR2 0x2E
> -#define R_JATT_ATT 0x2F /* undocumented */
> -#define A_ST_RD_STATE 0x30
> -#define A_ST_WR_STATE 0x30
> -#define R_RX_OFF 0x30
> -#define A_ST_CTRL0 0x31
> -#define R_SYNC_OUT 0x31
> -#define A_ST_CTRL1 0x32
> -#define A_ST_CTRL2 0x33
> -#define A_ST_SQ_WR 0x34
> -#define R_TX_OFF 0x34
> -#define R_SYNC_CTRL 0x35
> -#define A_ST_CLK_DLY 0x37
> -#define R_PWM0 0x38
> -#define R_PWM1 0x39
> -#define A_ST_B1_TX 0x3C
> -#define A_ST_B2_TX 0x3D
> -#define A_ST_D_TX 0x3E
> -#define R_GPIO_OUT0 0x40
> -#define R_GPIO_OUT1 0x41
> -#define R_GPIO_EN0 0x42
> -#define R_GPIO_EN1 0x43
> -#define R_GPIO_SEL 0x44
> -#define R_BRG_CTRL 0x45
> -#define R_PWM_MD 0x46
> -#define R_BRG_MD 0x47
> -#define R_BRG_TIM0 0x48
> -#define R_BRG_TIM1 0x49
> -#define R_BRG_TIM2 0x4A
> -#define R_BRG_TIM3 0x4B
> -#define R_BRG_TIM_SEL01 0x4C
> -#define R_BRG_TIM_SEL23 0x4D
> -#define R_BRG_TIM_SEL45 0x4E
> -#define R_BRG_TIM_SEL67 0x4F
> -#define A_SL_CFG 0xD0
> -#define A_CONF 0xD1
> -#define A_CH_MSK 0xF4
> -#define A_CON_HDLC 0xFA
> -#define A_SUBCH_CFG 0xFB
> -#define A_CHANNEL 0xFC
> -#define A_FIFO_SEQ 0xFD
> -#define A_IRQ_MSK 0xFF
> -
> -/* read only registers */
> -#define A_Z12 0x04
> -#define A_Z1L 0x04
> -#define A_Z1 0x04
> -#define A_Z1H 0x05
> -#define A_Z2L 0x06
> -#define A_Z2 0x06
> -#define A_Z2H 0x07
> -#define A_F1 0x0C
> -#define A_F12 0x0C
> -#define A_F2 0x0D
> -#define R_IRQ_OVIEW 0x10
> -#define R_IRQ_MISC 0x11
> -#define R_IRQ_STATECH 0x12
> -#define R_CONF_OFLOW 0x14
> -#define R_RAM_USE 0x15
> -#define R_CHIP_ID 0x16
> -#define R_BERT_STA 0x17
> -#define R_F0_CNTL 0x18
> -#define R_F0_CNTH 0x19
> -#define R_BERT_EC 0x1A
> -#define R_BERT_ECL 0x1A
> -#define R_BERT_ECH 0x1B
> -#define R_STATUS 0x1C
> -#define R_CHIP_RV 0x1F
> -#define R_STATE 0x20
> -#define R_SYNC_STA 0x24
> -#define R_RX_SL0_0 0x25
> -#define R_RX_SL0_1 0x26
> -#define R_RX_SL0_2 0x27
> -#define R_JATT_DIR 0x2b /* undocumented */
> -#define R_SLIP 0x2c
> -#define A_ST_RD_STA 0x30
> -#define R_FAS_EC 0x30
> -#define R_FAS_ECL 0x30
> -#define R_FAS_ECH 0x31
> -#define R_VIO_EC 0x32
> -#define R_VIO_ECL 0x32
> -#define R_VIO_ECH 0x33
> -#define A_ST_SQ_RD 0x34
> -#define R_CRC_EC 0x34
> -#define R_CRC_ECL 0x34
> -#define R_CRC_ECH 0x35
> -#define R_E_EC 0x36
> -#define R_E_ECL 0x36
> -#define R_E_ECH 0x37
> -#define R_SA6_SA13_EC 0x38
> -#define R_SA6_SA13_ECL 0x38
> -#define R_SA6_SA13_ECH 0x39
> -#define R_SA6_SA23_EC 0x3A
> -#define R_SA6_SA23_ECL 0x3A
> -#define R_SA6_SA23_ECH 0x3B
> -#define A_ST_B1_RX 0x3C
> -#define A_ST_B2_RX 0x3D
> -#define A_ST_D_RX 0x3E
> -#define A_ST_E_RX 0x3F
> -#define R_GPIO_IN0 0x40
> -#define R_GPIO_IN1 0x41
> -#define R_GPI_IN0 0x44
> -#define R_GPI_IN1 0x45
> -#define R_GPI_IN2 0x46
> -#define R_GPI_IN3 0x47
> -#define R_INT_DATA 0x88
> -#define R_IRQ_FIFO_BL0 0xC8
> -#define R_IRQ_FIFO_BL1 0xC9
> -#define R_IRQ_FIFO_BL2 0xCA
> -#define R_IRQ_FIFO_BL3 0xCB
> -#define R_IRQ_FIFO_BL4 0xCC
> -#define R_IRQ_FIFO_BL5 0xCD
> -#define R_IRQ_FIFO_BL6 0xCE
> -#define R_IRQ_FIFO_BL7 0xCF
> -
> -/* read and write registers */
> -#define A_FIFO_DATA0 0x80
> -#define A_FIFO_DATA1 0x80
> -#define A_FIFO_DATA2 0x80
> -#define A_FIFO_DATA0_NOINC 0x84
> -#define A_FIFO_DATA1_NOINC 0x84
> -#define A_FIFO_DATA2_NOINC 0x84
> -#define R_RAM_DATA 0xC0
> -
> -
> -/*
> - * BIT SETTING FOR HFC-4S/8S AND HFC-E1
> - */
> -
> -/* chapter 2: universal bus interface */
> -/* R_CIRM */
> -#define V_IRQ_SEL 0x01
> -#define V_SRES 0x08
> -#define V_HFCRES 0x10
> -#define V_PCMRES 0x20
> -#define V_STRES 0x40
> -#define V_ETRES 0x40
> -#define V_RLD_EPR 0x80
> -/* R_CTRL */
> -#define V_FIFO_LPRIO 0x02
> -#define V_SLOW_RD 0x04
> -#define V_EXT_RAM 0x08
> -#define V_CLK_OFF 0x20
> -#define V_ST_CLK 0x40
> -/* R_RAM_ADDR0 */
> -#define V_RAM_ADDR2 0x01
> -#define V_ADDR_RES 0x40
> -#define V_ADDR_INC 0x80
> -/* R_RAM_SZ */
> -#define V_RAM_SZ 0x01
> -#define V_PWM0_16KHZ 0x10
> -#define V_PWM1_16KHZ 0x20
> -#define V_FZ_MD 0x80
> -/* R_CHIP_ID */
> -#define V_PNP_IRQ 0x01
> -#define V_CHIP_ID 0x10
> -
> -/* chapter 3: data flow */
> -/* R_FIRST_FIFO */
> -#define V_FIRST_FIRO_DIR 0x01
> -#define V_FIRST_FIFO_NUM 0x02
> -/* R_FIFO_MD */
> -#define V_FIFO_MD 0x01
> -#define V_CSM_MD 0x04
> -#define V_FSM_MD 0x08
> -#define V_FIFO_SZ 0x10
> -/* R_FIFO */
> -#define V_FIFO_DIR 0x01
> -#define V_FIFO_NUM 0x02
> -#define V_REV 0x80
> -/* R_SLOT */
> -#define V_SL_DIR 0x01
> -#define V_SL_NUM 0x02
> -/* A_SL_CFG */
> -#define V_CH_DIR 0x01
> -#define V_CH_SEL 0x02
> -#define V_ROUTING 0x40
> -/* A_CON_HDLC */
> -#define V_IFF 0x01
> -#define V_HDLC_TRP 0x02
> -#define V_TRP_IRQ 0x04
> -#define V_DATA_FLOW 0x20
> -/* A_SUBCH_CFG */
> -#define V_BIT_CNT 0x01
> -#define V_START_BIT 0x08
> -#define V_LOOP_FIFO 0x40
> -#define V_INV_DATA 0x80
> -/* A_CHANNEL */
> -#define V_CH_DIR0 0x01
> -#define V_CH_NUM0 0x02
> -/* A_FIFO_SEQ */
> -#define V_NEXT_FIFO_DIR 0x01
> -#define V_NEXT_FIFO_NUM 0x02
> -#define V_SEQ_END 0x40
> -
> -/* chapter 4: FIFO handling and HDLC controller */
> -/* R_INC_RES_FIFO */
> -#define V_INC_F 0x01
> -#define V_RES_F 0x02
> -#define V_RES_LOST 0x04
> -
> -/* chapter 5: S/T interface */
> -/* R_SCI_MSK */
> -#define V_SCI_MSK_ST0 0x01
> -#define V_SCI_MSK_ST1 0x02
> -#define V_SCI_MSK_ST2 0x04
> -#define V_SCI_MSK_ST3 0x08
> -#define V_SCI_MSK_ST4 0x10
> -#define V_SCI_MSK_ST5 0x20
> -#define V_SCI_MSK_ST6 0x40
> -#define V_SCI_MSK_ST7 0x80
> -/* R_ST_SEL */
> -#define V_ST_SEL 0x01
> -#define V_MULT_ST 0x08
> -/* R_ST_SYNC */
> -#define V_SYNC_SEL 0x01
> -#define V_AUTO_SYNC 0x08
> -/* A_ST_WR_STA */
> -#define V_ST_SET_STA 0x01
> -#define V_ST_LD_STA 0x10
> -#define V_ST_ACT 0x20
> -#define V_SET_G2_G3 0x80
> -/* A_ST_CTRL0 */
> -#define V_B1_EN 0x01
> -#define V_B2_EN 0x02
> -#define V_ST_MD 0x04
> -#define V_D_PRIO 0x08
> -#define V_SQ_EN 0x10
> -#define V_96KHZ 0x20
> -#define V_TX_LI 0x40
> -#define V_ST_STOP 0x80
> -/* A_ST_CTRL1 */
> -#define V_G2_G3_EN 0x01
> -#define V_D_HI 0x04
> -#define V_E_IGNO 0x08
> -#define V_E_LO 0x10
> -#define V_B12_SWAP 0x80
> -/* A_ST_CTRL2 */
> -#define V_B1_RX_EN 0x01
> -#define V_B2_RX_EN 0x02
> -#define V_ST_TRIS 0x40
> -/* A_ST_CLK_DLY */
> -#define V_ST_CK_DLY 0x01
> -#define V_ST_SMPL 0x10
> -/* A_ST_D_TX */
> -#define V_ST_D_TX 0x40
> -/* R_IRQ_STATECH */
> -#define V_SCI_ST0 0x01
> -#define V_SCI_ST1 0x02
> -#define V_SCI_ST2 0x04
> -#define V_SCI_ST3 0x08
> -#define V_SCI_ST4 0x10
> -#define V_SCI_ST5 0x20
> -#define V_SCI_ST6 0x40
> -#define V_SCI_ST7 0x80
> -/* A_ST_RD_STA */
> -#define V_ST_STA 0x01
> -#define V_FR_SYNC_ST 0x10
> -#define V_TI2_EXP 0x20
> -#define V_INFO0 0x40
> -#define V_G2_G3 0x80
> -/* A_ST_SQ_RD */
> -#define V_ST_SQ 0x01
> -#define V_MF_RX_RDY 0x10
> -#define V_MF_TX_RDY 0x80
> -/* A_ST_D_RX */
> -#define V_ST_D_RX 0x40
> -/* A_ST_E_RX */
> -#define V_ST_E_RX 0x40
> -
> -/* chapter 5: E1 interface */
> -/* R_E1_WR_STA */
> -/* R_E1_RD_STA */
> -#define V_E1_SET_STA 0x01
> -#define V_E1_LD_STA 0x10
> -/* R_RX0 */
> -#define V_RX_CODE 0x01
> -#define V_RX_FBAUD 0x04
> -#define V_RX_CMI 0x08
> -#define V_RX_INV_CMI 0x10
> -#define V_RX_INV_CLK 0x20
> -#define V_RX_INV_DATA 0x40
> -#define V_AIS_ITU 0x80
> -/* R_RX_FR0 */
> -#define V_NO_INSYNC 0x01
> -#define V_AUTO_RESYNC 0x02
> -#define V_AUTO_RECO 0x04
> -#define V_SWORD_COND 0x08
> -#define V_SYNC_LOSS 0x10
> -#define V_XCRC_SYNC 0x20
> -#define V_MF_RESYNC 0x40
> -#define V_RESYNC 0x80
> -/* R_RX_FR1 */
> -#define V_RX_MF 0x01
> -#define V_RX_MF_SYNC 0x02
> -#define V_RX_SL0_RAM 0x04
> -#define V_ERR_SIM 0x20
> -#define V_RES_NMF 0x40
> -/* R_TX0 */
> -#define V_TX_CODE 0x01
> -#define V_TX_FBAUD 0x04
> -#define V_TX_CMI_CODE 0x08
> -#define V_TX_INV_CMI_CODE 0x10
> -#define V_TX_INV_CLK 0x20
> -#define V_TX_INV_DATA 0x40
> -#define V_OUT_EN 0x80
> -/* R_TX1 */
> -#define V_INV_CLK 0x01
> -#define V_EXCHG_DATA_LI 0x02
> -#define V_AIS_OUT 0x04
> -#define V_ATX 0x20
> -#define V_NTRI 0x40
> -#define V_AUTO_ERR_RES 0x80
> -/* R_TX_FR0 */
> -#define V_TRP_FAS 0x01
> -#define V_TRP_NFAS 0x02
> -#define V_TRP_RAL 0x04
> -#define V_TRP_SA 0x08
> -/* R_TX_FR1 */
> -#define V_TX_FAS 0x01
> -#define V_TX_NFAS 0x02
> -#define V_TX_RAL 0x04
> -#define V_TX_SA 0x08
> -/* R_TX_FR2 */
> -#define V_TX_MF 0x01
> -#define V_TRP_SL0 0x02
> -#define V_TX_SL0_RAM 0x04
> -#define V_TX_E 0x10
> -#define V_NEG_E 0x20
> -#define V_XS12_ON 0x40
> -#define V_XS15_ON 0x80
> -/* R_RX_OFF */
> -#define V_RX_SZ 0x01
> -#define V_RX_INIT 0x04
> -/* R_SYNC_OUT */
> -#define V_SYNC_E1_RX 0x01
> -#define V_IPATS0 0x20
> -#define V_IPATS1 0x40
> -#define V_IPATS2 0x80
> -/* R_TX_OFF */
> -#define V_TX_SZ 0x01
> -#define V_TX_INIT 0x04
> -/* R_SYNC_CTRL */
> -#define V_EXT_CLK_SYNC 0x01
> -#define V_SYNC_OFFS 0x02
> -#define V_PCM_SYNC 0x04
> -#define V_NEG_CLK 0x08
> -#define V_HCLK 0x10
> -/*
> - #define V_JATT_AUTO_DEL 0x20
> - #define V_JATT_AUTO 0x40
> -*/
> -#define V_JATT_OFF 0x80
> -/* R_STATE */
> -#define V_E1_STA 0x01
> -#define V_ALT_FR_RX 0x40
> -#define V_ALT_FR_TX 0x80
> -/* R_SYNC_STA */
> -#define V_RX_STA 0x01
> -#define V_FR_SYNC_E1 0x04
> -#define V_SIG_LOS 0x08
> -#define V_MFA_STA 0x10
> -#define V_AIS 0x40
> -#define V_NO_MF_SYNC 0x80
> -/* R_RX_SL0_0 */
> -#define V_SI_FAS 0x01
> -#define V_SI_NFAS 0x02
> -#define V_A 0x04
> -#define V_CRC_OK 0x08
> -#define V_TX_E1 0x10
> -#define V_TX_E2 0x20
> -#define V_RX_E1 0x40
> -#define V_RX_E2 0x80
> -/* R_SLIP */
> -#define V_SLIP_RX 0x01
> -#define V_FOSLIP_RX 0x08
> -#define V_SLIP_TX 0x10
> -#define V_FOSLIP_TX 0x80
> -
> -/* chapter 6: PCM interface */
> -/* R_PCM_MD0 */
> -#define V_PCM_MD 0x01
> -#define V_C4_POL 0x02
> -#define V_F0_NEG 0x04
> -#define V_F0_LEN 0x08
> -#define V_PCM_ADDR 0x10
> -/* R_SL_SEL0 */
> -#define V_SL_SEL0 0x01
> -#define V_SH_SEL0 0x80
> -/* R_SL_SEL1 */
> -#define V_SL_SEL1 0x01
> -#define V_SH_SEL1 0x80
> -/* R_SL_SEL2 */
> -#define V_SL_SEL2 0x01
> -#define V_SH_SEL2 0x80
> -/* R_SL_SEL3 */
> -#define V_SL_SEL3 0x01
> -#define V_SH_SEL3 0x80
> -/* R_SL_SEL4 */
> -#define V_SL_SEL4 0x01
> -#define V_SH_SEL4 0x80
> -/* R_SL_SEL5 */
> -#define V_SL_SEL5 0x01
> -#define V_SH_SEL5 0x80
> -/* R_SL_SEL6 */
> -#define V_SL_SEL6 0x01
> -#define V_SH_SEL6 0x80
> -/* R_SL_SEL7 */
> -#define V_SL_SEL7 0x01
> -#define V_SH_SEL7 0x80
> -/* R_PCM_MD1 */
> -#define V_ODEC_CON 0x01
> -#define V_PLL_ADJ 0x04
> -#define V_PCM_DR 0x10
> -#define V_PCM_LOOP 0x40
> -/* R_PCM_MD2 */
> -#define V_SYNC_PLL 0x02
> -#define V_SYNC_SRC 0x04
> -#define V_SYNC_OUT 0x08
> -#define V_ICR_FR_TIME 0x40
> -#define V_EN_PLL 0x80
> -
> -/* chapter 7: pulse width modulation */
> -/* R_PWM_MD */
> -#define V_EXT_IRQ_EN 0x08
> -#define V_PWM0_MD 0x10
> -#define V_PWM1_MD 0x40
> -
> -/* chapter 8: multiparty audio conferences */
> -/* R_CONF_EN */
> -#define V_CONF_EN 0x01
> -#define V_ULAW 0x80
> -/* A_CONF */
> -#define V_CONF_NUM 0x01
> -#define V_NOISE_SUPPR 0x08
> -#define V_ATT_LEV 0x20
> -#define V_CONF_SL 0x80
> -/* R_CONF_OFLOW */
> -#define V_CONF_OFLOW0 0x01
> -#define V_CONF_OFLOW1 0x02
> -#define V_CONF_OFLOW2 0x04
> -#define V_CONF_OFLOW3 0x08
> -#define V_CONF_OFLOW4 0x10
> -#define V_CONF_OFLOW5 0x20
> -#define V_CONF_OFLOW6 0x40
> -#define V_CONF_OFLOW7 0x80
> -
> -/* chapter 9: DTMF contoller */
> -/* R_DTMF0 */
> -#define V_DTMF_EN 0x01
> -#define V_HARM_SEL 0x02
> -#define V_DTMF_RX_CH 0x04
> -#define V_DTMF_STOP 0x08
> -#define V_CHBL_SEL 0x10
> -#define V_RST_DTMF 0x40
> -#define V_ULAW_SEL 0x80
> -
> -/* chapter 10: BERT */
> -/* R_BERT_WD_MD */
> -#define V_PAT_SEQ 0x01
> -#define V_BERT_ERR 0x08
> -#define V_AUTO_WD_RES 0x20
> -#define V_WD_RES 0x80
> -/* R_BERT_STA */
> -#define V_BERT_SYNC_SRC 0x01
> -#define V_BERT_SYNC 0x10
> -#define V_BERT_INV_DATA 0x20
> -
> -/* chapter 11: auxiliary interface */
> -/* R_BRG_PCM_CFG */
> -#define V_BRG_EN 0x01
> -#define V_BRG_MD 0x02
> -#define V_PCM_CLK 0x20
> -#define V_ADDR_WRDLY 0x40
> -/* R_BRG_CTRL */
> -#define V_BRG_CS 0x01
> -#define V_BRG_ADDR 0x08
> -#define V_BRG_CS_SRC 0x80
> -/* R_BRG_MD */
> -#define V_BRG_MD0 0x01
> -#define V_BRG_MD1 0x02
> -#define V_BRG_MD2 0x04
> -#define V_BRG_MD3 0x08
> -#define V_BRG_MD4 0x10
> -#define V_BRG_MD5 0x20
> -#define V_BRG_MD6 0x40
> -#define V_BRG_MD7 0x80
> -/* R_BRG_TIM0 */
> -#define V_BRG_TIM0_IDLE 0x01
> -#define V_BRG_TIM0_CLK 0x10
> -/* R_BRG_TIM1 */
> -#define V_BRG_TIM1_IDLE 0x01
> -#define V_BRG_TIM1_CLK 0x10
> -/* R_BRG_TIM2 */
> -#define V_BRG_TIM2_IDLE 0x01
> -#define V_BRG_TIM2_CLK 0x10
> -/* R_BRG_TIM3 */
> -#define V_BRG_TIM3_IDLE 0x01
> -#define V_BRG_TIM3_CLK 0x10
> -/* R_BRG_TIM_SEL01 */
> -#define V_BRG_WR_SEL0 0x01
> -#define V_BRG_RD_SEL0 0x04
> -#define V_BRG_WR_SEL1 0x10
> -#define V_BRG_RD_SEL1 0x40
> -/* R_BRG_TIM_SEL23 */
> -#define V_BRG_WR_SEL2 0x01
> -#define V_BRG_RD_SEL2 0x04
> -#define V_BRG_WR_SEL3 0x10
> -#define V_BRG_RD_SEL3 0x40
> -/* R_BRG_TIM_SEL45 */
> -#define V_BRG_WR_SEL4 0x01
> -#define V_BRG_RD_SEL4 0x04
> -#define V_BRG_WR_SEL5 0x10
> -#define V_BRG_RD_SEL5 0x40
> -/* R_BRG_TIM_SEL67 */
> -#define V_BRG_WR_SEL6 0x01
> -#define V_BRG_RD_SEL6 0x04
> -#define V_BRG_WR_SEL7 0x10
> -#define V_BRG_RD_SEL7 0x40
> -
> -/* chapter 12: clock, reset, interrupt, timer and watchdog */
> -/* R_IRQMSK_MISC */
> -#define V_STA_IRQMSK 0x01
> -#define V_TI_IRQMSK 0x02
> -#define V_PROC_IRQMSK 0x04
> -#define V_DTMF_IRQMSK 0x08
> -#define V_IRQ1S_MSK 0x10
> -#define V_SA6_IRQMSK 0x20
> -#define V_RX_EOMF_MSK 0x40
> -#define V_TX_EOMF_MSK 0x80
> -/* R_IRQ_CTRL */
> -#define V_FIFO_IRQ 0x01
> -#define V_GLOB_IRQ_EN 0x08
> -#define V_IRQ_POL 0x10
> -/* R_TI_WD */
> -#define V_EV_TS 0x01
> -#define V_WD_TS 0x10
> -/* A_IRQ_MSK */
> -#define V_IRQ 0x01
> -#define V_BERT_EN 0x02
> -#define V_MIX_IRQ 0x04
> -/* R_IRQ_OVIEW */
> -#define V_IRQ_FIFO_BL0 0x01
> -#define V_IRQ_FIFO_BL1 0x02
> -#define V_IRQ_FIFO_BL2 0x04
> -#define V_IRQ_FIFO_BL3 0x08
> -#define V_IRQ_FIFO_BL4 0x10
> -#define V_IRQ_FIFO_BL5 0x20
> -#define V_IRQ_FIFO_BL6 0x40
> -#define V_IRQ_FIFO_BL7 0x80
> -/* R_IRQ_MISC */
> -#define V_STA_IRQ 0x01
> -#define V_TI_IRQ 0x02
> -#define V_IRQ_PROC 0x04
> -#define V_DTMF_IRQ 0x08
> -#define V_IRQ1S 0x10
> -#define V_SA6_IRQ 0x20
> -#define V_RX_EOMF 0x40
> -#define V_TX_EOMF 0x80
> -/* R_STATUS */
> -#define V_BUSY 0x01
> -#define V_PROC 0x02
> -#define V_DTMF_STA 0x04
> -#define V_LOST_STA 0x08
> -#define V_SYNC_IN 0x10
> -#define V_EXT_IRQSTA 0x20
> -#define V_MISC_IRQSTA 0x40
> -#define V_FR_IRQSTA 0x80
> -/* R_IRQ_FIFO_BL0 */
> -#define V_IRQ_FIFO0_TX 0x01
> -#define V_IRQ_FIFO0_RX 0x02
> -#define V_IRQ_FIFO1_TX 0x04
> -#define V_IRQ_FIFO1_RX 0x08
> -#define V_IRQ_FIFO2_TX 0x10
> -#define V_IRQ_FIFO2_RX 0x20
> -#define V_IRQ_FIFO3_TX 0x40
> -#define V_IRQ_FIFO3_RX 0x80
> -/* R_IRQ_FIFO_BL1 */
> -#define V_IRQ_FIFO4_TX 0x01
> -#define V_IRQ_FIFO4_RX 0x02
> -#define V_IRQ_FIFO5_TX 0x04
> -#define V_IRQ_FIFO5_RX 0x08
> -#define V_IRQ_FIFO6_TX 0x10
> -#define V_IRQ_FIFO6_RX 0x20
> -#define V_IRQ_FIFO7_TX 0x40
> -#define V_IRQ_FIFO7_RX 0x80
> -/* R_IRQ_FIFO_BL2 */
> -#define V_IRQ_FIFO8_TX 0x01
> -#define V_IRQ_FIFO8_RX 0x02
> -#define V_IRQ_FIFO9_TX 0x04
> -#define V_IRQ_FIFO9_RX 0x08
> -#define V_IRQ_FIFO10_TX 0x10
> -#define V_IRQ_FIFO10_RX 0x20
> -#define V_IRQ_FIFO11_TX 0x40
> -#define V_IRQ_FIFO11_RX 0x80
> -/* R_IRQ_FIFO_BL3 */
> -#define V_IRQ_FIFO12_TX 0x01
> -#define V_IRQ_FIFO12_RX 0x02
> -#define V_IRQ_FIFO13_TX 0x04
> -#define V_IRQ_FIFO13_RX 0x08
> -#define V_IRQ_FIFO14_TX 0x10
> -#define V_IRQ_FIFO14_RX 0x20
> -#define V_IRQ_FIFO15_TX 0x40
> -#define V_IRQ_FIFO15_RX 0x80
> -/* R_IRQ_FIFO_BL4 */
> -#define V_IRQ_FIFO16_TX 0x01
> -#define V_IRQ_FIFO16_RX 0x02
> -#define V_IRQ_FIFO17_TX 0x04
> -#define V_IRQ_FIFO17_RX 0x08
> -#define V_IRQ_FIFO18_TX 0x10
> -#define V_IRQ_FIFO18_RX 0x20
> -#define V_IRQ_FIFO19_TX 0x40
> -#define V_IRQ_FIFO19_RX 0x80
> -/* R_IRQ_FIFO_BL5 */
> -#define V_IRQ_FIFO20_TX 0x01
> -#define V_IRQ_FIFO20_RX 0x02
> -#define V_IRQ_FIFO21_TX 0x04
> -#define V_IRQ_FIFO21_RX 0x08
> -#define V_IRQ_FIFO22_TX 0x10
> -#define V_IRQ_FIFO22_RX 0x20
> -#define V_IRQ_FIFO23_TX 0x40
> -#define V_IRQ_FIFO23_RX 0x80
> -/* R_IRQ_FIFO_BL6 */
> -#define V_IRQ_FIFO24_TX 0x01
> -#define V_IRQ_FIFO24_RX 0x02
> -#define V_IRQ_FIFO25_TX 0x04
> -#define V_IRQ_FIFO25_RX 0x08
> -#define V_IRQ_FIFO26_TX 0x10
> -#define V_IRQ_FIFO26_RX 0x20
> -#define V_IRQ_FIFO27_TX 0x40
> -#define V_IRQ_FIFO27_RX 0x80
> -/* R_IRQ_FIFO_BL7 */
> -#define V_IRQ_FIFO28_TX 0x01
> -#define V_IRQ_FIFO28_RX 0x02
> -#define V_IRQ_FIFO29_TX 0x04
> -#define V_IRQ_FIFO29_RX 0x08
> -#define V_IRQ_FIFO30_TX 0x10
> -#define V_IRQ_FIFO30_RX 0x20
> -#define V_IRQ_FIFO31_TX 0x40
> -#define V_IRQ_FIFO31_RX 0x80
> -
> -/* chapter 13: general purpose I/O pins (GPIO) and input pins (GPI) */
> -/* R_GPIO_OUT0 */
> -#define V_GPIO_OUT0 0x01
> -#define V_GPIO_OUT1 0x02
> -#define V_GPIO_OUT2 0x04
> -#define V_GPIO_OUT3 0x08
> -#define V_GPIO_OUT4 0x10
> -#define V_GPIO_OUT5 0x20
> -#define V_GPIO_OUT6 0x40
> -#define V_GPIO_OUT7 0x80
> -/* R_GPIO_OUT1 */
> -#define V_GPIO_OUT8 0x01
> -#define V_GPIO_OUT9 0x02
> -#define V_GPIO_OUT10 0x04
> -#define V_GPIO_OUT11 0x08
> -#define V_GPIO_OUT12 0x10
> -#define V_GPIO_OUT13 0x20
> -#define V_GPIO_OUT14 0x40
> -#define V_GPIO_OUT15 0x80
> -/* R_GPIO_EN0 */
> -#define V_GPIO_EN0 0x01
> -#define V_GPIO_EN1 0x02
> -#define V_GPIO_EN2 0x04
> -#define V_GPIO_EN3 0x08
> -#define V_GPIO_EN4 0x10
> -#define V_GPIO_EN5 0x20
> -#define V_GPIO_EN6 0x40
> -#define V_GPIO_EN7 0x80
> -/* R_GPIO_EN1 */
> -#define V_GPIO_EN8 0x01
> -#define V_GPIO_EN9 0x02
> -#define V_GPIO_EN10 0x04
> -#define V_GPIO_EN11 0x08
> -#define V_GPIO_EN12 0x10
> -#define V_GPIO_EN13 0x20
> -#define V_GPIO_EN14 0x40
> -#define V_GPIO_EN15 0x80
> -/* R_GPIO_SEL */
> -#define V_GPIO_SEL0 0x01
> -#define V_GPIO_SEL1 0x02
> -#define V_GPIO_SEL2 0x04
> -#define V_GPIO_SEL3 0x08
> -#define V_GPIO_SEL4 0x10
> -#define V_GPIO_SEL5 0x20
> -#define V_GPIO_SEL6 0x40
> -#define V_GPIO_SEL7 0x80
> -/* R_GPIO_IN0 */
> -#define V_GPIO_IN0 0x01
> -#define V_GPIO_IN1 0x02
> -#define V_GPIO_IN2 0x04
> -#define V_GPIO_IN3 0x08
> -#define V_GPIO_IN4 0x10
> -#define V_GPIO_IN5 0x20
> -#define V_GPIO_IN6 0x40
> -#define V_GPIO_IN7 0x80
> -/* R_GPIO_IN1 */
> -#define V_GPIO_IN8 0x01
> -#define V_GPIO_IN9 0x02
> -#define V_GPIO_IN10 0x04
> -#define V_GPIO_IN11 0x08
> -#define V_GPIO_IN12 0x10
> -#define V_GPIO_IN13 0x20
> -#define V_GPIO_IN14 0x40
> -#define V_GPIO_IN15 0x80
> -/* R_GPI_IN0 */
> -#define V_GPI_IN0 0x01
> -#define V_GPI_IN1 0x02
> -#define V_GPI_IN2 0x04
> -#define V_GPI_IN3 0x08
> -#define V_GPI_IN4 0x10
> -#define V_GPI_IN5 0x20
> -#define V_GPI_IN6 0x40
> -#define V_GPI_IN7 0x80
> -/* R_GPI_IN1 */
> -#define V_GPI_IN8 0x01
> -#define V_GPI_IN9 0x02
> -#define V_GPI_IN10 0x04
> -#define V_GPI_IN11 0x08
> -#define V_GPI_IN12 0x10
> -#define V_GPI_IN13 0x20
> -#define V_GPI_IN14 0x40
> -#define V_GPI_IN15 0x80
> -/* R_GPI_IN2 */
> -#define V_GPI_IN16 0x01
> -#define V_GPI_IN17 0x02
> -#define V_GPI_IN18 0x04
> -#define V_GPI_IN19 0x08
> -#define V_GPI_IN20 0x10
> -#define V_GPI_IN21 0x20
> -#define V_GPI_IN22 0x40
> -#define V_GPI_IN23 0x80
> -/* R_GPI_IN3 */
> -#define V_GPI_IN24 0x01
> -#define V_GPI_IN25 0x02
> -#define V_GPI_IN26 0x04
> -#define V_GPI_IN27 0x08
> -#define V_GPI_IN28 0x10
> -#define V_GPI_IN29 0x20
> -#define V_GPI_IN30 0x40
> -#define V_GPI_IN31 0x80
> -
> -/* map of all registers, used for debugging */
> -
> -#ifdef HFC_REGISTER_DEBUG
> -struct hfc_register_names {
> - char *name;
> - u_char reg;
> -} hfc_register_names[] = {
> - /* write registers */
> - {"R_CIRM", 0x00},
> - {"R_CTRL", 0x01},
> - {"R_BRG_PCM_CFG ", 0x02},
> - {"R_RAM_ADDR0", 0x08},
> - {"R_RAM_ADDR1", 0x09},
> - {"R_RAM_ADDR2", 0x0A},
> - {"R_FIRST_FIFO", 0x0B},
> - {"R_RAM_SZ", 0x0C},
> - {"R_FIFO_MD", 0x0D},
> - {"R_INC_RES_FIFO", 0x0E},
> - {"R_FIFO / R_FSM_IDX", 0x0F},
> - {"R_SLOT", 0x10},
> - {"R_IRQMSK_MISC", 0x11},
> - {"R_SCI_MSK", 0x12},
> - {"R_IRQ_CTRL", 0x13},
> - {"R_PCM_MD0", 0x14},
> - {"R_0x15", 0x15},
> - {"R_ST_SEL", 0x16},
> - {"R_ST_SYNC", 0x17},
> - {"R_CONF_EN", 0x18},
> - {"R_TI_WD", 0x1A},
> - {"R_BERT_WD_MD", 0x1B},
> - {"R_DTMF", 0x1C},
> - {"R_DTMF_N", 0x1D},
> - {"R_E1_XX_STA", 0x20},
> - {"R_LOS0", 0x22},
> - {"R_LOS1", 0x23},
> - {"R_RX0", 0x24},
> - {"R_RX_FR0", 0x25},
> - {"R_RX_FR1", 0x26},
> - {"R_TX0", 0x28},
> - {"R_TX1", 0x29},
> - {"R_TX_FR0", 0x2C},
> - {"R_TX_FR1", 0x2D},
> - {"R_TX_FR2", 0x2E},
> - {"R_JATT_ATT", 0x2F},
> - {"A_ST_xx_STA/R_RX_OFF", 0x30},
> - {"A_ST_CTRL0/R_SYNC_OUT", 0x31},
> - {"A_ST_CTRL1", 0x32},
> - {"A_ST_CTRL2", 0x33},
> - {"A_ST_SQ_WR", 0x34},
> - {"R_TX_OFF", 0x34},
> - {"R_SYNC_CTRL", 0x35},
> - {"A_ST_CLK_DLY", 0x37},
> - {"R_PWM0", 0x38},
> - {"R_PWM1", 0x39},
> - {"A_ST_B1_TX", 0x3C},
> - {"A_ST_B2_TX", 0x3D},
> - {"A_ST_D_TX", 0x3E},
> - {"R_GPIO_OUT0", 0x40},
> - {"R_GPIO_OUT1", 0x41},
> - {"R_GPIO_EN0", 0x42},
> - {"R_GPIO_EN1", 0x43},
> - {"R_GPIO_SEL", 0x44},
> - {"R_BRG_CTRL", 0x45},
> - {"R_PWM_MD", 0x46},
> - {"R_BRG_MD", 0x47},
> - {"R_BRG_TIM0", 0x48},
> - {"R_BRG_TIM1", 0x49},
> - {"R_BRG_TIM2", 0x4A},
> - {"R_BRG_TIM3", 0x4B},
> - {"R_BRG_TIM_SEL01", 0x4C},
> - {"R_BRG_TIM_SEL23", 0x4D},
> - {"R_BRG_TIM_SEL45", 0x4E},
> - {"R_BRG_TIM_SEL67", 0x4F},
> - {"A_FIFO_DATA0-2", 0x80},
> - {"A_FIFO_DATA0-2_NOINC", 0x84},
> - {"R_RAM_DATA", 0xC0},
> - {"A_SL_CFG", 0xD0},
> - {"A_CONF", 0xD1},
> - {"A_CH_MSK", 0xF4},
> - {"A_CON_HDLC", 0xFA},
> - {"A_SUBCH_CFG", 0xFB},
> - {"A_CHANNEL", 0xFC},
> - {"A_FIFO_SEQ", 0xFD},
> - {"A_IRQ_MSK", 0xFF},
> - {NULL, 0},
> -
> - /* read registers */
> - {"A_Z1", 0x04},
> - {"A_Z1H", 0x05},
> - {"A_Z2", 0x06},
> - {"A_Z2H", 0x07},
> - {"A_F1", 0x0C},
> - {"A_F2", 0x0D},
> - {"R_IRQ_OVIEW", 0x10},
> - {"R_IRQ_MISC", 0x11},
> - {"R_IRQ_STATECH", 0x12},
> - {"R_CONF_OFLOW", 0x14},
> - {"R_RAM_USE", 0x15},
> - {"R_CHIP_ID", 0x16},
> - {"R_BERT_STA", 0x17},
> - {"R_F0_CNTL", 0x18},
> - {"R_F0_CNTH", 0x19},
> - {"R_BERT_ECL", 0x1A},
> - {"R_BERT_ECH", 0x1B},
> - {"R_STATUS", 0x1C},
> - {"R_CHIP_RV", 0x1F},
> - {"R_STATE", 0x20},
> - {"R_SYNC_STA", 0x24},
> - {"R_RX_SL0_0", 0x25},
> - {"R_RX_SL0_1", 0x26},
> - {"R_RX_SL0_2", 0x27},
> - {"R_JATT_DIR", 0x2b},
> - {"R_SLIP", 0x2c},
> - {"A_ST_RD_STA", 0x30},
> - {"R_FAS_ECL", 0x30},
> - {"R_FAS_ECH", 0x31},
> - {"R_VIO_ECL", 0x32},
> - {"R_VIO_ECH", 0x33},
> - {"R_CRC_ECL / A_ST_SQ_RD", 0x34},
> - {"R_CRC_ECH", 0x35},
> - {"R_E_ECL", 0x36},
> - {"R_E_ECH", 0x37},
> - {"R_SA6_SA13_ECL", 0x38},
> - {"R_SA6_SA13_ECH", 0x39},
> - {"R_SA6_SA23_ECL", 0x3A},
> - {"R_SA6_SA23_ECH", 0x3B},
> - {"A_ST_B1_RX", 0x3C},
> - {"A_ST_B2_RX", 0x3D},
> - {"A_ST_D_RX", 0x3E},
> - {"A_ST_E_RX", 0x3F},
> - {"R_GPIO_IN0", 0x40},
> - {"R_GPIO_IN1", 0x41},
> - {"R_GPI_IN0", 0x44},
> - {"R_GPI_IN1", 0x45},
> - {"R_GPI_IN2", 0x46},
> - {"R_GPI_IN3", 0x47},
> - {"A_FIFO_DATA0-2", 0x80},
> - {"A_FIFO_DATA0-2_NOINC", 0x84},
> - {"R_INT_DATA", 0x88},
> - {"R_RAM_DATA", 0xC0},
> - {"R_IRQ_FIFO_BL0", 0xC8},
> - {"R_IRQ_FIFO_BL1", 0xC9},
> - {"R_IRQ_FIFO_BL2", 0xCA},
> - {"R_IRQ_FIFO_BL3", 0xCB},
> - {"R_IRQ_FIFO_BL4", 0xCC},
> - {"R_IRQ_FIFO_BL5", 0xCD},
> - {"R_IRQ_FIFO_BL6", 0xCE},
> - {"R_IRQ_FIFO_BL7", 0xCF},
> -};
> -#endif /* HFC_REGISTER_DEBUG */
> diff --git a/drivers/isdn/hardware/mISDN/hfc_multi_8xx.h b/drivers/isdn/hardware/mISDN/hfc_multi_8xx.h
> deleted file mode 100644
> index 448ded8f9d24..000000000000
> --- a/drivers/isdn/hardware/mISDN/hfc_multi_8xx.h
> +++ /dev/null
> @@ -1,167 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0 */
> -/*
> - * For License see notice in hfc_multi.c
> - *
> - * special IO and init functions for the embedded XHFC board
> - * from Speech Design
> - *
> - */
> -
> -#include <asm/cpm1.h>
> -
> -/* Change this to the value used by your board */
> -#ifndef IMAP_ADDR
> -#define IMAP_ADDR 0xFFF00000
> -#endif
> -
> -static void
> -#ifdef HFC_REGISTER_DEBUG
> -HFC_outb_embsd(struct hfc_multi *hc, u_char reg, u_char val,
> - const char *function, int line)
> -#else
> - HFC_outb_embsd(struct hfc_multi *hc, u_char reg, u_char val)
> -#endif
> -{
> - hc->immap->im_ioport.iop_padat |= PA_XHFC_A0;
> - writeb(reg, hc->xhfc_memaddr);
> - hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0);
> - writeb(val, hc->xhfc_memdata);
> -}
> -static u_char
> -#ifdef HFC_REGISTER_DEBUG
> -HFC_inb_embsd(struct hfc_multi *hc, u_char reg, const char *function, int line)
> -#else
> - HFC_inb_embsd(struct hfc_multi *hc, u_char reg)
> -#endif
> -{
> - hc->immap->im_ioport.iop_padat |= PA_XHFC_A0;
> - writeb(reg, hc->xhfc_memaddr);
> - hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0);
> - return readb(hc->xhfc_memdata);
> -}
> -static u_short
> -#ifdef HFC_REGISTER_DEBUG
> -HFC_inw_embsd(struct hfc_multi *hc, u_char reg, const char *function, int line)
> -#else
> - HFC_inw_embsd(struct hfc_multi *hc, u_char reg)
> -#endif
> -{
> - hc->immap->im_ioport.iop_padat |= PA_XHFC_A0;
> - writeb(reg, hc->xhfc_memaddr);
> - hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0);
> - return readb(hc->xhfc_memdata);
> -}
> -static void
> -#ifdef HFC_REGISTER_DEBUG
> -HFC_wait_embsd(struct hfc_multi *hc, const char *function, int line)
> -#else
> - HFC_wait_embsd(struct hfc_multi *hc)
> -#endif
> -{
> - hc->immap->im_ioport.iop_padat |= PA_XHFC_A0;
> - writeb(R_STATUS, hc->xhfc_memaddr);
> - hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0);
> - while (readb(hc->xhfc_memdata) & V_BUSY)
> - cpu_relax();
> -}
> -
> -/* write fifo data (EMBSD) */
> -void
> -write_fifo_embsd(struct hfc_multi *hc, u_char *data, int len)
> -{
> - hc->immap->im_ioport.iop_padat |= PA_XHFC_A0;
> - *hc->xhfc_memaddr = A_FIFO_DATA0;
> - hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0);
> - while (len) {
> - *hc->xhfc_memdata = *data;
> - data++;
> - len--;
> - }
> -}
> -
> -/* read fifo data (EMBSD) */
> -void
> -read_fifo_embsd(struct hfc_multi *hc, u_char *data, int len)
> -{
> - hc->immap->im_ioport.iop_padat |= PA_XHFC_A0;
> - *hc->xhfc_memaddr = A_FIFO_DATA0;
> - hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0);
> - while (len) {
> - *data = (u_char)(*hc->xhfc_memdata);
> - data++;
> - len--;
> - }
> -}
> -
> -static int
> -setup_embedded(struct hfc_multi *hc, struct hm_map *m)
> -{
> - printk(KERN_INFO
> - "HFC-multi: card manufacturer: '%s' card name: '%s' clock: %s\n",
> - m->vendor_name, m->card_name, m->clock2 ? "double" : "normal");
> -
> - hc->pci_dev = NULL;
> - if (m->clock2)
> - test_and_set_bit(HFC_CHIP_CLOCK2, &hc->chip);
> -
> - hc->leds = m->leds;
> - hc->ledstate = 0xAFFEAFFE;
> - hc->opticalsupport = m->opticalsupport;
> -
> - hc->pci_iobase = 0;
> - hc->pci_membase = 0;
> - hc->xhfc_membase = NULL;
> - hc->xhfc_memaddr = NULL;
> - hc->xhfc_memdata = NULL;
> -
> - /* set memory access methods */
> - if (m->io_mode) /* use mode from card config */
> - hc->io_mode = m->io_mode;
> - switch (hc->io_mode) {
> - case HFC_IO_MODE_EMBSD:
> - test_and_set_bit(HFC_CHIP_EMBSD, &hc->chip);
> - hc->slots = 128; /* required */
> - hc->HFC_outb = HFC_outb_embsd;
> - hc->HFC_inb = HFC_inb_embsd;
> - hc->HFC_inw = HFC_inw_embsd;
> - hc->HFC_wait = HFC_wait_embsd;
> - hc->read_fifo = read_fifo_embsd;
> - hc->write_fifo = write_fifo_embsd;
> - hc->xhfc_origmembase = XHFC_MEMBASE + XHFC_OFFSET * hc->id;
> - hc->xhfc_membase = (u_char *)ioremap(hc->xhfc_origmembase,
> - XHFC_MEMSIZE);
> - if (!hc->xhfc_membase) {
> - printk(KERN_WARNING
> - "HFC-multi: failed to remap xhfc address space. "
> - "(internal error)\n");
> - return -EIO;
> - }
> - hc->xhfc_memaddr = (u_long *)(hc->xhfc_membase + 4);
> - hc->xhfc_memdata = (u_long *)(hc->xhfc_membase);
> - printk(KERN_INFO
> - "HFC-multi: xhfc_membase:%#lx xhfc_origmembase:%#lx "
> - "xhfc_memaddr:%#lx xhfc_memdata:%#lx\n",
> - (u_long)hc->xhfc_membase, hc->xhfc_origmembase,
> - (u_long)hc->xhfc_memaddr, (u_long)hc->xhfc_memdata);
> - break;
> - default:
> - printk(KERN_WARNING "HFC-multi: Invalid IO mode.\n");
> - return -EIO;
> - }
> -
> - /* Prepare the MPC8XX PortA 10 as output (address/data selector) */
> - hc->immap = (struct immap *)(IMAP_ADDR);
> - hc->immap->im_ioport.iop_papar &= ~(PA_XHFC_A0);
> - hc->immap->im_ioport.iop_paodr &= ~(PA_XHFC_A0);
> - hc->immap->im_ioport.iop_padir |= PA_XHFC_A0;
> -
> - /* Prepare the MPC8xx PortB __X__ as input (ISDN__X__IRQ) */
> - hc->pb_irqmsk = (PB_XHFC_IRQ1 << hc->id);
> - hc->immap->im_cpm.cp_pbpar &= ~(hc->pb_irqmsk);
> - hc->immap->im_cpm.cp_pbodr &= ~(hc->pb_irqmsk);
> - hc->immap->im_cpm.cp_pbdir &= ~(hc->pb_irqmsk);
> -
> - /* At this point the needed config is done */
> - /* fifos are still not enabled */
> - return 0;
> -}
> diff --git a/drivers/isdn/hardware/mISDN/hfc_pci.h b/drivers/isdn/hardware/mISDN/hfc_pci.h
> deleted file mode 100644
> index a0e4806c11fa..000000000000
> --- a/drivers/isdn/hardware/mISDN/hfc_pci.h
> +++ /dev/null
> @@ -1,214 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-or-later */
> -/*
> - * specific defines for CCD's HFC 2BDS0 PCI chips
> - *
> - * Author Werner Cornelius (werner@isdn4linux.de)
> - *
> - * Copyright 1999 by Werner Cornelius (werner@isdn4linux.de)
> - */
> -
> -/*
> - * thresholds for transparent B-channel mode
> - * change mask and threshold simultaneously
> - */
> -#define HFCPCI_BTRANS_THRESHOLD 128
> -#define HFCPCI_FILLEMPTY 64
> -#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
> -#define HFCPCI_F0IO_POSITIV 0x02
> -#define HFCPCI_F0_NEGATIV 0x04
> -#define HFCPCI_F0_2C4 0x08
> -/* 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
> -
> -struct zt {
> - __le16 z1; /* Z1 pointer 16 Bit */
> - __le16 z2; /* Z2 pointer 16 Bit */
> -};
> -
> -struct dfifo {
> - 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 */
> - /* mask index with D_FREG_MASK for access */
> - struct zt za[MAX_D_FRAMES + 1];
> - u_char fill3[0x4000 - 0x2100]; /* align 16K */
> -};
> -
> -struct bzfifo {
> - struct zt za[MAX_B_FRAMES + 1]; /* only range 0x0..0x1F allowed */
> - u_char f1, f2; /* f pointers */
> - u_char fill[0x2100 - 0x2082]; /* alignment */
> -};
> -
> -
> -union fifo_area {
> - struct {
> - struct dfifo d_tx; /* D-send channel */
> - struct dfifo d_rx; /* D-receive channel */
> - } d_chan;
> - struct {
> - u_char fill1[0x200];
> - u_char txdat_b1[B_FIFO_SIZE];
> - struct bzfifo txbz_b1;
> - struct bzfifo txbz_b2;
> - u_char txdat_b2[B_FIFO_SIZE];
> - u_char fill2[D_FIFO_SIZE];
> - u_char rxdat_b1[B_FIFO_SIZE];
> - struct bzfifo rxbz_b1;
> - struct bzfifo rxbz_b2;
> - u_char rxdat_b2[B_FIFO_SIZE];
> - } b_chans;
> - u_char fill[32768];
> -};
> -
> -#define Write_hfc(a, b, c) (writeb(c, (a->hw.pci_io) + b))
> -#define Read_hfc(a, b) (readb((a->hw.pci_io) + b))
> diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.h b/drivers/isdn/hardware/mISDN/hfcsusb.h
> deleted file mode 100644
> index 7e2bc5068019..000000000000
> --- a/drivers/isdn/hardware/mISDN/hfcsusb.h
> +++ /dev/null
> @@ -1,425 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0 */
> -/*
> - * hfcsusb.h, HFC-S USB mISDN driver
> - */
> -
> -#ifndef __HFCSUSB_H__
> -#define __HFCSUSB_H__
> -
> -
> -#define DRIVER_NAME "HFC-S_USB"
> -
> -#define DBG_HFC_CALL_TRACE 0x00010000
> -#define DBG_HFC_FIFO_VERBOSE 0x00020000
> -#define DBG_HFC_USB_VERBOSE 0x00100000
> -#define DBG_HFC_URB_INFO 0x00200000
> -#define DBG_HFC_URB_ERROR 0x00400000
> -
> -#define DEFAULT_TRANSP_BURST_SZ 128
> -
> -#define HFC_CTRL_TIMEOUT 20 /* 5ms timeout writing/reading regs */
> -#define CLKDEL_TE 0x0f /* CLKDEL in TE mode */
> -#define CLKDEL_NT 0x6c /* CLKDEL in NT mode */
> -
> -/* hfcsusb Layer1 commands */
> -#define HFC_L1_ACTIVATE_TE 1
> -#define HFC_L1_ACTIVATE_NT 2
> -#define HFC_L1_DEACTIVATE_NT 3
> -#define HFC_L1_FORCE_DEACTIVATE_TE 4
> -
> -/* cmd FLAGS in HFCUSB_STATES register */
> -#define HFCUSB_LOAD_STATE 0x10
> -#define HFCUSB_ACTIVATE 0x20
> -#define HFCUSB_DO_ACTION 0x40
> -#define HFCUSB_NT_G2_G3 0x80
> -
> -/* timers */
> -#define NT_ACTIVATION_TIMER 0x01 /* enables NT mode activation Timer */
> -#define NT_T1_COUNT 10
> -
> -#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 96 /* 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_B1_SSL 0x20
> -#define HFCUSB_B2_SSL 0x21
> -#define HFCUSB_B1_RSL 0x24
> -#define HFCUSB_B2_RSL 0x25
> -#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
> -
> -
> -#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
> -
> -/* 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
> -};
> -
> -
> -/* 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 (-96 * 8)
> -
> -/* HFC-S USB register access by Control-URSs */
> -#define write_reg_atomic(a, b, c) \
> - usb_control_msg((a)->dev, (a)->ctrl_out_pipe, 0, 0x40, (c), (b), \
> - 0, 0, HFC_CTRL_TIMEOUT)
> -#define read_reg_atomic(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 64
> -
> -struct ctrl_buf {
> - __u8 hfcs_reg; /* register number */
> - __u8 reg_val; /* value to be written (or read) */
> -};
> -
> -/*
> - * 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}
> -};
> -
> -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 USB Error>";
> -}
> -
> -/* 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 */
> -
> -#define HFC_CHAN_B1 0
> -#define HFC_CHAN_B2 1
> -#define HFC_CHAN_D 2
> -#define HFC_CHAN_E 3
> -
> -
> -/*
> - * List of all supported endpoint configuration sets, used to find the
> - * best matching endpoint configuration within a device's 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_NOP, EP_NOP, EP_NOP, EP_NOP, EP_NOP, EP_NOP, EP_NOP, EP_NOP,
> - 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 */
> -};
> -
> -/* 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"
> -};
> -
> -
> -#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 */
> -
> -/* time in ms to perform a Flashing LED when B-Channel has traffic */
> -#define LED_TIME 250
> -
> -
> -
> -struct hfcsusb;
> -struct usb_fifo;
> -
> -/* structure defining input+output fifos (interrupt/bulk mode) */
> -struct iso_urb {
> - struct urb *urb;
> - __u8 buffer[ISO_BUFFER_SIZE]; /* buffer rx/tx USB URB data */
> - struct usb_fifo *owner_fifo; /* pointer to owner fifo */
> - __u8 indx; /* Fifos's ISO double buffer 0 or 1 ? */
> -#ifdef ISO_FRAME_START_DEBUG
> - int start_frames[ISO_FRAME_START_RING_COUNT];
> - __u8 iso_frm_strt_pos; /* index in start_frame[] */
> -#endif
> -};
> -
> -struct usb_fifo {
> - int fifonum; /* fifo index attached to this structure */
> - int active; /* fifo is currently active */
> - struct hfcsusb *hw; /* 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 urb *urb; /* transfer structure for usb routines */
> - __u8 buffer[128]; /* buffer USB INT OUT URB data */
> - int bit_line; /* how much bits are in the fifo? */
> -
> - __u8 usb_transfer_mode; /* switched between ISO and INT */
> - struct iso_urb iso[2]; /* two urbs to have one always
> - one pending */
> -
> - struct dchannel *dch; /* link to hfcsusb_t->dch */
> - struct bchannel *bch; /* link to hfcsusb_t->bch */
> - struct dchannel *ech; /* link to hfcsusb_t->ech, TODO: E-CHANNEL */
> - int last_urblen; /* remember length of last packet */
> - __u8 stop_gracefull; /* stops URB retransmission */
> -};
> -
> -struct hfcsusb {
> - struct list_head list;
> - struct dchannel dch;
> - struct bchannel bch[2];
> - struct dchannel ech; /* TODO : wait for struct echannel ;) */
> -
> - struct usb_device *dev; /* our device */
> - struct usb_interface *intf; /* used interface */
> - int if_used; /* used interface number */
> - int alt_used; /* used alternate config */
> - int cfg_used; /* configuration index used */
> - int vend_idx; /* index in hfcsusb_idtab */
> - int packet_size;
> - int iso_packet_size;
> - struct usb_fifo fifos[HFCUSB_NUM_FIFOS];
> -
> - /* control pipe background handling */
> - struct ctrl_buf ctrl_buff[HFC_CTRL_BUFSIZE];
> - int ctrl_in_idx, ctrl_out_idx, ctrl_cnt;
> - struct urb *ctrl_urb;
> - struct usb_ctrlrequest ctrl_write;
> - struct usb_ctrlrequest ctrl_read;
> - int ctrl_paksize;
> - int ctrl_in_pipe, ctrl_out_pipe;
> - spinlock_t ctrl_lock; /* lock for ctrl */
> - spinlock_t lock;
> -
> - __u8 threshold_mask;
> - __u8 led_state;
> -
> - __u8 protocol;
> - int nt_timer;
> - int open;
> - __u8 timers;
> - __u8 initdone;
> - char name[MISDN_MAX_IDLEN];
> -};
> -
> -/* private vendor specific data */
> -struct hfcsusb_vdata {
> - __u8 led_scheme; /* led display scheme */
> - signed short led_bits[8]; /* array of 8 possible LED bitmask */
> - char *vend_name; /* device name */
> -};
> -
> -
> -#define HFC_MAX_TE_LAYER1_STATE 8
> -#define HFC_MAX_NT_LAYER1_STATE 4
> -
> -static const char *HFC_TE_LAYER1_STATES[HFC_MAX_TE_LAYER1_STATE + 1] = {
> - "TE F0 - Reset",
> - "TE F1 - Reset",
> - "TE F2 - Sensing",
> - "TE F3 - Deactivated",
> - "TE F4 - Awaiting signal",
> - "TE F5 - Identifying input",
> - "TE F6 - Synchronized",
> - "TE F7 - Activated",
> - "TE F8 - Lost framing",
> -};
> -
> -static const char *HFC_NT_LAYER1_STATES[HFC_MAX_NT_LAYER1_STATE + 1] = {
> - "NT G0 - Reset",
> - "NT G1 - Deactive",
> - "NT G2 - Pending activation",
> - "NT G3 - Active",
> - "NT G4 - Pending deactivation",
> -};
> -
> -/* supported devices */
> -static const struct usb_device_id hfcsusb_idtab[] = {
> - {
> - USB_DEVICE(0x0959, 0x2bd0),
> - .driver_info = (unsigned long) &((struct 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) &((struct hfcsusb_vdata)
> - {LED_SCHEME1, {1, 2, 0, 0},
> - "DrayTek miniVigor 128 USB ISDN TA"}),
> - },
> - {
> - USB_DEVICE(0x07b0, 0x0007),
> - .driver_info = (unsigned long) &((struct hfcsusb_vdata)
> - {LED_SCHEME1, {0x80, -64, -32, -16},
> - "Billion tiny USB ISDN TA 128"}),
> - },
> - {
> - USB_DEVICE(0x0742, 0x2008),
> - .driver_info = (unsigned long) &((struct hfcsusb_vdata)
> - {LED_SCHEME1, {4, 0, 2, 1},
> - "Stollmann USB TA"}),
> - },
> - {
> - USB_DEVICE(0x0742, 0x2009),
> - .driver_info = (unsigned long) &((struct hfcsusb_vdata)
> - {LED_SCHEME1, {4, 0, 2, 1},
> - "Aceex USB ISDN TA"}),
> - },
> - {
> - USB_DEVICE(0x0742, 0x200A),
> - .driver_info = (unsigned long) &((struct hfcsusb_vdata)
> - {LED_SCHEME1, {4, 0, 2, 1},
> - "OEM USB ISDN TA"}),
> - },
> - {
> - USB_DEVICE(0x08e3, 0x0301),
> - .driver_info = (unsigned long) &((struct hfcsusb_vdata)
> - {LED_SCHEME1, {2, 0, 1, 4},
> - "Olitec USB RNIS"}),
> - },
> - {
> - USB_DEVICE(0x07fa, 0x0846),
> - .driver_info = (unsigned long) &((struct hfcsusb_vdata)
> - {LED_SCHEME1, {0x80, -64, -32, -16},
> - "Bewan Modem RNIS USB"}),
> - },
> - {
> - USB_DEVICE(0x07fa, 0x0847),
> - .driver_info = (unsigned long) &((struct hfcsusb_vdata)
> - {LED_SCHEME1, {0x80, -64, -32, -16},
> - "Djinn Numeris USB"}),
> - },
> - {
> - USB_DEVICE(0x07b0, 0x0006),
> - .driver_info = (unsigned long) &((struct hfcsusb_vdata)
> - {LED_SCHEME1, {0x80, -64, -32, -16},
> - "Twister ISDN TA"}),
> - },
> - {
> - USB_DEVICE(0x071d, 0x1005),
> - .driver_info = (unsigned long) &((struct hfcsusb_vdata)
> - {LED_SCHEME1, {0x02, 0, 0x01, 0x04},
> - "Eicon DIVA USB 4.0"}),
> - },
> - {
> - USB_DEVICE(0x0586, 0x0102),
> - .driver_info = (unsigned long) &((struct hfcsusb_vdata)
> - {LED_SCHEME1, {0x88, -64, -32, -16},
> - "ZyXEL OMNI.NET USB II"}),
> - },
> - {
> - USB_DEVICE(0x1ae7, 0x0525),
> - .driver_info = (unsigned long) &((struct hfcsusb_vdata)
> - {LED_SCHEME1, {0x88, -64, -32, -16},
> - "X-Tensions USB ISDN TA XC-525"}),
> - },
> - { }
> -};
> -
> -MODULE_DEVICE_TABLE(usb, hfcsusb_idtab);
> -
> -#endif /* __HFCSUSB_H__ */
> diff --git a/drivers/isdn/hardware/mISDN/iohelper.h b/drivers/isdn/hardware/mISDN/iohelper.h
> deleted file mode 100644
> index c81f7aba4b57..000000000000
> --- a/drivers/isdn/hardware/mISDN/iohelper.h
> +++ /dev/null
> @@ -1,96 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/*
> - * iohelper.h
> - * helper for define functions to access ISDN hardware
> - * supported are memory mapped IO
> - * indirect port IO (one port for address, one for data)
> - *
> - * Author Karsten Keil <keil@isdn4linux.de>
> - *
> - * Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
> - */
> -
> -#ifndef _IOHELPER_H
> -#define _IOHELPER_H
> -
> -typedef u8 (read_reg_func)(void *hwp, u8 offset);
> -typedef void (write_reg_func)(void *hwp, u8 offset, u8 value);
> -typedef void (fifo_func)(void *hwp, u8 offset, u8 *datap, int size);
> -
> -struct _ioport {
> - u32 port;
> - u32 ale;
> -};
> -
> -#define IOFUNC_IO(name, hws, ap) \
> - static u8 Read##name##_IO(void *p, u8 off) { \
> - struct hws *hw = p; \
> - return inb(hw->ap.port + off); \
> - } \
> - static void Write##name##_IO(void *p, u8 off, u8 val) { \
> - struct hws *hw = p; \
> - outb(val, hw->ap.port + off); \
> - } \
> - static void ReadFiFo##name##_IO(void *p, u8 off, u8 *dp, int size) { \
> - struct hws *hw = p; \
> - insb(hw->ap.port + off, dp, size); \
> - } \
> - static void WriteFiFo##name##_IO(void *p, u8 off, u8 *dp, int size) { \
> - struct hws *hw = p; \
> - outsb(hw->ap.port + off, dp, size); \
> - }
> -
> -#define IOFUNC_IND(name, hws, ap) \
> - static u8 Read##name##_IND(void *p, u8 off) { \
> - struct hws *hw = p; \
> - outb(off, hw->ap.ale); \
> - return inb(hw->ap.port); \
> - } \
> - static void Write##name##_IND(void *p, u8 off, u8 val) { \
> - struct hws *hw = p; \
> - outb(off, hw->ap.ale); \
> - outb(val, hw->ap.port); \
> - } \
> - static void ReadFiFo##name##_IND(void *p, u8 off, u8 *dp, int size) { \
> - struct hws *hw = p; \
> - outb(off, hw->ap.ale); \
> - insb(hw->ap.port, dp, size); \
> - } \
> - static void WriteFiFo##name##_IND(void *p, u8 off, u8 *dp, int size) { \
> - struct hws *hw = p; \
> - outb(off, hw->ap.ale); \
> - outsb(hw->ap.port, dp, size); \
> - }
> -
> -#define IOFUNC_MEMIO(name, hws, typ, adr) \
> - static u8 Read##name##_MIO(void *p, u8 off) { \
> - struct hws *hw = p; \
> - return readb(((typ *)hw->adr) + off); \
> - } \
> - static void Write##name##_MIO(void *p, u8 off, u8 val) { \
> - struct hws *hw = p; \
> - writeb(val, ((typ *)hw->adr) + off); \
> - } \
> - static void ReadFiFo##name##_MIO(void *p, u8 off, u8 *dp, int size) { \
> - struct hws *hw = p; \
> - while (size--) \
> - *dp++ = readb(((typ *)hw->adr) + off); \
> - } \
> - static void WriteFiFo##name##_MIO(void *p, u8 off, u8 *dp, int size) { \
> - struct hws *hw = p; \
> - while (size--) \
> - writeb(*dp++, ((typ *)hw->adr) + off); \
> - }
> -
> -#define ASSIGN_FUNC(typ, name, dest) do { \
> - dest.read_reg = &Read##name##_##typ; \
> - dest.write_reg = &Write##name##_##typ; \
> - dest.read_fifo = &ReadFiFo##name##_##typ; \
> - dest.write_fifo = &WriteFiFo##name##_##typ; \
> - } while (0)
> -#define ASSIGN_FUNC_IPAC(typ, target) do { \
> - ASSIGN_FUNC(typ, ISAC, target.isac); \
> - ASSIGN_FUNC(typ, IPAC, target); \
> - } while (0)
> -
> -#endif
> diff --git a/drivers/isdn/hardware/mISDN/ipac.h b/drivers/isdn/hardware/mISDN/ipac.h
> deleted file mode 100644
> index 2f0c4978a7a5..000000000000
> --- a/drivers/isdn/hardware/mISDN/ipac.h
> +++ /dev/null
> @@ -1,393 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/*
> - *
> - * ipac.h Defines for the Infineon (former Siemens) ISDN
> - * chip series
> - *
> - * Author Karsten Keil <keil@isdn4linux.de>
> - *
> - * Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
> - */
> -
> -#include "iohelper.h"
> -
> -struct isac_hw {
> - struct dchannel dch;
> - u32 type;
> - u32 off; /* offset to isac regs */
> - char *name;
> - spinlock_t *hwlock; /* lock HW access */
> - read_reg_func *read_reg;
> - write_reg_func *write_reg;
> - fifo_func *read_fifo;
> - fifo_func *write_fifo;
> - int (*monitor)(void *, u32, u8 *, int);
> - void (*release)(struct isac_hw *);
> - int (*init)(struct isac_hw *);
> - int (*ctrl)(struct isac_hw *, u32, u_long);
> - int (*open)(struct isac_hw *, struct channel_req *);
> - u8 *mon_tx;
> - u8 *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;
> - u8 arcofi_bc;
> - u8 arcofi_state;
> - u8 mocr;
> - u8 adf2;
> - u8 state;
> -};
> -
> -struct ipac_hw;
> -
> -struct hscx_hw {
> - struct bchannel bch;
> - struct ipac_hw *ip;
> - u8 fifo_size;
> - u8 off; /* offset to ICA or ICB */
> - u8 slot;
> - char log[64];
> -};
> -
> -struct ipac_hw {
> - struct isac_hw isac;
> - struct hscx_hw hscx[2];
> - char *name;
> - void *hw;
> - spinlock_t *hwlock; /* lock HW access */
> - struct module *owner;
> - u32 type;
> - read_reg_func *read_reg;
> - write_reg_func *write_reg;
> - fifo_func *read_fifo;
> - fifo_func *write_fifo;
> - void (*release)(struct ipac_hw *);
> - int (*init)(struct ipac_hw *);
> - int (*ctrl)(struct ipac_hw *, u32, u_long);
> - u8 conf;
> -};
> -
> -#define IPAC_TYPE_ISAC 0x0010
> -#define IPAC_TYPE_IPAC 0x0020
> -#define IPAC_TYPE_ISACX 0x0040
> -#define IPAC_TYPE_IPACX 0x0080
> -#define IPAC_TYPE_HSCX 0x0100
> -
> -#define ISAC_USE_ARCOFI 0x1000
> -
> -/* Monitor functions */
> -#define MONITOR_RX_0 0x1000
> -#define MONITOR_RX_1 0x1001
> -#define MONITOR_TX_0 0x2000
> -#define MONITOR_TX_1 0x2001
> -
> -/* All registers original Siemens Spec */
> -/* IPAC/ISAC registers */
> -#define ISAC_ISTA 0x20
> -#define ISAC_MASK 0x20
> -#define ISAC_CMDR 0x21
> -#define ISAC_STAR 0x21
> -#define ISAC_MODE 0x22
> -#define ISAC_TIMR 0x23
> -#define ISAC_EXIR 0x24
> -#define ISAC_RBCL 0x25
> -#define ISAC_RSTA 0x27
> -#define ISAC_RBCH 0x2A
> -#define ISAC_SPCR 0x30
> -#define ISAC_CIR0 0x31
> -#define ISAC_CIX0 0x31
> -#define ISAC_MOR0 0x32
> -#define ISAC_MOX0 0x32
> -#define ISAC_CIR1 0x33
> -#define ISAC_CIX1 0x33
> -#define ISAC_MOR1 0x34
> -#define ISAC_MOX1 0x34
> -#define ISAC_STCR 0x37
> -#define ISAC_ADF1 0x38
> -#define ISAC_ADF2 0x39
> -#define ISAC_MOCR 0x3a
> -#define ISAC_MOSR 0x3a
> -#define ISAC_SQRR 0x3b
> -#define ISAC_SQXR 0x3b
> -
> -#define ISAC_RBCH_XAC 0x80
> -
> -#define IPAC_D_TIN2 0x01
> -
> -/* IPAC/HSCX */
> -#define IPAC_ISTAB 0x20 /* RD */
> -#define IPAC_MASKB 0x20 /* WR */
> -#define IPAC_STARB 0x21 /* RD */
> -#define IPAC_CMDRB 0x21 /* WR */
> -#define IPAC_MODEB 0x22 /* R/W */
> -#define IPAC_EXIRB 0x24 /* RD */
> -#define IPAC_RBCLB 0x25 /* RD */
> -#define IPAC_RAH1 0x26 /* WR */
> -#define IPAC_RAH2 0x27 /* WR */
> -#define IPAC_RSTAB 0x27 /* RD */
> -#define IPAC_RAL1 0x28 /* R/W */
> -#define IPAC_RAL2 0x29 /* WR */
> -#define IPAC_RHCRB 0x29 /* RD */
> -#define IPAC_XBCL 0x2A /* WR */
> -#define IPAC_CCR2 0x2C /* R/W */
> -#define IPAC_RBCHB 0x2D /* RD */
> -#define IPAC_XBCH 0x2D /* WR */
> -#define HSCX_VSTR 0x2E /* RD */
> -#define IPAC_RLCR 0x2E /* WR */
> -#define IPAC_CCR1 0x2F /* R/W */
> -#define IPAC_TSAX 0x30 /* WR */
> -#define IPAC_TSAR 0x31 /* WR */
> -#define IPAC_XCCR 0x32 /* WR */
> -#define IPAC_RCCR 0x33 /* WR */
> -
> -/* IPAC_ISTAB/IPAC_MASKB bits */
> -#define IPAC_B_XPR 0x10
> -#define IPAC_B_RPF 0x40
> -#define IPAC_B_RME 0x80
> -#define IPAC_B_ON 0x2F
> -
> -/* IPAC_EXIRB bits */
> -#define IPAC_B_RFS 0x04
> -#define IPAC_B_RFO 0x10
> -#define IPAC_B_XDU 0x40
> -#define IPAC_B_XMR 0x80
> -
> -/* IPAC special registers */
> -#define IPAC_CONF 0xC0 /* R/W */
> -#define IPAC_ISTA 0xC1 /* RD */
> -#define IPAC_MASK 0xC1 /* WR */
> -#define IPAC_ID 0xC2 /* RD */
> -#define IPAC_ACFG 0xC3 /* R/W */
> -#define IPAC_AOE 0xC4 /* R/W */
> -#define IPAC_ARX 0xC5 /* RD */
> -#define IPAC_ATX 0xC5 /* WR */
> -#define IPAC_PITA1 0xC6 /* R/W */
> -#define IPAC_PITA2 0xC7 /* R/W */
> -#define IPAC_POTA1 0xC8 /* R/W */
> -#define IPAC_POTA2 0xC9 /* R/W */
> -#define IPAC_PCFG 0xCA /* R/W */
> -#define IPAC_SCFG 0xCB /* R/W */
> -#define IPAC_TIMR2 0xCC /* R/W */
> -
> -/* IPAC_ISTA/_MASK bits */
> -#define IPAC__EXB 0x01
> -#define IPAC__ICB 0x02
> -#define IPAC__EXA 0x04
> -#define IPAC__ICA 0x08
> -#define IPAC__EXD 0x10
> -#define IPAC__ICD 0x20
> -#define IPAC__INT0 0x40
> -#define IPAC__INT1 0x80
> -#define IPAC__ON 0xC0
> -
> -/* HSCX ISTA/MASK bits */
> -#define HSCX__EXB 0x01
> -#define HSCX__EXA 0x02
> -#define HSCX__ICA 0x04
> -
> -/* ISAC/ISACX/IPAC/IPACX L1 commands */
> -#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
> -
> -/* ISAC/ISACX/IPAC/IPACX L1 indications */
> -#define ISAC_IND_DR 0x0
> -#define ISAC_IND_RS 0x1
> -#define ISAC_IND_SD 0x2
> -#define ISAC_IND_DIS 0x3
> -#define ISAC_IND_RSY 0x4
> -#define ISAC_IND_DR6 0x5
> -#define ISAC_IND_EI 0x6
> -#define ISAC_IND_PU 0x7
> -#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
> -
> -/* the new ISACX / IPACX */
> -/* D-channel registers */
> -#define ISACX_RFIFOD 0x00 /* RD */
> -#define ISACX_XFIFOD 0x00 /* WR */
> -#define ISACX_ISTAD 0x20 /* RD */
> -#define ISACX_MASKD 0x20 /* WR */
> -#define ISACX_STARD 0x21 /* RD */
> -#define ISACX_CMDRD 0x21 /* WR */
> -#define ISACX_MODED 0x22 /* R/W */
> -#define ISACX_EXMD1 0x23 /* R/W */
> -#define ISACX_TIMR1 0x24 /* R/W */
> -#define ISACX_SAP1 0x25 /* WR */
> -#define ISACX_SAP2 0x26 /* WR */
> -#define ISACX_RBCLD 0x26 /* RD */
> -#define ISACX_RBCHD 0x27 /* RD */
> -#define ISACX_TEI1 0x27 /* WR */
> -#define ISACX_TEI2 0x28 /* WR */
> -#define ISACX_RSTAD 0x28 /* RD */
> -#define ISACX_TMD 0x29 /* R/W */
> -#define ISACX_CIR0 0x2E /* RD */
> -#define ISACX_CIX0 0x2E /* WR */
> -#define ISACX_CIR1 0x2F /* RD */
> -#define ISACX_CIX1 0x2F /* WR */
> -
> -/* Transceiver registers */
> -#define ISACX_TR_CONF0 0x30 /* R/W */
> -#define ISACX_TR_CONF1 0x31 /* R/W */
> -#define ISACX_TR_CONF2 0x32 /* R/W */
> -#define ISACX_TR_STA 0x33 /* RD */
> -#define ISACX_TR_CMD 0x34 /* R/W */
> -#define ISACX_SQRR1 0x35 /* RD */
> -#define ISACX_SQXR1 0x35 /* WR */
> -#define ISACX_SQRR2 0x36 /* RD */
> -#define ISACX_SQXR2 0x36 /* WR */
> -#define ISACX_SQRR3 0x37 /* RD */
> -#define ISACX_SQXR3 0x37 /* WR */
> -#define ISACX_ISTATR 0x38 /* RD */
> -#define ISACX_MASKTR 0x39 /* R/W */
> -#define ISACX_TR_MODE 0x3A /* R/W */
> -#define ISACX_ACFG1 0x3C /* R/W */
> -#define ISACX_ACFG2 0x3D /* R/W */
> -#define ISACX_AOE 0x3E /* R/W */
> -#define ISACX_ARX 0x3F /* RD */
> -#define ISACX_ATX 0x3F /* WR */
> -
> -/* IOM: Timeslot, DPS, CDA */
> -#define ISACX_CDA10 0x40 /* R/W */
> -#define ISACX_CDA11 0x41 /* R/W */
> -#define ISACX_CDA20 0x42 /* R/W */
> -#define ISACX_CDA21 0x43 /* R/W */
> -#define ISACX_CDA_TSDP10 0x44 /* R/W */
> -#define ISACX_CDA_TSDP11 0x45 /* R/W */
> -#define ISACX_CDA_TSDP20 0x46 /* R/W */
> -#define ISACX_CDA_TSDP21 0x47 /* R/W */
> -#define ISACX_BCHA_TSDP_BC1 0x48 /* R/W */
> -#define ISACX_BCHA_TSDP_BC2 0x49 /* R/W */
> -#define ISACX_BCHB_TSDP_BC1 0x4A /* R/W */
> -#define ISACX_BCHB_TSDP_BC2 0x4B /* R/W */
> -#define ISACX_TR_TSDP_BC1 0x4C /* R/W */
> -#define ISACX_TR_TSDP_BC2 0x4D /* R/W */
> -#define ISACX_CDA1_CR 0x4E /* R/W */
> -#define ISACX_CDA2_CR 0x4F /* R/W */
> -
> -/* IOM: Contol, Sync transfer, Monitor */
> -#define ISACX_TR_CR 0x50 /* R/W */
> -#define ISACX_TRC_CR 0x50 /* R/W */
> -#define ISACX_BCHA_CR 0x51 /* R/W */
> -#define ISACX_BCHB_CR 0x52 /* R/W */
> -#define ISACX_DCI_CR 0x53 /* R/W */
> -#define ISACX_DCIC_CR 0x53 /* R/W */
> -#define ISACX_MON_CR 0x54 /* R/W */
> -#define ISACX_SDS1_CR 0x55 /* R/W */
> -#define ISACX_SDS2_CR 0x56 /* R/W */
> -#define ISACX_IOM_CR 0x57 /* R/W */
> -#define ISACX_STI 0x58 /* RD */
> -#define ISACX_ASTI 0x58 /* WR */
> -#define ISACX_MSTI 0x59 /* R/W */
> -#define ISACX_SDS_CONF 0x5A /* R/W */
> -#define ISACX_MCDA 0x5B /* RD */
> -#define ISACX_MOR 0x5C /* RD */
> -#define ISACX_MOX 0x5C /* WR */
> -#define ISACX_MOSR 0x5D /* RD */
> -#define ISACX_MOCR 0x5E /* R/W */
> -#define ISACX_MSTA 0x5F /* RD */
> -#define ISACX_MCONF 0x5F /* WR */
> -
> -/* Interrupt and general registers */
> -#define ISACX_ISTA 0x60 /* RD */
> -#define ISACX_MASK 0x60 /* WR */
> -#define ISACX_AUXI 0x61 /* RD */
> -#define ISACX_AUXM 0x61 /* WR */
> -#define ISACX_MODE1 0x62 /* R/W */
> -#define ISACX_MODE2 0x63 /* R/W */
> -#define ISACX_ID 0x64 /* RD */
> -#define ISACX_SRES 0x64 /* WR */
> -#define ISACX_TIMR2 0x65 /* R/W */
> -
> -/* Register Bits */
> -/* ISACX/IPACX _ISTAD (R) and _MASKD (W) */
> -#define ISACX_D_XDU 0x04
> -#define ISACX_D_XMR 0x08
> -#define ISACX_D_XPR 0x10
> -#define ISACX_D_RFO 0x20
> -#define ISACX_D_RPF 0x40
> -#define ISACX_D_RME 0x80
> -
> -/* ISACX/IPACX _ISTA (R) and _MASK (W) */
> -#define ISACX__ICD 0x01
> -#define ISACX__MOS 0x02
> -#define ISACX__TRAN 0x04
> -#define ISACX__AUX 0x08
> -#define ISACX__CIC 0x10
> -#define ISACX__ST 0x20
> -#define IPACX__ON 0x2C
> -#define IPACX__ICB 0x40
> -#define IPACX__ICA 0x80
> -
> -/* ISACX/IPACX _CMDRD (W) */
> -#define ISACX_CMDRD_XRES 0x01
> -#define ISACX_CMDRD_XME 0x02
> -#define ISACX_CMDRD_XTF 0x08
> -#define ISACX_CMDRD_STI 0x10
> -#define ISACX_CMDRD_RRES 0x40
> -#define ISACX_CMDRD_RMC 0x80
> -
> -/* ISACX/IPACX _RSTAD (R) */
> -#define ISACX_RSTAD_TA 0x01
> -#define ISACX_RSTAD_CR 0x02
> -#define ISACX_RSTAD_SA0 0x04
> -#define ISACX_RSTAD_SA1 0x08
> -#define ISACX_RSTAD_RAB 0x10
> -#define ISACX_RSTAD_CRC 0x20
> -#define ISACX_RSTAD_RDO 0x40
> -#define ISACX_RSTAD_VFR 0x80
> -
> -/* ISACX/IPACX _CIR0 (R) */
> -#define ISACX_CIR0_BAS 0x01
> -#define ISACX_CIR0_SG 0x08
> -#define ISACX_CIR0_CIC1 0x08
> -#define ISACX_CIR0_CIC0 0x08
> -
> -/* B-channel registers */
> -#define IPACX_OFF_ICA 0x70
> -#define IPACX_OFF_ICB 0x80
> -
> -/* ICA: IPACX_OFF_ICA + Reg ICB: IPACX_OFF_ICB + Reg */
> -
> -#define IPACX_ISTAB 0x00 /* RD */
> -#define IPACX_MASKB 0x00 /* WR */
> -#define IPACX_STARB 0x01 /* RD */
> -#define IPACX_CMDRB 0x01 /* WR */
> -#define IPACX_MODEB 0x02 /* R/W */
> -#define IPACX_EXMB 0x03 /* R/W */
> -#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 /* R/W */
> -#define IPACX_RFIFOB 0x0A /* RD */
> -#define IPACX_XFIFOB 0x0A /* WR */
> -
> -/* IPACX_ISTAB / IPACX_MASKB bits */
> -#define IPACX_B_XDU 0x04
> -#define IPACX_B_XPR 0x10
> -#define IPACX_B_RFO 0x20
> -#define IPACX_B_RPF 0x40
> -#define IPACX_B_RME 0x80
> -
> -#define IPACX_B_ON 0x0B
> -
> -extern int mISDNisac_init(struct isac_hw *, void *);
> -extern irqreturn_t mISDNisac_irq(struct isac_hw *, u8);
> -extern u32 mISDNipac_init(struct ipac_hw *, void *);
> -extern irqreturn_t mISDNipac_irq(struct ipac_hw *, int);
> diff --git a/drivers/isdn/hardware/mISDN/isar.h b/drivers/isdn/hardware/mISDN/isar.h
> deleted file mode 100644
> index 36a9fa564b17..000000000000
> --- a/drivers/isdn/hardware/mISDN/isar.h
> +++ /dev/null
> @@ -1,256 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/*
> - *
> - * isar.h ISAR (Siemens PSB 7110) specific defines
> - *
> - * Author Karsten Keil (keil@isdn4linux.de)
> - *
> - * Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
> - */
> -
> -#include "iohelper.h"
> -
> -struct isar_hw;
> -
> -struct isar_ch {
> - struct bchannel bch;
> - struct isar_hw *is;
> - struct timer_list ftimer;
> - u8 nr;
> - u8 dpath;
> - u8 mml;
> - u8 state;
> - u8 cmd;
> - u8 mod;
> - u8 newcmd;
> - u8 newmod;
> - u8 try_mod;
> - u8 conmsg[16];
> -};
> -
> -struct isar_hw {
> - struct isar_ch ch[2];
> - void *hw;
> - spinlock_t *hwlock; /* lock HW access */
> - char *name;
> - struct module *owner;
> - read_reg_func *read_reg;
> - write_reg_func *write_reg;
> - fifo_func *read_fifo;
> - fifo_func *write_fifo;
> - int (*ctrl)(void *, u32, u_long);
> - void (*release)(struct isar_hw *);
> - int (*init)(struct isar_hw *);
> - int (*open)(struct isar_hw *, struct channel_req *);
> - int (*firmware)(struct isar_hw *, const u8 *, int);
> - unsigned long Flags;
> - int version;
> - u8 bstat;
> - u8 iis;
> - u8 cmsb;
> - u8 clsb;
> - u8 buf[256];
> - u8 log[256];
> -};
> -
> -#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_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_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
> -
> -#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_TDTMF 0x5a
> -
> -#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
> -
> -extern u32 mISDNisar_init(struct isar_hw *, void *);
> -extern void mISDNisar_irq(struct isar_hw *);
> diff --git a/drivers/isdn/hardware/mISDN/isdnhdlc.h b/drivers/isdn/hardware/mISDN/isdnhdlc.h
> deleted file mode 100644
> index fe2c1279c139..000000000000
> --- a/drivers/isdn/hardware/mISDN/isdnhdlc.h
> +++ /dev/null
> @@ -1,69 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-or-later */
> -/*
> - * hdlc.h -- General purpose ISDN HDLC decoder.
> - *
> - * Implementation of a HDLC decoder/encoder in software.
> - * Necessary because some ISDN devices don't have HDLC
> - * controllers.
> - *
> - * Copyright (C)
> - * 2009 Karsten Keil <keil@b1-systems.de>
> - * 2002 Wolfgang Mües <wolfgang@iksw-muees.de>
> - * 2001 Frode Isaksen <fisaksen@bewan.com>
> - * 2001 Kai Germaschewski <kai.germaschewski@gmx.de>
> - */
> -
> -#ifndef __ISDNHDLC_H__
> -#define __ISDNHDLC_H__
> -
> -struct isdnhdlc_vars {
> - int bit_shift;
> - int hdlc_bits1;
> - int data_bits;
> - int ffbit_shift; /* encoding only */
> - int state;
> - int dstpos;
> -
> - u16 crc;
> -
> - u8 cbin;
> - u8 shift_reg;
> - u8 ffvalue;
> -
> - /* set if transferring data */
> - u32 data_received:1;
> - /* set if D channel (send idle instead of flags) */
> - u32 dchannel:1;
> - /* set if 56K adaptation */
> - u32 do_adapt56:1;
> - /* set if in closing phase (need to send CRC + flag) */
> - u32 do_closing:1;
> - /* set if data is bitreverse */
> - u32 do_bitreverse:1;
> -};
> -
> -/* Feature Flags */
> -#define HDLC_56KBIT 0x01
> -#define HDLC_DCHANNEL 0x02
> -#define HDLC_BITREVERSE 0x04
> -
> -/*
> - The return value from isdnhdlc_decode is
> - the frame length, 0 if no complete frame was decoded,
> - or a negative error number
> -*/
> -#define HDLC_FRAMING_ERROR 1
> -#define HDLC_CRC_ERROR 2
> -#define HDLC_LENGTH_ERROR 3
> -
> -extern void isdnhdlc_rcv_init(struct isdnhdlc_vars *hdlc, u32 features);
> -
> -extern int isdnhdlc_decode(struct isdnhdlc_vars *hdlc, const u8 *src,
> - int slen, int *count, u8 *dst, int dsize);
> -
> -extern void isdnhdlc_out_init(struct isdnhdlc_vars *hdlc, u32 features);
> -
> -extern int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const u8 *src,
> - u16 slen, int *count, u8 *dst, int dsize);
> -
> -#endif /* __ISDNHDLC_H__ */
> diff --git a/drivers/isdn/hardware/mISDN/netjet.h b/drivers/isdn/hardware/mISDN/netjet.h
> deleted file mode 100644
> index b23ad9f6d4d0..000000000000
> --- a/drivers/isdn/hardware/mISDN/netjet.h
> +++ /dev/null
> @@ -1,44 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/*
> - * NETjet common header file
> - *
> - * Author Karsten Keil
> - * based on work of Matt Henderson and Daniel Potts,
> - * Traverse Technologies P/L www.traverse.com.au
> - *
> - * Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
> - */
> -
> -#define NJ_CTRL 0x00
> -#define NJ_DMACTRL 0x01
> -#define NJ_AUXCTRL 0x02
> -#define NJ_AUXDATA 0x03
> -#define NJ_IRQMASK0 0x04
> -#define NJ_IRQMASK1 0x05
> -#define NJ_IRQSTAT0 0x06
> -#define NJ_IRQSTAT1 0x07
> -#define NJ_DMA_READ_START 0x08
> -#define NJ_DMA_READ_IRQ 0x0c
> -#define NJ_DMA_READ_END 0x10
> -#define NJ_DMA_READ_ADR 0x14
> -#define NJ_DMA_WRITE_START 0x18
> -#define NJ_DMA_WRITE_IRQ 0x1c
> -#define NJ_DMA_WRITE_END 0x20
> -#define NJ_DMA_WRITE_ADR 0x24
> -#define NJ_PULSE_CNT 0x28
> -
> -#define NJ_ISAC_OFF 0xc0
> -#define NJ_ISACIRQ 0x10
> -
> -#define NJ_IRQM0_RD_MASK 0x03
> -#define NJ_IRQM0_RD_IRQ 0x01
> -#define NJ_IRQM0_RD_END 0x02
> -#define NJ_IRQM0_WR_MASK 0x0c
> -#define NJ_IRQM0_WR_IRQ 0x04
> -#define NJ_IRQM0_WR_END 0x08
> -
> -/* one page here is no need to be smaller */
> -#define NJ_DMA_SIZE 4096
> -/* 2 * 64 byte is a compromise between IRQ count and latency */
> -#define NJ_DMA_RXSIZE 128 /* 2 * 64 */
> -#define NJ_DMA_TXSIZE 128 /* 2 * 64 */
> diff --git a/drivers/isdn/hardware/mISDN/w6692.h b/drivers/isdn/hardware/mISDN/w6692.h
> deleted file mode 100644
> index 45e1dc5d6c2d..000000000000
> --- a/drivers/isdn/hardware/mISDN/w6692.h
> +++ /dev/null
> @@ -1,177 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/*
> - * Winbond W6692 specific defines
> - *
> - * Author Karsten Keil <keil@isdn4linux.de>
> - * based on the w6692 I4L driver from Petr Novak <petr.novak@i.cz>
> - *
> - * Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
> - */
> -
> -/* 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_PCTL_PCX 0x01
> -#define W_PCTL_XMODE 0x02
> -#define W_PCTL_OE0 0x04
> -#define W_PCTL_OE1 0x08
> -#define W_PCTL_OE2 0x10
> -#define W_PCTL_OE3 0x20
> -#define W_PCTL_OE4 0x40
> -#define W_PCTL_OE5 0x80
> -
> -#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/mISDN/core.h b/drivers/isdn/mISDN/core.h
> deleted file mode 100644
> index 5617c06de8e4..000000000000
> --- a/drivers/isdn/mISDN/core.h
> +++ /dev/null
> @@ -1,69 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/*
> - * Copyright 2008 by Karsten Keil <kkeil@novell.com>
> - */
> -
> -#ifndef mISDN_CORE_H
> -#define mISDN_CORE_H
> -
> -extern struct mISDNdevice *get_mdevice(u_int);
> -extern int get_mdevice_count(void);
> -
> -/* stack status flag */
> -#define mISDN_STACK_ACTION_MASK 0x0000ffff
> -#define mISDN_STACK_COMMAND_MASK 0x000f0000
> -#define mISDN_STACK_STATUS_MASK 0xfff00000
> -/* action bits 0-15 */
> -#define mISDN_STACK_WORK 0
> -#define mISDN_STACK_SETUP 1
> -#define mISDN_STACK_CLEARING 2
> -#define mISDN_STACK_RESTART 3
> -#define mISDN_STACK_WAKEUP 4
> -#define mISDN_STACK_ABORT 15
> -/* command bits 16-19 */
> -#define mISDN_STACK_STOPPED 16
> -#define mISDN_STACK_INIT 17
> -#define mISDN_STACK_THREADSTART 18
> -/* status bits 20-31 */
> -#define mISDN_STACK_BCHANNEL 20
> -#define mISDN_STACK_ACTIVE 29
> -#define mISDN_STACK_RUNNING 30
> -#define mISDN_STACK_KILLED 31
> -
> -
> -/* manager options */
> -#define MGR_OPT_USER 24
> -#define MGR_OPT_NETWORK 25
> -
> -extern int connect_Bstack(struct mISDNdevice *, struct mISDNchannel *,
> - u_int, struct sockaddr_mISDN *);
> -extern int connect_layer1(struct mISDNdevice *, struct mISDNchannel *,
> - u_int, struct sockaddr_mISDN *);
> -extern int create_l2entity(struct mISDNdevice *, struct mISDNchannel *,
> - u_int, struct sockaddr_mISDN *);
> -
> -extern int create_stack(struct mISDNdevice *);
> -extern int create_teimanager(struct mISDNdevice *);
> -extern void delete_teimanager(struct mISDNchannel *);
> -extern void delete_channel(struct mISDNchannel *);
> -extern void delete_stack(struct mISDNdevice *);
> -extern void mISDN_initstack(u_int *);
> -extern int misdn_sock_init(u_int *);
> -extern void misdn_sock_cleanup(void);
> -extern void add_layer2(struct mISDNchannel *, struct mISDNstack *);
> -extern void __add_layer2(struct mISDNchannel *, struct mISDNstack *);
> -
> -extern u_int get_all_Bprotocols(void);
> -struct Bprotocol *get_Bprotocol4mask(u_int);
> -
> -extern int mISDN_inittimer(u_int *);
> -extern void mISDN_timer_cleanup(void);
> -
> -extern int Isdnl1_Init(u_int *);
> -extern void Isdnl1_cleanup(void);
> -extern int Isdnl2_Init(u_int *);
> -extern void Isdnl2_cleanup(void);
> -
> -extern void mISDN_init_clock(u_int *);
> -
> -#endif
> diff --git a/drivers/isdn/mISDN/dsp.h b/drivers/isdn/mISDN/dsp.h
> deleted file mode 100644
> index baf31258f5c9..000000000000
> --- a/drivers/isdn/mISDN/dsp.h
> +++ /dev/null
> @@ -1,277 +0,0 @@
> -/*
> - * Audio support data for ISDN4Linux.
> - *
> - * Copyright 2002/2003 by Andreas Eversberg (jolly@eversberg.eu)
> - *
> - * This software may be used and distributed according to the terms
> - * of the GNU General Public License, incorporated herein by reference.
> - *
> - */
> -
> -#define DEBUG_DSP_CTRL 0x0001
> -#define DEBUG_DSP_CORE 0x0002
> -#define DEBUG_DSP_DTMF 0x0004
> -#define DEBUG_DSP_CMX 0x0010
> -#define DEBUG_DSP_TONE 0x0020
> -#define DEBUG_DSP_BLOWFISH 0x0040
> -#define DEBUG_DSP_DELAY 0x0100
> -#define DEBUG_DSP_CLOCK 0x0200
> -#define DEBUG_DSP_DTMFCOEFF 0x8000 /* heavy output */
> -
> -/* options may be:
> - *
> - * bit 0 = use ulaw instead of alaw
> - * bit 1 = enable hfc hardware acceleration for all channels
> - *
> - */
> -#define DSP_OPT_ULAW (1 << 0)
> -#define DSP_OPT_NOHARDWARE (1 << 1)
> -
> -#include <linux/timer.h>
> -#include <linux/workqueue.h>
> -
> -#include "dsp_ecdis.h"
> -
> -extern int dsp_options;
> -extern int dsp_debug;
> -extern int dsp_poll;
> -extern int dsp_tics;
> -extern spinlock_t dsp_lock;
> -extern struct work_struct dsp_workq;
> -extern u32 dsp_poll_diff; /* calculated fix-comma corrected poll value */
> -
> -/***************
> - * audio stuff *
> - ***************/
> -
> -extern s32 dsp_audio_alaw_to_s32[256];
> -extern s32 dsp_audio_ulaw_to_s32[256];
> -extern s32 *dsp_audio_law_to_s32;
> -extern u8 dsp_audio_s16_to_law[65536];
> -extern u8 dsp_audio_alaw_to_ulaw[256];
> -extern u8 dsp_audio_mix_law[65536];
> -extern u8 dsp_audio_seven2law[128];
> -extern u8 dsp_audio_law2seven[256];
> -extern void dsp_audio_generate_law_tables(void);
> -extern void dsp_audio_generate_s2law_table(void);
> -extern void dsp_audio_generate_seven(void);
> -extern void dsp_audio_generate_mix_table(void);
> -extern void dsp_audio_generate_ulaw_samples(void);
> -extern void dsp_audio_generate_volume_changes(void);
> -extern u8 dsp_silence;
> -
> -
> -/*************
> - * cmx stuff *
> - *************/
> -
> -#define MAX_POLL 256 /* maximum number of send-chunks */
> -
> -#define CMX_BUFF_SIZE 0x8000 /* must be 2**n (0x1000 about 1/2 second) */
> -#define CMX_BUFF_HALF 0x4000 /* CMX_BUFF_SIZE / 2 */
> -#define CMX_BUFF_MASK 0x7fff /* CMX_BUFF_SIZE - 1 */
> -
> -/* how many seconds will we check the lowest delay until the jitter buffer
> - is reduced by that delay */
> -#define MAX_SECONDS_JITTER_CHECK 5
> -
> -extern struct timer_list dsp_spl_tl;
> -
> -/* the datatype need to match jiffies datatype */
> -extern unsigned long dsp_spl_jiffies;
> -
> -/* the structure of conferences:
> - *
> - * each conference has a unique number, given by user space.
> - * the conferences are linked in a chain.
> - * each conference has members linked in a chain.
> - * each dsplayer points to a member, each member points to a dsplayer.
> - */
> -
> -/* all members within a conference (this is linked 1:1 with the dsp) */
> -struct dsp;
> -struct dsp_conf_member {
> - struct list_head list;
> - struct dsp *dsp;
> -};
> -
> -/* the list of all conferences */
> -struct dsp_conf {
> - struct list_head list;
> - u32 id;
> - /* all cmx stacks with the same ID are
> - connected */
> - struct list_head mlist;
> - int software; /* conf is processed by software */
> - int hardware; /* conf is processed by hardware */
> - /* note: if both unset, has only one member */
> -};
> -
> -
> -/**************
> - * DTMF stuff *
> - **************/
> -
> -#define DSP_DTMF_NPOINTS 102
> -
> -#define ECHOCAN_BUFF_SIZE 0x400 /* must be 2**n */
> -#define ECHOCAN_BUFF_MASK 0x3ff /* -1 */
> -
> -struct dsp_dtmf {
> - int enable; /* dtmf is enabled */
> - int treshold; /* above this is dtmf (square of) */
> - int software; /* dtmf uses software decoding */
> - int hardware; /* dtmf uses hardware decoding */
> - int size; /* number of bytes in buffer */
> - signed short buffer[DSP_DTMF_NPOINTS];
> - /* buffers one full dtmf frame */
> - u8 lastwhat, lastdigit;
> - int count;
> - u8 digits[16]; /* dtmf result */
> -};
> -
> -
> -/******************
> - * pipeline stuff *
> - ******************/
> -struct dsp_pipeline {
> - rwlock_t lock;
> - struct list_head list;
> - int inuse;
> -};
> -
> -/***************
> - * tones stuff *
> - ***************/
> -
> -struct dsp_tone {
> - int software; /* tones are generated by software */
> - int hardware; /* tones are generated by hardware */
> - int tone;
> - void *pattern;
> - int count;
> - int index;
> - struct timer_list tl;
> -};
> -
> -/***************
> - * echo stuff *
> - ***************/
> -
> -struct dsp_echo {
> - int software; /* echo is generated by software */
> - int hardware; /* echo is generated by hardware */
> -};
> -
> -/*****************
> - * general stuff *
> - *****************/
> -
> -struct dsp {
> - struct list_head list;
> - struct mISDNchannel ch;
> - struct mISDNchannel *up;
> - unsigned char name[64];
> - int b_active;
> - struct dsp_echo echo;
> - int rx_disabled; /* what the user wants */
> - int rx_is_off; /* what the card is */
> - int tx_mix;
> - struct dsp_tone tone;
> - struct dsp_dtmf dtmf;
> - int tx_volume, rx_volume;
> -
> - /* queue for sending frames */
> - struct work_struct workq;
> - struct sk_buff_head sendq;
> - int hdlc; /* if mode is hdlc */
> - int data_pending; /* currently an unconfirmed frame */
> -
> - /* conference stuff */
> - u32 conf_id;
> - struct dsp_conf *conf;
> - struct dsp_conf_member
> - *member;
> -
> - /* buffer stuff */
> - int rx_W; /* current write pos for data without timestamp */
> - int rx_R; /* current read pos for transmit clock */
> - int rx_init; /* if set, pointers will be adjusted first */
> - int tx_W; /* current write pos for transmit data */
> - int tx_R; /* current read pos for transmit clock */
> - int rx_delay[MAX_SECONDS_JITTER_CHECK];
> - int tx_delay[MAX_SECONDS_JITTER_CHECK];
> - u8 tx_buff[CMX_BUFF_SIZE];
> - u8 rx_buff[CMX_BUFF_SIZE];
> - int last_tx; /* if set, we transmitted last poll interval */
> - int cmx_delay; /* initial delay of buffers,
> - or 0 for dynamic jitter buffer */
> - int tx_dejitter; /* if set, dejitter tx buffer */
> - int tx_data; /* enables tx-data of CMX to upper layer */
> -
> - /* hardware stuff */
> - struct dsp_features features;
> - int features_rx_off; /* set if rx_off is featured */
> - int features_fill_empty; /* set if fill_empty is featured */
> - int pcm_slot_rx; /* current PCM slot (or -1) */
> - int pcm_bank_rx;
> - int pcm_slot_tx;
> - int pcm_bank_tx;
> - int hfc_conf; /* unique id of current conference (or -1) */
> -
> - /* encryption stuff */
> - int bf_enable;
> - u32 bf_p[18];
> - u32 bf_s[1024];
> - int bf_crypt_pos;
> - u8 bf_data_in[9];
> - u8 bf_crypt_out[9];
> - int bf_decrypt_in_pos;
> - int bf_decrypt_out_pos;
> - u8 bf_crypt_inring[16];
> - u8 bf_data_out[9];
> - int bf_sync;
> -
> - struct dsp_pipeline
> - pipeline;
> -};
> -
> -/* functions */
> -
> -extern void dsp_change_volume(struct sk_buff *skb, int volume);
> -
> -extern struct list_head dsp_ilist;
> -extern struct list_head conf_ilist;
> -extern void dsp_cmx_debug(struct dsp *dsp);
> -extern void dsp_cmx_hardware(struct dsp_conf *conf, struct dsp *dsp);
> -extern int dsp_cmx_conf(struct dsp *dsp, u32 conf_id);
> -extern void dsp_cmx_receive(struct dsp *dsp, struct sk_buff *skb);
> -extern void dsp_cmx_hdlc(struct dsp *dsp, struct sk_buff *skb);
> -extern void dsp_cmx_send(struct timer_list *arg);
> -extern void dsp_cmx_transmit(struct dsp *dsp, struct sk_buff *skb);
> -extern int dsp_cmx_del_conf_member(struct dsp *dsp);
> -extern int dsp_cmx_del_conf(struct dsp_conf *conf);
> -
> -extern void dsp_dtmf_goertzel_init(struct dsp *dsp);
> -extern void dsp_dtmf_hardware(struct dsp *dsp);
> -extern u8 *dsp_dtmf_goertzel_decode(struct dsp *dsp, u8 *data, int len,
> - int fmt);
> -
> -extern int dsp_tone(struct dsp *dsp, int tone);
> -extern void dsp_tone_copy(struct dsp *dsp, u8 *data, int len);
> -extern void dsp_tone_timeout(struct timer_list *t);
> -
> -extern void dsp_bf_encrypt(struct dsp *dsp, u8 *data, int len);
> -extern void dsp_bf_decrypt(struct dsp *dsp, u8 *data, int len);
> -extern int dsp_bf_init(struct dsp *dsp, const u8 *key, unsigned int keylen);
> -extern void dsp_bf_cleanup(struct dsp *dsp);
> -
> -extern int dsp_pipeline_module_init(void);
> -extern void dsp_pipeline_module_exit(void);
> -extern int dsp_pipeline_init(struct dsp_pipeline *pipeline);
> -extern void dsp_pipeline_destroy(struct dsp_pipeline *pipeline);
> -extern int dsp_pipeline_build(struct dsp_pipeline *pipeline, const char *cfg);
> -extern void dsp_pipeline_process_tx(struct dsp_pipeline *pipeline, u8 *data,
> - int len);
> -extern void dsp_pipeline_process_rx(struct dsp_pipeline *pipeline, u8 *data,
> - int len, unsigned int txlen);
> diff --git a/drivers/isdn/mISDN/dsp_biquad.h b/drivers/isdn/mISDN/dsp_biquad.h
> deleted file mode 100644
> index f40d52a4c4ee..000000000000
> --- a/drivers/isdn/mISDN/dsp_biquad.h
> +++ /dev/null
> @@ -1,51 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-or-later */
> -/*
> - * SpanDSP - a series of DSP components for telephony
> - *
> - * biquad.h - General telephony bi-quad section routines (currently this just
> - * handles canonic/type 2 form)
> - *
> - * Written by Steve Underwood <steveu@coppice.org>
> - *
> - * Copyright (C) 2001 Steve Underwood
> - *
> - * All rights reserved.
> - */
> -
> -struct biquad2_state {
> - int32_t gain;
> - int32_t a1;
> - int32_t a2;
> - int32_t b1;
> - int32_t b2;
> -
> - int32_t z1;
> - int32_t z2;
> -};
> -
> -static inline void biquad2_init(struct biquad2_state *bq,
> - int32_t gain, int32_t a1, int32_t a2, int32_t b1, int32_t b2)
> -{
> - bq->gain = gain;
> - bq->a1 = a1;
> - bq->a2 = a2;
> - bq->b1 = b1;
> - bq->b2 = b2;
> -
> - bq->z1 = 0;
> - bq->z2 = 0;
> -}
> -
> -static inline int16_t biquad2(struct biquad2_state *bq, int16_t sample)
> -{
> - int32_t y;
> - int32_t z0;
> -
> - z0 = sample * bq->gain + bq->z1 * bq->a1 + bq->z2 * bq->a2;
> - y = z0 + bq->z1 * bq->b1 + bq->z2 * bq->b2;
> -
> - bq->z2 = bq->z1;
> - bq->z1 = z0 >> 15;
> - y >>= 15;
> - return y;
> -}
> diff --git a/drivers/isdn/mISDN/dsp_ecdis.h b/drivers/isdn/mISDN/dsp_ecdis.h
> deleted file mode 100644
> index 4bcdf321875d..000000000000
> --- a/drivers/isdn/mISDN/dsp_ecdis.h
> +++ /dev/null
> @@ -1,96 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-or-later */
> -/*
> - * SpanDSP - a series of DSP components for telephony
> - *
> - * ec_disable_detector.h - A detector which should eventually meet the
> - * G.164/G.165 requirements for detecting the
> - * 2100Hz echo cancellor disable tone.
> - *
> - * Written by Steve Underwood <steveu@coppice.org>
> - *
> - * Copyright (C) 2001 Steve Underwood
> - *
> - * All rights reserved.
> - */
> -
> -#include "dsp_biquad.h"
> -
> -struct ec_disable_detector_state {
> - struct biquad2_state notch;
> - int notch_level;
> - int channel_level;
> - int tone_present;
> - int tone_cycle_duration;
> - int good_cycles;
> - int hit;
> -};
> -
> -
> -#define FALSE 0
> -#define TRUE (!FALSE)
> -
> -static inline void
> -echo_can_disable_detector_init(struct ec_disable_detector_state *det)
> -{
> - /* Elliptic notch */
> - /* This is actually centred at 2095Hz, but gets the balance we want, due
> - to the asymmetric walls of the notch */
> - biquad2_init(&det->notch,
> - (int32_t)(-0.7600000 * 32768.0),
> - (int32_t)(-0.1183852 * 32768.0),
> - (int32_t)(-0.5104039 * 32768.0),
> - (int32_t)(0.1567596 * 32768.0),
> - (int32_t)(1.0000000 * 32768.0));
> -
> - det->channel_level = 0;
> - det->notch_level = 0;
> - det->tone_present = FALSE;
> - det->tone_cycle_duration = 0;
> - det->good_cycles = 0;
> - det->hit = 0;
> -}
> -/*- End of function --------------------------------------------------------*/
> -
> -static inline int
> -echo_can_disable_detector_update(struct ec_disable_detector_state *det,
> - int16_t amp)
> -{
> - int16_t notched;
> -
> - notched = biquad2(&det->notch, amp);
> - /* Estimate the overall energy in the channel, and the energy in
> - the notch (i.e. overall channel energy - tone energy => noise).
> - Use abs instead of multiply for speed (is it really faster?).
> - Damp the overall energy a little more for a stable result.
> - Damp the notch energy a little less, so we don't damp out the
> - blip every time the phase reverses */
> - det->channel_level += ((abs(amp) - det->channel_level) >> 5);
> - det->notch_level += ((abs(notched) - det->notch_level) >> 4);
> - if (det->channel_level > 280) {
> - /* There is adequate energy in the channel.
> - Is it mostly at 2100Hz? */
> - if (det->notch_level * 6 < det->channel_level) {
> - /* The notch says yes, so we have the tone. */
> - if (!det->tone_present) {
> - /* Do we get a kick every 450+-25ms? */
> - if (det->tone_cycle_duration >= 425 * 8
> - && det->tone_cycle_duration <= 475 * 8) {
> - det->good_cycles++;
> - if (det->good_cycles > 2)
> - det->hit = TRUE;
> - }
> - det->tone_cycle_duration = 0;
> - }
> - det->tone_present = TRUE;
> - } else
> - det->tone_present = FALSE;
> - det->tone_cycle_duration++;
> - } else {
> - det->tone_present = FALSE;
> - det->tone_cycle_duration = 0;
> - det->good_cycles = 0;
> - }
> - return det->hit;
> -}
> -/*- End of function --------------------------------------------------------*/
> -/*- End of file ------------------------------------------------------------*/
> diff --git a/drivers/isdn/mISDN/dsp_hwec.h b/drivers/isdn/mISDN/dsp_hwec.h
> deleted file mode 100644
> index c9cb0ea249da..000000000000
> --- a/drivers/isdn/mISDN/dsp_hwec.h
> +++ /dev/null
> @@ -1,10 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0 */
> -/*
> - * dsp_hwec.h
> - */
> -
> -extern struct mISDN_dsp_element *dsp_hwec;
> -extern void dsp_hwec_enable(struct dsp *dsp, const char *arg);
> -extern void dsp_hwec_disable(struct dsp *dsp);
> -extern int dsp_hwec_init(void);
> -extern void dsp_hwec_exit(void);
> diff --git a/drivers/isdn/mISDN/fsm.h b/drivers/isdn/mISDN/fsm.h
> deleted file mode 100644
> index 211554b997f8..000000000000
> --- a/drivers/isdn/mISDN/fsm.h
> +++ /dev/null
> @@ -1,58 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/*
> - *
> - * Author Karsten Keil <kkeil@novell.com>
> - *
> - * Thanks to Jan den Ouden
> - * Fritz Elfert
> - * Copyright 2008 by Karsten Keil <kkeil@novell.com>
> - */
> -
> -#ifndef _MISDN_FSM_H
> -#define _MISDN_FSM_H
> -
> -#include <linux/timer.h>
> -
> -/* 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;
> -};
> -
> -extern int mISDN_FsmNew(struct Fsm *, struct FsmNode *, int);
> -extern void mISDN_FsmFree(struct Fsm *);
> -extern int mISDN_FsmEvent(struct FsmInst *, int , void *);
> -extern void mISDN_FsmChangeState(struct FsmInst *, int);
> -extern void mISDN_FsmInitTimer(struct FsmInst *, struct FsmTimer *);
> -extern int mISDN_FsmAddTimer(struct FsmTimer *, int, int, void *, int);
> -extern void mISDN_FsmRestartTimer(struct FsmTimer *, int, int, void *, int);
> -extern void mISDN_FsmDelTimer(struct FsmTimer *, int);
> -
> -#endif
> diff --git a/drivers/isdn/mISDN/l1oip.h b/drivers/isdn/mISDN/l1oip.h
> deleted file mode 100644
> index 48133d022812..000000000000
> --- a/drivers/isdn/mISDN/l1oip.h
> +++ /dev/null
> @@ -1,92 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0 */
> -/*
> - * see notice in l1oip.c
> - */
> -
> -/* debugging */
> -#define DEBUG_L1OIP_INIT 0x00010000
> -#define DEBUG_L1OIP_SOCKET 0x00020000
> -#define DEBUG_L1OIP_MGR 0x00040000
> -#define DEBUG_L1OIP_MSG 0x00080000
> -
> -/* enable to disorder received bchannels by sequence 2143658798... */
> -/*
> - #define REORDER_DEBUG
> -*/
> -
> -/* frames */
> -#define L1OIP_MAX_LEN 2048 /* max packet size form l2 */
> -#define L1OIP_MAX_PERFRAME 1400 /* max data size in one frame */
> -
> -
> -/* timers */
> -#define L1OIP_KEEPALIVE 15
> -#define L1OIP_TIMEOUT 65
> -
> -
> -/* socket */
> -#define L1OIP_DEFAULTPORT 931
> -
> -
> -/* channel structure */
> -struct l1oip_chan {
> - struct dchannel *dch;
> - struct bchannel *bch;
> - u32 tx_counter; /* counts xmit bytes/packets */
> - u32 rx_counter; /* counts recv bytes/packets */
> - u32 codecstate; /* used by codec to save data */
> -#ifdef REORDER_DEBUG
> - int disorder_flag;
> - struct sk_buff *disorder_skb;
> - u32 disorder_cnt;
> -#endif
> -};
> -
> -
> -/* card structure */
> -struct l1oip {
> - struct list_head list;
> -
> - /* card */
> - int registered; /* if registered with mISDN */
> - char name[MISDN_MAX_IDLEN];
> - int idx; /* card index */
> - int pri; /* 1=pri, 0=bri */
> - int d_idx; /* current dchannel number */
> - int b_num; /* number of bchannels */
> - u32 id; /* id of connection */
> - int ondemand; /* if transmis. is on demand */
> - int bundle; /* bundle channels in one frm */
> - int codec; /* codec to use for transmis. */
> - int limit; /* limit number of bchannels */
> - bool shutdown; /* if card is released */
> -
> - /* timer */
> - struct timer_list keep_tl;
> - struct timer_list timeout_tl;
> - int timeout_on;
> - struct work_struct workq;
> -
> - /* socket */
> - struct socket *socket; /* if set, socket is created */
> - struct completion socket_complete;/* completion of sock thread */
> - struct task_struct *socket_thread;
> - spinlock_t socket_lock; /* access sock outside thread */
> - u32 remoteip; /* if all set, ip is assigned */
> - u16 localport; /* must always be set */
> - u16 remoteport; /* must always be set */
> - struct sockaddr_in sin_local; /* local socket name */
> - struct sockaddr_in sin_remote; /* remote socket name */
> - struct msghdr sendmsg; /* ip message to send */
> - struct kvec sendiov; /* iov for message */
> -
> - /* frame */
> - struct l1oip_chan chan[128]; /* channel instances */
> -};
> -
> -extern int l1oip_law_to_4bit(u8 *data, int len, u8 *result, u32 *state);
> -extern int l1oip_4bit_to_law(u8 *data, int len, u8 *result);
> -extern int l1oip_alaw_to_ulaw(u8 *data, int len, u8 *result);
> -extern int l1oip_ulaw_to_alaw(u8 *data, int len, u8 *result);
> -extern void l1oip_4bit_free(void);
> -extern int l1oip_4bit_alloc(int ulaw);
> diff --git a/drivers/isdn/mISDN/layer1.h b/drivers/isdn/mISDN/layer1.h
> deleted file mode 100644
> index f03e86450daf..000000000000
> --- a/drivers/isdn/mISDN/layer1.h
> +++ /dev/null
> @@ -1,16 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/*
> - *
> - * Layer 1 defines
> - *
> - * Copyright 2008 by Karsten Keil <kkeil@novell.com>
> - */
> -
> -#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
> -#define FLG_L1_DBLOCKED 8
> diff --git a/drivers/isdn/mISDN/layer2.h b/drivers/isdn/mISDN/layer2.h
> deleted file mode 100644
> index c466fd94aa02..000000000000
> --- a/drivers/isdn/mISDN/layer2.h
> +++ /dev/null
> @@ -1,131 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/*
> - * Layer 2 defines
> - *
> - * Copyright 2008 by Karsten Keil <kkeil@novell.com>
> - */
> -
> -#include <linux/mISDNif.h>
> -#include <linux/skbuff.h>
> -#include "fsm.h"
> -
> -#define MAX_WINDOW 8
> -
> -struct manager {
> - struct mISDNchannel ch;
> - struct mISDNchannel bcast;
> - u_long options;
> - struct list_head layer2;
> - rwlock_t lock;
> - struct FsmInst deact;
> - struct FsmTimer datimer;
> - struct sk_buff_head sendq;
> - struct mISDNchannel *up;
> - u_int nextid;
> - u_int lastid;
> -};
> -
> -struct teimgr {
> - int ri;
> - int rcnt;
> - struct FsmInst tei_m;
> - struct FsmTimer timer;
> - int tval, nval;
> - struct layer2 *l2;
> - struct manager *mgr;
> -};
> -
> -struct laddr {
> - u_char A;
> - u_char B;
> -};
> -
> -struct layer2 {
> - struct list_head list;
> - struct mISDNchannel ch;
> - u_long flag;
> - int id;
> - struct mISDNchannel *up;
> - signed char sapi;
> - signed char tei;
> - struct laddr addr;
> - u_int maxlen;
> - struct teimgr *tm;
> - u_int vs, va, vr;
> - int rc;
> - u_int window;
> - u_int sow;
> - struct FsmInst l2m;
> - struct FsmTimer t200, t203;
> - int T200, N200, T203;
> - u_int next_id;
> - u_int down_id;
> - struct sk_buff *windowar[MAX_WINDOW];
> - struct sk_buff_head i_queue;
> - struct sk_buff_head ui_queue;
> - struct sk_buff_head down_queue;
> - struct sk_buff_head tmp_queue;
> -};
> -
> -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)
> -
> -extern struct layer2 *create_l2(struct mISDNchannel *, u_int,
> - u_long, int, int);
> -extern int tei_l2(struct layer2 *, u_int, u_long arg);
> -
> -
> -/* from tei.c */
> -extern int l2_tei(struct layer2 *, u_int, u_long arg);
> -extern void TEIrelease(struct layer2 *);
> -extern int TEIInit(u_int *);
> -extern void TEIFree(void);
> -
> -#define MAX_L2HEADER_LEN 4
> -
> -#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
> -
> -#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
> -#define FLG_L1_NOTREADY 17
> -#define FLG_LAPD_NET 18
> diff --git a/include/linux/isdn/capilli.h b/include/linux/isdn/capilli.h
> deleted file mode 100644
> index 12be09b6883b..000000000000
> --- a/include/linux/isdn/capilli.h
> +++ /dev/null
> @@ -1,95 +0,0 @@
> -/* $Id: capilli.h,v 1.1.2.2 2004/01/16 21:09:27 keil Exp $
> - *
> - * Kernel CAPI 2.0 Driver Interface for Linux
> - *
> - * Copyright 1999 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.
> - *
> - */
> -
> -#ifndef __CAPILLI_H__
> -#define __CAPILLI_H__
> -
> -#include <linux/kernel.h>
> -#include <linux/list.h>
> -#include <linux/capi.h>
> -#include <linux/kernelcapi.h>
> -
> -typedef struct capiloaddatapart {
> - int user; /* data in userspace ? */
> - int len;
> - unsigned char *data;
> -} capiloaddatapart;
> -
> -typedef struct capiloaddata {
> - capiloaddatapart firmware;
> - capiloaddatapart configuration;
> -} capiloaddata;
> -
> -typedef struct capicardparams {
> - unsigned int port;
> - unsigned irq;
> - int cardtype;
> - int cardnr;
> - unsigned int membase;
> -} capicardparams;
> -
> -struct capi_ctr {
> - /* filled in before calling attach_capi_ctr */
> - struct module *owner;
> - void *driverdata; /* driver specific */
> - char name[32]; /* name of controller */
> - char *driver_name; /* name of driver */
> - int (*load_firmware)(struct capi_ctr *, capiloaddata *);
> - void (*reset_ctr)(struct capi_ctr *);
> - void (*register_appl)(struct capi_ctr *, u16 appl,
> - capi_register_params *);
> - void (*release_appl)(struct capi_ctr *, u16 appl);
> - u16 (*send_message)(struct capi_ctr *, struct sk_buff *skb);
> -
> - char *(*procinfo)(struct capi_ctr *);
> - int (*proc_show)(struct seq_file *, void *);
> -
> - /* filled in before calling ready callback */
> - u8 manu[CAPI_MANUFACTURER_LEN]; /* CAPI_GET_MANUFACTURER */
> - capi_version version; /* CAPI_GET_VERSION */
> - capi_profile profile; /* CAPI_GET_PROFILE */
> - u8 serial[CAPI_SERIAL_LEN]; /* CAPI_GET_SERIAL */
> -
> - /* management information for kcapi */
> -
> - unsigned long nrecvctlpkt;
> - unsigned long nrecvdatapkt;
> - unsigned long nsentctlpkt;
> - unsigned long nsentdatapkt;
> -
> - int cnr; /* controller number */
> - unsigned short state; /* controller state */
> - int blocked; /* output blocked */
> - int traceflag; /* capi trace */
> -
> - struct proc_dir_entry *procent;
> - char procfn[128];
> -};
> -
> -int attach_capi_ctr(struct capi_ctr *);
> -int detach_capi_ctr(struct capi_ctr *);
> -
> -void capi_ctr_ready(struct capi_ctr * card);
> -void capi_ctr_down(struct capi_ctr * card);
> -void capi_ctr_handle_message(struct capi_ctr * card, u16 appl, struct sk_buff *skb);
> -
> -// ---------------------------------------------------------------------------
> -// needed for AVM capi drivers
> -
> -struct capi_driver {
> - char name[32]; /* driver name */
> - char revision[32];
> -
> - /* management information for kcapi */
> - struct list_head list;
> -};
> -
> -#endif /* __CAPILLI_H__ */
> diff --git a/include/linux/isdn/capiutil.h b/include/linux/isdn/capiutil.h
> deleted file mode 100644
> index 953fd500dff7..000000000000
> --- a/include/linux/isdn/capiutil.h
> +++ /dev/null
> @@ -1,60 +0,0 @@
> -/* $Id: capiutil.h,v 1.5.6.2 2001/09/23 22:24:33 kai Exp $
> - *
> - * CAPI 2.0 defines & types
> - *
> - * From CAPI 2.0 Development Kit AVM 1995 (msg.c)
> - * Rewritten for Linux 1996 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.
> - *
> - */
> -
> -#ifndef __CAPIUTIL_H__
> -#define __CAPIUTIL_H__
> -
> -#include <asm/types.h>
> -
> -#define CAPIMSG_BASELEN 8
> -#define CAPIMSG_U8(m, off) (m[off])
> -#define CAPIMSG_U16(m, off) (m[off]|(m[(off)+1]<<8))
> -#define CAPIMSG_U32(m, off) (m[off]|(m[(off)+1]<<8)|(m[(off)+2]<<16)|(m[(off)+3]<<24))
> -#define CAPIMSG_LEN(m) CAPIMSG_U16(m,0)
> -#define CAPIMSG_APPID(m) CAPIMSG_U16(m,2)
> -#define CAPIMSG_COMMAND(m) CAPIMSG_U8(m,4)
> -#define CAPIMSG_SUBCOMMAND(m) CAPIMSG_U8(m,5)
> -#define CAPIMSG_CMD(m) (((m[4])<<8)|(m[5]))
> -#define CAPIMSG_MSGID(m) CAPIMSG_U16(m,6)
> -#define CAPIMSG_CONTROLLER(m) (m[8] & 0x7f)
> -#define CAPIMSG_CONTROL(m) CAPIMSG_U32(m, 8)
> -#define CAPIMSG_NCCI(m) CAPIMSG_CONTROL(m)
> -#define CAPIMSG_DATALEN(m) CAPIMSG_U16(m,16) /* DATA_B3_REQ */
> -
> -static inline void capimsg_setu8(void *m, int off, __u8 val)
> -{
> - ((__u8 *)m)[off] = val;
> -}
> -
> -static inline void capimsg_setu16(void *m, int off, __u16 val)
> -{
> - ((__u8 *)m)[off] = val & 0xff;
> - ((__u8 *)m)[off+1] = (val >> 8) & 0xff;
> -}
> -
> -static inline void capimsg_setu32(void *m, int off, __u32 val)
> -{
> - ((__u8 *)m)[off] = val & 0xff;
> - ((__u8 *)m)[off+1] = (val >> 8) & 0xff;
> - ((__u8 *)m)[off+2] = (val >> 16) & 0xff;
> - ((__u8 *)m)[off+3] = (val >> 24) & 0xff;
> -}
> -
> -#define CAPIMSG_SETLEN(m, len) capimsg_setu16(m, 0, len)
> -#define CAPIMSG_SETAPPID(m, applid) capimsg_setu16(m, 2, applid)
> -#define CAPIMSG_SETCOMMAND(m,cmd) capimsg_setu8(m, 4, cmd)
> -#define CAPIMSG_SETSUBCOMMAND(m, cmd) capimsg_setu8(m, 5, cmd)
> -#define CAPIMSG_SETMSGID(m, msgid) capimsg_setu16(m, 6, msgid)
> -#define CAPIMSG_SETCONTROL(m, contr) capimsg_setu32(m, 8, contr)
> -#define CAPIMSG_SETDATALEN(m, len) capimsg_setu16(m, 16, len)
> -
> -#endif /* __CAPIUTIL_H__ */
> diff --git a/include/linux/kernelcapi.h b/include/linux/kernelcapi.h
> deleted file mode 100644
> index 94ba42bf9da1..000000000000
> --- a/include/linux/kernelcapi.h
> +++ /dev/null
> @@ -1,45 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0 */
> -/*
> - * $Id: kernelcapi.h,v 1.8.6.2 2001/02/07 11:31:31 kai Exp $
> - *
> - * Kernel CAPI 2.0 Interface for Linux
> - *
> - * (c) Copyright 1997 by Carsten Paeth (calle@calle.in-berlin.de)
> - *
> - */
> -#ifndef __KERNELCAPI_H__
> -#define __KERNELCAPI_H__
> -
> -#include <linux/list.h>
> -#include <linux/skbuff.h>
> -#include <linux/workqueue.h>
> -#include <linux/notifier.h>
> -#include <uapi/linux/kernelcapi.h>
> -
> -#define CAPI_NOERROR 0x0000
> -
> -#define CAPI_TOOMANYAPPLS 0x1001
> -#define CAPI_LOGBLKSIZETOSMALL 0x1002
> -#define CAPI_BUFFEXECEEDS64K 0x1003
> -#define CAPI_MSGBUFSIZETOOSMALL 0x1004
> -#define CAPI_ANZLOGCONNNOTSUPPORTED 0x1005
> -#define CAPI_REGRESERVED 0x1006
> -#define CAPI_REGBUSY 0x1007
> -#define CAPI_REGOSRESOURCEERR 0x1008
> -#define CAPI_REGNOTINSTALLED 0x1009
> -#define CAPI_REGCTRLERNOTSUPPORTEXTEQUIP 0x100a
> -#define CAPI_REGCTRLERONLYSUPPORTEXTEQUIP 0x100b
> -
> -#define CAPI_ILLAPPNR 0x1101
> -#define CAPI_ILLCMDORSUBCMDORMSGTOSMALL 0x1102
> -#define CAPI_SENDQUEUEFULL 0x1103
> -#define CAPI_RECEIVEQUEUEEMPTY 0x1104
> -#define CAPI_RECEIVEOVERFLOW 0x1105
> -#define CAPI_UNKNOWNNOTPAR 0x1106
> -#define CAPI_MSGBUSY 0x1107
> -#define CAPI_MSGOSRESOURCEERR 0x1108
> -#define CAPI_MSGNOTINSTALLED 0x1109
> -#define CAPI_MSGCTRLERNOTSUPPORTEXTEQUIP 0x110a
> -#define CAPI_MSGCTRLERONLYSUPPORTEXTEQUIP 0x110b
> -
> -#endif /* __KERNELCAPI_H__ */
> diff --git a/include/linux/mISDNdsp.h b/include/linux/mISDNdsp.h
> deleted file mode 100644
> index 00758f45fddc..000000000000
> --- a/include/linux/mISDNdsp.h
> +++ /dev/null
> @@ -1,40 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0 */
> -#ifndef __mISDNdsp_H__
> -#define __mISDNdsp_H__
> -
> -struct mISDN_dsp_element_arg {
> - char *name;
> - char *def;
> - char *desc;
> -};
> -
> -struct mISDN_dsp_element {
> - char *name;
> - void *(*new)(const char *arg);
> - void (*free)(void *p);
> - void (*process_tx)(void *p, unsigned char *data, int len);
> - void (*process_rx)(void *p, unsigned char *data, int len,
> - unsigned int txlen);
> - int num_args;
> - struct mISDN_dsp_element_arg
> - *args;
> -};
> -
> -extern int mISDN_dsp_element_register(struct mISDN_dsp_element *elem);
> -extern void mISDN_dsp_element_unregister(struct mISDN_dsp_element *elem);
> -
> -struct dsp_features {
> - int hfc_id; /* unique id to identify the chip (or -1) */
> - int hfc_dtmf; /* set if HFCmulti card supports dtmf */
> - int hfc_conf; /* set if HFCmulti card supports conferences */
> - int hfc_loops; /* set if card supports tone loops */
> - int hfc_echocanhw; /* set if card supports echocancelation*/
> - int pcm_id; /* unique id to identify the pcm bus (or -1) */
> - int pcm_slots; /* number of slots on the pcm bus */
> - int pcm_banks; /* number of IO banks of pcm bus */
> - int unclocked; /* data is not clocked (has jitter/loss) */
> - int unordered; /* data is unordered (packets have index) */
> -};
> -
> -#endif
> -
> diff --git a/include/linux/mISDNhw.h b/include/linux/mISDNhw.h
> deleted file mode 100644
> index ef4f8eb02eac..000000000000
> --- a/include/linux/mISDNhw.h
> +++ /dev/null
> @@ -1,192 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/*
> - *
> - * Author Karsten Keil <kkeil@novell.com>
> - *
> - * Basic declarations for the mISDN HW channels
> - *
> - * Copyright 2008 by Karsten Keil <kkeil@novell.com>
> - */
> -
> -#ifndef MISDNHW_H
> -#define MISDNHW_H
> -#include <linux/mISDNif.h>
> -#include <linux/timer.h>
> -
> -/*
> - * HW DEBUG 0xHHHHGGGG
> - * H - hardware driver specific bits
> - * G - for all drivers
> - */
> -
> -#define DEBUG_HW 0x00000001
> -#define DEBUG_HW_OPEN 0x00000002
> -#define DEBUG_HW_DCHANNEL 0x00000100
> -#define DEBUG_HW_DFIFO 0x00000200
> -#define DEBUG_HW_BCHANNEL 0x00001000
> -#define DEBUG_HW_BFIFO 0x00002000
> -
> -#define MAX_DFRAME_LEN_L1 300
> -#define MAX_MON_FRAME 32
> -#define MAX_LOG_SPACE 2048
> -#define MISDN_COPY_SIZE 32
> -
> -/* channel->Flags bit field */
> -#define FLG_TX_BUSY 0 /* tx_buf in use */
> -#define FLG_TX_NEXT 1 /* next_skb in use */
> -#define FLG_L1_BUSY 2 /* L1 is permanent busy */
> -#define FLG_L2_ACTIVATED 3 /* activated from L2 */
> -#define FLG_OPEN 5 /* channel is in use */
> -#define FLG_ACTIVE 6 /* channel is activated */
> -#define FLG_BUSY_TIMER 7
> -/* channel type */
> -#define FLG_DCHANNEL 8 /* channel is D-channel */
> -#define FLG_BCHANNEL 9 /* channel is B-channel */
> -#define FLG_ECHANNEL 10 /* channel is E-channel */
> -#define FLG_TRANSPARENT 12 /* channel use transparent data */
> -#define FLG_HDLC 13 /* channel use hdlc data */
> -#define FLG_L2DATA 14 /* channel use L2 DATA primitivs */
> -#define FLG_ORIGIN 15 /* channel is on origin site */
> -/* channel specific stuff */
> -#define FLG_FILLEMPTY 16 /* fill fifo on first frame (empty) */
> -/* arcofi specific */
> -#define FLG_ARCOFI_TIMER 17
> -#define FLG_ARCOFI_ERROR 18
> -/* isar specific */
> -#define FLG_INITIALIZED 17
> -#define FLG_DLEETX 18
> -#define FLG_LASTDLE 19
> -#define FLG_FIRST 20
> -#define FLG_LASTDATA 21
> -#define FLG_NMD_DATA 22
> -#define FLG_FTI_RUN 23
> -#define FLG_LL_OK 24
> -#define FLG_LL_CONN 25
> -#define FLG_DTMFSEND 26
> -#define FLG_TX_EMPTY 27
> -/* stop sending received data upstream */
> -#define FLG_RX_OFF 28
> -/* workq events */
> -#define FLG_RECVQUEUE 30
> -#define FLG_PHCHANGE 31
> -
> -#define schedule_event(s, ev) do { \
> - test_and_set_bit(ev, &((s)->Flags)); \
> - schedule_work(&((s)->workq)); \
> - } while (0)
> -
> -struct dchannel {
> - struct mISDNdevice dev;
> - u_long Flags;
> - struct work_struct workq;
> - void (*phfunc) (struct dchannel *);
> - u_int state;
> - void *l1;
> - void *hw;
> - int slot; /* multiport card channel slot */
> - struct timer_list timer;
> - /* receive data */
> - struct sk_buff *rx_skb;
> - int maxlen;
> - /* send data */
> - struct sk_buff_head squeue;
> - struct sk_buff_head rqueue;
> - struct sk_buff *tx_skb;
> - int tx_idx;
> - int debug;
> - /* statistics */
> - int err_crc;
> - int err_tx;
> - int err_rx;
> -};
> -
> -typedef int (dchannel_l1callback)(struct dchannel *, u_int);
> -extern int create_l1(struct dchannel *, dchannel_l1callback *);
> -
> -/* private L1 commands */
> -#define INFO0 0x8002
> -#define INFO1 0x8102
> -#define INFO2 0x8202
> -#define INFO3_P8 0x8302
> -#define INFO3_P10 0x8402
> -#define INFO4_P8 0x8502
> -#define INFO4_P10 0x8602
> -#define LOSTFRAMING 0x8702
> -#define ANYSIGNAL 0x8802
> -#define HW_POWERDOWN 0x8902
> -#define HW_RESET_REQ 0x8a02
> -#define HW_POWERUP_REQ 0x8b02
> -#define HW_DEACT_REQ 0x8c02
> -#define HW_ACTIVATE_REQ 0x8e02
> -#define HW_D_NOBLOCKED 0x8f02
> -#define HW_RESET_IND 0x9002
> -#define HW_POWERUP_IND 0x9102
> -#define HW_DEACT_IND 0x9202
> -#define HW_ACTIVATE_IND 0x9302
> -#define HW_DEACT_CNF 0x9402
> -#define HW_TESTLOOP 0x9502
> -#define HW_TESTRX_RAW 0x9602
> -#define HW_TESTRX_HDLC 0x9702
> -#define HW_TESTRX_OFF 0x9802
> -#define HW_TIMER3_IND 0x9902
> -#define HW_TIMER3_VALUE 0x9a00
> -#define HW_TIMER3_VMASK 0x00FF
> -
> -struct layer1;
> -extern int l1_event(struct layer1 *, u_int);
> -
> -#define MISDN_BCH_FILL_SIZE 4
> -
> -struct bchannel {
> - struct mISDNchannel ch;
> - int nr;
> - u_long Flags;
> - struct work_struct workq;
> - u_int state;
> - void *hw;
> - int slot; /* multiport card channel slot */
> - struct timer_list timer;
> - /* receive data */
> - u8 fill[MISDN_BCH_FILL_SIZE];
> - struct sk_buff *rx_skb;
> - unsigned short maxlen;
> - unsigned short init_maxlen; /* initial value */
> - unsigned short next_maxlen; /* pending value */
> - unsigned short minlen; /* for transparent data */
> - unsigned short init_minlen; /* initial value */
> - unsigned short next_minlen; /* pending value */
> - /* send data */
> - struct sk_buff *next_skb;
> - struct sk_buff *tx_skb;
> - struct sk_buff_head rqueue;
> - int rcount;
> - int tx_idx;
> - int debug;
> - /* statistics */
> - int err_crc;
> - int err_tx;
> - int err_rx;
> - int dropcnt;
> -};
> -
> -extern int mISDN_initdchannel(struct dchannel *, int, void *);
> -extern int mISDN_initbchannel(struct bchannel *, unsigned short,
> - unsigned short);
> -extern int mISDN_freedchannel(struct dchannel *);
> -extern void mISDN_clear_bchannel(struct bchannel *);
> -extern void mISDN_freebchannel(struct bchannel *);
> -extern int mISDN_ctrl_bchannel(struct bchannel *, struct mISDN_ctrl_req *);
> -extern void queue_ch_frame(struct mISDNchannel *, u_int,
> - int, struct sk_buff *);
> -extern int dchannel_senddata(struct dchannel *, struct sk_buff *);
> -extern int bchannel_senddata(struct bchannel *, struct sk_buff *);
> -extern int bchannel_get_rxbuf(struct bchannel *, int);
> -extern void recv_Dchannel(struct dchannel *);
> -extern void recv_Echannel(struct dchannel *, struct dchannel *);
> -extern void recv_Bchannel(struct bchannel *, unsigned int, bool);
> -extern void recv_Dchannel_skb(struct dchannel *, struct sk_buff *);
> -extern void recv_Bchannel_skb(struct bchannel *, struct sk_buff *);
> -extern int get_next_bframe(struct bchannel *);
> -extern int get_next_dframe(struct dchannel *);
> -
> -#endif
> diff --git a/include/linux/mISDNif.h b/include/linux/mISDNif.h
> deleted file mode 100644
> index 7aab4a769736..000000000000
> --- a/include/linux/mISDNif.h
> +++ /dev/null
> @@ -1,603 +0,0 @@
> -/*
> - *
> - * Author Karsten Keil <kkeil@novell.com>
> - *
> - * Copyright 2008 by Karsten Keil <kkeil@novell.com>
> - *
> - * This code is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE
> - * version 2.1 as published by the Free Software Foundation.
> - *
> - * This code is distributed in the hope that it will be useful,
> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> - * GNU LESSER GENERAL PUBLIC LICENSE for more details.
> - *
> - */
> -
> -#ifndef mISDNIF_H
> -#define mISDNIF_H
> -
> -#include <linux/types.h>
> -#include <linux/errno.h>
> -#include <linux/socket.h>
> -
> -/*
> - * ABI Version 32 bit
> - *
> - * <8 bit> Major version
> - * - changed if any interface become backwards incompatible
> - *
> - * <8 bit> Minor version
> - * - changed if any interface is extended but backwards compatible
> - *
> - * <16 bit> Release number
> - * - should be incremented on every checkin
> - */
> -#define MISDN_MAJOR_VERSION 1
> -#define MISDN_MINOR_VERSION 1
> -#define MISDN_RELEASE 29
> -
> -/* primitives for information exchange
> - * generell format
> - * <16 bit 0 >
> - * <8 bit command>
> - * BIT 8 = 1 LAYER private
> - * BIT 7 = 1 answer
> - * BIT 6 = 1 DATA
> - * <8 bit target layer mask>
> - *
> - * Layer = 00 is reserved for general commands
> - Layer = 01 L2 -> HW
> - Layer = 02 HW -> L2
> - Layer = 04 L3 -> L2
> - Layer = 08 L2 -> L3
> - * Layer = FF is reserved for broadcast commands
> - */
> -
> -#define MISDN_CMDMASK 0xff00
> -#define MISDN_LAYERMASK 0x00ff
> -
> -/* generell commands */
> -#define OPEN_CHANNEL 0x0100
> -#define CLOSE_CHANNEL 0x0200
> -#define CONTROL_CHANNEL 0x0300
> -#define CHECK_DATA 0x0400
> -
> -/* layer 2 -> layer 1 */
> -#define PH_ACTIVATE_REQ 0x0101
> -#define PH_DEACTIVATE_REQ 0x0201
> -#define PH_DATA_REQ 0x2001
> -#define MPH_ACTIVATE_REQ 0x0501
> -#define MPH_DEACTIVATE_REQ 0x0601
> -#define MPH_INFORMATION_REQ 0x0701
> -#define PH_CONTROL_REQ 0x0801
> -
> -/* layer 1 -> layer 2 */
> -#define PH_ACTIVATE_IND 0x0102
> -#define PH_ACTIVATE_CNF 0x4102
> -#define PH_DEACTIVATE_IND 0x0202
> -#define PH_DEACTIVATE_CNF 0x4202
> -#define PH_DATA_IND 0x2002
> -#define PH_DATA_E_IND 0x3002
> -#define MPH_ACTIVATE_IND 0x0502
> -#define MPH_DEACTIVATE_IND 0x0602
> -#define MPH_INFORMATION_IND 0x0702
> -#define PH_DATA_CNF 0x6002
> -#define PH_CONTROL_IND 0x0802
> -#define PH_CONTROL_CNF 0x4802
> -
> -/* layer 3 -> layer 2 */
> -#define DL_ESTABLISH_REQ 0x1004
> -#define DL_RELEASE_REQ 0x1104
> -#define DL_DATA_REQ 0x3004
> -#define DL_UNITDATA_REQ 0x3104
> -#define DL_INFORMATION_REQ 0x0004
> -
> -/* layer 2 -> layer 3 */
> -#define DL_ESTABLISH_IND 0x1008
> -#define DL_ESTABLISH_CNF 0x5008
> -#define DL_RELEASE_IND 0x1108
> -#define DL_RELEASE_CNF 0x5108
> -#define DL_DATA_IND 0x3008
> -#define DL_UNITDATA_IND 0x3108
> -#define DL_INFORMATION_IND 0x0008
> -
> -/* intern layer 2 management */
> -#define MDL_ASSIGN_REQ 0x1804
> -#define MDL_ASSIGN_IND 0x1904
> -#define MDL_REMOVE_REQ 0x1A04
> -#define MDL_REMOVE_IND 0x1B04
> -#define MDL_STATUS_UP_IND 0x1C04
> -#define MDL_STATUS_DOWN_IND 0x1D04
> -#define MDL_STATUS_UI_IND 0x1E04
> -#define MDL_ERROR_IND 0x1F04
> -#define MDL_ERROR_RSP 0x5F04
> -
> -/* intern layer 2 */
> -#define DL_TIMER200_IND 0x7004
> -#define DL_TIMER203_IND 0x7304
> -#define DL_INTERN_MSG 0x7804
> -
> -/* DL_INFORMATION_IND types */
> -#define DL_INFO_L2_CONNECT 0x0001
> -#define DL_INFO_L2_REMOVED 0x0002
> -
> -/* PH_CONTROL types */
> -/* TOUCH TONE IS 0x20XX XX "0"..."9", "A","B","C","D","*","#" */
> -#define DTMF_TONE_VAL 0x2000
> -#define DTMF_TONE_MASK 0x007F
> -#define DTMF_TONE_START 0x2100
> -#define DTMF_TONE_STOP 0x2200
> -#define DTMF_HFC_COEF 0x4000
> -#define DSP_CONF_JOIN 0x2403
> -#define DSP_CONF_SPLIT 0x2404
> -#define DSP_RECEIVE_OFF 0x2405
> -#define DSP_RECEIVE_ON 0x2406
> -#define DSP_ECHO_ON 0x2407
> -#define DSP_ECHO_OFF 0x2408
> -#define DSP_MIX_ON 0x2409
> -#define DSP_MIX_OFF 0x240a
> -#define DSP_DELAY 0x240b
> -#define DSP_JITTER 0x240c
> -#define DSP_TXDATA_ON 0x240d
> -#define DSP_TXDATA_OFF 0x240e
> -#define DSP_TX_DEJITTER 0x240f
> -#define DSP_TX_DEJ_OFF 0x2410
> -#define DSP_TONE_PATT_ON 0x2411
> -#define DSP_TONE_PATT_OFF 0x2412
> -#define DSP_VOL_CHANGE_TX 0x2413
> -#define DSP_VOL_CHANGE_RX 0x2414
> -#define DSP_BF_ENABLE_KEY 0x2415
> -#define DSP_BF_DISABLE 0x2416
> -#define DSP_BF_ACCEPT 0x2416
> -#define DSP_BF_REJECT 0x2417
> -#define DSP_PIPELINE_CFG 0x2418
> -#define HFC_VOL_CHANGE_TX 0x2601
> -#define HFC_VOL_CHANGE_RX 0x2602
> -#define HFC_SPL_LOOP_ON 0x2603
> -#define HFC_SPL_LOOP_OFF 0x2604
> -/* for T30 FAX and analog modem */
> -#define HW_MOD_FRM 0x4000
> -#define HW_MOD_FRH 0x4001
> -#define HW_MOD_FTM 0x4002
> -#define HW_MOD_FTH 0x4003
> -#define HW_MOD_FTS 0x4004
> -#define HW_MOD_CONNECT 0x4010
> -#define HW_MOD_OK 0x4011
> -#define HW_MOD_NOCARR 0x4012
> -#define HW_MOD_FCERROR 0x4013
> -#define HW_MOD_READY 0x4014
> -#define HW_MOD_LASTDATA 0x4015
> -
> -/* DSP_TONE_PATT_ON parameter */
> -#define TONE_OFF 0x0000
> -#define TONE_GERMAN_DIALTONE 0x0001
> -#define TONE_GERMAN_OLDDIALTONE 0x0002
> -#define TONE_AMERICAN_DIALTONE 0x0003
> -#define TONE_GERMAN_DIALPBX 0x0004
> -#define TONE_GERMAN_OLDDIALPBX 0x0005
> -#define TONE_AMERICAN_DIALPBX 0x0006
> -#define TONE_GERMAN_RINGING 0x0007
> -#define TONE_GERMAN_OLDRINGING 0x0008
> -#define TONE_AMERICAN_RINGPBX 0x000b
> -#define TONE_GERMAN_RINGPBX 0x000c
> -#define TONE_GERMAN_OLDRINGPBX 0x000d
> -#define TONE_AMERICAN_RINGING 0x000e
> -#define TONE_GERMAN_BUSY 0x000f
> -#define TONE_GERMAN_OLDBUSY 0x0010
> -#define TONE_AMERICAN_BUSY 0x0011
> -#define TONE_GERMAN_HANGUP 0x0012
> -#define TONE_GERMAN_OLDHANGUP 0x0013
> -#define TONE_AMERICAN_HANGUP 0x0014
> -#define TONE_SPECIAL_INFO 0x0015
> -#define TONE_GERMAN_GASSENBESETZT 0x0016
> -#define TONE_GERMAN_AUFSCHALTTON 0x0016
> -
> -/* MPH_INFORMATION_IND */
> -#define L1_SIGNAL_LOS_OFF 0x0010
> -#define L1_SIGNAL_LOS_ON 0x0011
> -#define L1_SIGNAL_AIS_OFF 0x0012
> -#define L1_SIGNAL_AIS_ON 0x0013
> -#define L1_SIGNAL_RDI_OFF 0x0014
> -#define L1_SIGNAL_RDI_ON 0x0015
> -#define L1_SIGNAL_SLIP_RX 0x0020
> -#define L1_SIGNAL_SLIP_TX 0x0021
> -
> -/*
> - * protocol ids
> - * D channel 1-31
> - * B channel 33 - 63
> - */
> -
> -#define ISDN_P_NONE 0
> -#define ISDN_P_BASE 0
> -#define ISDN_P_TE_S0 0x01
> -#define ISDN_P_NT_S0 0x02
> -#define ISDN_P_TE_E1 0x03
> -#define ISDN_P_NT_E1 0x04
> -#define ISDN_P_TE_UP0 0x05
> -#define ISDN_P_NT_UP0 0x06
> -
> -#define IS_ISDN_P_TE(p) ((p == ISDN_P_TE_S0) || (p == ISDN_P_TE_E1) || \
> - (p == ISDN_P_TE_UP0) || (p == ISDN_P_LAPD_TE))
> -#define IS_ISDN_P_NT(p) ((p == ISDN_P_NT_S0) || (p == ISDN_P_NT_E1) || \
> - (p == ISDN_P_NT_UP0) || (p == ISDN_P_LAPD_NT))
> -#define IS_ISDN_P_S0(p) ((p == ISDN_P_TE_S0) || (p == ISDN_P_NT_S0))
> -#define IS_ISDN_P_E1(p) ((p == ISDN_P_TE_E1) || (p == ISDN_P_NT_E1))
> -#define IS_ISDN_P_UP0(p) ((p == ISDN_P_TE_UP0) || (p == ISDN_P_NT_UP0))
> -
> -
> -#define ISDN_P_LAPD_TE 0x10
> -#define ISDN_P_LAPD_NT 0x11
> -
> -#define ISDN_P_B_MASK 0x1f
> -#define ISDN_P_B_START 0x20
> -
> -#define ISDN_P_B_RAW 0x21
> -#define ISDN_P_B_HDLC 0x22
> -#define ISDN_P_B_X75SLP 0x23
> -#define ISDN_P_B_L2DTMF 0x24
> -#define ISDN_P_B_L2DSP 0x25
> -#define ISDN_P_B_L2DSPHDLC 0x26
> -#define ISDN_P_B_T30_FAX 0x27
> -#define ISDN_P_B_MODEM_ASYNC 0x28
> -
> -#define OPTION_L2_PMX 1
> -#define OPTION_L2_PTP 2
> -#define OPTION_L2_FIXEDTEI 3
> -#define OPTION_L2_CLEANUP 4
> -#define OPTION_L1_HOLD 5
> -
> -/* should be in sync with linux/kobject.h:KOBJ_NAME_LEN */
> -#define MISDN_MAX_IDLEN 20
> -
> -struct mISDNhead {
> - unsigned int prim;
> - unsigned int id;
> -} __packed;
> -
> -#define MISDN_HEADER_LEN sizeof(struct mISDNhead)
> -#define MAX_DATA_SIZE 2048
> -#define MAX_DATA_MEM (MAX_DATA_SIZE + MISDN_HEADER_LEN)
> -#define MAX_DFRAME_LEN 260
> -
> -#define MISDN_ID_ADDR_MASK 0xFFFF
> -#define MISDN_ID_TEI_MASK 0xFF00
> -#define MISDN_ID_SAPI_MASK 0x00FF
> -#define MISDN_ID_TEI_ANY 0x7F00
> -
> -#define MISDN_ID_ANY 0xFFFF
> -#define MISDN_ID_NONE 0xFFFE
> -
> -#define GROUP_TEI 127
> -#define TEI_SAPI 63
> -#define CTRL_SAPI 0
> -
> -#define MISDN_MAX_CHANNEL 127
> -#define MISDN_CHMAP_SIZE ((MISDN_MAX_CHANNEL + 1) >> 3)
> -
> -#define SOL_MISDN 0
> -
> -struct sockaddr_mISDN {
> - sa_family_t family;
> - unsigned char dev;
> - unsigned char channel;
> - unsigned char sapi;
> - unsigned char tei;
> -};
> -
> -struct mISDNversion {
> - unsigned char major;
> - unsigned char minor;
> - unsigned short release;
> -};
> -
> -struct mISDN_devinfo {
> - u_int id;
> - u_int Dprotocols;
> - u_int Bprotocols;
> - u_int protocol;
> - u_char channelmap[MISDN_CHMAP_SIZE];
> - u_int nrbchan;
> - char name[MISDN_MAX_IDLEN];
> -};
> -
> -struct mISDN_devrename {
> - u_int id;
> - char name[MISDN_MAX_IDLEN]; /* new name */
> -};
> -
> -/* MPH_INFORMATION_REQ payload */
> -struct ph_info_ch {
> - __u32 protocol;
> - __u64 Flags;
> -};
> -
> -struct ph_info_dch {
> - struct ph_info_ch ch;
> - __u16 state;
> - __u16 num_bch;
> -};
> -
> -struct ph_info {
> - struct ph_info_dch dch;
> - struct ph_info_ch bch[];
> -};
> -
> -/* timer device ioctl */
> -#define IMADDTIMER _IOR('I', 64, int)
> -#define IMDELTIMER _IOR('I', 65, int)
> -
> -/* socket ioctls */
> -#define IMGETVERSION _IOR('I', 66, int)
> -#define IMGETCOUNT _IOR('I', 67, int)
> -#define IMGETDEVINFO _IOR('I', 68, int)
> -#define IMCTRLREQ _IOR('I', 69, int)
> -#define IMCLEAR_L2 _IOR('I', 70, int)
> -#define IMSETDEVNAME _IOR('I', 71, struct mISDN_devrename)
> -#define IMHOLD_L1 _IOR('I', 72, int)
> -
> -static inline int
> -test_channelmap(u_int nr, u_char *map)
> -{
> - if (nr <= MISDN_MAX_CHANNEL)
> - return map[nr >> 3] & (1 << (nr & 7));
> - else
> - return 0;
> -}
> -
> -static inline void
> -set_channelmap(u_int nr, u_char *map)
> -{
> - map[nr >> 3] |= (1 << (nr & 7));
> -}
> -
> -static inline void
> -clear_channelmap(u_int nr, u_char *map)
> -{
> - map[nr >> 3] &= ~(1 << (nr & 7));
> -}
> -
> -/* CONTROL_CHANNEL parameters */
> -#define MISDN_CTRL_GETOP 0x0000
> -#define MISDN_CTRL_LOOP 0x0001
> -#define MISDN_CTRL_CONNECT 0x0002
> -#define MISDN_CTRL_DISCONNECT 0x0004
> -#define MISDN_CTRL_RX_BUFFER 0x0008
> -#define MISDN_CTRL_PCMCONNECT 0x0010
> -#define MISDN_CTRL_PCMDISCONNECT 0x0020
> -#define MISDN_CTRL_SETPEER 0x0040
> -#define MISDN_CTRL_UNSETPEER 0x0080
> -#define MISDN_CTRL_RX_OFF 0x0100
> -#define MISDN_CTRL_FILL_EMPTY 0x0200
> -#define MISDN_CTRL_GETPEER 0x0400
> -#define MISDN_CTRL_L1_TIMER3 0x0800
> -#define MISDN_CTRL_HW_FEATURES_OP 0x2000
> -#define MISDN_CTRL_HW_FEATURES 0x2001
> -#define MISDN_CTRL_HFC_OP 0x4000
> -#define MISDN_CTRL_HFC_PCM_CONN 0x4001
> -#define MISDN_CTRL_HFC_PCM_DISC 0x4002
> -#define MISDN_CTRL_HFC_CONF_JOIN 0x4003
> -#define MISDN_CTRL_HFC_CONF_SPLIT 0x4004
> -#define MISDN_CTRL_HFC_RECEIVE_OFF 0x4005
> -#define MISDN_CTRL_HFC_RECEIVE_ON 0x4006
> -#define MISDN_CTRL_HFC_ECHOCAN_ON 0x4007
> -#define MISDN_CTRL_HFC_ECHOCAN_OFF 0x4008
> -#define MISDN_CTRL_HFC_WD_INIT 0x4009
> -#define MISDN_CTRL_HFC_WD_RESET 0x400A
> -
> -/* special RX buffer value for MISDN_CTRL_RX_BUFFER request.p1 is the minimum
> - * buffer size request.p2 the maximum. Using MISDN_CTRL_RX_SIZE_IGNORE will
> - * not change the value, but still read back the actual stetting.
> - */
> -#define MISDN_CTRL_RX_SIZE_IGNORE -1
> -
> -/* socket options */
> -#define MISDN_TIME_STAMP 0x0001
> -
> -struct mISDN_ctrl_req {
> - int op;
> - int channel;
> - int p1;
> - int p2;
> -};
> -
> -/* muxer options */
> -#define MISDN_OPT_ALL 1
> -#define MISDN_OPT_TEIMGR 2
> -
> -#ifdef __KERNEL__
> -#include <linux/list.h>
> -#include <linux/skbuff.h>
> -#include <linux/net.h>
> -#include <net/sock.h>
> -#include <linux/completion.h>
> -
> -#define DEBUG_CORE 0x000000ff
> -#define DEBUG_CORE_FUNC 0x00000002
> -#define DEBUG_SOCKET 0x00000004
> -#define DEBUG_MANAGER 0x00000008
> -#define DEBUG_SEND_ERR 0x00000010
> -#define DEBUG_MSG_THREAD 0x00000020
> -#define DEBUG_QUEUE_FUNC 0x00000040
> -#define DEBUG_L1 0x0000ff00
> -#define DEBUG_L1_FSM 0x00000200
> -#define DEBUG_L2 0x00ff0000
> -#define DEBUG_L2_FSM 0x00020000
> -#define DEBUG_L2_CTRL 0x00040000
> -#define DEBUG_L2_RECV 0x00080000
> -#define DEBUG_L2_TEI 0x00100000
> -#define DEBUG_L2_TEIFSM 0x00200000
> -#define DEBUG_TIMER 0x01000000
> -#define DEBUG_CLOCK 0x02000000
> -
> -#define mISDN_HEAD_P(s) ((struct mISDNhead *)&s->cb[0])
> -#define mISDN_HEAD_PRIM(s) (((struct mISDNhead *)&s->cb[0])->prim)
> -#define mISDN_HEAD_ID(s) (((struct mISDNhead *)&s->cb[0])->id)
> -
> -/* socket states */
> -#define MISDN_OPEN 1
> -#define MISDN_BOUND 2
> -#define MISDN_CLOSED 3
> -
> -struct mISDNchannel;
> -struct mISDNdevice;
> -struct mISDNstack;
> -struct mISDNclock;
> -
> -struct channel_req {
> - u_int protocol;
> - struct sockaddr_mISDN adr;
> - struct mISDNchannel *ch;
> -};
> -
> -typedef int (ctrl_func_t)(struct mISDNchannel *, u_int, void *);
> -typedef int (send_func_t)(struct mISDNchannel *, struct sk_buff *);
> -typedef int (create_func_t)(struct channel_req *);
> -
> -struct Bprotocol {
> - struct list_head list;
> - char *name;
> - u_int Bprotocols;
> - create_func_t *create;
> -};
> -
> -struct mISDNchannel {
> - struct list_head list;
> - u_int protocol;
> - u_int nr;
> - u_long opt;
> - u_int addr;
> - struct mISDNstack *st;
> - struct mISDNchannel *peer;
> - send_func_t *send;
> - send_func_t *recv;
> - ctrl_func_t *ctrl;
> -};
> -
> -struct mISDN_sock_list {
> - struct hlist_head head;
> - rwlock_t lock;
> -};
> -
> -struct mISDN_sock {
> - struct sock sk;
> - struct mISDNchannel ch;
> - u_int cmask;
> - struct mISDNdevice *dev;
> -};
> -
> -
> -
> -struct mISDNdevice {
> - struct mISDNchannel D;
> - u_int id;
> - u_int Dprotocols;
> - u_int Bprotocols;
> - u_int nrbchan;
> - u_char channelmap[MISDN_CHMAP_SIZE];
> - struct list_head bchannels;
> - struct mISDNchannel *teimgr;
> - struct device dev;
> -};
> -
> -struct mISDNstack {
> - u_long status;
> - struct mISDNdevice *dev;
> - struct task_struct *thread;
> - struct completion *notify;
> - wait_queue_head_t workq;
> - struct sk_buff_head msgq;
> - struct list_head layer2;
> - struct mISDNchannel *layer1;
> - struct mISDNchannel own;
> - struct mutex lmutex; /* protect lists */
> - struct mISDN_sock_list l1sock;
> -#ifdef MISDN_MSG_STATS
> - u_int msg_cnt;
> - u_int sleep_cnt;
> - u_int stopped_cnt;
> -#endif
> -};
> -
> -typedef int (clockctl_func_t)(void *, int);
> -
> -struct mISDNclock {
> - struct list_head list;
> - char name[64];
> - int pri;
> - clockctl_func_t *ctl;
> - void *priv;
> -};
> -
> -/* global alloc/queue functions */
> -
> -static inline struct sk_buff *
> -mI_alloc_skb(unsigned int len, gfp_t gfp_mask)
> -{
> - struct sk_buff *skb;
> -
> - skb = alloc_skb(len + MISDN_HEADER_LEN, gfp_mask);
> - if (likely(skb))
> - skb_reserve(skb, MISDN_HEADER_LEN);
> - return skb;
> -}
> -
> -static inline struct sk_buff *
> -_alloc_mISDN_skb(u_int prim, u_int id, u_int len, void *dp, gfp_t gfp_mask)
> -{
> - struct sk_buff *skb = mI_alloc_skb(len, gfp_mask);
> - struct mISDNhead *hh;
> -
> - if (!skb)
> - return NULL;
> - if (len)
> - skb_put_data(skb, dp, len);
> - hh = mISDN_HEAD_P(skb);
> - hh->prim = prim;
> - hh->id = id;
> - return skb;
> -}
> -
> -static inline void
> -_queue_data(struct mISDNchannel *ch, u_int prim,
> - u_int id, u_int len, void *dp, gfp_t gfp_mask)
> -{
> - struct sk_buff *skb;
> -
> - if (!ch->peer)
> - return;
> - skb = _alloc_mISDN_skb(prim, id, len, dp, gfp_mask);
> - if (!skb)
> - return;
> - if (ch->recv(ch->peer, skb))
> - dev_kfree_skb(skb);
> -}
> -
> -/* global register/unregister functions */
> -
> -extern int mISDN_register_device(struct mISDNdevice *,
> - struct device *parent, char *name);
> -extern void mISDN_unregister_device(struct mISDNdevice *);
> -extern int mISDN_register_Bprotocol(struct Bprotocol *);
> -extern void mISDN_unregister_Bprotocol(struct Bprotocol *);
> -extern struct mISDNclock *mISDN_register_clock(char *, int, clockctl_func_t *,
> - void *);
> -extern void mISDN_unregister_clock(struct mISDNclock *);
> -
> -static inline struct mISDNdevice *dev_to_mISDN(const struct device *dev)
> -{
> - if (dev)
> - return dev_get_drvdata(dev);
> - else
> - return NULL;
> -}
> -
> -extern void set_channel_address(struct mISDNchannel *, u_int, u_int);
> -extern void mISDN_clock_update(struct mISDNclock *, int, ktime_t *);
> -extern unsigned short mISDN_clock_get(void);
> -extern const char *mISDNDevName4ch(struct mISDNchannel *);
> -
> -#endif /* __KERNEL__ */
> -#endif /* mISDNIF_H */
> diff --git a/include/uapi/linux/capi.h b/include/uapi/linux/capi.h
> deleted file mode 100644
> index 31f946f8a88d..000000000000
> --- a/include/uapi/linux/capi.h
> +++ /dev/null
> @@ -1,134 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
> -/* $Id: capi.h,v 1.4.6.1 2001/09/23 22:25:05 kai Exp $
> - *
> - * CAPI 2.0 Interface for Linux
> - *
> - * Copyright 1997 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.
> - *
> - */
> -
> -#ifndef __LINUX_CAPI_H__
> -#define __LINUX_CAPI_H__
> -
> -#include <linux/types.h>
> -#include <linux/ioctl.h>
> -#ifndef __KERNEL__
> -#include <linux/kernelcapi.h>
> -#endif
> -
> -/*
> - * CAPI_REGISTER
> - */
> -
> -typedef struct capi_register_params { /* CAPI_REGISTER */
> - __u32 level3cnt; /* No. of simulatneous user data connections */
> - __u32 datablkcnt; /* No. of buffered data messages */
> - __u32 datablklen; /* Size of buffered data messages */
> -} capi_register_params;
> -
> -#define CAPI_REGISTER _IOW('C',0x01,struct capi_register_params)
> -
> -/*
> - * CAPI_GET_MANUFACTURER
> - */
> -
> -#define CAPI_MANUFACTURER_LEN 64
> -
> -#define CAPI_GET_MANUFACTURER _IOWR('C',0x06,int) /* broken: wanted size 64 (CAPI_MANUFACTURER_LEN) */
> -
> -/*
> - * CAPI_GET_VERSION
> - */
> -
> -typedef struct capi_version {
> - __u32 majorversion;
> - __u32 minorversion;
> - __u32 majormanuversion;
> - __u32 minormanuversion;
> -} capi_version;
> -
> -#define CAPI_GET_VERSION _IOWR('C',0x07,struct capi_version)
> -
> -/*
> - * CAPI_GET_SERIAL
> - */
> -
> -#define CAPI_SERIAL_LEN 8
> -#define CAPI_GET_SERIAL _IOWR('C',0x08,int) /* broken: wanted size 8 (CAPI_SERIAL_LEN) */
> -
> -/*
> - * CAPI_GET_PROFILE
> - */
> -
> -typedef struct capi_profile {
> - __u16 ncontroller; /* number of installed controller */
> - __u16 nbchannel; /* number of B-Channels */
> - __u32 goptions; /* global options */
> - __u32 support1; /* B1 protocols support */
> - __u32 support2; /* B2 protocols support */
> - __u32 support3; /* B3 protocols support */
> - __u32 reserved[6]; /* reserved */
> - __u32 manu[5]; /* manufacturer specific information */
> -} capi_profile;
> -
> -#define CAPI_GET_PROFILE _IOWR('C',0x09,struct capi_profile)
> -
> -typedef struct capi_manufacturer_cmd {
> - unsigned long cmd;
> - void __user *data;
> -} capi_manufacturer_cmd;
> -
> -/*
> - * CAPI_MANUFACTURER_CMD
> - */
> -
> -#define CAPI_MANUFACTURER_CMD _IOWR('C',0x20, struct capi_manufacturer_cmd)
> -
> -/*
> - * CAPI_GET_ERRCODE
> - * capi errcode is set, * if read, write, or ioctl returns EIO,
> - * ioctl returns errcode directly, and in arg, if != 0
> - */
> -
> -#define CAPI_GET_ERRCODE _IOR('C',0x21, __u16)
> -
> -/*
> - * CAPI_INSTALLED
> - */
> -#define CAPI_INSTALLED _IOR('C',0x22, __u16)
> -
> -
> -/*
> - * member contr is input for
> - * CAPI_GET_MANUFACTURER, CAPI_GET_VERSION, CAPI_GET_SERIAL
> - * and CAPI_GET_PROFILE
> - */
> -typedef union capi_ioctl_struct {
> - __u32 contr;
> - capi_register_params rparams;
> - __u8 manufacturer[CAPI_MANUFACTURER_LEN];
> - capi_version version;
> - __u8 serial[CAPI_SERIAL_LEN];
> - capi_profile profile;
> - capi_manufacturer_cmd cmd;
> - __u16 errcode;
> -} capi_ioctl_struct;
> -
> -/*
> - * Middleware extension
> - */
> -
> -#define CAPIFLAG_HIGHJACKING 0x0001
> -
> -#define CAPI_GET_FLAGS _IOR('C',0x23, unsigned)
> -#define CAPI_SET_FLAGS _IOR('C',0x24, unsigned)
> -#define CAPI_CLR_FLAGS _IOR('C',0x25, unsigned)
> -
> -#define CAPI_NCCI_OPENCOUNT _IOR('C',0x26, unsigned)
> -
> -#define CAPI_NCCI_GETUNIT _IOR('C',0x27, unsigned)
> -
> -#endif /* __LINUX_CAPI_H__ */
> diff --git a/include/uapi/linux/isdn/capicmd.h b/include/uapi/linux/isdn/capicmd.h
> deleted file mode 100644
> index 5ec88e7548a9..000000000000
> --- a/include/uapi/linux/isdn/capicmd.h
> +++ /dev/null
> @@ -1,117 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
> -/* $Id: capicmd.h,v 1.2.6.2 2001/09/23 22:24:33 kai Exp $
> - *
> - * CAPI 2.0 Interface for Linux
> - *
> - * Copyright 1997 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.
> - *
> - */
> -
> -#ifndef __CAPICMD_H__
> -#define __CAPICMD_H__
> -
> -#define CAPI_MSG_BASELEN 8
> -#define CAPI_DATA_B3_REQ_LEN (CAPI_MSG_BASELEN+4+4+2+2+2)
> -#define CAPI_DATA_B3_RESP_LEN (CAPI_MSG_BASELEN+4+2)
> -#define CAPI_DISCONNECT_B3_RESP_LEN (CAPI_MSG_BASELEN+4)
> -
> -/*----- CAPI commands -----*/
> -#define CAPI_ALERT 0x01
> -#define CAPI_CONNECT 0x02
> -#define CAPI_CONNECT_ACTIVE 0x03
> -#define CAPI_CONNECT_B3_ACTIVE 0x83
> -#define CAPI_CONNECT_B3 0x82
> -#define CAPI_CONNECT_B3_T90_ACTIVE 0x88
> -#define CAPI_DATA_B3 0x86
> -#define CAPI_DISCONNECT_B3 0x84
> -#define CAPI_DISCONNECT 0x04
> -#define CAPI_FACILITY 0x80
> -#define CAPI_INFO 0x08
> -#define CAPI_LISTEN 0x05
> -#define CAPI_MANUFACTURER 0xff
> -#define CAPI_RESET_B3 0x87
> -#define CAPI_SELECT_B_PROTOCOL 0x41
> -
> -/*----- CAPI subcommands -----*/
> -
> -#define CAPI_REQ 0x80
> -#define CAPI_CONF 0x81
> -#define CAPI_IND 0x82
> -#define CAPI_RESP 0x83
> -
> -/*----- CAPI combined commands -----*/
> -
> -#define CAPICMD(cmd,subcmd) (((cmd)<<8)|(subcmd))
> -
> -#define CAPI_DISCONNECT_REQ CAPICMD(CAPI_DISCONNECT,CAPI_REQ)
> -#define CAPI_DISCONNECT_CONF CAPICMD(CAPI_DISCONNECT,CAPI_CONF)
> -#define CAPI_DISCONNECT_IND CAPICMD(CAPI_DISCONNECT,CAPI_IND)
> -#define CAPI_DISCONNECT_RESP CAPICMD(CAPI_DISCONNECT,CAPI_RESP)
> -
> -#define CAPI_ALERT_REQ CAPICMD(CAPI_ALERT,CAPI_REQ)
> -#define CAPI_ALERT_CONF CAPICMD(CAPI_ALERT,CAPI_CONF)
> -
> -#define CAPI_CONNECT_REQ CAPICMD(CAPI_CONNECT,CAPI_REQ)
> -#define CAPI_CONNECT_CONF CAPICMD(CAPI_CONNECT,CAPI_CONF)
> -#define CAPI_CONNECT_IND CAPICMD(CAPI_CONNECT,CAPI_IND)
> -#define CAPI_CONNECT_RESP CAPICMD(CAPI_CONNECT,CAPI_RESP)
> -
> -#define CAPI_CONNECT_ACTIVE_REQ CAPICMD(CAPI_CONNECT_ACTIVE,CAPI_REQ)
> -#define CAPI_CONNECT_ACTIVE_CONF CAPICMD(CAPI_CONNECT_ACTIVE,CAPI_CONF)
> -#define CAPI_CONNECT_ACTIVE_IND CAPICMD(CAPI_CONNECT_ACTIVE,CAPI_IND)
> -#define CAPI_CONNECT_ACTIVE_RESP CAPICMD(CAPI_CONNECT_ACTIVE,CAPI_RESP)
> -
> -#define CAPI_SELECT_B_PROTOCOL_REQ CAPICMD(CAPI_SELECT_B_PROTOCOL,CAPI_REQ)
> -#define CAPI_SELECT_B_PROTOCOL_CONF CAPICMD(CAPI_SELECT_B_PROTOCOL,CAPI_CONF)
> -
> -#define CAPI_CONNECT_B3_ACTIVE_REQ CAPICMD(CAPI_CONNECT_B3_ACTIVE,CAPI_REQ)
> -#define CAPI_CONNECT_B3_ACTIVE_CONF CAPICMD(CAPI_CONNECT_B3_ACTIVE,CAPI_CONF)
> -#define CAPI_CONNECT_B3_ACTIVE_IND CAPICMD(CAPI_CONNECT_B3_ACTIVE,CAPI_IND)
> -#define CAPI_CONNECT_B3_ACTIVE_RESP CAPICMD(CAPI_CONNECT_B3_ACTIVE,CAPI_RESP)
> -
> -#define CAPI_CONNECT_B3_REQ CAPICMD(CAPI_CONNECT_B3,CAPI_REQ)
> -#define CAPI_CONNECT_B3_CONF CAPICMD(CAPI_CONNECT_B3,CAPI_CONF)
> -#define CAPI_CONNECT_B3_IND CAPICMD(CAPI_CONNECT_B3,CAPI_IND)
> -#define CAPI_CONNECT_B3_RESP CAPICMD(CAPI_CONNECT_B3,CAPI_RESP)
> -
> -
> -#define CAPI_CONNECT_B3_T90_ACTIVE_IND CAPICMD(CAPI_CONNECT_B3_T90_ACTIVE,CAPI_IND)
> -#define CAPI_CONNECT_B3_T90_ACTIVE_RESP CAPICMD(CAPI_CONNECT_B3_T90_ACTIVE,CAPI_RESP)
> -
> -#define CAPI_DATA_B3_REQ CAPICMD(CAPI_DATA_B3,CAPI_REQ)
> -#define CAPI_DATA_B3_CONF CAPICMD(CAPI_DATA_B3,CAPI_CONF)
> -#define CAPI_DATA_B3_IND CAPICMD(CAPI_DATA_B3,CAPI_IND)
> -#define CAPI_DATA_B3_RESP CAPICMD(CAPI_DATA_B3,CAPI_RESP)
> -
> -#define CAPI_DISCONNECT_B3_REQ CAPICMD(CAPI_DISCONNECT_B3,CAPI_REQ)
> -#define CAPI_DISCONNECT_B3_CONF CAPICMD(CAPI_DISCONNECT_B3,CAPI_CONF)
> -#define CAPI_DISCONNECT_B3_IND CAPICMD(CAPI_DISCONNECT_B3,CAPI_IND)
> -#define CAPI_DISCONNECT_B3_RESP CAPICMD(CAPI_DISCONNECT_B3,CAPI_RESP)
> -
> -#define CAPI_RESET_B3_REQ CAPICMD(CAPI_RESET_B3,CAPI_REQ)
> -#define CAPI_RESET_B3_CONF CAPICMD(CAPI_RESET_B3,CAPI_CONF)
> -#define CAPI_RESET_B3_IND CAPICMD(CAPI_RESET_B3,CAPI_IND)
> -#define CAPI_RESET_B3_RESP CAPICMD(CAPI_RESET_B3,CAPI_RESP)
> -
> -#define CAPI_LISTEN_REQ CAPICMD(CAPI_LISTEN,CAPI_REQ)
> -#define CAPI_LISTEN_CONF CAPICMD(CAPI_LISTEN,CAPI_CONF)
> -
> -#define CAPI_MANUFACTURER_REQ CAPICMD(CAPI_MANUFACTURER,CAPI_REQ)
> -#define CAPI_MANUFACTURER_CONF CAPICMD(CAPI_MANUFACTURER,CAPI_CONF)
> -#define CAPI_MANUFACTURER_IND CAPICMD(CAPI_MANUFACTURER,CAPI_IND)
> -#define CAPI_MANUFACTURER_RESP CAPICMD(CAPI_MANUFACTURER,CAPI_RESP)
> -
> -#define CAPI_FACILITY_REQ CAPICMD(CAPI_FACILITY,CAPI_REQ)
> -#define CAPI_FACILITY_CONF CAPICMD(CAPI_FACILITY,CAPI_CONF)
> -#define CAPI_FACILITY_IND CAPICMD(CAPI_FACILITY,CAPI_IND)
> -#define CAPI_FACILITY_RESP CAPICMD(CAPI_FACILITY,CAPI_RESP)
> -
> -#define CAPI_INFO_REQ CAPICMD(CAPI_INFO,CAPI_REQ)
> -#define CAPI_INFO_CONF CAPICMD(CAPI_INFO,CAPI_CONF)
> -#define CAPI_INFO_IND CAPICMD(CAPI_INFO,CAPI_IND)
> -#define CAPI_INFO_RESP CAPICMD(CAPI_INFO,CAPI_RESP)
> -
> -#endif /* __CAPICMD_H__ */
> diff --git a/include/uapi/linux/kernelcapi.h b/include/uapi/linux/kernelcapi.h
> deleted file mode 100644
> index 325a856e0e20..000000000000
> --- a/include/uapi/linux/kernelcapi.h
> +++ /dev/null
> @@ -1,48 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
> -/*
> - * $Id: kernelcapi.h,v 1.8.6.2 2001/02/07 11:31:31 kai Exp $
> - *
> - * Kernel CAPI 2.0 Interface for Linux
> - *
> - * (c) Copyright 1997 by Carsten Paeth (calle@calle.in-berlin.de)
> - *
> - */
> -
> -#ifndef _UAPI__KERNELCAPI_H__
> -#define _UAPI__KERNELCAPI_H__
> -
> -#define CAPI_MAXAPPL 240 /* maximum number of applications */
> -#define CAPI_MAXCONTR 32 /* maximum number of controller */
> -#define CAPI_MAXDATAWINDOW 8
> -
> -
> -typedef struct kcapi_flagdef {
> - int contr;
> - int flag;
> -} kcapi_flagdef;
> -
> -typedef struct kcapi_carddef {
> - char driver[32];
> - unsigned int port;
> - unsigned irq;
> - unsigned int membase;
> - int cardnr;
> -} kcapi_carddef;
> -
> -/* new ioctls >= 10 */
> -#define KCAPI_CMD_TRACE 10
> -#define KCAPI_CMD_ADDCARD 11 /* OBSOLETE */
> -
> -/*
> - * flag > 2 => trace also data
> - * flag & 1 => show trace
> - */
> -#define KCAPI_TRACE_OFF 0
> -#define KCAPI_TRACE_SHORT_NO_DATA 1
> -#define KCAPI_TRACE_FULL_NO_DATA 2
> -#define KCAPI_TRACE_SHORT 3
> -#define KCAPI_TRACE_FULL 4
> -
> -
> -
> -#endif /* _UAPI__KERNELCAPI_H__ */
> diff --git a/net/bluetooth/cmtp/cmtp.h b/net/bluetooth/cmtp/cmtp.h
> deleted file mode 100644
> index f6b9dc4e408f..000000000000
> --- a/net/bluetooth/cmtp/cmtp.h
> +++ /dev/null
> @@ -1,129 +0,0 @@
> -/*
> - CMTP implementation for Linux Bluetooth stack (BlueZ).
> - Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
> -
> - This program is free software; you can redistribute it and/or modify
> - it under the terms of the GNU General Public License version 2 as
> - published by the Free Software Foundation;
> -
> - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
> - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
> - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
> - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
> - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> -
> - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
> - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
> - SOFTWARE IS DISCLAIMED.
> -*/
> -
> -#ifndef __CMTP_H
> -#define __CMTP_H
> -
> -#include <linux/types.h>
> -#include <net/bluetooth/bluetooth.h>
> -
> -#define BTNAMSIZ 21
> -
> -/* CMTP ioctl defines */
> -#define CMTPCONNADD _IOW('C', 200, int)
> -#define CMTPCONNDEL _IOW('C', 201, int)
> -#define CMTPGETCONNLIST _IOR('C', 210, int)
> -#define CMTPGETCONNINFO _IOR('C', 211, int)
> -
> -#define CMTP_LOOPBACK 0
> -
> -struct cmtp_connadd_req {
> - int sock; /* Connected socket */
> - __u32 flags;
> -};
> -
> -struct cmtp_conndel_req {
> - bdaddr_t bdaddr;
> - __u32 flags;
> -};
> -
> -struct cmtp_conninfo {
> - bdaddr_t bdaddr;
> - __u32 flags;
> - __u16 state;
> - int num;
> -};
> -
> -struct cmtp_connlist_req {
> - __u32 cnum;
> - struct cmtp_conninfo __user *ci;
> -};
> -
> -int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock);
> -int cmtp_del_connection(struct cmtp_conndel_req *req);
> -int cmtp_get_connlist(struct cmtp_connlist_req *req);
> -int cmtp_get_conninfo(struct cmtp_conninfo *ci);
> -
> -/* CMTP session defines */
> -#define CMTP_INTEROP_TIMEOUT (HZ * 5)
> -#define CMTP_INITIAL_MSGNUM 0xff00
> -
> -struct cmtp_session {
> - struct list_head list;
> -
> - struct socket *sock;
> -
> - bdaddr_t bdaddr;
> -
> - unsigned long state;
> - unsigned long flags;
> -
> - uint mtu;
> -
> - char name[BTNAMSIZ];
> -
> - atomic_t terminate;
> - struct task_struct *task;
> -
> - wait_queue_head_t wait;
> -
> - int ncontroller;
> - int num;
> - struct capi_ctr ctrl;
> -
> - struct list_head applications;
> -
> - unsigned long blockids;
> - int msgnum;
> -
> - struct sk_buff_head transmit;
> -
> - struct sk_buff *reassembly[16];
> -};
> -
> -struct cmtp_application {
> - struct list_head list;
> -
> - unsigned long state;
> - int err;
> -
> - __u16 appl;
> - __u16 mapping;
> -
> - __u16 msgnum;
> -};
> -
> -struct cmtp_scb {
> - int id;
> - int data;
> -};
> -
> -int cmtp_attach_device(struct cmtp_session *session);
> -void cmtp_detach_device(struct cmtp_session *session);
> -
> -void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb);
> -
> -/* CMTP init defines */
> -int cmtp_init_sockets(void);
> -void cmtp_cleanup_sockets(void);
> -
> -#endif /* __CMTP_H */
> diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
> deleted file mode 100644
> index aa28b1d32c4e..000000000000
> --- a/drivers/isdn/capi/capi.c
> +++ /dev/null
> @@ -1,1435 +0,0 @@
> -/* $Id: capi.c,v 1.1.2.7 2004/04/28 09:48:59 armin Exp $
> - *
> - * CAPI 2.0 Interface for Linux
> - *
> - * Copyright 1996 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/compiler.h>
> -#include <linux/module.h>
> -#include <linux/ethtool.h>
> -#include <linux/errno.h>
> -#include <linux/kernel.h>
> -#include <linux/major.h>
> -#include <linux/sched.h>
> -#include <linux/slab.h>
> -#include <linux/fcntl.h>
> -#include <linux/fs.h>
> -#include <linux/signal.h>
> -#include <linux/mutex.h>
> -#include <linux/mm.h>
> -#include <linux/timer.h>
> -#include <linux/wait.h>
> -#include <linux/tty.h>
> -#include <linux/netdevice.h>
> -#include <linux/ppp_defs.h>
> -#include <linux/ppp-ioctl.h>
> -#include <linux/skbuff.h>
> -#include <linux/proc_fs.h>
> -#include <linux/seq_file.h>
> -#include <linux/poll.h>
> -#include <linux/capi.h>
> -#include <linux/kernelcapi.h>
> -#include <linux/init.h>
> -#include <linux/device.h>
> -#include <linux/moduleparam.h>
> -#include <linux/isdn/capiutil.h>
> -#include <linux/isdn/capicmd.h>
> -
> -#include "kcapi.h"
> -
> -MODULE_DESCRIPTION("CAPI4Linux: kernel CAPI layer and /dev/capi20 interface");
> -MODULE_AUTHOR("Carsten Paeth");
> -MODULE_LICENSE("GPL");
> -
> -/* -------- driver information -------------------------------------- */
> -
> -static DEFINE_MUTEX(capi_mutex);
> -static const struct class capi_class = {
> - .name = "capi",
> -};
> -static int capi_major = 68; /* allocated */
> -
> -module_param_named(major, capi_major, uint, 0);
> -
> -#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
> -#define CAPINC_NR_PORTS 32
> -#define CAPINC_MAX_PORTS 256
> -
> -static int capi_ttyminors = CAPINC_NR_PORTS;
> -
> -module_param_named(ttyminors, capi_ttyminors, uint, 0);
> -#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
> -
> -/* -------- defines ------------------------------------------------- */
> -
> -#define CAPINC_MAX_RECVQUEUE 10
> -#define CAPINC_MAX_SENDQUEUE 10
> -#define CAPI_MAX_BLKSIZE 2048
> -
> -/* -------- data structures ----------------------------------------- */
> -
> -struct capidev;
> -struct capincci;
> -struct capiminor;
> -
> -struct ackqueue_entry {
> - struct list_head list;
> - u16 datahandle;
> -};
> -
> -struct capiminor {
> - unsigned int minor;
> -
> - struct capi20_appl *ap;
> - u32 ncci;
> - atomic_t datahandle;
> - atomic_t msgid;
> -
> - struct tty_port port;
> - int ttyinstop;
> - int ttyoutstop;
> -
> - struct sk_buff_head inqueue;
> -
> - struct sk_buff_head outqueue;
> - int outbytes;
> - struct sk_buff *outskb;
> - spinlock_t outlock;
> -
> - /* transmit path */
> - struct list_head ackqueue;
> - int nack;
> - spinlock_t ackqlock;
> -};
> -
> -struct capincci {
> - struct list_head list;
> - u32 ncci;
> - struct capidev *cdev;
> -#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
> - struct capiminor *minorp;
> -#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
> -};
> -
> -struct capidev {
> - struct list_head list;
> - struct capi20_appl ap;
> - u16 errcode;
> - unsigned userflags;
> -
> - struct sk_buff_head recvqueue;
> - wait_queue_head_t recvwait;
> -
> - struct list_head nccis;
> -
> - struct mutex lock;
> -};
> -
> -/* -------- global variables ---------------------------------------- */
> -
> -static DEFINE_MUTEX(capidev_list_lock);
> -static LIST_HEAD(capidev_list);
> -
> -#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
> -
> -static DEFINE_SPINLOCK(capiminors_lock);
> -static struct capiminor **capiminors;
> -
> -static struct tty_driver *capinc_tty_driver;
> -
> -/* -------- datahandles --------------------------------------------- */
> -
> -static int capiminor_add_ack(struct capiminor *mp, u16 datahandle)
> -{
> - struct ackqueue_entry *n;
> -
> - n = kmalloc_obj(*n, GFP_ATOMIC);
> - if (unlikely(!n)) {
> - printk(KERN_ERR "capi: alloc datahandle failed\n");
> - return -1;
> - }
> - n->datahandle = datahandle;
> - INIT_LIST_HEAD(&n->list);
> - spin_lock_bh(&mp->ackqlock);
> - list_add_tail(&n->list, &mp->ackqueue);
> - mp->nack++;
> - spin_unlock_bh(&mp->ackqlock);
> - return 0;
> -}
> -
> -static int capiminor_del_ack(struct capiminor *mp, u16 datahandle)
> -{
> - struct ackqueue_entry *p, *tmp;
> -
> - spin_lock_bh(&mp->ackqlock);
> - list_for_each_entry_safe(p, tmp, &mp->ackqueue, list) {
> - if (p->datahandle == datahandle) {
> - list_del(&p->list);
> - mp->nack--;
> - spin_unlock_bh(&mp->ackqlock);
> - kfree(p);
> - return 0;
> - }
> - }
> - spin_unlock_bh(&mp->ackqlock);
> - return -1;
> -}
> -
> -static void capiminor_del_all_ack(struct capiminor *mp)
> -{
> - struct ackqueue_entry *p, *tmp;
> -
> - list_for_each_entry_safe(p, tmp, &mp->ackqueue, list) {
> - list_del(&p->list);
> - kfree(p);
> - mp->nack--;
> - }
> -}
> -
> -
> -/* -------- struct capiminor ---------------------------------------- */
> -
> -static void capiminor_destroy(struct tty_port *port)
> -{
> - struct capiminor *mp = container_of(port, struct capiminor, port);
> -
> - kfree_skb(mp->outskb);
> - skb_queue_purge(&mp->inqueue);
> - skb_queue_purge(&mp->outqueue);
> - capiminor_del_all_ack(mp);
> - kfree(mp);
> -}
> -
> -static const struct tty_port_operations capiminor_port_ops = {
> - .destruct = capiminor_destroy,
> -};
> -
> -static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci)
> -{
> - struct capiminor *mp;
> - struct device *dev;
> - unsigned int minor;
> -
> - mp = kzalloc_obj(*mp);
> - if (!mp) {
> - printk(KERN_ERR "capi: can't alloc capiminor\n");
> - return NULL;
> - }
> -
> - mp->ap = ap;
> - mp->ncci = ncci;
> - INIT_LIST_HEAD(&mp->ackqueue);
> - spin_lock_init(&mp->ackqlock);
> -
> - skb_queue_head_init(&mp->inqueue);
> - skb_queue_head_init(&mp->outqueue);
> - spin_lock_init(&mp->outlock);
> -
> - tty_port_init(&mp->port);
> - mp->port.ops = &capiminor_port_ops;
> -
> - /* Allocate the least unused minor number. */
> - spin_lock(&capiminors_lock);
> - for (minor = 0; minor < capi_ttyminors; minor++)
> - if (!capiminors[minor]) {
> - capiminors[minor] = mp;
> - break;
> - }
> - spin_unlock(&capiminors_lock);
> -
> - if (minor == capi_ttyminors) {
> - printk(KERN_NOTICE "capi: out of minors\n");
> - goto err_out1;
> - }
> -
> - mp->minor = minor;
> -
> - dev = tty_port_register_device(&mp->port, capinc_tty_driver, minor,
> - NULL);
> - if (IS_ERR(dev))
> - goto err_out2;
> -
> - return mp;
> -
> -err_out2:
> - spin_lock(&capiminors_lock);
> - capiminors[minor] = NULL;
> - spin_unlock(&capiminors_lock);
> -
> -err_out1:
> - tty_port_put(&mp->port);
> - return NULL;
> -}
> -
> -static struct capiminor *capiminor_get(unsigned int minor)
> -{
> - struct capiminor *mp;
> -
> - spin_lock(&capiminors_lock);
> - mp = capiminors[minor];
> - if (mp)
> - tty_port_get(&mp->port);
> - spin_unlock(&capiminors_lock);
> -
> - return mp;
> -}
> -
> -static inline void capiminor_put(struct capiminor *mp)
> -{
> - tty_port_put(&mp->port);
> -}
> -
> -static void capiminor_free(struct capiminor *mp)
> -{
> - tty_unregister_device(capinc_tty_driver, mp->minor);
> -
> - spin_lock(&capiminors_lock);
> - capiminors[mp->minor] = NULL;
> - spin_unlock(&capiminors_lock);
> -
> - capiminor_put(mp);
> -}
> -
> -/* -------- struct capincci ----------------------------------------- */
> -
> -static void capincci_alloc_minor(struct capidev *cdev, struct capincci *np)
> -{
> - if (cdev->userflags & CAPIFLAG_HIGHJACKING)
> - np->minorp = capiminor_alloc(&cdev->ap, np->ncci);
> -}
> -
> -static void capincci_free_minor(struct capincci *np)
> -{
> - struct capiminor *mp = np->minorp;
> -
> - if (mp) {
> - tty_port_tty_vhangup(&mp->port);
> - capiminor_free(mp);
> - }
> -}
> -
> -static inline unsigned int capincci_minor_opencount(struct capincci *np)
> -{
> - struct capiminor *mp = np->minorp;
> - unsigned int count = 0;
> - struct tty_struct *tty;
> -
> - if (mp) {
> - tty = tty_port_tty_get(&mp->port);
> - if (tty) {
> - count = tty->count;
> - tty_kref_put(tty);
> - }
> - }
> - return count;
> -}
> -
> -#else /* !CONFIG_ISDN_CAPI_MIDDLEWARE */
> -
> -static inline void
> -capincci_alloc_minor(struct capidev *cdev, struct capincci *np) { }
> -static inline void capincci_free_minor(struct capincci *np) { }
> -
> -#endif /* !CONFIG_ISDN_CAPI_MIDDLEWARE */
> -
> -static struct capincci *capincci_alloc(struct capidev *cdev, u32 ncci)
> -{
> - struct capincci *np;
> -
> - np = kzalloc_obj(*np);
> - if (!np)
> - return NULL;
> - np->ncci = ncci;
> - np->cdev = cdev;
> -
> - capincci_alloc_minor(cdev, np);
> -
> - list_add_tail(&np->list, &cdev->nccis);
> -
> - return np;
> -}
> -
> -static void capincci_free(struct capidev *cdev, u32 ncci)
> -{
> - struct capincci *np, *tmp;
> -
> - list_for_each_entry_safe(np, tmp, &cdev->nccis, list)
> - if (ncci == 0xffffffff || np->ncci == ncci) {
> - capincci_free_minor(np);
> - list_del(&np->list);
> - kfree(np);
> - }
> -}
> -
> -#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
> -static struct capincci *capincci_find(struct capidev *cdev, u32 ncci)
> -{
> - struct capincci *np;
> -
> - list_for_each_entry(np, &cdev->nccis, list)
> - if (np->ncci == ncci)
> - return np;
> - return NULL;
> -}
> -
> -/* -------- handle data queue --------------------------------------- */
> -
> -static struct sk_buff *
> -gen_data_b3_resp_for(struct capiminor *mp, struct sk_buff *skb)
> -{
> - struct sk_buff *nskb;
> - nskb = alloc_skb(CAPI_DATA_B3_RESP_LEN, GFP_KERNEL);
> - if (nskb) {
> - u16 datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN + 4 + 4 + 2);
> - unsigned char *s = skb_put(nskb, CAPI_DATA_B3_RESP_LEN);
> - capimsg_setu16(s, 0, CAPI_DATA_B3_RESP_LEN);
> - capimsg_setu16(s, 2, mp->ap->applid);
> - capimsg_setu8 (s, 4, CAPI_DATA_B3);
> - capimsg_setu8 (s, 5, CAPI_RESP);
> - capimsg_setu16(s, 6, atomic_inc_return(&mp->msgid));
> - capimsg_setu32(s, 8, mp->ncci);
> - capimsg_setu16(s, 12, datahandle);
> - }
> - return nskb;
> -}
> -
> -static int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb)
> -{
> - unsigned int datalen = skb->len - CAPIMSG_LEN(skb->data);
> - struct tty_struct *tty;
> - struct sk_buff *nskb;
> - u16 errcode, datahandle;
> - struct tty_ldisc *ld;
> - int ret = -1;
> -
> - tty = tty_port_tty_get(&mp->port);
> - if (!tty) {
> - pr_debug("capi: currently no receiver\n");
> - return -1;
> - }
> -
> - ld = tty_ldisc_ref(tty);
> - if (!ld) {
> - /* fatal error, do not requeue */
> - ret = 0;
> - kfree_skb(skb);
> - goto deref_tty;
> - }
> -
> - if (ld->ops->receive_buf == NULL) {
> - pr_debug("capi: ldisc has no receive_buf function\n");
> - /* fatal error, do not requeue */
> - goto free_skb;
> - }
> - if (mp->ttyinstop) {
> - pr_debug("capi: recv tty throttled\n");
> - goto deref_ldisc;
> - }
> -
> - if (tty->receive_room < datalen) {
> - pr_debug("capi: no room in tty\n");
> - goto deref_ldisc;
> - }
> -
> - nskb = gen_data_b3_resp_for(mp, skb);
> - if (!nskb) {
> - printk(KERN_ERR "capi: gen_data_b3_resp failed\n");
> - goto deref_ldisc;
> - }
> -
> - datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN + 4);
> -
> - errcode = capi20_put_message(mp->ap, nskb);
> -
> - if (errcode == CAPI_NOERROR) {
> - skb_pull(skb, CAPIMSG_LEN(skb->data));
> - pr_debug("capi: DATA_B3_RESP %u len=%d => ldisc\n",
> - datahandle, skb->len);
> - ld->ops->receive_buf(tty, skb->data, NULL, skb->len);
> - } else {
> - printk(KERN_ERR "capi: send DATA_B3_RESP failed=%x\n",
> - errcode);
> - kfree_skb(nskb);
> -
> - if (errcode == CAPI_SENDQUEUEFULL)
> - goto deref_ldisc;
> - }
> -
> -free_skb:
> - ret = 0;
> - kfree_skb(skb);
> -
> -deref_ldisc:
> - tty_ldisc_deref(ld);
> -
> -deref_tty:
> - tty_kref_put(tty);
> - return ret;
> -}
> -
> -static void handle_minor_recv(struct capiminor *mp)
> -{
> - struct sk_buff *skb;
> -
> - while ((skb = skb_dequeue(&mp->inqueue)) != NULL)
> - if (handle_recv_skb(mp, skb) < 0) {
> - skb_queue_head(&mp->inqueue, skb);
> - return;
> - }
> -}
> -
> -static void handle_minor_send(struct capiminor *mp)
> -{
> - struct tty_struct *tty;
> - struct sk_buff *skb;
> - u16 len;
> - u16 errcode;
> - u16 datahandle;
> -
> - tty = tty_port_tty_get(&mp->port);
> - if (!tty)
> - return;
> -
> - if (mp->ttyoutstop) {
> - pr_debug("capi: send: tty stopped\n");
> - tty_kref_put(tty);
> - return;
> - }
> -
> - while (1) {
> - spin_lock_bh(&mp->outlock);
> - skb = __skb_dequeue(&mp->outqueue);
> - if (!skb) {
> - spin_unlock_bh(&mp->outlock);
> - break;
> - }
> - len = (u16)skb->len;
> - mp->outbytes -= len;
> - spin_unlock_bh(&mp->outlock);
> -
> - datahandle = atomic_inc_return(&mp->datahandle);
> - skb_push(skb, CAPI_DATA_B3_REQ_LEN);
> - memset(skb->data, 0, CAPI_DATA_B3_REQ_LEN);
> - capimsg_setu16(skb->data, 0, CAPI_DATA_B3_REQ_LEN);
> - capimsg_setu16(skb->data, 2, mp->ap->applid);
> - capimsg_setu8 (skb->data, 4, CAPI_DATA_B3);
> - capimsg_setu8 (skb->data, 5, CAPI_REQ);
> - capimsg_setu16(skb->data, 6, atomic_inc_return(&mp->msgid));
> - capimsg_setu32(skb->data, 8, mp->ncci); /* NCCI */
> - capimsg_setu32(skb->data, 12, (u32)(long)skb->data);/* Data32 */
> - capimsg_setu16(skb->data, 16, len); /* Data length */
> - capimsg_setu16(skb->data, 18, datahandle);
> - capimsg_setu16(skb->data, 20, 0); /* Flags */
> -
> - if (capiminor_add_ack(mp, datahandle) < 0) {
> - skb_pull(skb, CAPI_DATA_B3_REQ_LEN);
> -
> - spin_lock_bh(&mp->outlock);
> - __skb_queue_head(&mp->outqueue, skb);
> - mp->outbytes += len;
> - spin_unlock_bh(&mp->outlock);
> -
> - break;
> - }
> - errcode = capi20_put_message(mp->ap, skb);
> - if (errcode == CAPI_NOERROR) {
> - pr_debug("capi: DATA_B3_REQ %u len=%u\n",
> - datahandle, len);
> - continue;
> - }
> - capiminor_del_ack(mp, datahandle);
> -
> - if (errcode == CAPI_SENDQUEUEFULL) {
> - skb_pull(skb, CAPI_DATA_B3_REQ_LEN);
> -
> - spin_lock_bh(&mp->outlock);
> - __skb_queue_head(&mp->outqueue, skb);
> - mp->outbytes += len;
> - spin_unlock_bh(&mp->outlock);
> -
> - break;
> - }
> -
> - /* ups, drop packet */
> - printk(KERN_ERR "capi: put_message = %x\n", errcode);
> - kfree_skb(skb);
> - }
> - tty_kref_put(tty);
> -}
> -
> -#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
> -/* -------- function called by lower level -------------------------- */
> -
> -static void capi_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
> -{
> - struct capidev *cdev = ap->private;
> -#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
> - struct capiminor *mp;
> - u16 datahandle;
> - struct capincci *np;
> -#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
> -
> - mutex_lock(&cdev->lock);
> -
> - if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_CONF) {
> - u16 info = CAPIMSG_U16(skb->data, 12); // Info field
> - if ((info & 0xff00) == 0)
> - capincci_alloc(cdev, CAPIMSG_NCCI(skb->data));
> - }
> - if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_IND)
> - capincci_alloc(cdev, CAPIMSG_NCCI(skb->data));
> -
> - if (CAPIMSG_COMMAND(skb->data) != CAPI_DATA_B3) {
> - skb_queue_tail(&cdev->recvqueue, skb);
> - wake_up_interruptible(&cdev->recvwait);
> - goto unlock_out;
> - }
> -
> -#ifndef CONFIG_ISDN_CAPI_MIDDLEWARE
> - skb_queue_tail(&cdev->recvqueue, skb);
> - wake_up_interruptible(&cdev->recvwait);
> -
> -#else /* CONFIG_ISDN_CAPI_MIDDLEWARE */
> -
> - np = capincci_find(cdev, CAPIMSG_CONTROL(skb->data));
> - if (!np) {
> - printk(KERN_ERR "BUG: capi_signal: ncci not found\n");
> - skb_queue_tail(&cdev->recvqueue, skb);
> - wake_up_interruptible(&cdev->recvwait);
> - goto unlock_out;
> - }
> -
> - mp = np->minorp;
> - if (!mp) {
> - skb_queue_tail(&cdev->recvqueue, skb);
> - wake_up_interruptible(&cdev->recvwait);
> - goto unlock_out;
> - }
> - if (CAPIMSG_SUBCOMMAND(skb->data) == CAPI_IND) {
> - datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN + 4 + 4 + 2);
> - pr_debug("capi_signal: DATA_B3_IND %u len=%d\n",
> - datahandle, skb->len-CAPIMSG_LEN(skb->data));
> - skb_queue_tail(&mp->inqueue, skb);
> -
> - handle_minor_recv(mp);
> -
> - } else if (CAPIMSG_SUBCOMMAND(skb->data) == CAPI_CONF) {
> -
> - datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN + 4);
> - pr_debug("capi_signal: DATA_B3_CONF %u 0x%x\n",
> - datahandle,
> - CAPIMSG_U16(skb->data, CAPIMSG_BASELEN + 4 + 2));
> - kfree_skb(skb);
> - capiminor_del_ack(mp, datahandle);
> - tty_port_tty_wakeup(&mp->port);
> - handle_minor_send(mp);
> -
> - } else {
> - /* ups, let capi application handle it :-) */
> - skb_queue_tail(&cdev->recvqueue, skb);
> - wake_up_interruptible(&cdev->recvwait);
> - }
> -#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
> -
> -unlock_out:
> - mutex_unlock(&cdev->lock);
> -}
> -
> -/* -------- file_operations for capidev ----------------------------- */
> -
> -static ssize_t
> -capi_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
> -{
> - struct capidev *cdev = file->private_data;
> - struct sk_buff *skb;
> - size_t copied;
> - int err;
> -
> - if (!cdev->ap.applid)
> - return -ENODEV;
> -
> - skb = skb_dequeue(&cdev->recvqueue);
> - if (!skb) {
> - if (file->f_flags & O_NONBLOCK)
> - return -EAGAIN;
> - err = wait_event_interruptible(cdev->recvwait,
> - (skb = skb_dequeue(&cdev->recvqueue)));
> - if (err)
> - return err;
> - }
> - if (skb->len > count) {
> - skb_queue_head(&cdev->recvqueue, skb);
> - return -EMSGSIZE;
> - }
> - if (copy_to_user(buf, skb->data, skb->len)) {
> - skb_queue_head(&cdev->recvqueue, skb);
> - return -EFAULT;
> - }
> - copied = skb->len;
> -
> - kfree_skb(skb);
> -
> - return copied;
> -}
> -
> -static ssize_t
> -capi_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
> -{
> - struct capidev *cdev = file->private_data;
> - struct sk_buff *skb;
> - u16 mlen;
> -
> - if (!cdev->ap.applid)
> - return -ENODEV;
> -
> - if (count < CAPIMSG_BASELEN)
> - return -EINVAL;
> -
> - skb = alloc_skb(count, GFP_USER);
> - if (!skb)
> - return -ENOMEM;
> -
> - if (copy_from_user(skb_put(skb, count), buf, count)) {
> - kfree_skb(skb);
> - return -EFAULT;
> - }
> - mlen = CAPIMSG_LEN(skb->data);
> - if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) {
> - if (count < CAPI_DATA_B3_REQ_LEN ||
> - (size_t)(mlen + CAPIMSG_DATALEN(skb->data)) != count) {
> - kfree_skb(skb);
> - return -EINVAL;
> - }
> - } else {
> - if (mlen != count) {
> - kfree_skb(skb);
> - return -EINVAL;
> - }
> - }
> - CAPIMSG_SETAPPID(skb->data, cdev->ap.applid);
> -
> - if (CAPIMSG_CMD(skb->data) == CAPI_DISCONNECT_B3_RESP) {
> - if (count < CAPI_DISCONNECT_B3_RESP_LEN) {
> - kfree_skb(skb);
> - return -EINVAL;
> - }
> - mutex_lock(&cdev->lock);
> - capincci_free(cdev, CAPIMSG_NCCI(skb->data));
> - mutex_unlock(&cdev->lock);
> - }
> -
> - cdev->errcode = capi20_put_message(&cdev->ap, skb);
> -
> - if (cdev->errcode) {
> - kfree_skb(skb);
> - return -EIO;
> - }
> - return count;
> -}
> -
> -static __poll_t
> -capi_poll(struct file *file, poll_table *wait)
> -{
> - struct capidev *cdev = file->private_data;
> - __poll_t mask = 0;
> -
> - if (!cdev->ap.applid)
> - return EPOLLERR;
> -
> - poll_wait(file, &(cdev->recvwait), wait);
> - mask = EPOLLOUT | EPOLLWRNORM;
> - if (!skb_queue_empty_lockless(&cdev->recvqueue))
> - mask |= EPOLLIN | EPOLLRDNORM;
> - return mask;
> -}
> -
> -static int
> -capi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
> -{
> - struct capidev *cdev = file->private_data;
> - capi_ioctl_struct data;
> - int retval = -EINVAL;
> - void __user *argp = (void __user *)arg;
> -
> - switch (cmd) {
> - case CAPI_REGISTER:
> - mutex_lock(&cdev->lock);
> -
> - if (cdev->ap.applid) {
> - retval = -EEXIST;
> - goto register_out;
> - }
> - if (copy_from_user(&cdev->ap.rparam, argp,
> - sizeof(struct capi_register_params))) {
> - retval = -EFAULT;
> - goto register_out;
> - }
> - cdev->ap.private = cdev;
> - cdev->ap.recv_message = capi_recv_message;
> - cdev->errcode = capi20_register(&cdev->ap);
> - retval = (int)cdev->ap.applid;
> - if (cdev->errcode) {
> - cdev->ap.applid = 0;
> - retval = -EIO;
> - }
> -
> -register_out:
> - mutex_unlock(&cdev->lock);
> - return retval;
> -
> - case CAPI_GET_VERSION:
> - if (copy_from_user(&data.contr, argp,
> - sizeof(data.contr)))
> - return -EFAULT;
> - cdev->errcode = capi20_get_version(data.contr, &data.version);
> - if (cdev->errcode)
> - return -EIO;
> - if (copy_to_user(argp, &data.version,
> - sizeof(data.version)))
> - return -EFAULT;
> - return 0;
> -
> - case CAPI_GET_SERIAL:
> - if (copy_from_user(&data.contr, argp,
> - sizeof(data.contr)))
> - return -EFAULT;
> - cdev->errcode = capi20_get_serial(data.contr, data.serial);
> - if (cdev->errcode)
> - return -EIO;
> - if (copy_to_user(argp, data.serial,
> - sizeof(data.serial)))
> - return -EFAULT;
> - return 0;
> -
> - case CAPI_GET_PROFILE:
> - if (copy_from_user(&data.contr, argp,
> - sizeof(data.contr)))
> - return -EFAULT;
> -
> - if (data.contr == 0) {
> - cdev->errcode = capi20_get_profile(data.contr, &data.profile);
> - if (cdev->errcode)
> - return -EIO;
> -
> - retval = copy_to_user(argp,
> - &data.profile.ncontroller,
> - sizeof(data.profile.ncontroller));
> -
> - } else {
> - cdev->errcode = capi20_get_profile(data.contr, &data.profile);
> - if (cdev->errcode)
> - return -EIO;
> -
> - retval = copy_to_user(argp, &data.profile,
> - sizeof(data.profile));
> - }
> - if (retval)
> - return -EFAULT;
> - return 0;
> -
> - case CAPI_GET_MANUFACTURER:
> - if (copy_from_user(&data.contr, argp,
> - sizeof(data.contr)))
> - return -EFAULT;
> - cdev->errcode = capi20_get_manufacturer(data.contr, data.manufacturer);
> - if (cdev->errcode)
> - return -EIO;
> -
> - if (copy_to_user(argp, data.manufacturer,
> - sizeof(data.manufacturer)))
> - return -EFAULT;
> -
> - return 0;
> -
> - case CAPI_GET_ERRCODE:
> - data.errcode = cdev->errcode;
> - cdev->errcode = CAPI_NOERROR;
> - if (arg) {
> - if (copy_to_user(argp, &data.errcode,
> - sizeof(data.errcode)))
> - return -EFAULT;
> - }
> - return data.errcode;
> -
> - case CAPI_INSTALLED:
> - if (capi20_isinstalled() == CAPI_NOERROR)
> - return 0;
> - return -ENXIO;
> -
> - case CAPI_MANUFACTURER_CMD: {
> - struct capi_manufacturer_cmd mcmd;
> - if (!capable(CAP_SYS_ADMIN))
> - return -EPERM;
> - if (copy_from_user(&mcmd, argp, sizeof(mcmd)))
> - return -EFAULT;
> - return capi20_manufacturer(mcmd.cmd, mcmd.data);
> - }
> - case CAPI_SET_FLAGS:
> - case CAPI_CLR_FLAGS: {
> - unsigned userflags;
> -
> - if (copy_from_user(&userflags, argp, sizeof(userflags)))
> - return -EFAULT;
> -
> - mutex_lock(&cdev->lock);
> - if (cmd == CAPI_SET_FLAGS)
> - cdev->userflags |= userflags;
> - else
> - cdev->userflags &= ~userflags;
> - mutex_unlock(&cdev->lock);
> - return 0;
> - }
> - case CAPI_GET_FLAGS:
> - if (copy_to_user(argp, &cdev->userflags,
> - sizeof(cdev->userflags)))
> - return -EFAULT;
> - return 0;
> -
> -#ifndef CONFIG_ISDN_CAPI_MIDDLEWARE
> - case CAPI_NCCI_OPENCOUNT:
> - return 0;
> -
> -#else /* CONFIG_ISDN_CAPI_MIDDLEWARE */
> - case CAPI_NCCI_OPENCOUNT: {
> - struct capincci *nccip;
> - unsigned ncci;
> - int count = 0;
> -
> - if (copy_from_user(&ncci, argp, sizeof(ncci)))
> - return -EFAULT;
> -
> - mutex_lock(&cdev->lock);
> - nccip = capincci_find(cdev, (u32)ncci);
> - if (nccip)
> - count = capincci_minor_opencount(nccip);
> - mutex_unlock(&cdev->lock);
> - return count;
> - }
> -
> - case CAPI_NCCI_GETUNIT: {
> - struct capincci *nccip;
> - struct capiminor *mp;
> - unsigned ncci;
> - int unit = -ESRCH;
> -
> - if (copy_from_user(&ncci, argp, sizeof(ncci)))
> - return -EFAULT;
> -
> - mutex_lock(&cdev->lock);
> - nccip = capincci_find(cdev, (u32)ncci);
> - if (nccip) {
> - mp = nccip->minorp;
> - if (mp)
> - unit = mp->minor;
> - }
> - mutex_unlock(&cdev->lock);
> - return unit;
> - }
> -#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
> -
> - default:
> - return -EINVAL;
> - }
> -}
> -
> -static long
> -capi_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
> -{
> - int ret;
> -
> - mutex_lock(&capi_mutex);
> - ret = capi_ioctl(file, cmd, arg);
> - mutex_unlock(&capi_mutex);
> -
> - return ret;
> -}
> -
> -#ifdef CONFIG_COMPAT
> -static long
> -capi_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
> -{
> - int ret;
> -
> - if (cmd == CAPI_MANUFACTURER_CMD) {
> - struct {
> - compat_ulong_t cmd;
> - compat_uptr_t data;
> - } mcmd32;
> -
> - if (!capable(CAP_SYS_ADMIN))
> - return -EPERM;
> - if (copy_from_user(&mcmd32, compat_ptr(arg), sizeof(mcmd32)))
> - return -EFAULT;
> -
> - mutex_lock(&capi_mutex);
> - ret = capi20_manufacturer(mcmd32.cmd, compat_ptr(mcmd32.data));
> - mutex_unlock(&capi_mutex);
> -
> - return ret;
> - }
> -
> - return capi_unlocked_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
> -}
> -#endif
> -
> -static int capi_open(struct inode *inode, struct file *file)
> -{
> - struct capidev *cdev;
> -
> - cdev = kzalloc_obj(*cdev);
> - if (!cdev)
> - return -ENOMEM;
> -
> - mutex_init(&cdev->lock);
> - skb_queue_head_init(&cdev->recvqueue);
> - init_waitqueue_head(&cdev->recvwait);
> - INIT_LIST_HEAD(&cdev->nccis);
> - file->private_data = cdev;
> -
> - mutex_lock(&capidev_list_lock);
> - list_add_tail(&cdev->list, &capidev_list);
> - mutex_unlock(&capidev_list_lock);
> -
> - return stream_open(inode, file);
> -}
> -
> -static int capi_release(struct inode *inode, struct file *file)
> -{
> - struct capidev *cdev = file->private_data;
> -
> - mutex_lock(&capidev_list_lock);
> - list_del(&cdev->list);
> - mutex_unlock(&capidev_list_lock);
> -
> - if (cdev->ap.applid)
> - capi20_release(&cdev->ap);
> - skb_queue_purge(&cdev->recvqueue);
> - capincci_free(cdev, 0xffffffff);
> -
> - kfree(cdev);
> - return 0;
> -}
> -
> -static const struct file_operations capi_fops =
> -{
> - .owner = THIS_MODULE,
> - .read = capi_read,
> - .write = capi_write,
> - .poll = capi_poll,
> - .unlocked_ioctl = capi_unlocked_ioctl,
> -#ifdef CONFIG_COMPAT
> - .compat_ioctl = capi_compat_ioctl,
> -#endif
> - .open = capi_open,
> - .release = capi_release,
> -};
> -
> -#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
> -/* -------- tty_operations for capincci ----------------------------- */
> -
> -static int
> -capinc_tty_install(struct tty_driver *driver, struct tty_struct *tty)
> -{
> - struct capiminor *mp = capiminor_get(tty->index);
> - int ret = tty_standard_install(driver, tty);
> -
> - if (ret == 0)
> - tty->driver_data = mp;
> - else
> - capiminor_put(mp);
> - return ret;
> -}
> -
> -static void capinc_tty_cleanup(struct tty_struct *tty)
> -{
> - struct capiminor *mp = tty->driver_data;
> - tty->driver_data = NULL;
> - capiminor_put(mp);
> -}
> -
> -static int capinc_tty_open(struct tty_struct *tty, struct file *filp)
> -{
> - struct capiminor *mp = tty->driver_data;
> - int err;
> -
> - err = tty_port_open(&mp->port, tty, filp);
> - if (err)
> - return err;
> -
> - handle_minor_recv(mp);
> - return 0;
> -}
> -
> -static void capinc_tty_close(struct tty_struct *tty, struct file *filp)
> -{
> - struct capiminor *mp = tty->driver_data;
> -
> - tty_port_close(&mp->port, tty, filp);
> -}
> -
> -static ssize_t capinc_tty_write(struct tty_struct *tty, const u8 *buf,
> - size_t count)
> -{
> - struct capiminor *mp = tty->driver_data;
> - struct sk_buff *skb;
> -
> - pr_debug("capinc_tty_write(count=%zu)\n", count);
> -
> - spin_lock_bh(&mp->outlock);
> - skb = mp->outskb;
> - if (skb) {
> - mp->outskb = NULL;
> - __skb_queue_tail(&mp->outqueue, skb);
> - mp->outbytes += skb->len;
> - }
> -
> - skb = alloc_skb(CAPI_DATA_B3_REQ_LEN + count, GFP_ATOMIC);
> - if (!skb) {
> - printk(KERN_ERR "capinc_tty_write: alloc_skb failed\n");
> - spin_unlock_bh(&mp->outlock);
> - return -ENOMEM;
> - }
> -
> - skb_reserve(skb, CAPI_DATA_B3_REQ_LEN);
> - skb_put_data(skb, buf, count);
> -
> - __skb_queue_tail(&mp->outqueue, skb);
> - mp->outbytes += skb->len;
> - spin_unlock_bh(&mp->outlock);
> -
> - handle_minor_send(mp);
> -
> - return count;
> -}
> -
> -static int capinc_tty_put_char(struct tty_struct *tty, u8 ch)
> -{
> - struct capiminor *mp = tty->driver_data;
> - bool invoke_send = false;
> - struct sk_buff *skb;
> - int ret = 1;
> -
> - pr_debug("capinc_put_char(%u)\n", ch);
> -
> - spin_lock_bh(&mp->outlock);
> - skb = mp->outskb;
> - if (skb) {
> - if (skb_tailroom(skb) > 0) {
> - skb_put_u8(skb, ch);
> - goto unlock_out;
> - }
> - mp->outskb = NULL;
> - __skb_queue_tail(&mp->outqueue, skb);
> - mp->outbytes += skb->len;
> - invoke_send = true;
> - }
> -
> - skb = alloc_skb(CAPI_DATA_B3_REQ_LEN + CAPI_MAX_BLKSIZE, GFP_ATOMIC);
> - if (skb) {
> - skb_reserve(skb, CAPI_DATA_B3_REQ_LEN);
> - skb_put_u8(skb, ch);
> - mp->outskb = skb;
> - } else {
> - printk(KERN_ERR "capinc_put_char: char %u lost\n", ch);
> - ret = 0;
> - }
> -
> -unlock_out:
> - spin_unlock_bh(&mp->outlock);
> -
> - if (invoke_send)
> - handle_minor_send(mp);
> -
> - return ret;
> -}
> -
> -static void capinc_tty_flush_chars(struct tty_struct *tty)
> -{
> - struct capiminor *mp = tty->driver_data;
> - struct sk_buff *skb;
> -
> - spin_lock_bh(&mp->outlock);
> - skb = mp->outskb;
> - if (skb) {
> - mp->outskb = NULL;
> - __skb_queue_tail(&mp->outqueue, skb);
> - mp->outbytes += skb->len;
> - spin_unlock_bh(&mp->outlock);
> -
> - handle_minor_send(mp);
> - } else
> - spin_unlock_bh(&mp->outlock);
> -
> - handle_minor_recv(mp);
> -}
> -
> -static unsigned int capinc_tty_write_room(struct tty_struct *tty)
> -{
> - struct capiminor *mp = tty->driver_data;
> - unsigned int room;
> -
> - room = CAPINC_MAX_SENDQUEUE-skb_queue_len(&mp->outqueue);
> - room *= CAPI_MAX_BLKSIZE;
> - pr_debug("capinc_tty_write_room = %u\n", room);
> - return room;
> -}
> -
> -static unsigned int capinc_tty_chars_in_buffer(struct tty_struct *tty)
> -{
> - struct capiminor *mp = tty->driver_data;
> -
> - pr_debug("capinc_tty_chars_in_buffer = %d nack=%d sq=%d rq=%d\n",
> - mp->outbytes, mp->nack,
> - skb_queue_len(&mp->outqueue),
> - skb_queue_len(&mp->inqueue));
> - return mp->outbytes;
> -}
> -
> -static void capinc_tty_throttle(struct tty_struct *tty)
> -{
> - struct capiminor *mp = tty->driver_data;
> - mp->ttyinstop = 1;
> -}
> -
> -static void capinc_tty_unthrottle(struct tty_struct *tty)
> -{
> - struct capiminor *mp = tty->driver_data;
> -
> - mp->ttyinstop = 0;
> - handle_minor_recv(mp);
> -}
> -
> -static void capinc_tty_stop(struct tty_struct *tty)
> -{
> - struct capiminor *mp = tty->driver_data;
> -
> - mp->ttyoutstop = 1;
> -}
> -
> -static void capinc_tty_start(struct tty_struct *tty)
> -{
> - struct capiminor *mp = tty->driver_data;
> -
> - mp->ttyoutstop = 0;
> - handle_minor_send(mp);
> -}
> -
> -static void capinc_tty_hangup(struct tty_struct *tty)
> -{
> - struct capiminor *mp = tty->driver_data;
> -
> - tty_port_hangup(&mp->port);
> -}
> -
> -static void capinc_tty_send_xchar(struct tty_struct *tty, u8 ch)
> -{
> - pr_debug("capinc_tty_send_xchar(%u)\n", ch);
> -}
> -
> -static const struct tty_operations capinc_ops = {
> - .open = capinc_tty_open,
> - .close = capinc_tty_close,
> - .write = capinc_tty_write,
> - .put_char = capinc_tty_put_char,
> - .flush_chars = capinc_tty_flush_chars,
> - .write_room = capinc_tty_write_room,
> - .chars_in_buffer = capinc_tty_chars_in_buffer,
> - .throttle = capinc_tty_throttle,
> - .unthrottle = capinc_tty_unthrottle,
> - .stop = capinc_tty_stop,
> - .start = capinc_tty_start,
> - .hangup = capinc_tty_hangup,
> - .send_xchar = capinc_tty_send_xchar,
> - .install = capinc_tty_install,
> - .cleanup = capinc_tty_cleanup,
> -};
> -
> -static int __init capinc_tty_init(void)
> -{
> - struct tty_driver *drv;
> - int err;
> -
> - if (capi_ttyminors > CAPINC_MAX_PORTS)
> - capi_ttyminors = CAPINC_MAX_PORTS;
> - if (capi_ttyminors <= 0)
> - capi_ttyminors = CAPINC_NR_PORTS;
> -
> - capiminors = kzalloc_objs(struct capiminor *, capi_ttyminors);
> - if (!capiminors)
> - return -ENOMEM;
> -
> - drv = tty_alloc_driver(capi_ttyminors, TTY_DRIVER_REAL_RAW |
> - TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_DYNAMIC_DEV);
> - if (IS_ERR(drv)) {
> - kfree(capiminors);
> - return PTR_ERR(drv);
> - }
> - drv->driver_name = "capi_nc";
> - drv->name = "capi!";
> - drv->major = 0;
> - drv->minor_start = 0;
> - drv->type = TTY_DRIVER_TYPE_SERIAL;
> - drv->subtype = SERIAL_TYPE_NORMAL;
> - drv->init_termios = tty_std_termios;
> - drv->init_termios.c_iflag = ICRNL;
> - drv->init_termios.c_oflag = OPOST | ONLCR;
> - drv->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
> - drv->init_termios.c_lflag = 0;
> - tty_set_operations(drv, &capinc_ops);
> -
> - err = tty_register_driver(drv);
> - if (err) {
> - tty_driver_kref_put(drv);
> - kfree(capiminors);
> - printk(KERN_ERR "Couldn't register capi_nc driver\n");
> - return err;
> - }
> - capinc_tty_driver = drv;
> - return 0;
> -}
> -
> -static void __exit capinc_tty_exit(void)
> -{
> - tty_unregister_driver(capinc_tty_driver);
> - tty_driver_kref_put(capinc_tty_driver);
> - kfree(capiminors);
> -}
> -
> -#else /* !CONFIG_ISDN_CAPI_MIDDLEWARE */
> -
> -static inline int capinc_tty_init(void)
> -{
> - return 0;
> -}
> -
> -static inline void capinc_tty_exit(void) { }
> -
> -#endif /* !CONFIG_ISDN_CAPI_MIDDLEWARE */
> -
> -/* -------- /proc functions ----------------------------------------- */
> -
> -/*
> - * /proc/capi/capi20:
> - * minor applid nrecvctlpkt nrecvdatapkt nsendctlpkt nsenddatapkt
> - */
> -static int __maybe_unused capi20_proc_show(struct seq_file *m, void *v)
> -{
> - struct capidev *cdev;
> - struct list_head *l;
> -
> - mutex_lock(&capidev_list_lock);
> - list_for_each(l, &capidev_list) {
> - cdev = list_entry(l, struct capidev, list);
> - seq_printf(m, "0 %d %lu %lu %lu %lu\n",
> - cdev->ap.applid,
> - cdev->ap.nrecvctlpkt,
> - cdev->ap.nrecvdatapkt,
> - cdev->ap.nsentctlpkt,
> - cdev->ap.nsentdatapkt);
> - }
> - mutex_unlock(&capidev_list_lock);
> - return 0;
> -}
> -
> -/*
> - * /proc/capi/capi20ncci:
> - * applid ncci
> - */
> -static int __maybe_unused capi20ncci_proc_show(struct seq_file *m, void *v)
> -{
> - struct capidev *cdev;
> - struct capincci *np;
> -
> - mutex_lock(&capidev_list_lock);
> - list_for_each_entry(cdev, &capidev_list, list) {
> - mutex_lock(&cdev->lock);
> - list_for_each_entry(np, &cdev->nccis, list)
> - seq_printf(m, "%d 0x%x\n", cdev->ap.applid, np->ncci);
> - mutex_unlock(&cdev->lock);
> - }
> - mutex_unlock(&capidev_list_lock);
> - return 0;
> -}
> -
> -static void __init proc_init(void)
> -{
> - proc_create_single("capi/capi20", 0, NULL, capi20_proc_show);
> - proc_create_single("capi/capi20ncci", 0, NULL, capi20ncci_proc_show);
> -}
> -
> -static void __exit proc_exit(void)
> -{
> - remove_proc_entry("capi/capi20", NULL);
> - remove_proc_entry("capi/capi20ncci", NULL);
> -}
> -
> -/* -------- init function and module interface ---------------------- */
> -
> -
> -static int __init capi_init(void)
> -{
> - const char *compileinfo;
> - int major_ret;
> - int ret;
> -
> - ret = kcapi_init();
> - if (ret)
> - return ret;
> -
> - major_ret = register_chrdev(capi_major, "capi20", &capi_fops);
> - if (major_ret < 0) {
> - printk(KERN_ERR "capi20: unable to get major %d\n", capi_major);
> - kcapi_exit();
> - return major_ret;
> - }
> -
> - ret = class_register(&capi_class);
> - if (ret) {
> - unregister_chrdev(capi_major, "capi20");
> - kcapi_exit();
> - return ret;
> - }
> -
> - device_create(&capi_class, NULL, MKDEV(capi_major, 0), NULL, "capi20");
> -
> - if (capinc_tty_init() < 0) {
> - device_destroy(&capi_class, MKDEV(capi_major, 0));
> - class_unregister(&capi_class);
> - unregister_chrdev(capi_major, "capi20");
> - kcapi_exit();
> - return -ENOMEM;
> - }
> -
> - proc_init();
> -
> -#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
> - compileinfo = " (middleware)";
> -#else
> - compileinfo = " (no middleware)";
> -#endif
> - printk(KERN_NOTICE "CAPI 2.0 started up with major %d%s\n",
> - capi_major, compileinfo);
> -
> - return 0;
> -}
> -
> -static void __exit capi_exit(void)
> -{
> - proc_exit();
> -
> - device_destroy(&capi_class, MKDEV(capi_major, 0));
> - class_unregister(&capi_class);
> - unregister_chrdev(capi_major, "capi20");
> -
> - capinc_tty_exit();
> -
> - kcapi_exit();
> -}
> -
> -module_init(capi_init);
> -module_exit(capi_exit);
> diff --git a/drivers/isdn/capi/capiutil.c b/drivers/isdn/capi/capiutil.c
> deleted file mode 100644
> index eec9b36343b7..000000000000
> --- a/drivers/isdn/capi/capiutil.c
> +++ /dev/null
> @@ -1,677 +0,0 @@
> -/* $Id: capiutil.c,v 1.13.6.4 2001/09/23 22:24:33 kai Exp $
> - *
> - * CAPI 2.0 convert capi message to capi message struct
> - *
> - * From CAPI 2.0 Development Kit AVM 1995 (msg.c)
> - * Rewritten for Linux 1996 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/module.h>
> -#include <linux/string.h>
> -#include <linux/ctype.h>
> -#include <linux/stddef.h>
> -#include <linux/kernel.h>
> -#include <linux/mm.h>
> -#include <linux/init.h>
> -#include <linux/isdn/capiutil.h>
> -#include <linux/slab.h>
> -
> -#include "kcapi.h"
> -
> -/* from CAPI2.0 DDK AVM Berlin GmbH */
> -
> -typedef struct {
> - int typ;
> - size_t off;
> -} _cdef;
> -
> -#define _CBYTE 1
> -#define _CWORD 2
> -#define _CDWORD 3
> -#define _CSTRUCT 4
> -#define _CMSTRUCT 5
> -#define _CEND 6
> -
> -static _cdef cdef[] =
> -{
> - /*00 */
> - {_CEND},
> - /*01 */
> - {_CEND},
> - /*02 */
> - {_CEND},
> - /*03 */
> - {_CDWORD, offsetof(_cmsg, adr.adrController)},
> - /*04 */
> - {_CMSTRUCT, offsetof(_cmsg, AdditionalInfo)},
> - /*05 */
> - {_CSTRUCT, offsetof(_cmsg, B1configuration)},
> - /*06 */
> - {_CWORD, offsetof(_cmsg, B1protocol)},
> - /*07 */
> - {_CSTRUCT, offsetof(_cmsg, B2configuration)},
> - /*08 */
> - {_CWORD, offsetof(_cmsg, B2protocol)},
> - /*09 */
> - {_CSTRUCT, offsetof(_cmsg, B3configuration)},
> - /*0a */
> - {_CWORD, offsetof(_cmsg, B3protocol)},
> - /*0b */
> - {_CSTRUCT, offsetof(_cmsg, BC)},
> - /*0c */
> - {_CSTRUCT, offsetof(_cmsg, BChannelinformation)},
> - /*0d */
> - {_CMSTRUCT, offsetof(_cmsg, BProtocol)},
> - /*0e */
> - {_CSTRUCT, offsetof(_cmsg, CalledPartyNumber)},
> - /*0f */
> - {_CSTRUCT, offsetof(_cmsg, CalledPartySubaddress)},
> - /*10 */
> - {_CSTRUCT, offsetof(_cmsg, CallingPartyNumber)},
> - /*11 */
> - {_CSTRUCT, offsetof(_cmsg, CallingPartySubaddress)},
> - /*12 */
> - {_CDWORD, offsetof(_cmsg, CIPmask)},
> - /*13 */
> - {_CDWORD, offsetof(_cmsg, CIPmask2)},
> - /*14 */
> - {_CWORD, offsetof(_cmsg, CIPValue)},
> - /*15 */
> - {_CDWORD, offsetof(_cmsg, Class)},
> - /*16 */
> - {_CSTRUCT, offsetof(_cmsg, ConnectedNumber)},
> - /*17 */
> - {_CSTRUCT, offsetof(_cmsg, ConnectedSubaddress)},
> - /*18 */
> - {_CDWORD, offsetof(_cmsg, Data)},
> - /*19 */
> - {_CWORD, offsetof(_cmsg, DataHandle)},
> - /*1a */
> - {_CWORD, offsetof(_cmsg, DataLength)},
> - /*1b */
> - {_CSTRUCT, offsetof(_cmsg, FacilityConfirmationParameter)},
> - /*1c */
> - {_CSTRUCT, offsetof(_cmsg, Facilitydataarray)},
> - /*1d */
> - {_CSTRUCT, offsetof(_cmsg, FacilityIndicationParameter)},
> - /*1e */
> - {_CSTRUCT, offsetof(_cmsg, FacilityRequestParameter)},
> - /*1f */
> - {_CWORD, offsetof(_cmsg, FacilitySelector)},
> - /*20 */
> - {_CWORD, offsetof(_cmsg, Flags)},
> - /*21 */
> - {_CDWORD, offsetof(_cmsg, Function)},
> - /*22 */
> - {_CSTRUCT, offsetof(_cmsg, HLC)},
> - /*23 */
> - {_CWORD, offsetof(_cmsg, Info)},
> - /*24 */
> - {_CSTRUCT, offsetof(_cmsg, InfoElement)},
> - /*25 */
> - {_CDWORD, offsetof(_cmsg, InfoMask)},
> - /*26 */
> - {_CWORD, offsetof(_cmsg, InfoNumber)},
> - /*27 */
> - {_CSTRUCT, offsetof(_cmsg, Keypadfacility)},
> - /*28 */
> - {_CSTRUCT, offsetof(_cmsg, LLC)},
> - /*29 */
> - {_CSTRUCT, offsetof(_cmsg, ManuData)},
> - /*2a */
> - {_CDWORD, offsetof(_cmsg, ManuID)},
> - /*2b */
> - {_CSTRUCT, offsetof(_cmsg, NCPI)},
> - /*2c */
> - {_CWORD, offsetof(_cmsg, Reason)},
> - /*2d */
> - {_CWORD, offsetof(_cmsg, Reason_B3)},
> - /*2e */
> - {_CWORD, offsetof(_cmsg, Reject)},
> - /*2f */
> - {_CSTRUCT, offsetof(_cmsg, Useruserdata)}
> -};
> -
> -static unsigned char *cpars[] =
> -{
> - /* ALERT_REQ */ [0x01] = "\x03\x04\x0c\x27\x2f\x1c\x01\x01",
> - /* CONNECT_REQ */ [0x02] = "\x03\x14\x0e\x10\x0f\x11\x0d\x06\x08\x0a\x05\x07\x09\x01\x0b\x28\x22\x04\x0c\x27\x2f\x1c\x01\x01",
> - /* DISCONNECT_REQ */ [0x04] = "\x03\x04\x0c\x27\x2f\x1c\x01\x01",
> - /* LISTEN_REQ */ [0x05] = "\x03\x25\x12\x13\x10\x11\x01",
> - /* INFO_REQ */ [0x08] = "\x03\x0e\x04\x0c\x27\x2f\x1c\x01\x01",
> - /* FACILITY_REQ */ [0x09] = "\x03\x1f\x1e\x01",
> - /* SELECT_B_PROTOCOL_REQ */ [0x0a] = "\x03\x0d\x06\x08\x0a\x05\x07\x09\x01\x01",
> - /* CONNECT_B3_REQ */ [0x0b] = "\x03\x2b\x01",
> - /* DISCONNECT_B3_REQ */ [0x0d] = "\x03\x2b\x01",
> - /* DATA_B3_REQ */ [0x0f] = "\x03\x18\x1a\x19\x20\x01",
> - /* RESET_B3_REQ */ [0x10] = "\x03\x2b\x01",
> - /* ALERT_CONF */ [0x13] = "\x03\x23\x01",
> - /* CONNECT_CONF */ [0x14] = "\x03\x23\x01",
> - /* DISCONNECT_CONF */ [0x16] = "\x03\x23\x01",
> - /* LISTEN_CONF */ [0x17] = "\x03\x23\x01",
> - /* MANUFACTURER_REQ */ [0x18] = "\x03\x2a\x15\x21\x29\x01",
> - /* INFO_CONF */ [0x1a] = "\x03\x23\x01",
> - /* FACILITY_CONF */ [0x1b] = "\x03\x23\x1f\x1b\x01",
> - /* SELECT_B_PROTOCOL_CONF */ [0x1c] = "\x03\x23\x01",
> - /* CONNECT_B3_CONF */ [0x1d] = "\x03\x23\x01",
> - /* DISCONNECT_B3_CONF */ [0x1f] = "\x03\x23\x01",
> - /* DATA_B3_CONF */ [0x21] = "\x03\x19\x23\x01",
> - /* RESET_B3_CONF */ [0x22] = "\x03\x23\x01",
> - /* CONNECT_IND */ [0x26] = "\x03\x14\x0e\x10\x0f\x11\x0b\x28\x22\x04\x0c\x27\x2f\x1c\x01\x01",
> - /* CONNECT_ACTIVE_IND */ [0x27] = "\x03\x16\x17\x28\x01",
> - /* DISCONNECT_IND */ [0x28] = "\x03\x2c\x01",
> - /* MANUFACTURER_CONF */ [0x2a] = "\x03\x2a\x15\x21\x29\x01",
> - /* INFO_IND */ [0x2c] = "\x03\x26\x24\x01",
> - /* FACILITY_IND */ [0x2d] = "\x03\x1f\x1d\x01",
> - /* CONNECT_B3_IND */ [0x2f] = "\x03\x2b\x01",
> - /* CONNECT_B3_ACTIVE_IND */ [0x30] = "\x03\x2b\x01",
> - /* DISCONNECT_B3_IND */ [0x31] = "\x03\x2d\x2b\x01",
> - /* DATA_B3_IND */ [0x33] = "\x03\x18\x1a\x19\x20\x01",
> - /* RESET_B3_IND */ [0x34] = "\x03\x2b\x01",
> - /* CONNECT_B3_T90_ACTIVE_IND */ [0x35] = "\x03\x2b\x01",
> - /* CONNECT_RESP */ [0x38] = "\x03\x2e\x0d\x06\x08\x0a\x05\x07\x09\x01\x16\x17\x28\x04\x0c\x27\x2f\x1c\x01\x01",
> - /* CONNECT_ACTIVE_RESP */ [0x39] = "\x03\x01",
> - /* DISCONNECT_RESP */ [0x3a] = "\x03\x01",
> - /* MANUFACTURER_IND */ [0x3c] = "\x03\x2a\x15\x21\x29\x01",
> - /* INFO_RESP */ [0x3e] = "\x03\x01",
> - /* FACILITY_RESP */ [0x3f] = "\x03\x1f\x01",
> - /* CONNECT_B3_RESP */ [0x41] = "\x03\x2e\x2b\x01",
> - /* CONNECT_B3_ACTIVE_RESP */ [0x42] = "\x03\x01",
> - /* DISCONNECT_B3_RESP */ [0x43] = "\x03\x01",
> - /* DATA_B3_RESP */ [0x45] = "\x03\x19\x01",
> - /* RESET_B3_RESP */ [0x46] = "\x03\x01",
> - /* CONNECT_B3_T90_ACTIVE_RESP */ [0x47] = "\x03\x01",
> - /* MANUFACTURER_RESP */ [0x4e] = "\x03\x2a\x15\x21\x29\x01",
> -};
> -
> -/*-------------------------------------------------------*/
> -
> -#define byteTLcpy(x, y) *(u8 *)(x) = *(u8 *)(y);
> -#define wordTLcpy(x, y) *(u16 *)(x) = *(u16 *)(y);
> -#define dwordTLcpy(x, y) memcpy(x, y, 4);
> -#define structTLcpy(x, y, l) memcpy(x, y, l)
> -#define structTLcpyovl(x, y, l) memmove(x, y, l)
> -
> -#define byteTRcpy(x, y) *(u8 *)(y) = *(u8 *)(x);
> -#define wordTRcpy(x, y) *(u16 *)(y) = *(u16 *)(x);
> -#define dwordTRcpy(x, y) memcpy(y, x, 4);
> -#define structTRcpy(x, y, l) memcpy(y, x, l)
> -#define structTRcpyovl(x, y, l) memmove(y, x, l)
> -
> -/*-------------------------------------------------------*/
> -static unsigned command_2_index(u8 c, u8 sc)
> -{
> - if (c & 0x80)
> - c = 0x9 + (c & 0x0f);
> - else if (c == 0x41)
> - c = 0x9 + 0x1;
> - if (c > 0x18)
> - c = 0x00;
> - return (sc & 3) * (0x9 + 0x9) + c;
> -}
> -
> -/**
> - * capi_cmd2par() - find parameter string for CAPI 2.0 command/subcommand
> - * @cmd: command number
> - * @subcmd: subcommand number
> - *
> - * Return value: static string, NULL if command/subcommand unknown
> - */
> -
> -static unsigned char *capi_cmd2par(u8 cmd, u8 subcmd)
> -{
> - return cpars[command_2_index(cmd, subcmd)];
> -}
> -
> -/*-------------------------------------------------------*/
> -#define TYP (cdef[cmsg->par[cmsg->p]].typ)
> -#define OFF (((u8 *)cmsg) + cdef[cmsg->par[cmsg->p]].off)
> -
> -static void jumpcstruct(_cmsg *cmsg)
> -{
> - unsigned layer;
> - for (cmsg->p++, layer = 1; layer;) {
> - /* $$$$$ assert (cmsg->p); */
> - cmsg->p++;
> - switch (TYP) {
> - case _CMSTRUCT:
> - layer++;
> - break;
> - case _CEND:
> - layer--;
> - break;
> - }
> - }
> -}
> -
> -/*-------------------------------------------------------*/
> -
> -static char *mnames[] =
> -{
> - [0x01] = "ALERT_REQ",
> - [0x02] = "CONNECT_REQ",
> - [0x04] = "DISCONNECT_REQ",
> - [0x05] = "LISTEN_REQ",
> - [0x08] = "INFO_REQ",
> - [0x09] = "FACILITY_REQ",
> - [0x0a] = "SELECT_B_PROTOCOL_REQ",
> - [0x0b] = "CONNECT_B3_REQ",
> - [0x0d] = "DISCONNECT_B3_REQ",
> - [0x0f] = "DATA_B3_REQ",
> - [0x10] = "RESET_B3_REQ",
> - [0x13] = "ALERT_CONF",
> - [0x14] = "CONNECT_CONF",
> - [0x16] = "DISCONNECT_CONF",
> - [0x17] = "LISTEN_CONF",
> - [0x18] = "MANUFACTURER_REQ",
> - [0x1a] = "INFO_CONF",
> - [0x1b] = "FACILITY_CONF",
> - [0x1c] = "SELECT_B_PROTOCOL_CONF",
> - [0x1d] = "CONNECT_B3_CONF",
> - [0x1f] = "DISCONNECT_B3_CONF",
> - [0x21] = "DATA_B3_CONF",
> - [0x22] = "RESET_B3_CONF",
> - [0x26] = "CONNECT_IND",
> - [0x27] = "CONNECT_ACTIVE_IND",
> - [0x28] = "DISCONNECT_IND",
> - [0x2a] = "MANUFACTURER_CONF",
> - [0x2c] = "INFO_IND",
> - [0x2d] = "FACILITY_IND",
> - [0x2f] = "CONNECT_B3_IND",
> - [0x30] = "CONNECT_B3_ACTIVE_IND",
> - [0x31] = "DISCONNECT_B3_IND",
> - [0x33] = "DATA_B3_IND",
> - [0x34] = "RESET_B3_IND",
> - [0x35] = "CONNECT_B3_T90_ACTIVE_IND",
> - [0x38] = "CONNECT_RESP",
> - [0x39] = "CONNECT_ACTIVE_RESP",
> - [0x3a] = "DISCONNECT_RESP",
> - [0x3c] = "MANUFACTURER_IND",
> - [0x3e] = "INFO_RESP",
> - [0x3f] = "FACILITY_RESP",
> - [0x41] = "CONNECT_B3_RESP",
> - [0x42] = "CONNECT_B3_ACTIVE_RESP",
> - [0x43] = "DISCONNECT_B3_RESP",
> - [0x45] = "DATA_B3_RESP",
> - [0x46] = "RESET_B3_RESP",
> - [0x47] = "CONNECT_B3_T90_ACTIVE_RESP",
> - [0x4e] = "MANUFACTURER_RESP"
> -};
> -
> -/**
> - * capi_cmd2str() - convert CAPI 2.0 command/subcommand number to name
> - * @cmd: command number
> - * @subcmd: subcommand number
> - *
> - * Return value: static string
> - */
> -
> -char *capi_cmd2str(u8 cmd, u8 subcmd)
> -{
> - char *result;
> -
> - result = mnames[command_2_index(cmd, subcmd)];
> - if (result == NULL)
> - result = "INVALID_COMMAND";
> - return result;
> -}
> -
> -
> -/*-------------------------------------------------------*/
> -
> -#ifdef CONFIG_CAPI_TRACE
> -
> -/*-------------------------------------------------------*/
> -
> -static char *pnames[] =
> -{
> - /*00 */ NULL,
> - /*01 */ NULL,
> - /*02 */ NULL,
> - /*03 */ "Controller/PLCI/NCCI",
> - /*04 */ "AdditionalInfo",
> - /*05 */ "B1configuration",
> - /*06 */ "B1protocol",
> - /*07 */ "B2configuration",
> - /*08 */ "B2protocol",
> - /*09 */ "B3configuration",
> - /*0a */ "B3protocol",
> - /*0b */ "BC",
> - /*0c */ "BChannelinformation",
> - /*0d */ "BProtocol",
> - /*0e */ "CalledPartyNumber",
> - /*0f */ "CalledPartySubaddress",
> - /*10 */ "CallingPartyNumber",
> - /*11 */ "CallingPartySubaddress",
> - /*12 */ "CIPmask",
> - /*13 */ "CIPmask2",
> - /*14 */ "CIPValue",
> - /*15 */ "Class",
> - /*16 */ "ConnectedNumber",
> - /*17 */ "ConnectedSubaddress",
> - /*18 */ "Data32",
> - /*19 */ "DataHandle",
> - /*1a */ "DataLength",
> - /*1b */ "FacilityConfirmationParameter",
> - /*1c */ "Facilitydataarray",
> - /*1d */ "FacilityIndicationParameter",
> - /*1e */ "FacilityRequestParameter",
> - /*1f */ "FacilitySelector",
> - /*20 */ "Flags",
> - /*21 */ "Function",
> - /*22 */ "HLC",
> - /*23 */ "Info",
> - /*24 */ "InfoElement",
> - /*25 */ "InfoMask",
> - /*26 */ "InfoNumber",
> - /*27 */ "Keypadfacility",
> - /*28 */ "LLC",
> - /*29 */ "ManuData",
> - /*2a */ "ManuID",
> - /*2b */ "NCPI",
> - /*2c */ "Reason",
> - /*2d */ "Reason_B3",
> - /*2e */ "Reject",
> - /*2f */ "Useruserdata"
> -};
> -
> -#include <linux/stdarg.h>
> -
> -/*-------------------------------------------------------*/
> -static _cdebbuf *bufprint(_cdebbuf *cdb, char *fmt, ...)
> -{
> - va_list f;
> - size_t n, r;
> -
> - if (!cdb)
> - return NULL;
> - va_start(f, fmt);
> - r = cdb->size - cdb->pos;
> - n = vsnprintf(cdb->p, r, fmt, f);
> - va_end(f);
> - if (n >= r) {
> - /* truncated, need bigger buffer */
> - size_t ns = 2 * cdb->size;
> - u_char *nb;
> -
> - while ((ns - cdb->pos) <= n)
> - ns *= 2;
> - nb = kmalloc(ns, GFP_ATOMIC);
> - if (!nb) {
> - cdebbuf_free(cdb);
> - return NULL;
> - }
> - memcpy(nb, cdb->buf, cdb->pos);
> - kfree(cdb->buf);
> - nb[cdb->pos] = 0;
> - cdb->buf = nb;
> - cdb->p = cdb->buf + cdb->pos;
> - cdb->size = ns;
> - va_start(f, fmt);
> - r = cdb->size - cdb->pos;
> - n = vsnprintf(cdb->p, r, fmt, f);
> - va_end(f);
> - }
> - cdb->p += n;
> - cdb->pos += n;
> - return cdb;
> -}
> -
> -static _cdebbuf *printstructlen(_cdebbuf *cdb, u8 *m, unsigned len)
> -{
> - unsigned hex = 0;
> -
> - if (!cdb)
> - return NULL;
> - for (; len; len--, m++)
> - if (isalnum(*m) || *m == ' ') {
> - if (hex)
> - cdb = bufprint(cdb, ">");
> - cdb = bufprint(cdb, "%c", *m);
> - hex = 0;
> - } else {
> - if (!hex)
> - cdb = bufprint(cdb, "<%02x", *m);
> - else
> - cdb = bufprint(cdb, " %02x", *m);
> - hex = 1;
> - }
> - if (hex)
> - cdb = bufprint(cdb, ">");
> - return cdb;
> -}
> -
> -static _cdebbuf *printstruct(_cdebbuf *cdb, u8 *m)
> -{
> - unsigned len;
> -
> - if (m[0] != 0xff) {
> - len = m[0];
> - m += 1;
> - } else {
> - len = ((u16 *) (m + 1))[0];
> - m += 3;
> - }
> - cdb = printstructlen(cdb, m, len);
> - return cdb;
> -}
> -
> -/*-------------------------------------------------------*/
> -#define NAME (pnames[cmsg->par[cmsg->p]])
> -
> -static _cdebbuf *protocol_message_2_pars(_cdebbuf *cdb, _cmsg *cmsg, int level)
> -{
> - if (!cmsg->par)
> - return NULL; /* invalid command/subcommand */
> -
> - for (; TYP != _CEND; cmsg->p++) {
> - int slen = 29 + 3 - level;
> - int i;
> -
> - if (!cdb)
> - return NULL;
> - cdb = bufprint(cdb, " ");
> - for (i = 0; i < level - 1; i++)
> - cdb = bufprint(cdb, " ");
> -
> - switch (TYP) {
> - case _CBYTE:
> - cdb = bufprint(cdb, "%-*s = 0x%x\n", slen, NAME, *(u8 *) (cmsg->m + cmsg->l));
> - cmsg->l++;
> - break;
> - case _CWORD:
> - cdb = bufprint(cdb, "%-*s = 0x%x\n", slen, NAME, *(u16 *) (cmsg->m + cmsg->l));
> - cmsg->l += 2;
> - break;
> - case _CDWORD:
> - cdb = bufprint(cdb, "%-*s = 0x%lx\n", slen, NAME, *(u32 *) (cmsg->m + cmsg->l));
> - cmsg->l += 4;
> - break;
> - case _CSTRUCT:
> - cdb = bufprint(cdb, "%-*s = ", slen, NAME);
> - if (cmsg->m[cmsg->l] == '\0')
> - cdb = bufprint(cdb, "default");
> - else
> - cdb = printstruct(cdb, cmsg->m + cmsg->l);
> - cdb = bufprint(cdb, "\n");
> - if (cmsg->m[cmsg->l] != 0xff)
> - cmsg->l += 1 + cmsg->m[cmsg->l];
> - else
> - cmsg->l += 3 + *(u16 *) (cmsg->m + cmsg->l + 1);
> -
> - break;
> -
> - case _CMSTRUCT:
> -/*----- Metastruktur 0 -----*/
> - if (cmsg->m[cmsg->l] == '\0') {
> - cdb = bufprint(cdb, "%-*s = default\n", slen, NAME);
> - cmsg->l++;
> - jumpcstruct(cmsg);
> - } else {
> - char *name = NAME;
> - unsigned _l = cmsg->l;
> - cdb = bufprint(cdb, "%-*s\n", slen, name);
> - cmsg->l = (cmsg->m + _l)[0] == 255 ? cmsg->l + 3 : cmsg->l + 1;
> - cmsg->p++;
> - cdb = protocol_message_2_pars(cdb, cmsg, level + 1);
> - }
> - break;
> - }
> - }
> - return cdb;
> -}
> -/*-------------------------------------------------------*/
> -
> -static _cdebbuf *g_debbuf;
> -static u_long g_debbuf_lock;
> -static _cmsg *g_cmsg;
> -
> -static _cdebbuf *cdebbuf_alloc(void)
> -{
> - _cdebbuf *cdb;
> -
> - if (likely(!test_and_set_bit(1, &g_debbuf_lock))) {
> - cdb = g_debbuf;
> - goto init;
> - } else
> - cdb = kmalloc_obj(_cdebbuf, GFP_ATOMIC);
> - if (!cdb)
> - return NULL;
> - cdb->buf = kmalloc(CDEBUG_SIZE, GFP_ATOMIC);
> - if (!cdb->buf) {
> - kfree(cdb);
> - return NULL;
> - }
> - cdb->size = CDEBUG_SIZE;
> -init:
> - cdb->buf[0] = 0;
> - cdb->p = cdb->buf;
> - cdb->pos = 0;
> - return cdb;
> -}
> -
> -/**
> - * cdebbuf_free() - free CAPI debug buffer
> - * @cdb: buffer to free
> - */
> -
> -void cdebbuf_free(_cdebbuf *cdb)
> -{
> - if (likely(cdb == g_debbuf)) {
> - test_and_clear_bit(1, &g_debbuf_lock);
> - return;
> - }
> - if (likely(cdb))
> - kfree(cdb->buf);
> - kfree(cdb);
> -}
> -
> -
> -/**
> - * capi_message2str() - format CAPI 2.0 message for printing
> - * @msg: CAPI 2.0 message
> - *
> - * Allocates a CAPI debug buffer and fills it with a printable representation
> - * of the CAPI 2.0 message in @msg.
> - * Return value: allocated debug buffer, NULL on error
> - * The returned buffer should be freed by a call to cdebbuf_free() after use.
> - */
> -
> -_cdebbuf *capi_message2str(u8 *msg)
> -{
> - _cdebbuf *cdb;
> - _cmsg *cmsg;
> -
> - cdb = cdebbuf_alloc();
> - if (unlikely(!cdb))
> - return NULL;
> - if (likely(cdb == g_debbuf))
> - cmsg = g_cmsg;
> - else
> - cmsg = kmalloc_obj(_cmsg, GFP_ATOMIC);
> - if (unlikely(!cmsg)) {
> - cdebbuf_free(cdb);
> - return NULL;
> - }
> - cmsg->m = msg;
> - cmsg->l = 8;
> - cmsg->p = 0;
> - byteTRcpy(cmsg->m + 4, &cmsg->Command);
> - byteTRcpy(cmsg->m + 5, &cmsg->Subcommand);
> - cmsg->par = capi_cmd2par(cmsg->Command, cmsg->Subcommand);
> -
> - cdb = bufprint(cdb, "%-26s ID=%03d #0x%04x LEN=%04d\n",
> - capi_cmd2str(cmsg->Command, cmsg->Subcommand),
> - ((unsigned short *) msg)[1],
> - ((unsigned short *) msg)[3],
> - ((unsigned short *) msg)[0]);
> -
> - cdb = protocol_message_2_pars(cdb, cmsg, 1);
> - if (unlikely(cmsg != g_cmsg))
> - kfree(cmsg);
> - return cdb;
> -}
> -
> -int __init cdebug_init(void)
> -{
> - g_cmsg = kmalloc_obj(_cmsg);
> - if (!g_cmsg)
> - return -ENOMEM;
> - g_debbuf = kmalloc_obj(_cdebbuf);
> - if (!g_debbuf) {
> - kfree(g_cmsg);
> - return -ENOMEM;
> - }
> - g_debbuf->buf = kmalloc(CDEBUG_GSIZE, GFP_KERNEL);
> - if (!g_debbuf->buf) {
> - kfree(g_cmsg);
> - kfree(g_debbuf);
> - return -ENOMEM;
> - }
> - g_debbuf->size = CDEBUG_GSIZE;
> - g_debbuf->buf[0] = 0;
> - g_debbuf->p = g_debbuf->buf;
> - g_debbuf->pos = 0;
> - return 0;
> -}
> -
> -void cdebug_exit(void)
> -{
> - if (g_debbuf)
> - kfree(g_debbuf->buf);
> - kfree(g_debbuf);
> - kfree(g_cmsg);
> -}
> -
> -#else /* !CONFIG_CAPI_TRACE */
> -
> -static _cdebbuf g_debbuf = {"CONFIG_CAPI_TRACE not enabled", NULL, 0, 0};
> -
> -_cdebbuf *capi_message2str(u8 *msg)
> -{
> - return &g_debbuf;
> -}
> -
> -_cdebbuf *capi_cmsg2str(_cmsg *cmsg)
> -{
> - return &g_debbuf;
> -}
> -
> -void cdebbuf_free(_cdebbuf *cdb)
> -{
> -}
> -
> -int __init cdebug_init(void)
> -{
> - return 0;
> -}
> -
> -void cdebug_exit(void)
> -{
> -}
> -
> -#endif
> diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c
> deleted file mode 100644
> index f9fa17d68095..000000000000
> --- a/drivers/isdn/capi/kcapi.c
> +++ /dev/null
> @@ -1,933 +0,0 @@
> -/* $Id: kcapi.c,v 1.1.2.8 2004/03/26 19:57:20 armin Exp $
> - *
> - * Kernel CAPI 2.0 Module
> - *
> - * Copyright 1999 by Carsten Paeth <calle@calle.de>
> - * Copyright 2002 by Kai Germaschewski <kai@germaschewski.name>
> - *
> - * This software may be used and distributed according to the terms
> - * of the GNU General Public License, incorporated herein by reference.
> - *
> - */
> -
> -#include "kcapi.h"
> -#include <linux/module.h>
> -#include <linux/mm.h>
> -#include <linux/interrupt.h>
> -#include <linux/ioport.h>
> -#include <linux/proc_fs.h>
> -#include <linux/sched/signal.h>
> -#include <linux/seq_file.h>
> -#include <linux/skbuff.h>
> -#include <linux/workqueue.h>
> -#include <linux/capi.h>
> -#include <linux/kernelcapi.h>
> -#include <linux/init.h>
> -#include <linux/moduleparam.h>
> -#include <linux/delay.h>
> -#include <linux/slab.h>
> -#include <linux/uaccess.h>
> -#include <linux/isdn/capicmd.h>
> -#include <linux/isdn/capiutil.h>
> -#include <linux/mutex.h>
> -#include <linux/rcupdate.h>
> -
> -static int showcapimsgs;
> -static struct workqueue_struct *kcapi_wq;
> -
> -module_param(showcapimsgs, uint, 0);
> -
> -/* ------------------------------------------------------------- */
> -
> -struct capictr_event {
> - struct work_struct work;
> - unsigned int type;
> - u32 controller;
> -};
> -
> -/* ------------------------------------------------------------- */
> -
> -static const struct capi_version driver_version = {2, 0, 1, 1 << 4};
> -static char driver_serial[CAPI_SERIAL_LEN] = "0004711";
> -static char capi_manufakturer[64] = "AVM Berlin";
> -
> -#define NCCI2CTRL(ncci) (((ncci) >> 24) & 0x7f)
> -
> -struct capi_ctr *capi_controller[CAPI_MAXCONTR];
> -DEFINE_MUTEX(capi_controller_lock);
> -
> -struct capi20_appl *capi_applications[CAPI_MAXAPPL];
> -
> -static int ncontrollers;
> -
> -/* -------- controller ref counting -------------------------------------- */
> -
> -static inline struct capi_ctr *
> -capi_ctr_get(struct capi_ctr *ctr)
> -{
> - if (!try_module_get(ctr->owner))
> - return NULL;
> - return ctr;
> -}
> -
> -static inline void
> -capi_ctr_put(struct capi_ctr *ctr)
> -{
> - module_put(ctr->owner);
> -}
> -
> -/* ------------------------------------------------------------- */
> -
> -static inline struct capi_ctr *get_capi_ctr_by_nr(u16 contr)
> -{
> - if (contr < 1 || contr - 1 >= CAPI_MAXCONTR)
> - return NULL;
> -
> - return capi_controller[contr - 1];
> -}
> -
> -static inline struct capi20_appl *__get_capi_appl_by_nr(u16 applid)
> -{
> - lockdep_assert_held(&capi_controller_lock);
> -
> - if (applid < 1 || applid - 1 >= CAPI_MAXAPPL)
> - return NULL;
> -
> - return capi_applications[applid - 1];
> -}
> -
> -static inline struct capi20_appl *get_capi_appl_by_nr(u16 applid)
> -{
> - if (applid < 1 || applid - 1 >= CAPI_MAXAPPL)
> - return NULL;
> -
> - return rcu_dereference(capi_applications[applid - 1]);
> -}
> -
> -/* -------- util functions ------------------------------------ */
> -
> -static inline int capi_cmd_valid(u8 cmd)
> -{
> - switch (cmd) {
> - case CAPI_ALERT:
> - case CAPI_CONNECT:
> - case CAPI_CONNECT_ACTIVE:
> - case CAPI_CONNECT_B3_ACTIVE:
> - case CAPI_CONNECT_B3:
> - case CAPI_CONNECT_B3_T90_ACTIVE:
> - case CAPI_DATA_B3:
> - case CAPI_DISCONNECT_B3:
> - case CAPI_DISCONNECT:
> - case CAPI_FACILITY:
> - case CAPI_INFO:
> - case CAPI_LISTEN:
> - case CAPI_MANUFACTURER:
> - case CAPI_RESET_B3:
> - case CAPI_SELECT_B_PROTOCOL:
> - return 1;
> - }
> - return 0;
> -}
> -
> -static inline int capi_subcmd_valid(u8 subcmd)
> -{
> - switch (subcmd) {
> - case CAPI_REQ:
> - case CAPI_CONF:
> - case CAPI_IND:
> - case CAPI_RESP:
> - return 1;
> - }
> - return 0;
> -}
> -
> -/* ------------------------------------------------------------ */
> -
> -static void
> -register_appl(struct capi_ctr *ctr, u16 applid, capi_register_params *rparam)
> -{
> - ctr = capi_ctr_get(ctr);
> -
> - if (ctr)
> - ctr->register_appl(ctr, applid, rparam);
> - else
> - printk(KERN_WARNING "%s: cannot get controller resources\n",
> - __func__);
> -}
> -
> -
> -static void release_appl(struct capi_ctr *ctr, u16 applid)
> -{
> - DBG("applid %#x", applid);
> -
> - ctr->release_appl(ctr, applid);
> - capi_ctr_put(ctr);
> -}
> -
> -static void notify_up(u32 contr)
> -{
> - struct capi20_appl *ap;
> - struct capi_ctr *ctr;
> - u16 applid;
> -
> - mutex_lock(&capi_controller_lock);
> -
> - if (showcapimsgs & 1)
> - printk(KERN_DEBUG "kcapi: notify up contr %d\n", contr);
> -
> - ctr = get_capi_ctr_by_nr(contr);
> - if (ctr) {
> - if (ctr->state == CAPI_CTR_RUNNING)
> - goto unlock_out;
> -
> - ctr->state = CAPI_CTR_RUNNING;
> -
> - for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
> - ap = __get_capi_appl_by_nr(applid);
> - if (ap)
> - register_appl(ctr, applid, &ap->rparam);
> - }
> - } else
> - printk(KERN_WARNING "%s: invalid contr %d\n", __func__, contr);
> -
> -unlock_out:
> - mutex_unlock(&capi_controller_lock);
> -}
> -
> -static void ctr_down(struct capi_ctr *ctr, int new_state)
> -{
> - struct capi20_appl *ap;
> - u16 applid;
> -
> - if (ctr->state == CAPI_CTR_DETECTED || ctr->state == CAPI_CTR_DETACHED)
> - return;
> -
> - ctr->state = new_state;
> -
> - memset(ctr->manu, 0, sizeof(ctr->manu));
> - memset(&ctr->version, 0, sizeof(ctr->version));
> - memset(&ctr->profile, 0, sizeof(ctr->profile));
> - memset(ctr->serial, 0, sizeof(ctr->serial));
> -
> - for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
> - ap = __get_capi_appl_by_nr(applid);
> - if (ap)
> - capi_ctr_put(ctr);
> - }
> -}
> -
> -static void notify_down(u32 contr)
> -{
> - struct capi_ctr *ctr;
> -
> - mutex_lock(&capi_controller_lock);
> -
> - if (showcapimsgs & 1)
> - printk(KERN_DEBUG "kcapi: notify down contr %d\n", contr);
> -
> - ctr = get_capi_ctr_by_nr(contr);
> - if (ctr)
> - ctr_down(ctr, CAPI_CTR_DETECTED);
> - else
> - printk(KERN_WARNING "%s: invalid contr %d\n", __func__, contr);
> -
> - mutex_unlock(&capi_controller_lock);
> -}
> -
> -static void do_notify_work(struct work_struct *work)
> -{
> - struct capictr_event *event =
> - container_of(work, struct capictr_event, work);
> -
> - switch (event->type) {
> - case CAPICTR_UP:
> - notify_up(event->controller);
> - break;
> - case CAPICTR_DOWN:
> - notify_down(event->controller);
> - break;
> - }
> -
> - kfree(event);
> -}
> -
> -static int notify_push(unsigned int event_type, u32 controller)
> -{
> - struct capictr_event *event = kmalloc_obj(*event, GFP_ATOMIC);
> -
> - if (!event)
> - return -ENOMEM;
> -
> - INIT_WORK(&event->work, do_notify_work);
> - event->type = event_type;
> - event->controller = controller;
> -
> - queue_work(kcapi_wq, &event->work);
> - return 0;
> -}
> -
> -/* -------- Receiver ------------------------------------------ */
> -
> -static void recv_handler(struct work_struct *work)
> -{
> - struct sk_buff *skb;
> - struct capi20_appl *ap =
> - container_of(work, struct capi20_appl, recv_work);
> -
> - if ((!ap) || (ap->release_in_progress))
> - return;
> -
> - mutex_lock(&ap->recv_mtx);
> - while ((skb = skb_dequeue(&ap->recv_queue))) {
> - if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_IND)
> - ap->nrecvdatapkt++;
> - else
> - ap->nrecvctlpkt++;
> -
> - ap->recv_message(ap, skb);
> - }
> - mutex_unlock(&ap->recv_mtx);
> -}
> -
> -/**
> - * capi_ctr_handle_message() - handle incoming CAPI message
> - * @ctr: controller descriptor structure.
> - * @appl: application ID.
> - * @skb: message.
> - *
> - * Called by hardware driver to pass a CAPI message to the application.
> - */
> -
> -void capi_ctr_handle_message(struct capi_ctr *ctr, u16 appl,
> - struct sk_buff *skb)
> -{
> - struct capi20_appl *ap;
> - int showctl = 0;
> - u8 cmd, subcmd;
> - _cdebbuf *cdb;
> -
> - if (ctr->state != CAPI_CTR_RUNNING) {
> - cdb = capi_message2str(skb->data);
> - if (cdb) {
> - printk(KERN_INFO "kcapi: controller [%03d] not active, got: %s",
> - ctr->cnr, cdb->buf);
> - cdebbuf_free(cdb);
> - } else
> - printk(KERN_INFO "kcapi: controller [%03d] not active, cannot trace\n",
> - ctr->cnr);
> - goto error;
> - }
> -
> - cmd = CAPIMSG_COMMAND(skb->data);
> - subcmd = CAPIMSG_SUBCOMMAND(skb->data);
> - if (cmd == CAPI_DATA_B3 && subcmd == CAPI_IND) {
> - ctr->nrecvdatapkt++;
> - if (ctr->traceflag > 2)
> - showctl |= 2;
> - } else {
> - ctr->nrecvctlpkt++;
> - if (ctr->traceflag)
> - showctl |= 2;
> - }
> - showctl |= (ctr->traceflag & 1);
> - if (showctl & 2) {
> - if (showctl & 1) {
> - printk(KERN_DEBUG "kcapi: got [%03d] id#%d %s len=%u\n",
> - ctr->cnr, CAPIMSG_APPID(skb->data),
> - capi_cmd2str(cmd, subcmd),
> - CAPIMSG_LEN(skb->data));
> - } else {
> - cdb = capi_message2str(skb->data);
> - if (cdb) {
> - printk(KERN_DEBUG "kcapi: got [%03d] %s\n",
> - ctr->cnr, cdb->buf);
> - cdebbuf_free(cdb);
> - } else
> - printk(KERN_DEBUG "kcapi: got [%03d] id#%d %s len=%u, cannot trace\n",
> - ctr->cnr, CAPIMSG_APPID(skb->data),
> - capi_cmd2str(cmd, subcmd),
> - CAPIMSG_LEN(skb->data));
> - }
> -
> - }
> -
> - rcu_read_lock();
> - ap = get_capi_appl_by_nr(CAPIMSG_APPID(skb->data));
> - if (!ap) {
> - rcu_read_unlock();
> - cdb = capi_message2str(skb->data);
> - if (cdb) {
> - printk(KERN_ERR "kcapi: handle_message: applid %d state released (%s)\n",
> - CAPIMSG_APPID(skb->data), cdb->buf);
> - cdebbuf_free(cdb);
> - } else
> - printk(KERN_ERR "kcapi: handle_message: applid %d state released (%s) cannot trace\n",
> - CAPIMSG_APPID(skb->data),
> - capi_cmd2str(cmd, subcmd));
> - goto error;
> - }
> - skb_queue_tail(&ap->recv_queue, skb);
> - queue_work(kcapi_wq, &ap->recv_work);
> - rcu_read_unlock();
> -
> - return;
> -
> -error:
> - kfree_skb(skb);
> -}
> -
> -EXPORT_SYMBOL(capi_ctr_handle_message);
> -
> -/**
> - * capi_ctr_ready() - signal CAPI controller ready
> - * @ctr: controller descriptor structure.
> - *
> - * Called by hardware driver to signal that the controller is up and running.
> - */
> -
> -void capi_ctr_ready(struct capi_ctr *ctr)
> -{
> - printk(KERN_NOTICE "kcapi: controller [%03d] \"%s\" ready.\n",
> - ctr->cnr, ctr->name);
> -
> - notify_push(CAPICTR_UP, ctr->cnr);
> -}
> -
> -EXPORT_SYMBOL(capi_ctr_ready);
> -
> -/**
> - * capi_ctr_down() - signal CAPI controller not ready
> - * @ctr: controller descriptor structure.
> - *
> - * Called by hardware driver to signal that the controller is down and
> - * unavailable for use.
> - */
> -
> -void capi_ctr_down(struct capi_ctr *ctr)
> -{
> - printk(KERN_NOTICE "kcapi: controller [%03d] down.\n", ctr->cnr);
> -
> - notify_push(CAPICTR_DOWN, ctr->cnr);
> -}
> -
> -EXPORT_SYMBOL(capi_ctr_down);
> -
> -/* ------------------------------------------------------------- */
> -
> -/**
> - * attach_capi_ctr() - register CAPI controller
> - * @ctr: controller descriptor structure.
> - *
> - * Called by hardware driver to register a controller with the CAPI subsystem.
> - * Return value: 0 on success, error code < 0 on error
> - */
> -
> -int attach_capi_ctr(struct capi_ctr *ctr)
> -{
> - int i;
> -
> - mutex_lock(&capi_controller_lock);
> -
> - for (i = 0; i < CAPI_MAXCONTR; i++) {
> - if (!capi_controller[i])
> - break;
> - }
> - if (i == CAPI_MAXCONTR) {
> - mutex_unlock(&capi_controller_lock);
> - printk(KERN_ERR "kcapi: out of controller slots\n");
> - return -EBUSY;
> - }
> - capi_controller[i] = ctr;
> -
> - ctr->nrecvctlpkt = 0;
> - ctr->nrecvdatapkt = 0;
> - ctr->nsentctlpkt = 0;
> - ctr->nsentdatapkt = 0;
> - ctr->cnr = i + 1;
> - ctr->state = CAPI_CTR_DETECTED;
> - ctr->blocked = 0;
> - ctr->traceflag = showcapimsgs;
> -
> - sprintf(ctr->procfn, "capi/controllers/%d", ctr->cnr);
> - ctr->procent = proc_create_single_data(ctr->procfn, 0, NULL,
> - ctr->proc_show, ctr);
> -
> - ncontrollers++;
> -
> - mutex_unlock(&capi_controller_lock);
> -
> - printk(KERN_NOTICE "kcapi: controller [%03d]: %s attached\n",
> - ctr->cnr, ctr->name);
> - return 0;
> -}
> -
> -EXPORT_SYMBOL(attach_capi_ctr);
> -
> -/**
> - * detach_capi_ctr() - unregister CAPI controller
> - * @ctr: controller descriptor structure.
> - *
> - * Called by hardware driver to remove the registration of a controller
> - * with the CAPI subsystem.
> - * Return value: 0 on success, error code < 0 on error
> - */
> -
> -int detach_capi_ctr(struct capi_ctr *ctr)
> -{
> - int err = 0;
> -
> - mutex_lock(&capi_controller_lock);
> -
> - ctr_down(ctr, CAPI_CTR_DETACHED);
> -
> - if (ctr->cnr < 1 || ctr->cnr - 1 >= CAPI_MAXCONTR) {
> - err = -EINVAL;
> - goto unlock_out;
> - }
> -
> - if (capi_controller[ctr->cnr - 1] != ctr) {
> - err = -EINVAL;
> - goto unlock_out;
> - }
> - capi_controller[ctr->cnr - 1] = NULL;
> - ncontrollers--;
> -
> - if (ctr->procent)
> - remove_proc_entry(ctr->procfn, NULL);
> -
> - printk(KERN_NOTICE "kcapi: controller [%03d]: %s unregistered\n",
> - ctr->cnr, ctr->name);
> -
> -unlock_out:
> - mutex_unlock(&capi_controller_lock);
> -
> - return err;
> -}
> -
> -EXPORT_SYMBOL(detach_capi_ctr);
> -
> -/* ------------------------------------------------------------- */
> -/* -------- CAPI2.0 Interface ---------------------------------- */
> -/* ------------------------------------------------------------- */
> -
> -/**
> - * capi20_isinstalled() - CAPI 2.0 operation CAPI_INSTALLED
> - *
> - * Return value: CAPI result code (CAPI_NOERROR if at least one ISDN controller
> - * is ready for use, CAPI_REGNOTINSTALLED otherwise)
> - */
> -
> -u16 capi20_isinstalled(void)
> -{
> - u16 ret = CAPI_REGNOTINSTALLED;
> - int i;
> -
> - mutex_lock(&capi_controller_lock);
> -
> - for (i = 0; i < CAPI_MAXCONTR; i++)
> - if (capi_controller[i] &&
> - capi_controller[i]->state == CAPI_CTR_RUNNING) {
> - ret = CAPI_NOERROR;
> - break;
> - }
> -
> - mutex_unlock(&capi_controller_lock);
> -
> - return ret;
> -}
> -
> -/**
> - * capi20_register() - CAPI 2.0 operation CAPI_REGISTER
> - * @ap: CAPI application descriptor structure.
> - *
> - * Register an application's presence with CAPI.
> - * A unique application ID is assigned and stored in @ap->applid.
> - * After this function returns successfully, the message receive
> - * callback function @ap->recv_message() may be called at any time
> - * until capi20_release() has been called for the same @ap.
> - * Return value: CAPI result code
> - */
> -
> -u16 capi20_register(struct capi20_appl *ap)
> -{
> - int i;
> - u16 applid;
> -
> - DBG("");
> -
> - if (ap->rparam.datablklen < 128)
> - return CAPI_LOGBLKSIZETOSMALL;
> -
> - ap->nrecvctlpkt = 0;
> - ap->nrecvdatapkt = 0;
> - ap->nsentctlpkt = 0;
> - ap->nsentdatapkt = 0;
> - mutex_init(&ap->recv_mtx);
> - skb_queue_head_init(&ap->recv_queue);
> - INIT_WORK(&ap->recv_work, recv_handler);
> - ap->release_in_progress = 0;
> -
> - mutex_lock(&capi_controller_lock);
> -
> - for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
> - if (capi_applications[applid - 1] == NULL)
> - break;
> - }
> - if (applid > CAPI_MAXAPPL) {
> - mutex_unlock(&capi_controller_lock);
> - return CAPI_TOOMANYAPPLS;
> - }
> -
> - ap->applid = applid;
> - capi_applications[applid - 1] = ap;
> -
> - for (i = 0; i < CAPI_MAXCONTR; i++) {
> - if (!capi_controller[i] ||
> - capi_controller[i]->state != CAPI_CTR_RUNNING)
> - continue;
> - register_appl(capi_controller[i], applid, &ap->rparam);
> - }
> -
> - mutex_unlock(&capi_controller_lock);
> -
> - if (showcapimsgs & 1) {
> - printk(KERN_DEBUG "kcapi: appl %d up\n", applid);
> - }
> -
> - return CAPI_NOERROR;
> -}
> -
> -/**
> - * capi20_release() - CAPI 2.0 operation CAPI_RELEASE
> - * @ap: CAPI application descriptor structure.
> - *
> - * Terminate an application's registration with CAPI.
> - * After this function returns successfully, the message receive
> - * callback function @ap->recv_message() will no longer be called.
> - * Return value: CAPI result code
> - */
> -
> -u16 capi20_release(struct capi20_appl *ap)
> -{
> - int i;
> -
> - DBG("applid %#x", ap->applid);
> -
> - mutex_lock(&capi_controller_lock);
> -
> - ap->release_in_progress = 1;
> - capi_applications[ap->applid - 1] = NULL;
> -
> - synchronize_rcu();
> -
> - for (i = 0; i < CAPI_MAXCONTR; i++) {
> - if (!capi_controller[i] ||
> - capi_controller[i]->state != CAPI_CTR_RUNNING)
> - continue;
> - release_appl(capi_controller[i], ap->applid);
> - }
> -
> - mutex_unlock(&capi_controller_lock);
> -
> - flush_workqueue(kcapi_wq);
> - skb_queue_purge(&ap->recv_queue);
> -
> - if (showcapimsgs & 1) {
> - printk(KERN_DEBUG "kcapi: appl %d down\n", ap->applid);
> - }
> -
> - return CAPI_NOERROR;
> -}
> -
> -/**
> - * capi20_put_message() - CAPI 2.0 operation CAPI_PUT_MESSAGE
> - * @ap: CAPI application descriptor structure.
> - * @skb: CAPI message.
> - *
> - * Transfer a single message to CAPI.
> - * Return value: CAPI result code
> - */
> -
> -u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb)
> -{
> - struct capi_ctr *ctr;
> - int showctl = 0;
> - u8 cmd, subcmd;
> -
> - DBG("applid %#x", ap->applid);
> -
> - if (ncontrollers == 0)
> - return CAPI_REGNOTINSTALLED;
> - if ((ap->applid == 0) || ap->release_in_progress)
> - return CAPI_ILLAPPNR;
> - if (skb->len < 12
> - || !capi_cmd_valid(CAPIMSG_COMMAND(skb->data))
> - || !capi_subcmd_valid(CAPIMSG_SUBCOMMAND(skb->data)))
> - return CAPI_ILLCMDORSUBCMDORMSGTOSMALL;
> -
> - /*
> - * The controller reference is protected by the existence of the
> - * application passed to us. We assume that the caller properly
> - * synchronizes this service with capi20_release.
> - */
> - ctr = get_capi_ctr_by_nr(CAPIMSG_CONTROLLER(skb->data));
> - if (!ctr || ctr->state != CAPI_CTR_RUNNING)
> - return CAPI_REGNOTINSTALLED;
> - if (ctr->blocked)
> - return CAPI_SENDQUEUEFULL;
> -
> - cmd = CAPIMSG_COMMAND(skb->data);
> - subcmd = CAPIMSG_SUBCOMMAND(skb->data);
> -
> - if (cmd == CAPI_DATA_B3 && subcmd == CAPI_REQ) {
> - ctr->nsentdatapkt++;
> - ap->nsentdatapkt++;
> - if (ctr->traceflag > 2)
> - showctl |= 2;
> - } else {
> - ctr->nsentctlpkt++;
> - ap->nsentctlpkt++;
> - if (ctr->traceflag)
> - showctl |= 2;
> - }
> - showctl |= (ctr->traceflag & 1);
> - if (showctl & 2) {
> - if (showctl & 1) {
> - printk(KERN_DEBUG "kcapi: put [%03d] id#%d %s len=%u\n",
> - CAPIMSG_CONTROLLER(skb->data),
> - CAPIMSG_APPID(skb->data),
> - capi_cmd2str(cmd, subcmd),
> - CAPIMSG_LEN(skb->data));
> - } else {
> - _cdebbuf *cdb = capi_message2str(skb->data);
> - if (cdb) {
> - printk(KERN_DEBUG "kcapi: put [%03d] %s\n",
> - CAPIMSG_CONTROLLER(skb->data),
> - cdb->buf);
> - cdebbuf_free(cdb);
> - } else
> - printk(KERN_DEBUG "kcapi: put [%03d] id#%d %s len=%u cannot trace\n",
> - CAPIMSG_CONTROLLER(skb->data),
> - CAPIMSG_APPID(skb->data),
> - capi_cmd2str(cmd, subcmd),
> - CAPIMSG_LEN(skb->data));
> - }
> - }
> - return ctr->send_message(ctr, skb);
> -}
> -
> -/**
> - * capi20_get_manufacturer() - CAPI 2.0 operation CAPI_GET_MANUFACTURER
> - * @contr: controller number.
> - * @buf: result buffer (64 bytes).
> - *
> - * Retrieve information about the manufacturer of the specified ISDN controller
> - * or (for @contr == 0) the driver itself.
> - * Return value: CAPI result code
> - */
> -
> -u16 capi20_get_manufacturer(u32 contr, u8 buf[CAPI_MANUFACTURER_LEN])
> -{
> - struct capi_ctr *ctr;
> - u16 ret;
> -
> - if (contr == 0) {
> - strscpy_pad(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN);
> - return CAPI_NOERROR;
> - }
> -
> - mutex_lock(&capi_controller_lock);
> -
> - ctr = get_capi_ctr_by_nr(contr);
> - if (ctr && ctr->state == CAPI_CTR_RUNNING) {
> - strscpy_pad(buf, ctr->manu, CAPI_MANUFACTURER_LEN);
> - ret = CAPI_NOERROR;
> - } else
> - ret = CAPI_REGNOTINSTALLED;
> -
> - mutex_unlock(&capi_controller_lock);
> - return ret;
> -}
> -
> -/**
> - * capi20_get_version() - CAPI 2.0 operation CAPI_GET_VERSION
> - * @contr: controller number.
> - * @verp: result structure.
> - *
> - * Retrieve version information for the specified ISDN controller
> - * or (for @contr == 0) the driver itself.
> - * Return value: CAPI result code
> - */
> -
> -u16 capi20_get_version(u32 contr, struct capi_version *verp)
> -{
> - struct capi_ctr *ctr;
> - u16 ret;
> -
> - if (contr == 0) {
> - *verp = driver_version;
> - return CAPI_NOERROR;
> - }
> -
> - mutex_lock(&capi_controller_lock);
> -
> - ctr = get_capi_ctr_by_nr(contr);
> - if (ctr && ctr->state == CAPI_CTR_RUNNING) {
> - memcpy(verp, &ctr->version, sizeof(capi_version));
> - ret = CAPI_NOERROR;
> - } else
> - ret = CAPI_REGNOTINSTALLED;
> -
> - mutex_unlock(&capi_controller_lock);
> - return ret;
> -}
> -
> -/**
> - * capi20_get_serial() - CAPI 2.0 operation CAPI_GET_SERIAL_NUMBER
> - * @contr: controller number.
> - * @serial: result buffer (8 bytes).
> - *
> - * Retrieve the serial number of the specified ISDN controller
> - * or (for @contr == 0) the driver itself.
> - * Return value: CAPI result code
> - */
> -
> -u16 capi20_get_serial(u32 contr, u8 serial[CAPI_SERIAL_LEN])
> -{
> - struct capi_ctr *ctr;
> - u16 ret;
> -
> - if (contr == 0) {
> - strscpy(serial, driver_serial, CAPI_SERIAL_LEN);
> - return CAPI_NOERROR;
> - }
> -
> - mutex_lock(&capi_controller_lock);
> -
> - ctr = get_capi_ctr_by_nr(contr);
> - if (ctr && ctr->state == CAPI_CTR_RUNNING) {
> - strscpy(serial, ctr->serial, CAPI_SERIAL_LEN);
> - ret = CAPI_NOERROR;
> - } else
> - ret = CAPI_REGNOTINSTALLED;
> -
> - mutex_unlock(&capi_controller_lock);
> - return ret;
> -}
> -
> -/**
> - * capi20_get_profile() - CAPI 2.0 operation CAPI_GET_PROFILE
> - * @contr: controller number.
> - * @profp: result structure.
> - *
> - * Retrieve capability information for the specified ISDN controller
> - * or (for @contr == 0) the number of installed controllers.
> - * Return value: CAPI result code
> - */
> -
> -u16 capi20_get_profile(u32 contr, struct capi_profile *profp)
> -{
> - struct capi_ctr *ctr;
> - u16 ret;
> -
> - if (contr == 0) {
> - profp->ncontroller = ncontrollers;
> - return CAPI_NOERROR;
> - }
> -
> - mutex_lock(&capi_controller_lock);
> -
> - ctr = get_capi_ctr_by_nr(contr);
> - if (ctr && ctr->state == CAPI_CTR_RUNNING) {
> - memcpy(profp, &ctr->profile, sizeof(struct capi_profile));
> - ret = CAPI_NOERROR;
> - } else
> - ret = CAPI_REGNOTINSTALLED;
> -
> - mutex_unlock(&capi_controller_lock);
> - return ret;
> -}
> -
> -/**
> - * capi20_manufacturer() - CAPI 2.0 operation CAPI_MANUFACTURER
> - * @cmd: command.
> - * @data: parameter.
> - *
> - * Perform manufacturer specific command.
> - * Return value: CAPI result code
> - */
> -
> -int capi20_manufacturer(unsigned long cmd, void __user *data)
> -{
> - struct capi_ctr *ctr;
> - int retval;
> -
> - switch (cmd) {
> - case KCAPI_CMD_TRACE:
> - {
> - kcapi_flagdef fdef;
> -
> - if (copy_from_user(&fdef, data, sizeof(kcapi_flagdef)))
> - return -EFAULT;
> -
> - mutex_lock(&capi_controller_lock);
> -
> - ctr = get_capi_ctr_by_nr(fdef.contr);
> - if (ctr) {
> - ctr->traceflag = fdef.flag;
> - printk(KERN_INFO "kcapi: contr [%03d] set trace=%d\n",
> - ctr->cnr, ctr->traceflag);
> - retval = 0;
> - } else
> - retval = -ESRCH;
> -
> - mutex_unlock(&capi_controller_lock);
> -
> - return retval;
> - }
> -
> - default:
> - printk(KERN_ERR "kcapi: manufacturer command %lu unknown.\n",
> - cmd);
> - break;
> -
> - }
> - return -EINVAL;
> -}
> -
> -/* ------------------------------------------------------------- */
> -/* -------- Init & Cleanup ------------------------------------- */
> -/* ------------------------------------------------------------- */
> -
> -/*
> - * init / exit functions
> - */
> -
> -int __init kcapi_init(void)
> -{
> - int err;
> -
> - kcapi_wq = alloc_workqueue("kcapi", WQ_PERCPU, 0);
> - if (!kcapi_wq)
> - return -ENOMEM;
> -
> - err = cdebug_init();
> - if (err) {
> - destroy_workqueue(kcapi_wq);
> - return err;
> - }
> -
> - if (IS_ENABLED(CONFIG_PROC_FS))
> - kcapi_proc_init();
> -
> - return 0;
> -}
> -
> -void kcapi_exit(void)
> -{
> - if (IS_ENABLED(CONFIG_PROC_FS))
> - kcapi_proc_exit();
> -
> - cdebug_exit();
> - destroy_workqueue(kcapi_wq);
> -}
> diff --git a/drivers/isdn/capi/kcapi_proc.c b/drivers/isdn/capi/kcapi_proc.c
> deleted file mode 100644
> index 77e951206809..000000000000
> --- a/drivers/isdn/capi/kcapi_proc.c
> +++ /dev/null
> @@ -1,231 +0,0 @@
> -/*
> - * Kernel CAPI 2.0 Module - /proc/capi handling
> - *
> - * Copyright 1999 by Carsten Paeth <calle@calle.de>
> - * Copyright 2002 by Kai Germaschewski <kai@germaschewski.name>
> - *
> - * This software may be used and distributed according to the terms
> - * of the GNU General Public License, incorporated herein by reference.
> - *
> - */
> -
> -
> -#include "kcapi.h"
> -#include <linux/proc_fs.h>
> -#include <linux/seq_file.h>
> -#include <linux/init.h>
> -#include <linux/export.h>
> -
> -static char *state2str(unsigned short state)
> -{
> - switch (state) {
> - case CAPI_CTR_DETECTED: return "detected";
> - case CAPI_CTR_LOADING: return "loading";
> - case CAPI_CTR_RUNNING: return "running";
> - default: return "???";
> - }
> -}
> -
> -// /proc/capi
> -// ===========================================================================
> -
> -// /proc/capi/controller:
> -// cnr driver cardstate name driverinfo
> -// /proc/capi/contrstats:
> -// cnr nrecvctlpkt nrecvdatapkt nsentctlpkt nsentdatapkt
> -// ---------------------------------------------------------------------------
> -
> -static void *controller_start(struct seq_file *seq, loff_t *pos)
> - __acquires(capi_controller_lock)
> -{
> - mutex_lock(&capi_controller_lock);
> -
> - if (*pos < CAPI_MAXCONTR)
> - return &capi_controller[*pos];
> -
> - return NULL;
> -}
> -
> -static void *controller_next(struct seq_file *seq, void *v, loff_t *pos)
> -{
> - ++*pos;
> - if (*pos < CAPI_MAXCONTR)
> - return &capi_controller[*pos];
> -
> - return NULL;
> -}
> -
> -static void controller_stop(struct seq_file *seq, void *v)
> - __releases(capi_controller_lock)
> -{
> - mutex_unlock(&capi_controller_lock);
> -}
> -
> -static int controller_show(struct seq_file *seq, void *v)
> -{
> - struct capi_ctr *ctr = *(struct capi_ctr **) v;
> -
> - if (!ctr)
> - return 0;
> -
> - seq_printf(seq, "%d %-10s %-8s %-16s %s\n",
> - ctr->cnr, ctr->driver_name,
> - state2str(ctr->state),
> - ctr->name,
> - ctr->procinfo ? ctr->procinfo(ctr) : "");
> -
> - return 0;
> -}
> -
> -static int contrstats_show(struct seq_file *seq, void *v)
> -{
> - struct capi_ctr *ctr = *(struct capi_ctr **) v;
> -
> - if (!ctr)
> - return 0;
> -
> - seq_printf(seq, "%d %lu %lu %lu %lu\n",
> - ctr->cnr,
> - ctr->nrecvctlpkt,
> - ctr->nrecvdatapkt,
> - ctr->nsentctlpkt,
> - ctr->nsentdatapkt);
> -
> - return 0;
> -}
> -
> -static const struct seq_operations seq_controller_ops = {
> - .start = controller_start,
> - .next = controller_next,
> - .stop = controller_stop,
> - .show = controller_show,
> -};
> -
> -static const struct seq_operations seq_contrstats_ops = {
> - .start = controller_start,
> - .next = controller_next,
> - .stop = controller_stop,
> - .show = contrstats_show,
> -};
> -
> -// /proc/capi/applications:
> -// applid l3cnt dblkcnt dblklen #ncci recvqueuelen
> -// /proc/capi/applstats:
> -// applid nrecvctlpkt nrecvdatapkt nsentctlpkt nsentdatapkt
> -// ---------------------------------------------------------------------------
> -
> -static void *applications_start(struct seq_file *seq, loff_t *pos)
> - __acquires(capi_controller_lock)
> -{
> - mutex_lock(&capi_controller_lock);
> -
> - if (*pos < CAPI_MAXAPPL)
> - return &capi_applications[*pos];
> -
> - return NULL;
> -}
> -
> -static void *
> -applications_next(struct seq_file *seq, void *v, loff_t *pos)
> -{
> - ++*pos;
> - if (*pos < CAPI_MAXAPPL)
> - return &capi_applications[*pos];
> -
> - return NULL;
> -}
> -
> -static void applications_stop(struct seq_file *seq, void *v)
> - __releases(capi_controller_lock)
> -{
> - mutex_unlock(&capi_controller_lock);
> -}
> -
> -static int
> -applications_show(struct seq_file *seq, void *v)
> -{
> - struct capi20_appl *ap = *(struct capi20_appl **) v;
> -
> - if (!ap)
> - return 0;
> -
> - seq_printf(seq, "%u %d %d %d\n",
> - ap->applid,
> - ap->rparam.level3cnt,
> - ap->rparam.datablkcnt,
> - ap->rparam.datablklen);
> -
> - return 0;
> -}
> -
> -static int
> -applstats_show(struct seq_file *seq, void *v)
> -{
> - struct capi20_appl *ap = *(struct capi20_appl **) v;
> -
> - if (!ap)
> - return 0;
> -
> - seq_printf(seq, "%u %lu %lu %lu %lu\n",
> - ap->applid,
> - ap->nrecvctlpkt,
> - ap->nrecvdatapkt,
> - ap->nsentctlpkt,
> - ap->nsentdatapkt);
> -
> - return 0;
> -}
> -
> -static const struct seq_operations seq_applications_ops = {
> - .start = applications_start,
> - .next = applications_next,
> - .stop = applications_stop,
> - .show = applications_show,
> -};
> -
> -static const struct seq_operations seq_applstats_ops = {
> - .start = applications_start,
> - .next = applications_next,
> - .stop = applications_stop,
> - .show = applstats_show,
> -};
> -
> -// ---------------------------------------------------------------------------
> -
> -/* /proc/capi/drivers is always empty */
> -static ssize_t empty_read(struct file *file, char __user *buf,
> - size_t size, loff_t *off)
> -{
> - return 0;
> -}
> -
> -static const struct proc_ops empty_proc_ops = {
> - .proc_read = empty_read,
> - .proc_lseek = default_llseek,
> -};
> -
> -// ---------------------------------------------------------------------------
> -
> -void __init
> -kcapi_proc_init(void)
> -{
> - proc_mkdir("capi", NULL);
> - proc_mkdir("capi/controllers", NULL);
> - proc_create_seq("capi/controller", 0, NULL, &seq_controller_ops);
> - proc_create_seq("capi/contrstats", 0, NULL, &seq_contrstats_ops);
> - proc_create_seq("capi/applications", 0, NULL, &seq_applications_ops);
> - proc_create_seq("capi/applstats", 0, NULL, &seq_applstats_ops);
> - proc_create("capi/driver", 0, NULL, &empty_proc_ops);
> -}
> -
> -void
> -kcapi_proc_exit(void)
> -{
> - remove_proc_entry("capi/driver", NULL);
> - remove_proc_entry("capi/controller", NULL);
> - remove_proc_entry("capi/contrstats", NULL);
> - remove_proc_entry("capi/applications", NULL);
> - remove_proc_entry("capi/applstats", NULL);
> - remove_proc_entry("capi/controllers", NULL);
> - remove_proc_entry("capi", NULL);
> -}
> diff --git a/drivers/isdn/hardware/mISDN/avmfritz.c b/drivers/isdn/hardware/mISDN/avmfritz.c
> deleted file mode 100644
> index 55e0b9efa194..000000000000
> --- a/drivers/isdn/hardware/mISDN/avmfritz.c
> +++ /dev/null
> @@ -1,1164 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * avm_fritz.c low level stuff for AVM FRITZ!CARD PCI ISDN cards
> - * Thanks to AVM, Berlin for informations
> - *
> - * Author Karsten Keil <keil@isdn4linux.de>
> - *
> - * Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
> - */
> -#include <linux/interrupt.h>
> -#include <linux/module.h>
> -#include <linux/pci.h>
> -#include <linux/delay.h>
> -#include <linux/mISDNhw.h>
> -#include <linux/slab.h>
> -#include <linux/unaligned.h>
> -#include "ipac.h"
> -
> -
> -#define AVMFRITZ_REV "2.3"
> -
> -static int AVM_cnt;
> -static int debug;
> -
> -enum {
> - AVM_FRITZ_PCI,
> - AVM_FRITZ_PCIV2,
> -};
> -
> -#define HDLC_FIFO 0x0
> -#define HDLC_STATUS 0x4
> -#define CHIP_WINDOW 0x10
> -
> -#define CHIP_INDEX 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_FIFO_SIZE_128 0x20
> -#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_V1 0x3f00
> -#define HDLC_STAT_RML_MASK_V2 0x7f00
> -
> -#define HDLC_CMD_XRS 0x80
> -#define HDLC_CMD_XME 0x01
> -#define HDLC_CMD_RRS 0x20
> -#define HDLC_CMD_XML_MASK 0x3f00
> -
> -#define HDLC_FIFO_SIZE_V1 32
> -#define HDLC_FIFO_SIZE_V2 128
> -
> -/* Fritz PCI v2.0 */
> -
> -#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_ISACX_INDEX 0x04
> -#define AVM_ISACX_DATA 0x08
> -
> -/* data struct */
> -#define LOG_SIZE 63
> -
> -struct hdlc_stat_reg {
> -#ifdef __BIG_ENDIAN
> - u8 fill;
> - u8 mode;
> - u8 xml;
> - u8 cmd;
> -#else
> - u8 cmd;
> - u8 xml;
> - u8 mode;
> - u8 fill;
> -#endif
> -} __attribute__((packed));
> -
> -struct hdlc_hw {
> - union {
> - u32 ctrl;
> - struct hdlc_stat_reg sr;
> - } ctrl;
> - u32 stat;
> -};
> -
> -struct fritzcard {
> - struct list_head list;
> - struct pci_dev *pdev;
> - char name[MISDN_MAX_IDLEN];
> - u8 type;
> - u8 ctrlreg;
> - u16 irq;
> - u32 irqcnt;
> - u32 addr;
> - spinlock_t lock; /* hw lock */
> - struct isac_hw isac;
> - struct hdlc_hw hdlc[2];
> - struct bchannel bch[2];
> - char log[LOG_SIZE + 1];
> -};
> -
> -static LIST_HEAD(Cards);
> -static DEFINE_RWLOCK(card_lock); /* protect Cards */
> -
> -static void
> -_set_debug(struct fritzcard *card)
> -{
> - card->isac.dch.debug = debug;
> - card->bch[0].debug = debug;
> - card->bch[1].debug = debug;
> -}
> -
> -static int
> -set_debug(const char *val, const struct kernel_param *kp)
> -{
> - int ret;
> - struct fritzcard *card;
> -
> - ret = param_set_uint(val, kp);
> - if (!ret) {
> - read_lock(&card_lock);
> - list_for_each_entry(card, &Cards, list)
> - _set_debug(card);
> - read_unlock(&card_lock);
> - }
> - return ret;
> -}
> -
> -MODULE_AUTHOR("Karsten Keil");
> -MODULE_DESCRIPTION("mISDN driver for AVM FRITZ!CARD PCI ISDN cards");
> -MODULE_LICENSE("GPL v2");
> -MODULE_VERSION(AVMFRITZ_REV);
> -module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR);
> -MODULE_PARM_DESC(debug, "avmfritz debug mask");
> -
> -/* Interface functions */
> -
> -static u8
> -ReadISAC_V1(void *p, u8 offset)
> -{
> - struct fritzcard *fc = p;
> - u8 idx = (offset > 0x2f) ? AVM_ISAC_REG_HIGH : AVM_ISAC_REG_LOW;
> -
> - outb(idx, fc->addr + CHIP_INDEX);
> - return inb(fc->addr + CHIP_WINDOW + (offset & 0xf));
> -}
> -
> -static void
> -WriteISAC_V1(void *p, u8 offset, u8 value)
> -{
> - struct fritzcard *fc = p;
> - u8 idx = (offset > 0x2f) ? AVM_ISAC_REG_HIGH : AVM_ISAC_REG_LOW;
> -
> - outb(idx, fc->addr + CHIP_INDEX);
> - outb(value, fc->addr + CHIP_WINDOW + (offset & 0xf));
> -}
> -
> -static void
> -ReadFiFoISAC_V1(void *p, u8 off, u8 *data, int size)
> -{
> - struct fritzcard *fc = p;
> -
> - outb(AVM_ISAC_FIFO, fc->addr + CHIP_INDEX);
> - insb(fc->addr + CHIP_WINDOW, data, size);
> -}
> -
> -static void
> -WriteFiFoISAC_V1(void *p, u8 off, u8 *data, int size)
> -{
> - struct fritzcard *fc = p;
> -
> - outb(AVM_ISAC_FIFO, fc->addr + CHIP_INDEX);
> - outsb(fc->addr + CHIP_WINDOW, data, size);
> -}
> -
> -static u8
> -ReadISAC_V2(void *p, u8 offset)
> -{
> - struct fritzcard *fc = p;
> -
> - outl(offset, fc->addr + AVM_ISACX_INDEX);
> - return 0xff & inl(fc->addr + AVM_ISACX_DATA);
> -}
> -
> -static void
> -WriteISAC_V2(void *p, u8 offset, u8 value)
> -{
> - struct fritzcard *fc = p;
> -
> - outl(offset, fc->addr + AVM_ISACX_INDEX);
> - outl(value, fc->addr + AVM_ISACX_DATA);
> -}
> -
> -static void
> -ReadFiFoISAC_V2(void *p, u8 off, u8 *data, int size)
> -{
> - struct fritzcard *fc = p;
> - int i;
> -
> - outl(off, fc->addr + AVM_ISACX_INDEX);
> - for (i = 0; i < size; i++)
> - data[i] = 0xff & inl(fc->addr + AVM_ISACX_DATA);
> -}
> -
> -static void
> -WriteFiFoISAC_V2(void *p, u8 off, u8 *data, int size)
> -{
> - struct fritzcard *fc = p;
> - int i;
> -
> - outl(off, fc->addr + AVM_ISACX_INDEX);
> - for (i = 0; i < size; i++)
> - outl(data[i], fc->addr + AVM_ISACX_DATA);
> -}
> -
> -static struct bchannel *
> -Sel_BCS(struct fritzcard *fc, u32 channel)
> -{
> - if (test_bit(FLG_ACTIVE, &fc->bch[0].Flags) &&
> - (fc->bch[0].nr & channel))
> - return &fc->bch[0];
> - else if (test_bit(FLG_ACTIVE, &fc->bch[1].Flags) &&
> - (fc->bch[1].nr & channel))
> - return &fc->bch[1];
> - else
> - return NULL;
> -}
> -
> -static inline void
> -__write_ctrl_pci(struct fritzcard *fc, struct hdlc_hw *hdlc, u32 channel) {
> - u32 idx = channel == 2 ? AVM_HDLC_2 : AVM_HDLC_1;
> -
> - outl(idx, fc->addr + CHIP_INDEX);
> - outl(hdlc->ctrl.ctrl, fc->addr + CHIP_WINDOW + HDLC_STATUS);
> -}
> -
> -static inline void
> -__write_ctrl_pciv2(struct fritzcard *fc, struct hdlc_hw *hdlc, u32 channel) {
> - outl(hdlc->ctrl.ctrl, fc->addr + (channel == 2 ? AVM_HDLC_STATUS_2 :
> - AVM_HDLC_STATUS_1));
> -}
> -
> -static void
> -write_ctrl(struct bchannel *bch, int which) {
> - struct fritzcard *fc = bch->hw;
> - struct hdlc_hw *hdlc;
> -
> - hdlc = &fc->hdlc[(bch->nr - 1) & 1];
> - pr_debug("%s: hdlc %c wr%x ctrl %x\n", fc->name, '@' + bch->nr,
> - which, hdlc->ctrl.ctrl);
> - switch (fc->type) {
> - case AVM_FRITZ_PCIV2:
> - __write_ctrl_pciv2(fc, hdlc, bch->nr);
> - break;
> - case AVM_FRITZ_PCI:
> - __write_ctrl_pci(fc, hdlc, bch->nr);
> - break;
> - }
> -}
> -
> -
> -static inline u32
> -__read_status_pci(u_long addr, u32 channel)
> -{
> - outl(channel == 2 ? AVM_HDLC_2 : AVM_HDLC_1, addr + CHIP_INDEX);
> - return inl(addr + CHIP_WINDOW + HDLC_STATUS);
> -}
> -
> -static inline u32
> -__read_status_pciv2(u_long addr, u32 channel)
> -{
> - return inl(addr + (channel == 2 ? AVM_HDLC_STATUS_2 :
> - AVM_HDLC_STATUS_1));
> -}
> -
> -
> -static u32
> -read_status(struct fritzcard *fc, u32 channel)
> -{
> - switch (fc->type) {
> - case AVM_FRITZ_PCIV2:
> - return __read_status_pciv2(fc->addr, channel);
> - case AVM_FRITZ_PCI:
> - return __read_status_pci(fc->addr, channel);
> - }
> - /* dummy */
> - return 0;
> -}
> -
> -static void
> -enable_hwirq(struct fritzcard *fc)
> -{
> - fc->ctrlreg |= AVM_STATUS0_ENA_IRQ;
> - outb(fc->ctrlreg, fc->addr + 2);
> -}
> -
> -static void
> -disable_hwirq(struct fritzcard *fc)
> -{
> - fc->ctrlreg &= ~AVM_STATUS0_ENA_IRQ;
> - outb(fc->ctrlreg, fc->addr + 2);
> -}
> -
> -static int
> -modehdlc(struct bchannel *bch, int protocol)
> -{
> - struct fritzcard *fc = bch->hw;
> - struct hdlc_hw *hdlc;
> - u8 mode;
> -
> - hdlc = &fc->hdlc[(bch->nr - 1) & 1];
> - pr_debug("%s: hdlc %c protocol %x-->%x ch %d\n", fc->name,
> - '@' + bch->nr, bch->state, protocol, bch->nr);
> - hdlc->ctrl.ctrl = 0;
> - mode = (fc->type == AVM_FRITZ_PCIV2) ? HDLC_FIFO_SIZE_128 : 0;
> -
> - switch (protocol) {
> - case -1: /* used for init */
> - bch->state = -1;
> - fallthrough;
> - case ISDN_P_NONE:
> - if (bch->state == ISDN_P_NONE)
> - break;
> - hdlc->ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS;
> - hdlc->ctrl.sr.mode = mode | HDLC_MODE_TRANS;
> - write_ctrl(bch, 5);
> - bch->state = ISDN_P_NONE;
> - test_and_clear_bit(FLG_HDLC, &bch->Flags);
> - test_and_clear_bit(FLG_TRANSPARENT, &bch->Flags);
> - break;
> - case ISDN_P_B_RAW:
> - bch->state = protocol;
> - hdlc->ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS;
> - hdlc->ctrl.sr.mode = mode | HDLC_MODE_TRANS;
> - write_ctrl(bch, 5);
> - hdlc->ctrl.sr.cmd = HDLC_CMD_XRS;
> - write_ctrl(bch, 1);
> - hdlc->ctrl.sr.cmd = 0;
> - test_and_set_bit(FLG_TRANSPARENT, &bch->Flags);
> - break;
> - case ISDN_P_B_HDLC:
> - bch->state = protocol;
> - hdlc->ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS;
> - hdlc->ctrl.sr.mode = mode | HDLC_MODE_ITF_FLG;
> - write_ctrl(bch, 5);
> - hdlc->ctrl.sr.cmd = HDLC_CMD_XRS;
> - write_ctrl(bch, 1);
> - hdlc->ctrl.sr.cmd = 0;
> - test_and_set_bit(FLG_HDLC, &bch->Flags);
> - break;
> - default:
> - pr_info("%s: protocol not known %x\n", fc->name, protocol);
> - return -ENOPROTOOPT;
> - }
> - return 0;
> -}
> -
> -static void
> -hdlc_empty_fifo(struct bchannel *bch, int count)
> -{
> - u32 *ptr;
> - u8 *p;
> - u32 val, addr;
> - int cnt;
> - struct fritzcard *fc = bch->hw;
> -
> - pr_debug("%s: %s %d\n", fc->name, __func__, count);
> - if (test_bit(FLG_RX_OFF, &bch->Flags)) {
> - p = NULL;
> - bch->dropcnt += count;
> - } else {
> - cnt = bchannel_get_rxbuf(bch, count);
> - if (cnt < 0) {
> - pr_warn("%s.B%d: No bufferspace for %d bytes\n",
> - fc->name, bch->nr, count);
> - return;
> - }
> - p = skb_put(bch->rx_skb, count);
> - }
> - ptr = (u32 *)p;
> - if (fc->type == AVM_FRITZ_PCIV2)
> - addr = fc->addr + (bch->nr == 2 ?
> - AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1);
> - else {
> - addr = fc->addr + CHIP_WINDOW;
> - outl(bch->nr == 2 ? AVM_HDLC_2 : AVM_HDLC_1, fc->addr);
> - }
> - cnt = 0;
> - while (cnt < count) {
> - val = le32_to_cpu(inl(addr));
> - if (p) {
> - put_unaligned(val, ptr);
> - ptr++;
> - }
> - cnt += 4;
> - }
> - if (p && (debug & DEBUG_HW_BFIFO)) {
> - snprintf(fc->log, LOG_SIZE, "B%1d-recv %s %d ",
> - bch->nr, fc->name, count);
> - print_hex_dump_bytes(fc->log, DUMP_PREFIX_OFFSET, p, count);
> - }
> -}
> -
> -static void
> -hdlc_fill_fifo(struct bchannel *bch)
> -{
> - struct fritzcard *fc = bch->hw;
> - struct hdlc_hw *hdlc;
> - int count, fs, cnt = 0, idx;
> - bool fillempty = false;
> - u8 *p;
> - u32 *ptr, val, addr;
> -
> - idx = (bch->nr - 1) & 1;
> - hdlc = &fc->hdlc[idx];
> - fs = (fc->type == AVM_FRITZ_PCIV2) ?
> - HDLC_FIFO_SIZE_V2 : HDLC_FIFO_SIZE_V1;
> - if (!bch->tx_skb) {
> - if (!test_bit(FLG_TX_EMPTY, &bch->Flags))
> - return;
> - count = fs;
> - p = bch->fill;
> - fillempty = true;
> - } else {
> - count = bch->tx_skb->len - bch->tx_idx;
> - if (count <= 0)
> - return;
> - p = bch->tx_skb->data + bch->tx_idx;
> - }
> - hdlc->ctrl.sr.cmd &= ~HDLC_CMD_XME;
> - if (count > fs) {
> - count = fs;
> - } else {
> - if (test_bit(FLG_HDLC, &bch->Flags))
> - hdlc->ctrl.sr.cmd |= HDLC_CMD_XME;
> - }
> - ptr = (u32 *)p;
> - if (!fillempty) {
> - pr_debug("%s.B%d: %d/%d/%d", fc->name, bch->nr, count,
> - bch->tx_idx, bch->tx_skb->len);
> - bch->tx_idx += count;
> - } else {
> - pr_debug("%s.B%d: fillempty %d\n", fc->name, bch->nr, count);
> - }
> - hdlc->ctrl.sr.xml = ((count == fs) ? 0 : count);
> - if (fc->type == AVM_FRITZ_PCIV2) {
> - __write_ctrl_pciv2(fc, hdlc, bch->nr);
> - addr = fc->addr + (bch->nr == 2 ?
> - AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1);
> - } else {
> - __write_ctrl_pci(fc, hdlc, bch->nr);
> - addr = fc->addr + CHIP_WINDOW;
> - }
> - if (fillempty) {
> - while (cnt < count) {
> - /* all bytes the same - no worry about endian */
> - outl(*ptr, addr);
> - cnt += 4;
> - }
> - } else {
> - while (cnt < count) {
> - val = get_unaligned(ptr);
> - outl(cpu_to_le32(val), addr);
> - ptr++;
> - cnt += 4;
> - }
> - }
> - if ((debug & DEBUG_HW_BFIFO) && !fillempty) {
> - snprintf(fc->log, LOG_SIZE, "B%1d-send %s %d ",
> - bch->nr, fc->name, count);
> - print_hex_dump_bytes(fc->log, DUMP_PREFIX_OFFSET, p, count);
> - }
> -}
> -
> -static void
> -HDLC_irq_xpr(struct bchannel *bch)
> -{
> - if (bch->tx_skb && bch->tx_idx < bch->tx_skb->len) {
> - hdlc_fill_fifo(bch);
> - } else {
> - dev_kfree_skb(bch->tx_skb);
> - if (get_next_bframe(bch)) {
> - hdlc_fill_fifo(bch);
> - test_and_clear_bit(FLG_TX_EMPTY, &bch->Flags);
> - } else if (test_bit(FLG_TX_EMPTY, &bch->Flags)) {
> - hdlc_fill_fifo(bch);
> - }
> - }
> -}
> -
> -static void
> -HDLC_irq(struct bchannel *bch, u32 stat)
> -{
> - struct fritzcard *fc = bch->hw;
> - int len, fs;
> - u32 rmlMask;
> - struct hdlc_hw *hdlc;
> -
> - hdlc = &fc->hdlc[(bch->nr - 1) & 1];
> - pr_debug("%s: ch%d stat %#x\n", fc->name, bch->nr, stat);
> - if (fc->type == AVM_FRITZ_PCIV2) {
> - rmlMask = HDLC_STAT_RML_MASK_V2;
> - fs = HDLC_FIFO_SIZE_V2;
> - } else {
> - rmlMask = HDLC_STAT_RML_MASK_V1;
> - fs = HDLC_FIFO_SIZE_V1;
> - }
> - if (stat & HDLC_INT_RPR) {
> - if (stat & HDLC_STAT_RDO) {
> - pr_warn("%s: ch%d stat %x RDO\n",
> - fc->name, bch->nr, stat);
> - hdlc->ctrl.sr.xml = 0;
> - hdlc->ctrl.sr.cmd |= HDLC_CMD_RRS;
> - write_ctrl(bch, 1);
> - hdlc->ctrl.sr.cmd &= ~HDLC_CMD_RRS;
> - write_ctrl(bch, 1);
> - if (bch->rx_skb)
> - skb_trim(bch->rx_skb, 0);
> - } else {
> - len = (stat & rmlMask) >> 8;
> - if (!len)
> - len = fs;
> - hdlc_empty_fifo(bch, len);
> - if (!bch->rx_skb)
> - goto handle_tx;
> - if (test_bit(FLG_TRANSPARENT, &bch->Flags)) {
> - recv_Bchannel(bch, 0, false);
> - } else if (stat & HDLC_STAT_RME) {
> - if ((stat & HDLC_STAT_CRCVFRRAB) ==
> - HDLC_STAT_CRCVFR) {
> - recv_Bchannel(bch, 0, false);
> - } else {
> - pr_warn("%s: got invalid frame\n",
> - fc->name);
> - skb_trim(bch->rx_skb, 0);
> - }
> - }
> - }
> - }
> -handle_tx:
> - if (stat & HDLC_INT_XDU) {
> - /* Here we lost an TX interrupt, so
> - * restart transmitting the whole frame on HDLC
> - * in transparent mode we send the next data
> - */
> - pr_warn("%s: ch%d stat %x XDU %s\n", fc->name, bch->nr,
> - stat, bch->tx_skb ? "tx_skb" : "no tx_skb");
> - if (bch->tx_skb && bch->tx_skb->len) {
> - if (!test_bit(FLG_TRANSPARENT, &bch->Flags))
> - bch->tx_idx = 0;
> - } else if (test_bit(FLG_FILLEMPTY, &bch->Flags)) {
> - test_and_set_bit(FLG_TX_EMPTY, &bch->Flags);
> - }
> - hdlc->ctrl.sr.xml = 0;
> - hdlc->ctrl.sr.cmd |= HDLC_CMD_XRS;
> - write_ctrl(bch, 1);
> - hdlc->ctrl.sr.cmd &= ~HDLC_CMD_XRS;
> - HDLC_irq_xpr(bch);
> - return;
> - } else if (stat & HDLC_INT_XPR)
> - HDLC_irq_xpr(bch);
> -}
> -
> -static inline void
> -HDLC_irq_main(struct fritzcard *fc)
> -{
> - u32 stat;
> - struct bchannel *bch;
> -
> - stat = read_status(fc, 1);
> - if (stat & HDLC_INT_MASK) {
> - bch = Sel_BCS(fc, 1);
> - if (bch)
> - HDLC_irq(bch, stat);
> - else
> - pr_debug("%s: spurious ch1 IRQ\n", fc->name);
> - }
> - stat = read_status(fc, 2);
> - if (stat & HDLC_INT_MASK) {
> - bch = Sel_BCS(fc, 2);
> - if (bch)
> - HDLC_irq(bch, stat);
> - else
> - pr_debug("%s: spurious ch2 IRQ\n", fc->name);
> - }
> -}
> -
> -static irqreturn_t
> -avm_fritz_interrupt(int intno, void *dev_id)
> -{
> - struct fritzcard *fc = dev_id;
> - u8 val;
> - u8 sval;
> -
> - spin_lock(&fc->lock);
> - sval = inb(fc->addr + 2);
> - pr_debug("%s: irq stat0 %x\n", fc->name, sval);
> - if ((sval & AVM_STATUS0_IRQ_MASK) == AVM_STATUS0_IRQ_MASK) {
> - /* shared IRQ from other HW */
> - spin_unlock(&fc->lock);
> - return IRQ_NONE;
> - }
> - fc->irqcnt++;
> -
> - if (!(sval & AVM_STATUS0_IRQ_ISAC)) {
> - val = ReadISAC_V1(fc, ISAC_ISTA);
> - mISDNisac_irq(&fc->isac, val);
> - }
> - if (!(sval & AVM_STATUS0_IRQ_HDLC))
> - HDLC_irq_main(fc);
> - spin_unlock(&fc->lock);
> - return IRQ_HANDLED;
> -}
> -
> -static irqreturn_t
> -avm_fritzv2_interrupt(int intno, void *dev_id)
> -{
> - struct fritzcard *fc = dev_id;
> - u8 val;
> - u8 sval;
> -
> - spin_lock(&fc->lock);
> - sval = inb(fc->addr + 2);
> - pr_debug("%s: irq stat0 %x\n", fc->name, sval);
> - if (!(sval & AVM_STATUS0_IRQ_MASK)) {
> - /* shared IRQ from other HW */
> - spin_unlock(&fc->lock);
> - return IRQ_NONE;
> - }
> - fc->irqcnt++;
> -
> - if (sval & AVM_STATUS0_IRQ_HDLC)
> - HDLC_irq_main(fc);
> - if (sval & AVM_STATUS0_IRQ_ISAC) {
> - val = ReadISAC_V2(fc, ISACX_ISTA);
> - mISDNisac_irq(&fc->isac, val);
> - }
> - if (sval & AVM_STATUS0_IRQ_TIMER) {
> - pr_debug("%s: timer irq\n", fc->name);
> - outb(fc->ctrlreg | AVM_STATUS0_RES_TIMER, fc->addr + 2);
> - udelay(1);
> - outb(fc->ctrlreg, fc->addr + 2);
> - }
> - spin_unlock(&fc->lock);
> - return IRQ_HANDLED;
> -}
> -
> -static int
> -avm_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)
> -{
> - struct bchannel *bch = container_of(ch, struct bchannel, ch);
> - struct fritzcard *fc = bch->hw;
> - int ret = -EINVAL;
> - struct mISDNhead *hh = mISDN_HEAD_P(skb);
> - unsigned long flags;
> -
> - switch (hh->prim) {
> - case PH_DATA_REQ:
> - spin_lock_irqsave(&fc->lock, flags);
> - ret = bchannel_senddata(bch, skb);
> - if (ret > 0) { /* direct TX */
> - hdlc_fill_fifo(bch);
> - ret = 0;
> - }
> - spin_unlock_irqrestore(&fc->lock, flags);
> - return ret;
> - case PH_ACTIVATE_REQ:
> - spin_lock_irqsave(&fc->lock, flags);
> - if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags))
> - ret = modehdlc(bch, ch->protocol);
> - else
> - ret = 0;
> - spin_unlock_irqrestore(&fc->lock, flags);
> - if (!ret)
> - _queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
> - NULL, GFP_KERNEL);
> - break;
> - case PH_DEACTIVATE_REQ:
> - spin_lock_irqsave(&fc->lock, flags);
> - mISDN_clear_bchannel(bch);
> - modehdlc(bch, ISDN_P_NONE);
> - spin_unlock_irqrestore(&fc->lock, flags);
> - _queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
> - NULL, GFP_KERNEL);
> - ret = 0;
> - break;
> - }
> - if (!ret)
> - dev_kfree_skb(skb);
> - return ret;
> -}
> -
> -static void
> -inithdlc(struct fritzcard *fc)
> -{
> - modehdlc(&fc->bch[0], -1);
> - modehdlc(&fc->bch[1], -1);
> -}
> -
> -static void
> -clear_pending_hdlc_ints(struct fritzcard *fc)
> -{
> - u32 val;
> -
> - val = read_status(fc, 1);
> - pr_debug("%s: HDLC 1 STA %x\n", fc->name, val);
> - val = read_status(fc, 2);
> - pr_debug("%s: HDLC 2 STA %x\n", fc->name, val);
> -}
> -
> -static void
> -reset_avm(struct fritzcard *fc)
> -{
> - switch (fc->type) {
> - case AVM_FRITZ_PCI:
> - fc->ctrlreg = AVM_STATUS0_RESET | AVM_STATUS0_DIS_TIMER;
> - break;
> - case AVM_FRITZ_PCIV2:
> - fc->ctrlreg = AVM_STATUS0_RESET;
> - break;
> - }
> - if (debug & DEBUG_HW)
> - pr_notice("%s: reset\n", fc->name);
> - disable_hwirq(fc);
> - mdelay(5);
> - switch (fc->type) {
> - case AVM_FRITZ_PCI:
> - fc->ctrlreg = AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER;
> - disable_hwirq(fc);
> - outb(AVM_STATUS1_ENA_IOM, fc->addr + 3);
> - break;
> - case AVM_FRITZ_PCIV2:
> - fc->ctrlreg = 0;
> - disable_hwirq(fc);
> - break;
> - }
> - mdelay(1);
> - if (debug & DEBUG_HW)
> - pr_notice("%s: S0/S1 %x/%x\n", fc->name,
> - inb(fc->addr + 2), inb(fc->addr + 3));
> -}
> -
> -static int
> -init_card(struct fritzcard *fc)
> -{
> - int ret, cnt = 3;
> - u_long flags;
> -
> - reset_avm(fc); /* disable IRQ */
> - if (fc->type == AVM_FRITZ_PCIV2)
> - ret = request_irq(fc->irq, avm_fritzv2_interrupt,
> - IRQF_SHARED, fc->name, fc);
> - else
> - ret = request_irq(fc->irq, avm_fritz_interrupt,
> - IRQF_SHARED, fc->name, fc);
> - if (ret) {
> - pr_info("%s: couldn't get interrupt %d\n",
> - fc->name, fc->irq);
> - return ret;
> - }
> - while (cnt--) {
> - spin_lock_irqsave(&fc->lock, flags);
> - ret = fc->isac.init(&fc->isac);
> - if (ret) {
> - spin_unlock_irqrestore(&fc->lock, flags);
> - pr_info("%s: ISAC init failed with %d\n",
> - fc->name, ret);
> - break;
> - }
> - clear_pending_hdlc_ints(fc);
> - inithdlc(fc);
> - enable_hwirq(fc);
> - /* RESET Receiver and Transmitter */
> - if (fc->type == AVM_FRITZ_PCIV2) {
> - WriteISAC_V2(fc, ISACX_MASK, 0);
> - WriteISAC_V2(fc, ISACX_CMDRD, 0x41);
> - } else {
> - WriteISAC_V1(fc, ISAC_MASK, 0);
> - WriteISAC_V1(fc, ISAC_CMDR, 0x41);
> - }
> - spin_unlock_irqrestore(&fc->lock, flags);
> - /* Timeout 10ms */
> - msleep_interruptible(10);
> - if (debug & DEBUG_HW)
> - pr_notice("%s: IRQ %d count %d\n", fc->name,
> - fc->irq, fc->irqcnt);
> - if (!fc->irqcnt) {
> - pr_info("%s: IRQ(%d) getting no IRQs during init %d\n",
> - fc->name, fc->irq, 3 - cnt);
> - reset_avm(fc);
> - } else
> - return 0;
> - }
> - free_irq(fc->irq, fc);
> - return -EIO;
> -}
> -
> -static int
> -channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
> -{
> - return mISDN_ctrl_bchannel(bch, cq);
> -}
> -
> -static int
> -avm_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
> -{
> - struct bchannel *bch = container_of(ch, struct bchannel, ch);
> - struct fritzcard *fc = bch->hw;
> - int ret = -EINVAL;
> - u_long flags;
> -
> - pr_debug("%s: %s cmd:%x %p\n", fc->name, __func__, cmd, arg);
> - switch (cmd) {
> - case CLOSE_CHANNEL:
> - test_and_clear_bit(FLG_OPEN, &bch->Flags);
> - cancel_work_sync(&bch->workq);
> - spin_lock_irqsave(&fc->lock, flags);
> - mISDN_clear_bchannel(bch);
> - modehdlc(bch, ISDN_P_NONE);
> - spin_unlock_irqrestore(&fc->lock, flags);
> - ch->protocol = ISDN_P_NONE;
> - ch->peer = NULL;
> - module_put(THIS_MODULE);
> - ret = 0;
> - break;
> - case CONTROL_CHANNEL:
> - ret = channel_bctrl(bch, arg);
> - break;
> - default:
> - pr_info("%s: %s unknown prim(%x)\n", fc->name, __func__, cmd);
> - }
> - return ret;
> -}
> -
> -static int
> -channel_ctrl(struct fritzcard *fc, struct mISDN_ctrl_req *cq)
> -{
> - int ret = 0;
> -
> - switch (cq->op) {
> - case MISDN_CTRL_GETOP:
> - cq->op = MISDN_CTRL_LOOP | MISDN_CTRL_L1_TIMER3;
> - break;
> - case MISDN_CTRL_LOOP:
> - /* cq->channel: 0 disable, 1 B1 loop 2 B2 loop, 3 both */
> - if (cq->channel < 0 || cq->channel > 3) {
> - ret = -EINVAL;
> - break;
> - }
> - ret = fc->isac.ctrl(&fc->isac, HW_TESTLOOP, cq->channel);
> - break;
> - case MISDN_CTRL_L1_TIMER3:
> - ret = fc->isac.ctrl(&fc->isac, HW_TIMER3_VALUE, cq->p1);
> - break;
> - default:
> - pr_info("%s: %s unknown Op %x\n", fc->name, __func__, cq->op);
> - ret = -EINVAL;
> - break;
> - }
> - return ret;
> -}
> -
> -static int
> -open_bchannel(struct fritzcard *fc, struct channel_req *rq)
> -{
> - struct bchannel *bch;
> -
> - if (rq->adr.channel == 0 || rq->adr.channel > 2)
> - return -EINVAL;
> - if (rq->protocol == ISDN_P_NONE)
> - return -EINVAL;
> - bch = &fc->bch[rq->adr.channel - 1];
> - if (test_and_set_bit(FLG_OPEN, &bch->Flags))
> - return -EBUSY; /* b-channel can be only open once */
> - bch->ch.protocol = rq->protocol;
> - rq->ch = &bch->ch;
> - return 0;
> -}
> -
> -/*
> - * device control function
> - */
> -static int
> -avm_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
> -{
> - struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
> - struct dchannel *dch = container_of(dev, struct dchannel, dev);
> - struct fritzcard *fc = dch->hw;
> - struct channel_req *rq;
> - int err = 0;
> -
> - pr_debug("%s: %s cmd:%x %p\n", fc->name, __func__, cmd, arg);
> - switch (cmd) {
> - case OPEN_CHANNEL:
> - rq = arg;
> - if (rq->protocol == ISDN_P_TE_S0)
> - err = fc->isac.open(&fc->isac, rq);
> - else
> - err = open_bchannel(fc, rq);
> - if (err)
> - break;
> - if (!try_module_get(THIS_MODULE))
> - pr_info("%s: cannot get module\n", fc->name);
> - break;
> - case CLOSE_CHANNEL:
> - pr_debug("%s: dev(%d) close from %p\n", fc->name, dch->dev.id,
> - __builtin_return_address(0));
> - module_put(THIS_MODULE);
> - break;
> - case CONTROL_CHANNEL:
> - err = channel_ctrl(fc, arg);
> - break;
> - default:
> - pr_debug("%s: %s unknown command %x\n",
> - fc->name, __func__, cmd);
> - return -EINVAL;
> - }
> - return err;
> -}
> -
> -static int
> -setup_fritz(struct fritzcard *fc)
> -{
> - u32 val, ver;
> -
> - if (!request_region(fc->addr, 32, fc->name)) {
> - pr_info("%s: AVM config port %x-%x already in use\n",
> - fc->name, fc->addr, fc->addr + 31);
> - return -EIO;
> - }
> - switch (fc->type) {
> - case AVM_FRITZ_PCI:
> - val = inl(fc->addr);
> - outl(AVM_HDLC_1, fc->addr + CHIP_INDEX);
> - ver = inl(fc->addr + CHIP_WINDOW + HDLC_STATUS) >> 24;
> - if (debug & DEBUG_HW) {
> - pr_notice("%s: PCI stat %#x\n", fc->name, val);
> - pr_notice("%s: PCI Class %X Rev %d\n", fc->name,
> - val & 0xff, (val >> 8) & 0xff);
> - pr_notice("%s: HDLC version %x\n", fc->name, ver & 0xf);
> - }
> - ASSIGN_FUNC(V1, ISAC, fc->isac);
> - fc->isac.type = IPAC_TYPE_ISAC;
> - break;
> - case AVM_FRITZ_PCIV2:
> - val = inl(fc->addr);
> - ver = inl(fc->addr + AVM_HDLC_STATUS_1) >> 24;
> - if (debug & DEBUG_HW) {
> - pr_notice("%s: PCI V2 stat %#x\n", fc->name, val);
> - pr_notice("%s: PCI V2 Class %X Rev %d\n", fc->name,
> - val & 0xff, (val >> 8) & 0xff);
> - pr_notice("%s: HDLC version %x\n", fc->name, ver & 0xf);
> - }
> - ASSIGN_FUNC(V2, ISAC, fc->isac);
> - fc->isac.type = IPAC_TYPE_ISACX;
> - break;
> - default:
> - release_region(fc->addr, 32);
> - pr_info("%s: AVM unknown type %d\n", fc->name, fc->type);
> - return -ENODEV;
> - }
> - pr_notice("%s: %s config irq:%d base:0x%X\n", fc->name,
> - (fc->type == AVM_FRITZ_PCI) ? "AVM Fritz!CARD PCI" :
> - "AVM Fritz!CARD PCIv2", fc->irq, fc->addr);
> - return 0;
> -}
> -
> -static void
> -release_card(struct fritzcard *card)
> -{
> - u_long flags;
> -
> - disable_hwirq(card);
> - spin_lock_irqsave(&card->lock, flags);
> - modehdlc(&card->bch[0], ISDN_P_NONE);
> - modehdlc(&card->bch[1], ISDN_P_NONE);
> - spin_unlock_irqrestore(&card->lock, flags);
> - card->isac.release(&card->isac);
> - free_irq(card->irq, card);
> - mISDN_freebchannel(&card->bch[1]);
> - mISDN_freebchannel(&card->bch[0]);
> - mISDN_unregister_device(&card->isac.dch.dev);
> - release_region(card->addr, 32);
> - pci_disable_device(card->pdev);
> - pci_set_drvdata(card->pdev, NULL);
> - write_lock_irqsave(&card_lock, flags);
> - list_del(&card->list);
> - write_unlock_irqrestore(&card_lock, flags);
> - kfree(card);
> - AVM_cnt--;
> -}
> -
> -static int
> -setup_instance(struct fritzcard *card)
> -{
> - int i, err;
> - unsigned short minsize;
> - u_long flags;
> -
> - snprintf(card->name, MISDN_MAX_IDLEN - 1, "AVM.%d", AVM_cnt + 1);
> - write_lock_irqsave(&card_lock, flags);
> - list_add_tail(&card->list, &Cards);
> - write_unlock_irqrestore(&card_lock, flags);
> -
> - _set_debug(card);
> - card->isac.name = card->name;
> - spin_lock_init(&card->lock);
> - card->isac.hwlock = &card->lock;
> - mISDNisac_init(&card->isac, card);
> -
> - card->isac.dch.dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
> - (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
> - card->isac.dch.dev.D.ctrl = avm_dctrl;
> - for (i = 0; i < 2; i++) {
> - card->bch[i].nr = i + 1;
> - set_channelmap(i + 1, card->isac.dch.dev.channelmap);
> - if (AVM_FRITZ_PCIV2 == card->type)
> - minsize = HDLC_FIFO_SIZE_V2;
> - else
> - minsize = HDLC_FIFO_SIZE_V1;
> - mISDN_initbchannel(&card->bch[i], MAX_DATA_MEM, minsize);
> - card->bch[i].hw = card;
> - card->bch[i].ch.send = avm_l2l1B;
> - card->bch[i].ch.ctrl = avm_bctrl;
> - card->bch[i].ch.nr = i + 1;
> - list_add(&card->bch[i].ch.list, &card->isac.dch.dev.bchannels);
> - }
> - err = setup_fritz(card);
> - if (err)
> - goto error;
> - err = mISDN_register_device(&card->isac.dch.dev, &card->pdev->dev,
> - card->name);
> - if (err)
> - goto error_reg;
> - err = init_card(card);
> - if (!err) {
> - AVM_cnt++;
> - pr_notice("AVM %d cards installed DEBUG\n", AVM_cnt);
> - return 0;
> - }
> - mISDN_unregister_device(&card->isac.dch.dev);
> -error_reg:
> - release_region(card->addr, 32);
> -error:
> - card->isac.release(&card->isac);
> - mISDN_freebchannel(&card->bch[1]);
> - mISDN_freebchannel(&card->bch[0]);
> - write_lock_irqsave(&card_lock, flags);
> - list_del(&card->list);
> - write_unlock_irqrestore(&card_lock, flags);
> - kfree(card);
> - return err;
> -}
> -
> -static int
> -fritzpci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
> -{
> - int err = -ENOMEM;
> - struct fritzcard *card;
> -
> - card = kzalloc_obj(struct fritzcard);
> - if (!card) {
> - pr_info("No kmem for fritzcard\n");
> - return err;
> - }
> - if (pdev->device == PCI_DEVICE_ID_AVM_A1_V2)
> - card->type = AVM_FRITZ_PCIV2;
> - else
> - card->type = AVM_FRITZ_PCI;
> - card->pdev = pdev;
> - err = pci_enable_device(pdev);
> - if (err) {
> - kfree(card);
> - return err;
> - }
> -
> - pr_notice("mISDN: found adapter %s at %s\n",
> - (char *) ent->driver_data, pci_name(pdev));
> -
> - card->addr = pci_resource_start(pdev, 1);
> - card->irq = pdev->irq;
> - pci_set_drvdata(pdev, card);
> - err = setup_instance(card);
> - if (err)
> - pci_set_drvdata(pdev, NULL);
> - return err;
> -}
> -
> -static void
> -fritz_remove_pci(struct pci_dev *pdev)
> -{
> - struct fritzcard *card = pci_get_drvdata(pdev);
> -
> - if (card)
> - release_card(card);
> - else
> - if (debug)
> - pr_info("%s: drvdata already removed\n", __func__);
> -}
> -
> -static const struct pci_device_id fcpci_ids[] = {
> - { PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_A1, PCI_ANY_ID, PCI_ANY_ID,
> - 0, 0, (unsigned long) "Fritz!Card PCI"},
> - { PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_A1_V2, PCI_ANY_ID, PCI_ANY_ID,
> - 0, 0, (unsigned long) "Fritz!Card PCI v2" },
> - { }
> -};
> -MODULE_DEVICE_TABLE(pci, fcpci_ids);
> -
> -static struct pci_driver fcpci_driver = {
> - .name = "fcpci",
> - .probe = fritzpci_probe,
> - .remove = fritz_remove_pci,
> - .id_table = fcpci_ids,
> -};
> -
> -static int __init AVM_init(void)
> -{
> - int err;
> -
> - pr_notice("AVM Fritz PCI driver Rev. %s\n", AVMFRITZ_REV);
> - err = pci_register_driver(&fcpci_driver);
> - return err;
> -}
> -
> -static void __exit AVM_cleanup(void)
> -{
> - pci_unregister_driver(&fcpci_driver);
> -}
> -
> -module_init(AVM_init);
> -module_exit(AVM_cleanup);
> diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c
> deleted file mode 100644
> index b3d28976b33a..000000000000
> --- a/drivers/isdn/hardware/mISDN/hfcmulti.c
> +++ /dev/null
> @@ -1,5540 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-or-later
> -/*
> - * hfcmulti.c low level driver for hfc-4s/hfc-8s/hfc-e1 based cards
> - *
> - * Author Andreas Eversberg (jolly@eversberg.eu)
> - * ported to mqueue mechanism:
> - * Peter Sprenger (sprengermoving-bytes.de)
> - *
> - * inspired by existing hfc-pci driver:
> - * Copyright 1999 by Werner Cornelius (werner@isdn-development.de)
> - * Copyright 2008 by Karsten Keil (kkeil@suse.de)
> - * Copyright 2008 by Andreas Eversberg (jolly@eversberg.eu)
> - *
> - * Thanks to Cologne Chip AG for this great controller!
> - */
> -
> -/*
> - * module parameters:
> - * type:
> - * By default (0), the card is automatically detected.
> - * Or use the following combinations:
> - * Bit 0-7 = 0x00001 = HFC-E1 (1 port)
> - * or Bit 0-7 = 0x00004 = HFC-4S (4 ports)
> - * or Bit 0-7 = 0x00008 = HFC-8S (8 ports)
> - * Bit 8 = 0x00100 = uLaw (instead of aLaw)
> - * Bit 9 = 0x00200 = Disable DTMF detect on all B-channels via hardware
> - * Bit 10 = spare
> - * Bit 11 = 0x00800 = Force PCM bus into slave mode. (otherwise auto)
> - * or Bit 12 = 0x01000 = Force PCM bus into master mode. (otherwise auto)
> - * Bit 13 = spare
> - * Bit 14 = 0x04000 = Use external ram (128K)
> - * Bit 15 = 0x08000 = Use external ram (512K)
> - * Bit 16 = 0x10000 = Use 64 timeslots instead of 32
> - * or Bit 17 = 0x20000 = Use 128 timeslots instead of anything else
> - * Bit 18 = spare
> - * Bit 19 = 0x80000 = Send the Watchdog a Signal (Dual E1 with Watchdog)
> - * (all other bits are reserved and shall be 0)
> - * example: 0x20204 one HFC-4S with dtmf detection and 128 timeslots on PCM
> - * bus (PCM master)
> - *
> - * port: (optional or required for all ports on all installed cards)
> - * HFC-4S/HFC-8S only bits:
> - * Bit 0 = 0x001 = Use master clock for this S/T interface
> - * (only once per chip).
> - * Bit 1 = 0x002 = transmitter line setup (non capacitive mode)
> - * Don't use this unless you know what you are doing!
> - * Bit 2 = 0x004 = Disable E-channel. (No E-channel processing)
> - * example: 0x0001,0x0000,0x0000,0x0000 one HFC-4S with master clock
> - * received from port 1
> - *
> - * HFC-E1 only bits:
> - * Bit 0 = 0x0001 = interface: 0=copper, 1=optical
> - * Bit 1 = 0x0002 = reserved (later for 32 B-channels transparent mode)
> - * Bit 2 = 0x0004 = Report LOS
> - * Bit 3 = 0x0008 = Report AIS
> - * Bit 4 = 0x0010 = Report SLIP
> - * Bit 5 = 0x0020 = Report RDI
> - * Bit 8 = 0x0100 = Turn off CRC-4 Multiframe Mode, use double frame
> - * mode instead.
> - * Bit 9 = 0x0200 = Force get clock from interface, even in NT mode.
> - * or Bit 10 = 0x0400 = Force put clock to interface, even in TE mode.
> - * Bit 11 = 0x0800 = Use direct RX clock for PCM sync rather than PLL.
> - * (E1 only)
> - * Bit 12-13 = 0xX000 = elastic jitter buffer (1-3), Set both bits to 0
> - * for default.
> - * (all other bits are reserved and shall be 0)
> - *
> - * debug:
> - * NOTE: only one debug value must be given for all cards
> - * enable debugging (see hfc_multi.h for debug options)
> - *
> - * poll:
> - * NOTE: only one poll value must be given for all cards
> - * Give the number of samples for each fifo process.
> - * By default 128 is used. Decrease to reduce delay, increase to
> - * reduce cpu load. If unsure, don't mess with it!
> - * Valid is 8, 16, 32, 64, 128, 256.
> - *
> - * pcm:
> - * NOTE: only one pcm value must be given for every card.
> - * The PCM bus id tells the mISDNdsp module about the connected PCM bus.
> - * By default (0), the PCM bus id is 100 for the card that is PCM master.
> - * If multiple cards are PCM master (because they are not interconnected),
> - * each card with PCM master will have increasing PCM id.
> - * All PCM buses with the same ID are expected to be connected and have
> - * common time slots slots.
> - * Only one chip of the PCM bus must be master, the others slave.
> - * -1 means no support of PCM bus not even.
> - * Omit this value, if all cards are interconnected or none is connected.
> - * If unsure, don't give this parameter.
> - *
> - * dmask and bmask:
> - * NOTE: One dmask value must be given for every HFC-E1 card.
> - * If omitted, the E1 card has D-channel on time slot 16, which is default.
> - * dmask is a 32 bit mask. The bit must be set for an alternate time slot.
> - * If multiple bits are set, multiple virtual card fragments are created.
> - * For each bit set, a bmask value must be given. Each bit on the bmask
> - * value stands for a B-channel. The bmask may not overlap with dmask or
> - * with other bmask values for that card.
> - * Example: dmask=0x00020002 bmask=0x0000fffc,0xfffc0000
> - * This will create one fragment with D-channel on slot 1 with
> - * B-channels on slots 2..15, and a second fragment with D-channel
> - * on slot 17 with B-channels on slot 18..31. Slot 16 is unused.
> - * If bit 0 is set (dmask=0x00000001) the D-channel is on slot 0 and will
> - * not function.
> - * Example: dmask=0x00000001 bmask=0xfffffffe
> - * This will create a port with all 31 usable timeslots as
> - * B-channels.
> - * If no bits are set on bmask, no B-channel is created for that fragment.
> - * Example: dmask=0xfffffffe bmask=0,0,0,0.... (31 0-values for bmask)
> - * This will create 31 ports with one D-channel only.
> - * If you don't know how to use it, you don't need it!
> - *
> - * iomode:
> - * NOTE: only one mode value must be given for every card.
> - * -> See hfc_multi.h for HFC_IO_MODE_* values
> - * By default, the IO mode is pci memory IO (MEMIO).
> - * Some cards require specific IO mode, so it cannot be changed.
> - * It may be useful to set IO mode to register io (REGIO) to solve
> - * PCI bridge problems.
> - * If unsure, don't give this parameter.
> - *
> - * clockdelay_nt:
> - * NOTE: only one clockdelay_nt value must be given once for all cards.
> - * Give the value of the clock control register (A_ST_CLK_DLY)
> - * of the S/T interfaces in NT mode.
> - * This register is needed for the TBR3 certification, so don't change it.
> - *
> - * clockdelay_te:
> - * NOTE: only one clockdelay_te value must be given once
> - * Give the value of the clock control register (A_ST_CLK_DLY)
> - * of the S/T interfaces in TE mode.
> - * This register is needed for the TBR3 certification, so don't change it.
> - *
> - * clock:
> - * NOTE: only one clock value must be given once
> - * Selects interface with clock source for mISDN and applications.
> - * Set to card number starting with 1. Set to -1 to disable.
> - * By default, the first card is used as clock source.
> - *
> - * hwid:
> - * NOTE: only one hwid value must be given once
> - * Enable special embedded devices with XHFC controllers.
> - */
> -
> -/*
> - * debug register access (never use this, it will flood your system log)
> - * #define HFC_REGISTER_DEBUG
> - */
> -
> -#define HFC_MULTI_VERSION "2.03"
> -
> -#include <linux/interrupt.h>
> -#include <linux/module.h>
> -#include <linux/slab.h>
> -#include <linux/pci.h>
> -#include <linux/delay.h>
> -#include <linux/mISDNhw.h>
> -#include <linux/mISDNdsp.h>
> -
> -/*
> - #define IRQCOUNT_DEBUG
> - #define IRQ_DEBUG
> -*/
> -
> -#include "hfc_multi.h"
> -#ifdef ECHOPREP
> -#include "gaintab.h"
> -#endif
> -
> -#define MAX_CARDS 8
> -#define MAX_PORTS (8 * MAX_CARDS)
> -#define MAX_FRAGS (32 * MAX_CARDS)
> -
> -static LIST_HEAD(HFClist);
> -static DEFINE_SPINLOCK(HFClock); /* global hfc list lock */
> -
> -static void ph_state_change(struct dchannel *);
> -
> -static struct hfc_multi *syncmaster;
> -static int plxsd_master; /* if we have a master card (yet) */
> -static DEFINE_SPINLOCK(plx_lock); /* may not acquire other lock inside */
> -
> -#define TYP_E1 1
> -#define TYP_4S 4
> -#define TYP_8S 8
> -
> -static int poll_timer = 6; /* default = 128 samples = 16ms */
> -/* number of POLL_TIMER interrupts for G2 timeout (ca 1s) */
> -static int nt_t1_count[] = { 3840, 1920, 960, 480, 240, 120, 60, 30 };
> -#define CLKDEL_TE 0x0f /* CLKDEL in TE mode */
> -#define CLKDEL_NT 0x6c /* CLKDEL in NT mode
> - (0x60 MUST be included!) */
> -
> -#define DIP_4S 0x1 /* DIP Switches for Beronet 1S/2S/4S cards */
> -#define DIP_8S 0x2 /* DIP Switches for Beronet 8S+ cards */
> -#define DIP_E1 0x3 /* DIP Switches for Beronet E1 cards */
> -
> -/*
> - * module stuff
> - */
> -
> -static uint type[MAX_CARDS];
> -static int pcm[MAX_CARDS];
> -static uint dmask[MAX_CARDS];
> -static uint bmask[MAX_FRAGS];
> -static uint iomode[MAX_CARDS];
> -static uint port[MAX_PORTS];
> -static uint debug;
> -static uint poll;
> -static int clock;
> -static uint timer;
> -static uint clockdelay_te = CLKDEL_TE;
> -static uint clockdelay_nt = CLKDEL_NT;
> -#define HWID_NONE 0
> -#define HWID_MINIP4 1
> -#define HWID_MINIP8 2
> -#define HWID_MINIP16 3
> -static uint hwid = HWID_NONE;
> -
> -static int HFC_cnt, E1_cnt, bmask_cnt, Port_cnt, PCM_cnt = 99;
> -
> -MODULE_AUTHOR("Andreas Eversberg");
> -MODULE_DESCRIPTION("mISDN driver for hfc-4s/hfc-8s/hfc-e1 based cards");
> -MODULE_LICENSE("GPL");
> -MODULE_VERSION(HFC_MULTI_VERSION);
> -module_param(debug, uint, S_IRUGO | S_IWUSR);
> -module_param(poll, uint, S_IRUGO | S_IWUSR);
> -module_param(clock, int, S_IRUGO | S_IWUSR);
> -module_param(timer, uint, S_IRUGO | S_IWUSR);
> -module_param(clockdelay_te, uint, S_IRUGO | S_IWUSR);
> -module_param(clockdelay_nt, uint, S_IRUGO | S_IWUSR);
> -module_param_array(type, uint, NULL, S_IRUGO | S_IWUSR);
> -module_param_array(pcm, int, NULL, S_IRUGO | S_IWUSR);
> -module_param_array(dmask, uint, NULL, S_IRUGO | S_IWUSR);
> -module_param_array(bmask, uint, NULL, S_IRUGO | S_IWUSR);
> -module_param_array(iomode, uint, NULL, S_IRUGO | S_IWUSR);
> -module_param_array(port, uint, NULL, S_IRUGO | S_IWUSR);
> -module_param(hwid, uint, S_IRUGO | S_IWUSR); /* The hardware ID */
> -
> -#ifdef HFC_REGISTER_DEBUG
> -#define HFC_outb(hc, reg, val) \
> - (hc->HFC_outb(hc, reg, val, __func__, __LINE__))
> -#define HFC_outb_nodebug(hc, reg, val) \
> - (hc->HFC_outb_nodebug(hc, reg, val, __func__, __LINE__))
> -#define HFC_inb(hc, reg) \
> - (hc->HFC_inb(hc, reg, __func__, __LINE__))
> -#define HFC_inb_nodebug(hc, reg) \
> - (hc->HFC_inb_nodebug(hc, reg, __func__, __LINE__))
> -#define HFC_inw(hc, reg) \
> - (hc->HFC_inw(hc, reg, __func__, __LINE__))
> -#define HFC_inw_nodebug(hc, reg) \
> - (hc->HFC_inw_nodebug(hc, reg, __func__, __LINE__))
> -#define HFC_wait(hc) \
> - (hc->HFC_wait(hc, __func__, __LINE__))
> -#define HFC_wait_nodebug(hc) \
> - (hc->HFC_wait_nodebug(hc, __func__, __LINE__))
> -#else
> -#define HFC_outb(hc, reg, val) (hc->HFC_outb(hc, reg, val))
> -#define HFC_outb_nodebug(hc, reg, val) (hc->HFC_outb_nodebug(hc, reg, val))
> -#define HFC_inb(hc, reg) (hc->HFC_inb(hc, reg))
> -#define HFC_inb_nodebug(hc, reg) (hc->HFC_inb_nodebug(hc, reg))
> -#define HFC_inw(hc, reg) (hc->HFC_inw(hc, reg))
> -#define HFC_inw_nodebug(hc, reg) (hc->HFC_inw_nodebug(hc, reg))
> -#define HFC_wait(hc) (hc->HFC_wait(hc))
> -#define HFC_wait_nodebug(hc) (hc->HFC_wait_nodebug(hc))
> -#endif
> -
> -#ifdef CONFIG_MISDN_HFCMULTI_8xx
> -#include "hfc_multi_8xx.h"
> -#endif
> -
> -/* HFC_IO_MODE_PCIMEM */
> -static void
> -#ifdef HFC_REGISTER_DEBUG
> -HFC_outb_pcimem(struct hfc_multi *hc, u_char reg, u_char val,
> - const char *function, int line)
> -#else
> - HFC_outb_pcimem(struct hfc_multi *hc, u_char reg, u_char val)
> -#endif
> -{
> - writeb(val, hc->pci_membase + reg);
> -}
> -static u_char
> -#ifdef HFC_REGISTER_DEBUG
> -HFC_inb_pcimem(struct hfc_multi *hc, u_char reg, const char *function, int line)
> -#else
> - HFC_inb_pcimem(struct hfc_multi *hc, u_char reg)
> -#endif
> -{
> - return readb(hc->pci_membase + reg);
> -}
> -static u_short
> -#ifdef HFC_REGISTER_DEBUG
> -HFC_inw_pcimem(struct hfc_multi *hc, u_char reg, const char *function, int line)
> -#else
> - HFC_inw_pcimem(struct hfc_multi *hc, u_char reg)
> -#endif
> -{
> - return readw(hc->pci_membase + reg);
> -}
> -static void
> -#ifdef HFC_REGISTER_DEBUG
> -HFC_wait_pcimem(struct hfc_multi *hc, const char *function, int line)
> -#else
> - HFC_wait_pcimem(struct hfc_multi *hc)
> -#endif
> -{
> - while (readb(hc->pci_membase + R_STATUS) & V_BUSY)
> - cpu_relax();
> -}
> -
> -/* HFC_IO_MODE_REGIO */
> -static void
> -#ifdef HFC_REGISTER_DEBUG
> -HFC_outb_regio(struct hfc_multi *hc, u_char reg, u_char val,
> - const char *function, int line)
> -#else
> - HFC_outb_regio(struct hfc_multi *hc, u_char reg, u_char val)
> -#endif
> -{
> - outb(reg, hc->pci_iobase + 4);
> - outb(val, hc->pci_iobase);
> -}
> -static u_char
> -#ifdef HFC_REGISTER_DEBUG
> -HFC_inb_regio(struct hfc_multi *hc, u_char reg, const char *function, int line)
> -#else
> - HFC_inb_regio(struct hfc_multi *hc, u_char reg)
> -#endif
> -{
> - outb(reg, hc->pci_iobase + 4);
> - return inb(hc->pci_iobase);
> -}
> -static u_short
> -#ifdef HFC_REGISTER_DEBUG
> -HFC_inw_regio(struct hfc_multi *hc, u_char reg, const char *function, int line)
> -#else
> - HFC_inw_regio(struct hfc_multi *hc, u_char reg)
> -#endif
> -{
> - outb(reg, hc->pci_iobase + 4);
> - return inw(hc->pci_iobase);
> -}
> -static void
> -#ifdef HFC_REGISTER_DEBUG
> -HFC_wait_regio(struct hfc_multi *hc, const char *function, int line)
> -#else
> - HFC_wait_regio(struct hfc_multi *hc)
> -#endif
> -{
> - outb(R_STATUS, hc->pci_iobase + 4);
> - while (inb(hc->pci_iobase) & V_BUSY)
> - cpu_relax();
> -}
> -
> -#ifdef HFC_REGISTER_DEBUG
> -static void
> -HFC_outb_debug(struct hfc_multi *hc, u_char reg, u_char val,
> - const char *function, int line)
> -{
> - char regname[256] = "", bits[9] = "xxxxxxxx";
> - int i;
> -
> - i = -1;
> - while (hfc_register_names[++i].name) {
> - if (hfc_register_names[i].reg == reg)
> - strcat(regname, hfc_register_names[i].name);
> - }
> - if (regname[0] == '\0')
> - strcpy(regname, "register");
> -
> - bits[7] = '0' + (!!(val & 1));
> - bits[6] = '0' + (!!(val & 2));
> - bits[5] = '0' + (!!(val & 4));
> - bits[4] = '0' + (!!(val & 8));
> - bits[3] = '0' + (!!(val & 16));
> - bits[2] = '0' + (!!(val & 32));
> - bits[1] = '0' + (!!(val & 64));
> - bits[0] = '0' + (!!(val & 128));
> - printk(KERN_DEBUG
> - "HFC_outb(chip %d, %02x=%s, 0x%02x=%s); in %s() line %d\n",
> - hc->id, reg, regname, val, bits, function, line);
> - HFC_outb_nodebug(hc, reg, val);
> -}
> -static u_char
> -HFC_inb_debug(struct hfc_multi *hc, u_char reg, const char *function, int line)
> -{
> - char regname[256] = "", bits[9] = "xxxxxxxx";
> - u_char val = HFC_inb_nodebug(hc, reg);
> - int i;
> -
> - i = 0;
> - while (hfc_register_names[i++].name)
> - ;
> - while (hfc_register_names[++i].name) {
> - if (hfc_register_names[i].reg == reg)
> - strcat(regname, hfc_register_names[i].name);
> - }
> - if (regname[0] == '\0')
> - strcpy(regname, "register");
> -
> - bits[7] = '0' + (!!(val & 1));
> - bits[6] = '0' + (!!(val & 2));
> - bits[5] = '0' + (!!(val & 4));
> - bits[4] = '0' + (!!(val & 8));
> - bits[3] = '0' + (!!(val & 16));
> - bits[2] = '0' + (!!(val & 32));
> - bits[1] = '0' + (!!(val & 64));
> - bits[0] = '0' + (!!(val & 128));
> - printk(KERN_DEBUG
> - "HFC_inb(chip %d, %02x=%s) = 0x%02x=%s; in %s() line %d\n",
> - hc->id, reg, regname, val, bits, function, line);
> - return val;
> -}
> -static u_short
> -HFC_inw_debug(struct hfc_multi *hc, u_char reg, const char *function, int line)
> -{
> - char regname[256] = "";
> - u_short val = HFC_inw_nodebug(hc, reg);
> - int i;
> -
> - i = 0;
> - while (hfc_register_names[i++].name)
> - ;
> - while (hfc_register_names[++i].name) {
> - if (hfc_register_names[i].reg == reg)
> - strcat(regname, hfc_register_names[i].name);
> - }
> - if (regname[0] == '\0')
> - strcpy(regname, "register");
> -
> - printk(KERN_DEBUG
> - "HFC_inw(chip %d, %02x=%s) = 0x%04x; in %s() line %d\n",
> - hc->id, reg, regname, val, function, line);
> - return val;
> -}
> -static void
> -HFC_wait_debug(struct hfc_multi *hc, const char *function, int line)
> -{
> - printk(KERN_DEBUG "HFC_wait(chip %d); in %s() line %d\n",
> - hc->id, function, line);
> - HFC_wait_nodebug(hc);
> -}
> -#endif
> -
> -/* write fifo data (REGIO) */
> -static void
> -write_fifo_regio(struct hfc_multi *hc, u_char *data, int len)
> -{
> - outb(A_FIFO_DATA0, (hc->pci_iobase) + 4);
> - while (len >> 2) {
> - outl(cpu_to_le32(*(u32 *)data), hc->pci_iobase);
> - data += 4;
> - len -= 4;
> - }
> - while (len >> 1) {
> - outw(cpu_to_le16(*(u16 *)data), hc->pci_iobase);
> - data += 2;
> - len -= 2;
> - }
> - while (len) {
> - outb(*data, hc->pci_iobase);
> - data++;
> - len--;
> - }
> -}
> -/* write fifo data (PCIMEM) */
> -static void
> -write_fifo_pcimem(struct hfc_multi *hc, u_char *data, int len)
> -{
> - while (len >> 2) {
> - writel(cpu_to_le32(*(u32 *)data),
> - hc->pci_membase + A_FIFO_DATA0);
> - data += 4;
> - len -= 4;
> - }
> - while (len >> 1) {
> - writew(cpu_to_le16(*(u16 *)data),
> - hc->pci_membase + A_FIFO_DATA0);
> - data += 2;
> - len -= 2;
> - }
> - while (len) {
> - writeb(*data, hc->pci_membase + A_FIFO_DATA0);
> - data++;
> - len--;
> - }
> -}
> -
> -/* read fifo data (REGIO) */
> -static void
> -read_fifo_regio(struct hfc_multi *hc, u_char *data, int len)
> -{
> - outb(A_FIFO_DATA0, (hc->pci_iobase) + 4);
> - while (len >> 2) {
> - *(u32 *)data = le32_to_cpu(inl(hc->pci_iobase));
> - data += 4;
> - len -= 4;
> - }
> - while (len >> 1) {
> - *(u16 *)data = le16_to_cpu(inw(hc->pci_iobase));
> - data += 2;
> - len -= 2;
> - }
> - while (len) {
> - *data = inb(hc->pci_iobase);
> - data++;
> - len--;
> - }
> -}
> -
> -/* read fifo data (PCIMEM) */
> -static void
> -read_fifo_pcimem(struct hfc_multi *hc, u_char *data, int len)
> -{
> - while (len >> 2) {
> - *(u32 *)data =
> - le32_to_cpu(readl(hc->pci_membase + A_FIFO_DATA0));
> - data += 4;
> - len -= 4;
> - }
> - while (len >> 1) {
> - *(u16 *)data =
> - le16_to_cpu(readw(hc->pci_membase + A_FIFO_DATA0));
> - data += 2;
> - len -= 2;
> - }
> - while (len) {
> - *data = readb(hc->pci_membase + A_FIFO_DATA0);
> - data++;
> - len--;
> - }
> -}
> -
> -static void
> -enable_hwirq(struct hfc_multi *hc)
> -{
> - hc->hw.r_irq_ctrl |= V_GLOB_IRQ_EN;
> - HFC_outb(hc, R_IRQ_CTRL, hc->hw.r_irq_ctrl);
> -}
> -
> -static void
> -disable_hwirq(struct hfc_multi *hc)
> -{
> - hc->hw.r_irq_ctrl &= ~((u_char)V_GLOB_IRQ_EN);
> - HFC_outb(hc, R_IRQ_CTRL, hc->hw.r_irq_ctrl);
> -}
> -
> -#define NUM_EC 2
> -#define MAX_TDM_CHAN 32
> -
> -
> -static inline void
> -enablepcibridge(struct hfc_multi *c)
> -{
> - HFC_outb(c, R_BRG_PCM_CFG, (0x0 << 6) | 0x3); /* was _io before */
> -}
> -
> -static inline void
> -disablepcibridge(struct hfc_multi *c)
> -{
> - HFC_outb(c, R_BRG_PCM_CFG, (0x0 << 6) | 0x2); /* was _io before */
> -}
> -
> -static inline unsigned char
> -readpcibridge(struct hfc_multi *hc, unsigned char address)
> -{
> - unsigned short cipv;
> - unsigned char data;
> -
> - if (!hc->pci_iobase)
> - return 0;
> -
> - /* slow down a PCI read access by 1 PCI clock cycle */
> - HFC_outb(hc, R_CTRL, 0x4); /*was _io before*/
> -
> - if (address == 0)
> - cipv = 0x4000;
> - else
> - cipv = 0x5800;
> -
> - /* select local bridge port address by writing to CIP port */
> - /* data = HFC_inb(c, cipv); * was _io before */
> - outw(cipv, hc->pci_iobase + 4);
> - data = inb(hc->pci_iobase);
> -
> - /* restore R_CTRL for normal PCI read cycle speed */
> - HFC_outb(hc, R_CTRL, 0x0); /* was _io before */
> -
> - return data;
> -}
> -
> -static inline void
> -writepcibridge(struct hfc_multi *hc, unsigned char address, unsigned char data)
> -{
> - unsigned short cipv;
> - unsigned int datav;
> -
> - if (!hc->pci_iobase)
> - return;
> -
> - if (address == 0)
> - cipv = 0x4000;
> - else
> - cipv = 0x5800;
> -
> - /* select local bridge port address by writing to CIP port */
> - outw(cipv, hc->pci_iobase + 4);
> - /* define a 32 bit dword with 4 identical bytes for write sequence */
> - datav = data | ((__u32) data << 8) | ((__u32) data << 16) |
> - ((__u32) data << 24);
> -
> - /*
> - * write this 32 bit dword to the bridge data port
> - * this will initiate a write sequence of up to 4 writes to the same
> - * address on the local bus interface the number of write accesses
> - * is undefined but >=1 and depends on the next PCI transaction
> - * during write sequence on the local bus
> - */
> - outl(datav, hc->pci_iobase);
> -}
> -
> -static inline void
> -cpld_set_reg(struct hfc_multi *hc, unsigned char reg)
> -{
> - /* Do data pin read low byte */
> - HFC_outb(hc, R_GPIO_OUT1, reg);
> -}
> -
> -static inline void
> -cpld_write_reg(struct hfc_multi *hc, unsigned char reg, unsigned char val)
> -{
> - cpld_set_reg(hc, reg);
> -
> - enablepcibridge(hc);
> - writepcibridge(hc, 1, val);
> - disablepcibridge(hc);
> -
> - return;
> -}
> -
> -static inline void
> -vpm_write_address(struct hfc_multi *hc, unsigned short addr)
> -{
> - cpld_write_reg(hc, 0, 0xff & addr);
> - cpld_write_reg(hc, 1, 0x01 & (addr >> 8));
> -}
> -
> -static inline unsigned char
> -vpm_in(struct hfc_multi *c, int which, unsigned short addr)
> -{
> - unsigned char res;
> -
> - vpm_write_address(c, addr);
> -
> - if (!which)
> - cpld_set_reg(c, 2);
> - else
> - cpld_set_reg(c, 3);
> -
> - enablepcibridge(c);
> - res = readpcibridge(c, 1);
> - disablepcibridge(c);
> -
> - cpld_set_reg(c, 0);
> -
> - return res;
> -}
> -
> -static inline void
> -vpm_out(struct hfc_multi *c, int which, unsigned short addr,
> - unsigned char data)
> -{
> - vpm_write_address(c, addr);
> -
> - enablepcibridge(c);
> -
> - if (!which)
> - cpld_set_reg(c, 2);
> - else
> - cpld_set_reg(c, 3);
> -
> - writepcibridge(c, 1, data);
> -
> - cpld_set_reg(c, 0);
> -
> - disablepcibridge(c);
> -
> - {
> - unsigned char regin;
> - regin = vpm_in(c, which, addr);
> - if (regin != data)
> - printk(KERN_DEBUG "Wrote 0x%x to register 0x%x but got back "
> - "0x%x\n", data, addr, regin);
> - }
> -
> -}
> -
> -
> -static void
> -vpm_init(struct hfc_multi *wc)
> -{
> - unsigned char reg;
> - unsigned int mask;
> - unsigned int i, x, y;
> - unsigned int ver;
> -
> - for (x = 0; x < NUM_EC; x++) {
> - /* Setup GPIO's */
> - if (!x) {
> - ver = vpm_in(wc, x, 0x1a0);
> - printk(KERN_DEBUG "VPM: Chip %d: ver %02x\n", x, ver);
> - }
> -
> - for (y = 0; y < 4; y++) {
> - vpm_out(wc, x, 0x1a8 + y, 0x00); /* GPIO out */
> - vpm_out(wc, x, 0x1ac + y, 0x00); /* GPIO dir */
> - vpm_out(wc, x, 0x1b0 + y, 0x00); /* GPIO sel */
> - }
> -
> - /* Setup TDM path - sets fsync and tdm_clk as inputs */
> - reg = vpm_in(wc, x, 0x1a3); /* misc_con */
> - vpm_out(wc, x, 0x1a3, reg & ~2);
> -
> - /* Setup Echo length (256 taps) */
> - vpm_out(wc, x, 0x022, 1);
> - vpm_out(wc, x, 0x023, 0xff);
> -
> - /* Setup timeslots */
> - vpm_out(wc, x, 0x02f, 0x00);
> - mask = 0x02020202 << (x * 4);
> -
> - /* Setup the tdm channel masks for all chips */
> - for (i = 0; i < 4; i++)
> - vpm_out(wc, x, 0x33 - i, (mask >> (i << 3)) & 0xff);
> -
> - /* Setup convergence rate */
> - printk(KERN_DEBUG "VPM: A-law mode\n");
> - reg = 0x00 | 0x10 | 0x01;
> - vpm_out(wc, x, 0x20, reg);
> - printk(KERN_DEBUG "VPM reg 0x20 is %x\n", reg);
> - /*vpm_out(wc, x, 0x20, (0x00 | 0x08 | 0x20 | 0x10)); */
> -
> - vpm_out(wc, x, 0x24, 0x02);
> - reg = vpm_in(wc, x, 0x24);
> - printk(KERN_DEBUG "NLP Thresh is set to %d (0x%x)\n", reg, reg);
> -
> - /* Initialize echo cans */
> - for (i = 0; i < MAX_TDM_CHAN; i++) {
> - if (mask & (0x00000001 << i))
> - vpm_out(wc, x, i, 0x00);
> - }
> -
> - /*
> - * ARM arch at least disallows a udelay of
> - * more than 2ms... it gives a fake "__bad_udelay"
> - * reference at link-time.
> - * long delays in kernel code are pretty sucky anyway
> - * for now work around it using 5 x 2ms instead of 1 x 10ms
> - */
> -
> - udelay(2000);
> - udelay(2000);
> - udelay(2000);
> - udelay(2000);
> - udelay(2000);
> -
> - /* Put in bypass mode */
> - for (i = 0; i < MAX_TDM_CHAN; i++) {
> - if (mask & (0x00000001 << i))
> - vpm_out(wc, x, i, 0x01);
> - }
> -
> - /* Enable bypass */
> - for (i = 0; i < MAX_TDM_CHAN; i++) {
> - if (mask & (0x00000001 << i))
> - vpm_out(wc, x, 0x78 + i, 0x01);
> - }
> -
> - }
> -}
> -
> -#ifdef UNUSED
> -static void
> -vpm_check(struct hfc_multi *hctmp)
> -{
> - unsigned char gpi2;
> -
> - gpi2 = HFC_inb(hctmp, R_GPI_IN2);
> -
> - if ((gpi2 & 0x3) != 0x3)
> - printk(KERN_DEBUG "Got interrupt 0x%x from VPM!\n", gpi2);
> -}
> -#endif /* UNUSED */
> -
> -
> -/*
> - * Interface to enable/disable the HW Echocan
> - *
> - * these functions are called within a spin_lock_irqsave on
> - * the channel instance lock, so we are not disturbed by irqs
> - *
> - * we can later easily change the interface to make other
> - * things configurable, for now we configure the taps
> - *
> - */
> -
> -static void
> -vpm_echocan_on(struct hfc_multi *hc, int ch, int taps)
> -{
> - unsigned int timeslot;
> - unsigned int unit;
> - struct bchannel *bch = hc->chan[ch].bch;
> -#ifdef TXADJ
> - int txadj = -4;
> - struct sk_buff *skb;
> -#endif
> - if (hc->chan[ch].protocol != ISDN_P_B_RAW)
> - return;
> -
> - if (!bch)
> - return;
> -
> -#ifdef TXADJ
> - skb = _alloc_mISDN_skb(PH_CONTROL_IND, HFC_VOL_CHANGE_TX,
> - sizeof(int), &txadj, GFP_ATOMIC);
> - if (skb)
> - recv_Bchannel_skb(bch, skb);
> -#endif
> -
> - timeslot = ((ch / 4) * 8) + ((ch % 4) * 4) + 1;
> - unit = ch % 4;
> -
> - printk(KERN_NOTICE "vpm_echocan_on called taps [%d] on timeslot %d\n",
> - taps, timeslot);
> -
> - vpm_out(hc, unit, timeslot, 0x7e);
> -}
> -
> -static void
> -vpm_echocan_off(struct hfc_multi *hc, int ch)
> -{
> - unsigned int timeslot;
> - unsigned int unit;
> - struct bchannel *bch = hc->chan[ch].bch;
> -#ifdef TXADJ
> - int txadj = 0;
> - struct sk_buff *skb;
> -#endif
> -
> - if (hc->chan[ch].protocol != ISDN_P_B_RAW)
> - return;
> -
> - if (!bch)
> - return;
> -
> -#ifdef TXADJ
> - skb = _alloc_mISDN_skb(PH_CONTROL_IND, HFC_VOL_CHANGE_TX,
> - sizeof(int), &txadj, GFP_ATOMIC);
> - if (skb)
> - recv_Bchannel_skb(bch, skb);
> -#endif
> -
> - timeslot = ((ch / 4) * 8) + ((ch % 4) * 4) + 1;
> - unit = ch % 4;
> -
> - printk(KERN_NOTICE "vpm_echocan_off called on timeslot %d\n",
> - timeslot);
> - /* FILLME */
> - vpm_out(hc, unit, timeslot, 0x01);
> -}
> -
> -
> -/*
> - * Speech Design resync feature
> - * NOTE: This is called sometimes outside interrupt handler.
> - * We must lock irqsave, so no other interrupt (other card) will occur!
> - * Also multiple interrupts may nest, so must lock each access (lists, card)!
> - */
> -static inline void
> -hfcmulti_resync(struct hfc_multi *locked, struct hfc_multi *newmaster, int rm)
> -{
> - struct hfc_multi *hc, *next, *pcmmaster = NULL;
> - void __iomem *plx_acc_32;
> - u_int pv;
> - u_long flags;
> -
> - spin_lock_irqsave(&HFClock, flags);
> - spin_lock(&plx_lock); /* must be locked inside other locks */
> -
> - if (debug & DEBUG_HFCMULTI_PLXSD)
> - printk(KERN_DEBUG "%s: RESYNC(syncmaster=0x%p)\n",
> - __func__, syncmaster);
> -
> - /* select new master */
> - if (newmaster) {
> - if (debug & DEBUG_HFCMULTI_PLXSD)
> - printk(KERN_DEBUG "using provided controller\n");
> - } else {
> - list_for_each_entry_safe(hc, next, &HFClist, list) {
> - if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
> - if (hc->syncronized) {
> - newmaster = hc;
> - break;
> - }
> - }
> - }
> - }
> -
> - /* Disable sync of all cards */
> - list_for_each_entry_safe(hc, next, &HFClist, list) {
> - if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
> - plx_acc_32 = hc->plx_membase + PLX_GPIOC;
> - pv = readl(plx_acc_32);
> - pv &= ~PLX_SYNC_O_EN;
> - writel(pv, plx_acc_32);
> - if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip)) {
> - pcmmaster = hc;
> - if (hc->ctype == HFC_TYPE_E1) {
> - if (debug & DEBUG_HFCMULTI_PLXSD)
> - printk(KERN_DEBUG
> - "Schedule SYNC_I\n");
> - hc->e1_resync |= 1; /* get SYNC_I */
> - }
> - }
> - }
> - }
> -
> - if (newmaster) {
> - hc = newmaster;
> - if (debug & DEBUG_HFCMULTI_PLXSD)
> - printk(KERN_DEBUG "id=%d (0x%p) = synchronized with "
> - "interface.\n", hc->id, hc);
> - /* Enable new sync master */
> - plx_acc_32 = hc->plx_membase + PLX_GPIOC;
> - pv = readl(plx_acc_32);
> - pv |= PLX_SYNC_O_EN;
> - writel(pv, plx_acc_32);
> - /* switch to jatt PLL, if not disabled by RX_SYNC */
> - if (hc->ctype == HFC_TYPE_E1
> - && !test_bit(HFC_CHIP_RX_SYNC, &hc->chip)) {
> - if (debug & DEBUG_HFCMULTI_PLXSD)
> - printk(KERN_DEBUG "Schedule jatt PLL\n");
> - hc->e1_resync |= 2; /* switch to jatt */
> - }
> - } else {
> - if (pcmmaster) {
> - hc = pcmmaster;
> - if (debug & DEBUG_HFCMULTI_PLXSD)
> - printk(KERN_DEBUG
> - "id=%d (0x%p) = PCM master synchronized "
> - "with QUARTZ\n", hc->id, hc);
> - if (hc->ctype == HFC_TYPE_E1) {
> - /* Use the crystal clock for the PCM
> - master card */
> - if (debug & DEBUG_HFCMULTI_PLXSD)
> - printk(KERN_DEBUG
> - "Schedule QUARTZ for HFC-E1\n");
> - hc->e1_resync |= 4; /* switch quartz */
> - } else {
> - if (debug & DEBUG_HFCMULTI_PLXSD)
> - printk(KERN_DEBUG
> - "QUARTZ is automatically "
> - "enabled by HFC-%dS\n", hc->ctype);
> - }
> - plx_acc_32 = hc->plx_membase + PLX_GPIOC;
> - pv = readl(plx_acc_32);
> - pv |= PLX_SYNC_O_EN;
> - writel(pv, plx_acc_32);
> - } else
> - if (!rm)
> - printk(KERN_ERR "%s no pcm master, this MUST "
> - "not happen!\n", __func__);
> - }
> - syncmaster = newmaster;
> -
> - spin_unlock(&plx_lock);
> - spin_unlock_irqrestore(&HFClock, flags);
> -}
> -
> -/* This must be called AND hc must be locked irqsave!!! */
> -static inline void
> -plxsd_checksync(struct hfc_multi *hc, int rm)
> -{
> - if (hc->syncronized) {
> - if (syncmaster == NULL) {
> - if (debug & DEBUG_HFCMULTI_PLXSD)
> - printk(KERN_DEBUG "%s: GOT sync on card %d"
> - " (id=%d)\n", __func__, hc->id + 1,
> - hc->id);
> - hfcmulti_resync(hc, hc, rm);
> - }
> - } else {
> - if (syncmaster == hc) {
> - if (debug & DEBUG_HFCMULTI_PLXSD)
> - printk(KERN_DEBUG "%s: LOST sync on card %d"
> - " (id=%d)\n", __func__, hc->id + 1,
> - hc->id);
> - hfcmulti_resync(hc, NULL, rm);
> - }
> - }
> -}
> -
> -
> -/*
> - * free hardware resources used by driver
> - */
> -static void
> -release_io_hfcmulti(struct hfc_multi *hc)
> -{
> - void __iomem *plx_acc_32;
> - u_int pv;
> - u_long plx_flags;
> -
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: entered\n", __func__);
> -
> - /* soft reset also masks all interrupts */
> - hc->hw.r_cirm |= V_SRES;
> - HFC_outb(hc, R_CIRM, hc->hw.r_cirm);
> - udelay(1000);
> - hc->hw.r_cirm &= ~V_SRES;
> - HFC_outb(hc, R_CIRM, hc->hw.r_cirm);
> - udelay(1000); /* instead of 'wait' that may cause locking */
> -
> - /* release Speech Design card, if PLX was initialized */
> - if (test_bit(HFC_CHIP_PLXSD, &hc->chip) && hc->plx_membase) {
> - if (debug & DEBUG_HFCMULTI_PLXSD)
> - printk(KERN_DEBUG "%s: release PLXSD card %d\n",
> - __func__, hc->id + 1);
> - spin_lock_irqsave(&plx_lock, plx_flags);
> - plx_acc_32 = hc->plx_membase + PLX_GPIOC;
> - writel(PLX_GPIOC_INIT, plx_acc_32);
> - pv = readl(plx_acc_32);
> - /* Termination off */
> - pv &= ~PLX_TERM_ON;
> - /* Disconnect the PCM */
> - pv |= PLX_SLAVE_EN_N;
> - pv &= ~PLX_MASTER_EN;
> - pv &= ~PLX_SYNC_O_EN;
> - /* Put the DSP in Reset */
> - pv &= ~PLX_DSP_RES_N;
> - writel(pv, plx_acc_32);
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: PCM off: PLX_GPIO=%x\n",
> - __func__, pv);
> - spin_unlock_irqrestore(&plx_lock, plx_flags);
> - }
> -
> - /* disable memory mapped ports / io ports */
> - test_and_clear_bit(HFC_CHIP_PLXSD, &hc->chip); /* prevent resync */
> - if (hc->pci_dev)
> - pci_write_config_word(hc->pci_dev, PCI_COMMAND, 0);
> - if (hc->pci_membase)
> - iounmap(hc->pci_membase);
> - if (hc->plx_membase)
> - iounmap(hc->plx_membase);
> - if (hc->pci_iobase)
> - release_region(hc->pci_iobase, 8);
> - if (hc->xhfc_membase)
> - iounmap((void *)hc->xhfc_membase);
> -
> - if (hc->pci_dev) {
> - pci_disable_device(hc->pci_dev);
> - pci_set_drvdata(hc->pci_dev, NULL);
> - }
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: done\n", __func__);
> -}
> -
> -/*
> - * function called to reset the HFC chip. A complete software reset of chip
> - * and fifos is done. All configuration of the chip is done.
> - */
> -
> -static int
> -init_chip(struct hfc_multi *hc)
> -{
> - u_long flags, val, val2 = 0, rev;
> - int i, err = 0;
> - u_char r_conf_en, rval;
> - void __iomem *plx_acc_32;
> - u_int pv;
> - u_long plx_flags, hfc_flags;
> - int plx_count;
> - struct hfc_multi *pos, *next, *plx_last_hc;
> -
> - spin_lock_irqsave(&hc->lock, flags);
> - /* reset all registers */
> - memset(&hc->hw, 0, sizeof(struct hfcm_hw));
> -
> - /* revision check */
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: entered\n", __func__);
> - val = HFC_inb(hc, R_CHIP_ID);
> - if ((val >> 4) != 0x8 && (val >> 4) != 0xc && (val >> 4) != 0xe &&
> - (val >> 1) != 0x31) {
> - printk(KERN_INFO "HFC_multi: unknown CHIP_ID:%x\n", (u_int)val);
> - err = -EIO;
> - goto out;
> - }
> - rev = HFC_inb(hc, R_CHIP_RV);
> - printk(KERN_INFO
> - "HFC_multi: detected HFC with chip ID=0x%lx revision=%ld%s\n",
> - val, rev, (rev == 0 && (hc->ctype != HFC_TYPE_XHFC)) ?
> - " (old FIFO handling)" : "");
> - if (hc->ctype != HFC_TYPE_XHFC && rev == 0) {
> - test_and_set_bit(HFC_CHIP_REVISION0, &hc->chip);
> - printk(KERN_WARNING
> - "HFC_multi: NOTE: Your chip is revision 0, "
> - "ask Cologne Chip for update. Newer chips "
> - "have a better FIFO handling. Old chips "
> - "still work but may have slightly lower "
> - "HDLC transmit performance.\n");
> - }
> - if (rev > 1) {
> - printk(KERN_WARNING "HFC_multi: WARNING: This driver doesn't "
> - "consider chip revision = %ld. The chip / "
> - "bridge may not work.\n", rev);
> - }
> -
> - /* set s-ram size */
> - hc->Flen = 0x10;
> - hc->Zmin = 0x80;
> - hc->Zlen = 384;
> - hc->DTMFbase = 0x1000;
> - if (test_bit(HFC_CHIP_EXRAM_128, &hc->chip)) {
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: changing to 128K external RAM\n",
> - __func__);
> - hc->hw.r_ctrl |= V_EXT_RAM;
> - hc->hw.r_ram_sz = 1;
> - hc->Flen = 0x20;
> - hc->Zmin = 0xc0;
> - hc->Zlen = 1856;
> - hc->DTMFbase = 0x2000;
> - }
> - if (test_bit(HFC_CHIP_EXRAM_512, &hc->chip)) {
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: changing to 512K external RAM\n",
> - __func__);
> - hc->hw.r_ctrl |= V_EXT_RAM;
> - hc->hw.r_ram_sz = 2;
> - hc->Flen = 0x20;
> - hc->Zmin = 0xc0;
> - hc->Zlen = 8000;
> - hc->DTMFbase = 0x2000;
> - }
> - if (hc->ctype == HFC_TYPE_XHFC) {
> - hc->Flen = 0x8;
> - hc->Zmin = 0x0;
> - hc->Zlen = 64;
> - hc->DTMFbase = 0x0;
> - }
> - hc->max_trans = poll << 1;
> - if (hc->max_trans > hc->Zlen)
> - hc->max_trans = hc->Zlen;
> -
> - /* Speech Design PLX bridge */
> - if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
> - if (debug & DEBUG_HFCMULTI_PLXSD)
> - printk(KERN_DEBUG "%s: initializing PLXSD card %d\n",
> - __func__, hc->id + 1);
> - spin_lock_irqsave(&plx_lock, plx_flags);
> - plx_acc_32 = hc->plx_membase + PLX_GPIOC;
> - writel(PLX_GPIOC_INIT, plx_acc_32);
> - pv = readl(plx_acc_32);
> - /* The first and the last cards are terminating the PCM bus */
> - pv |= PLX_TERM_ON; /* hc is currently the last */
> - /* Disconnect the PCM */
> - pv |= PLX_SLAVE_EN_N;
> - pv &= ~PLX_MASTER_EN;
> - pv &= ~PLX_SYNC_O_EN;
> - /* Put the DSP in Reset */
> - pv &= ~PLX_DSP_RES_N;
> - writel(pv, plx_acc_32);
> - spin_unlock_irqrestore(&plx_lock, plx_flags);
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: slave/term: PLX_GPIO=%x\n",
> - __func__, pv);
> - /*
> - * If we are the 3rd PLXSD card or higher, we must turn
> - * termination of last PLXSD card off.
> - */
> - spin_lock_irqsave(&HFClock, hfc_flags);
> - plx_count = 0;
> - plx_last_hc = NULL;
> - list_for_each_entry_safe(pos, next, &HFClist, list) {
> - if (test_bit(HFC_CHIP_PLXSD, &pos->chip)) {
> - plx_count++;
> - if (pos != hc)
> - plx_last_hc = pos;
> - }
> - }
> - if (plx_count >= 3) {
> - if (debug & DEBUG_HFCMULTI_PLXSD)
> - printk(KERN_DEBUG "%s: card %d is between, so "
> - "we disable termination\n",
> - __func__, plx_last_hc->id + 1);
> - spin_lock_irqsave(&plx_lock, plx_flags);
> - plx_acc_32 = plx_last_hc->plx_membase + PLX_GPIOC;
> - pv = readl(plx_acc_32);
> - pv &= ~PLX_TERM_ON;
> - writel(pv, plx_acc_32);
> - spin_unlock_irqrestore(&plx_lock, plx_flags);
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG
> - "%s: term off: PLX_GPIO=%x\n",
> - __func__, pv);
> - }
> - spin_unlock_irqrestore(&HFClock, hfc_flags);
> - hc->hw.r_pcm_md0 = V_F0_LEN; /* shift clock for DSP */
> - }
> -
> - if (test_bit(HFC_CHIP_EMBSD, &hc->chip))
> - hc->hw.r_pcm_md0 = V_F0_LEN; /* shift clock for DSP */
> -
> - /* we only want the real Z2 read-pointer for revision > 0 */
> - if (!test_bit(HFC_CHIP_REVISION0, &hc->chip))
> - hc->hw.r_ram_sz |= V_FZ_MD;
> -
> - /* select pcm mode */
> - if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip)) {
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: setting PCM into slave mode\n",
> - __func__);
> - } else
> - if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip) && !plxsd_master) {
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: setting PCM into master mode\n",
> - __func__);
> - hc->hw.r_pcm_md0 |= V_PCM_MD;
> - } else {
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: performing PCM auto detect\n",
> - __func__);
> - }
> -
> - /* soft reset */
> - HFC_outb(hc, R_CTRL, hc->hw.r_ctrl);
> - if (hc->ctype == HFC_TYPE_XHFC)
> - HFC_outb(hc, 0x0C /* R_FIFO_THRES */,
> - 0x11 /* 16 Bytes TX/RX */);
> - else
> - HFC_outb(hc, R_RAM_SZ, hc->hw.r_ram_sz);
> - HFC_outb(hc, R_FIFO_MD, 0);
> - if (hc->ctype == HFC_TYPE_XHFC)
> - hc->hw.r_cirm = V_SRES | V_HFCRES | V_PCMRES | V_STRES;
> - else
> - hc->hw.r_cirm = V_SRES | V_HFCRES | V_PCMRES | V_STRES
> - | V_RLD_EPR;
> - HFC_outb(hc, R_CIRM, hc->hw.r_cirm);
> - udelay(100);
> - hc->hw.r_cirm = 0;
> - HFC_outb(hc, R_CIRM, hc->hw.r_cirm);
> - udelay(100);
> - if (hc->ctype != HFC_TYPE_XHFC)
> - HFC_outb(hc, R_RAM_SZ, hc->hw.r_ram_sz);
> -
> - /* Speech Design PLX bridge pcm and sync mode */
> - if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
> - spin_lock_irqsave(&plx_lock, plx_flags);
> - plx_acc_32 = hc->plx_membase + PLX_GPIOC;
> - pv = readl(plx_acc_32);
> - /* Connect PCM */
> - if (hc->hw.r_pcm_md0 & V_PCM_MD) {
> - pv |= PLX_MASTER_EN | PLX_SLAVE_EN_N;
> - pv |= PLX_SYNC_O_EN;
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: master: PLX_GPIO=%x\n",
> - __func__, pv);
> - } else {
> - pv &= ~(PLX_MASTER_EN | PLX_SLAVE_EN_N);
> - pv &= ~PLX_SYNC_O_EN;
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: slave: PLX_GPIO=%x\n",
> - __func__, pv);
> - }
> - writel(pv, plx_acc_32);
> - spin_unlock_irqrestore(&plx_lock, plx_flags);
> - }
> -
> - /* PCM setup */
> - HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0x90);
> - if (hc->slots == 32)
> - HFC_outb(hc, R_PCM_MD1, 0x00);
> - if (hc->slots == 64)
> - HFC_outb(hc, R_PCM_MD1, 0x10);
> - if (hc->slots == 128)
> - HFC_outb(hc, R_PCM_MD1, 0x20);
> - HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0xa0);
> - if (test_bit(HFC_CHIP_PLXSD, &hc->chip))
> - HFC_outb(hc, R_PCM_MD2, V_SYNC_SRC); /* sync via SYNC_I / O */
> - else if (test_bit(HFC_CHIP_EMBSD, &hc->chip))
> - HFC_outb(hc, R_PCM_MD2, 0x10); /* V_C2O_EN */
> - else
> - HFC_outb(hc, R_PCM_MD2, 0x00); /* sync from interface */
> - HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0x00);
> - for (i = 0; i < 256; i++) {
> - HFC_outb_nodebug(hc, R_SLOT, i);
> - HFC_outb_nodebug(hc, A_SL_CFG, 0);
> - if (hc->ctype != HFC_TYPE_XHFC)
> - HFC_outb_nodebug(hc, A_CONF, 0);
> - hc->slot_owner[i] = -1;
> - }
> -
> - /* set clock speed */
> - if (test_bit(HFC_CHIP_CLOCK2, &hc->chip)) {
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG
> - "%s: setting double clock\n", __func__);
> - HFC_outb(hc, R_BRG_PCM_CFG, V_PCM_CLK);
> - }
> -
> - if (test_bit(HFC_CHIP_EMBSD, &hc->chip))
> - HFC_outb(hc, 0x02 /* R_CLK_CFG */, 0x40 /* V_CLKO_OFF */);
> -
> - /* B410P GPIO */
> - if (test_bit(HFC_CHIP_B410P, &hc->chip)) {
> - printk(KERN_NOTICE "Setting GPIOs\n");
> - HFC_outb(hc, R_GPIO_SEL, 0x30);
> - HFC_outb(hc, R_GPIO_EN1, 0x3);
> - udelay(1000);
> - printk(KERN_NOTICE "calling vpm_init\n");
> - vpm_init(hc);
> - }
> -
> - /* check if R_F0_CNT counts (8 kHz frame count) */
> - val = HFC_inb(hc, R_F0_CNTL);
> - val += HFC_inb(hc, R_F0_CNTH) << 8;
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG
> - "HFC_multi F0_CNT %ld after reset\n", val);
> - spin_unlock_irqrestore(&hc->lock, flags);
> - set_current_state(TASK_UNINTERRUPTIBLE);
> - schedule_timeout((HZ / 100) ? : 1); /* Timeout minimum 10ms */
> - spin_lock_irqsave(&hc->lock, flags);
> - val2 = HFC_inb(hc, R_F0_CNTL);
> - val2 += HFC_inb(hc, R_F0_CNTH) << 8;
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG
> - "HFC_multi F0_CNT %ld after 10 ms (1st try)\n",
> - val2);
> - if (val2 >= val + 8) { /* 1 ms */
> - /* it counts, so we keep the pcm mode */
> - if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip))
> - printk(KERN_INFO "controller is PCM bus MASTER\n");
> - else
> - if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip))
> - printk(KERN_INFO "controller is PCM bus SLAVE\n");
> - else {
> - test_and_set_bit(HFC_CHIP_PCM_SLAVE, &hc->chip);
> - printk(KERN_INFO "controller is PCM bus SLAVE "
> - "(auto detected)\n");
> - }
> - } else {
> - /* does not count */
> - if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip)) {
> - controller_fail:
> - printk(KERN_ERR "HFC_multi ERROR, getting no 125us "
> - "pulse. Seems that controller fails.\n");
> - err = -EIO;
> - goto out;
> - }
> - if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip)) {
> - printk(KERN_INFO "controller is PCM bus SLAVE "
> - "(ignoring missing PCM clock)\n");
> - } else {
> - /* only one pcm master */
> - if (test_bit(HFC_CHIP_PLXSD, &hc->chip)
> - && plxsd_master) {
> - printk(KERN_ERR "HFC_multi ERROR, no clock "
> - "on another Speech Design card found. "
> - "Please be sure to connect PCM cable.\n");
> - err = -EIO;
> - goto out;
> - }
> - /* retry with master clock */
> - if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
> - spin_lock_irqsave(&plx_lock, plx_flags);
> - plx_acc_32 = hc->plx_membase + PLX_GPIOC;
> - pv = readl(plx_acc_32);
> - pv |= PLX_MASTER_EN | PLX_SLAVE_EN_N;
> - pv |= PLX_SYNC_O_EN;
> - writel(pv, plx_acc_32);
> - spin_unlock_irqrestore(&plx_lock, plx_flags);
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: master: "
> - "PLX_GPIO=%x\n", __func__, pv);
> - }
> - hc->hw.r_pcm_md0 |= V_PCM_MD;
> - HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0x00);
> - spin_unlock_irqrestore(&hc->lock, flags);
> - set_current_state(TASK_UNINTERRUPTIBLE);
> - schedule_timeout((HZ / 100) ?: 1); /* Timeout min. 10ms */
> - spin_lock_irqsave(&hc->lock, flags);
> - val2 = HFC_inb(hc, R_F0_CNTL);
> - val2 += HFC_inb(hc, R_F0_CNTH) << 8;
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "HFC_multi F0_CNT %ld after "
> - "10 ms (2nd try)\n", val2);
> - if (val2 >= val + 8) { /* 1 ms */
> - test_and_set_bit(HFC_CHIP_PCM_MASTER,
> - &hc->chip);
> - printk(KERN_INFO "controller is PCM bus MASTER "
> - "(auto detected)\n");
> - } else
> - goto controller_fail;
> - }
> - }
> -
> - /* Release the DSP Reset */
> - if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
> - if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip))
> - plxsd_master = 1;
> - spin_lock_irqsave(&plx_lock, plx_flags);
> - plx_acc_32 = hc->plx_membase + PLX_GPIOC;
> - pv = readl(plx_acc_32);
> - pv |= PLX_DSP_RES_N;
> - writel(pv, plx_acc_32);
> - spin_unlock_irqrestore(&plx_lock, plx_flags);
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: reset off: PLX_GPIO=%x\n",
> - __func__, pv);
> - }
> -
> - /* pcm id */
> - if (hc->pcm)
> - printk(KERN_INFO "controller has given PCM BUS ID %d\n",
> - hc->pcm);
> - else {
> - if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip)
> - || test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
> - PCM_cnt++; /* SD has proprietary bridging */
> - }
> - hc->pcm = PCM_cnt;
> - printk(KERN_INFO "controller has PCM BUS ID %d "
> - "(auto selected)\n", hc->pcm);
> - }
> -
> - /* set up timer */
> - HFC_outb(hc, R_TI_WD, poll_timer);
> - hc->hw.r_irqmsk_misc |= V_TI_IRQMSK;
> -
> - /* set E1 state machine IRQ */
> - if (hc->ctype == HFC_TYPE_E1)
> - hc->hw.r_irqmsk_misc |= V_STA_IRQMSK;
> -
> - /* set DTMF detection */
> - if (test_bit(HFC_CHIP_DTMF, &hc->chip)) {
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: enabling DTMF detection "
> - "for all B-channel\n", __func__);
> - hc->hw.r_dtmf = V_DTMF_EN | V_DTMF_STOP;
> - if (test_bit(HFC_CHIP_ULAW, &hc->chip))
> - hc->hw.r_dtmf |= V_ULAW_SEL;
> - HFC_outb(hc, R_DTMF_N, 102 - 1);
> - hc->hw.r_irqmsk_misc |= V_DTMF_IRQMSK;
> - }
> -
> - /* conference engine */
> - if (test_bit(HFC_CHIP_ULAW, &hc->chip))
> - r_conf_en = V_CONF_EN | V_ULAW;
> - else
> - r_conf_en = V_CONF_EN;
> - if (hc->ctype != HFC_TYPE_XHFC)
> - HFC_outb(hc, R_CONF_EN, r_conf_en);
> -
> - /* setting leds */
> - switch (hc->leds) {
> - case 1: /* HFC-E1 OEM */
> - if (test_bit(HFC_CHIP_WATCHDOG, &hc->chip))
> - HFC_outb(hc, R_GPIO_SEL, 0x32);
> - else
> - HFC_outb(hc, R_GPIO_SEL, 0x30);
> -
> - HFC_outb(hc, R_GPIO_EN1, 0x0f);
> - HFC_outb(hc, R_GPIO_OUT1, 0x00);
> -
> - HFC_outb(hc, R_GPIO_EN0, V_GPIO_EN2 | V_GPIO_EN3);
> - break;
> -
> - case 2: /* HFC-4S OEM */
> - case 3:
> - HFC_outb(hc, R_GPIO_SEL, 0xf0);
> - HFC_outb(hc, R_GPIO_EN1, 0xff);
> - HFC_outb(hc, R_GPIO_OUT1, 0x00);
> - break;
> - }
> -
> - if (test_bit(HFC_CHIP_EMBSD, &hc->chip)) {
> - hc->hw.r_st_sync = 0x10; /* V_AUTO_SYNCI */
> - HFC_outb(hc, R_ST_SYNC, hc->hw.r_st_sync);
> - }
> -
> - /* set master clock */
> - if (hc->masterclk >= 0) {
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: setting ST master clock "
> - "to port %d (0..%d)\n",
> - __func__, hc->masterclk, hc->ports - 1);
> - hc->hw.r_st_sync |= (hc->masterclk | V_AUTO_SYNC);
> - HFC_outb(hc, R_ST_SYNC, hc->hw.r_st_sync);
> - }
> -
> -
> -
> - /* setting misc irq */
> - HFC_outb(hc, R_IRQMSK_MISC, hc->hw.r_irqmsk_misc);
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "r_irqmsk_misc.2: 0x%x\n",
> - hc->hw.r_irqmsk_misc);
> -
> - /* RAM access test */
> - HFC_outb(hc, R_RAM_ADDR0, 0);
> - HFC_outb(hc, R_RAM_ADDR1, 0);
> - HFC_outb(hc, R_RAM_ADDR2, 0);
> - for (i = 0; i < 256; i++) {
> - HFC_outb_nodebug(hc, R_RAM_ADDR0, i);
> - HFC_outb_nodebug(hc, R_RAM_DATA, ((i * 3) & 0xff));
> - }
> - for (i = 0; i < 256; i++) {
> - HFC_outb_nodebug(hc, R_RAM_ADDR0, i);
> - HFC_inb_nodebug(hc, R_RAM_DATA);
> - rval = HFC_inb_nodebug(hc, R_INT_DATA);
> - if (rval != ((i * 3) & 0xff)) {
> - printk(KERN_DEBUG
> - "addr:%x val:%x should:%x\n", i, rval,
> - (i * 3) & 0xff);
> - err++;
> - }
> - }
> - if (err) {
> - printk(KERN_DEBUG "aborting - %d RAM access errors\n", err);
> - err = -EIO;
> - goto out;
> - }
> -
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: done\n", __func__);
> -out:
> - spin_unlock_irqrestore(&hc->lock, flags);
> - return err;
> -}
> -
> -
> -/*
> - * control the watchdog
> - */
> -static void
> -hfcmulti_watchdog(struct hfc_multi *hc)
> -{
> - hc->wdcount++;
> -
> - if (hc->wdcount > 10) {
> - hc->wdcount = 0;
> - hc->wdbyte = hc->wdbyte == V_GPIO_OUT2 ?
> - V_GPIO_OUT3 : V_GPIO_OUT2;
> -
> - /* printk("Sending Watchdog Kill %x\n",hc->wdbyte); */
> - HFC_outb(hc, R_GPIO_EN0, V_GPIO_EN2 | V_GPIO_EN3);
> - HFC_outb(hc, R_GPIO_OUT0, hc->wdbyte);
> - }
> -}
> -
> -
> -
> -/*
> - * output leds
> - */
> -static void
> -hfcmulti_leds(struct hfc_multi *hc)
> -{
> - unsigned long lled;
> - unsigned long leddw;
> - int i, state, active, leds;
> - struct dchannel *dch;
> - int led[4];
> -
> - switch (hc->leds) {
> - case 1: /* HFC-E1 OEM */
> - /* 2 red steady: LOS
> - * 1 red steady: L1 not active
> - * 2 green steady: L1 active
> - * 1st green flashing: activity on TX
> - * 2nd green flashing: activity on RX
> - */
> - led[0] = 0;
> - led[1] = 0;
> - led[2] = 0;
> - led[3] = 0;
> - dch = hc->chan[hc->dnum[0]].dch;
> - if (dch) {
> - if (hc->chan[hc->dnum[0]].los)
> - led[1] = 1;
> - if (hc->e1_state != 1) {
> - led[0] = 1;
> - hc->flash[2] = 0;
> - hc->flash[3] = 0;
> - } else {
> - led[2] = 1;
> - led[3] = 1;
> - if (!hc->flash[2] && hc->activity_tx)
> - hc->flash[2] = poll;
> - if (!hc->flash[3] && hc->activity_rx)
> - hc->flash[3] = poll;
> - if (hc->flash[2] && hc->flash[2] < 1024)
> - led[2] = 0;
> - if (hc->flash[3] && hc->flash[3] < 1024)
> - led[3] = 0;
> - if (hc->flash[2] >= 2048)
> - hc->flash[2] = 0;
> - if (hc->flash[3] >= 2048)
> - hc->flash[3] = 0;
> - if (hc->flash[2])
> - hc->flash[2] += poll;
> - if (hc->flash[3])
> - hc->flash[3] += poll;
> - }
> - }
> - leds = (led[0] | (led[1]<<2) | (led[2]<<1) | (led[3]<<3))^0xF;
> - /* leds are inverted */
> - if (leds != (int)hc->ledstate) {
> - HFC_outb_nodebug(hc, R_GPIO_OUT1, leds);
> - hc->ledstate = leds;
> - }
> - break;
> -
> - case 2: /* HFC-4S OEM */
> - /* red steady: PH_DEACTIVATE
> - * green steady: PH_ACTIVATE
> - * green flashing: activity on TX
> - */
> - for (i = 0; i < 4; i++) {
> - state = 0;
> - active = -1;
> - dch = hc->chan[(i << 2) | 2].dch;
> - if (dch) {
> - state = dch->state;
> - if (dch->dev.D.protocol == ISDN_P_NT_S0)
> - active = 3;
> - else
> - active = 7;
> - }
> - if (state) {
> - if (state == active) {
> - led[i] = 1; /* led green */
> - hc->activity_tx |= hc->activity_rx;
> - if (!hc->flash[i] &&
> - (hc->activity_tx & (1 << i)))
> - hc->flash[i] = poll;
> - if (hc->flash[i] && hc->flash[i] < 1024)
> - led[i] = 0; /* led off */
> - if (hc->flash[i] >= 2048)
> - hc->flash[i] = 0;
> - if (hc->flash[i])
> - hc->flash[i] += poll;
> - } else {
> - led[i] = 2; /* led red */
> - hc->flash[i] = 0;
> - }
> - } else
> - led[i] = 0; /* led off */
> - }
> - if (test_bit(HFC_CHIP_B410P, &hc->chip)) {
> - leds = 0;
> - for (i = 0; i < 4; i++) {
> - if (led[i] == 1) {
> - /*green*/
> - leds |= (0x2 << (i * 2));
> - } else if (led[i] == 2) {
> - /*red*/
> - leds |= (0x1 << (i * 2));
> - }
> - }
> - if (leds != (int)hc->ledstate) {
> - vpm_out(hc, 0, 0x1a8 + 3, leds);
> - hc->ledstate = leds;
> - }
> - } else {
> - leds = ((led[3] > 0) << 0) | ((led[1] > 0) << 1) |
> - ((led[0] > 0) << 2) | ((led[2] > 0) << 3) |
> - ((led[3] & 1) << 4) | ((led[1] & 1) << 5) |
> - ((led[0] & 1) << 6) | ((led[2] & 1) << 7);
> - if (leds != (int)hc->ledstate) {
> - HFC_outb_nodebug(hc, R_GPIO_EN1, leds & 0x0F);
> - HFC_outb_nodebug(hc, R_GPIO_OUT1, leds >> 4);
> - hc->ledstate = leds;
> - }
> - }
> - break;
> -
> - case 3: /* HFC 1S/2S Beronet */
> - /* red steady: PH_DEACTIVATE
> - * green steady: PH_ACTIVATE
> - * green flashing: activity on TX
> - */
> - for (i = 0; i < 2; i++) {
> - state = 0;
> - active = -1;
> - dch = hc->chan[(i << 2) | 2].dch;
> - if (dch) {
> - state = dch->state;
> - if (dch->dev.D.protocol == ISDN_P_NT_S0)
> - active = 3;
> - else
> - active = 7;
> - }
> - if (state) {
> - if (state == active) {
> - led[i] = 1; /* led green */
> - hc->activity_tx |= hc->activity_rx;
> - if (!hc->flash[i] &&
> - (hc->activity_tx & (1 << i)))
> - hc->flash[i] = poll;
> - if (hc->flash[i] < 1024)
> - led[i] = 0; /* led off */
> - if (hc->flash[i] >= 2048)
> - hc->flash[i] = 0;
> - if (hc->flash[i])
> - hc->flash[i] += poll;
> - } else {
> - led[i] = 2; /* led red */
> - hc->flash[i] = 0;
> - }
> - } else
> - led[i] = 0; /* led off */
> - }
> - leds = (led[0] > 0) | ((led[1] > 0) << 1) | ((led[0]&1) << 2)
> - | ((led[1]&1) << 3);
> - if (leds != (int)hc->ledstate) {
> - HFC_outb_nodebug(hc, R_GPIO_EN1,
> - ((led[0] > 0) << 2) | ((led[1] > 0) << 3));
> - HFC_outb_nodebug(hc, R_GPIO_OUT1,
> - ((led[0] & 1) << 2) | ((led[1] & 1) << 3));
> - hc->ledstate = leds;
> - }
> - break;
> - case 8: /* HFC 8S+ Beronet */
> - /* off: PH_DEACTIVATE
> - * steady: PH_ACTIVATE
> - * flashing: activity on TX
> - */
> - lled = 0xff; /* leds off */
> - for (i = 0; i < 8; i++) {
> - state = 0;
> - active = -1;
> - dch = hc->chan[(i << 2) | 2].dch;
> - if (dch) {
> - state = dch->state;
> - if (dch->dev.D.protocol == ISDN_P_NT_S0)
> - active = 3;
> - else
> - active = 7;
> - }
> - if (state) {
> - if (state == active) {
> - lled &= ~(1 << i); /* led on */
> - hc->activity_tx |= hc->activity_rx;
> - if (!hc->flash[i] &&
> - (hc->activity_tx & (1 << i)))
> - hc->flash[i] = poll;
> - if (hc->flash[i] < 1024)
> - lled |= 1 << i; /* led off */
> - if (hc->flash[i] >= 2048)
> - hc->flash[i] = 0;
> - if (hc->flash[i])
> - hc->flash[i] += poll;
> - } else
> - hc->flash[i] = 0;
> - }
> - }
> - leddw = lled << 24 | lled << 16 | lled << 8 | lled;
> - if (leddw != hc->ledstate) {
> - /* HFC_outb(hc, R_BRG_PCM_CFG, 1);
> - HFC_outb(c, R_BRG_PCM_CFG, (0x0 << 6) | 0x3); */
> - /* was _io before */
> - HFC_outb_nodebug(hc, R_BRG_PCM_CFG, 1 | V_PCM_CLK);
> - outw(0x4000, hc->pci_iobase + 4);
> - outl(leddw, hc->pci_iobase);
> - HFC_outb_nodebug(hc, R_BRG_PCM_CFG, V_PCM_CLK);
> - hc->ledstate = leddw;
> - }
> - break;
> - }
> - hc->activity_tx = 0;
> - hc->activity_rx = 0;
> -}
> -/*
> - * read dtmf coefficients
> - */
> -
> -static void
> -hfcmulti_dtmf(struct hfc_multi *hc)
> -{
> - s32 *coeff;
> - u_int mantissa;
> - int co, ch;
> - struct bchannel *bch = NULL;
> - u8 exponent;
> - int dtmf = 0;
> - int addr;
> - u16 w_float;
> - struct sk_buff *skb;
> - struct mISDNhead *hh;
> -
> - if (debug & DEBUG_HFCMULTI_DTMF)
> - printk(KERN_DEBUG "%s: dtmf detection irq\n", __func__);
> - for (ch = 0; ch <= 31; ch++) {
> - /* only process enabled B-channels */
> - bch = hc->chan[ch].bch;
> - if (!bch)
> - continue;
> - if (!hc->created[hc->chan[ch].port])
> - continue;
> - if (!test_bit(FLG_TRANSPARENT, &bch->Flags))
> - continue;
> - if (debug & DEBUG_HFCMULTI_DTMF)
> - printk(KERN_DEBUG "%s: dtmf channel %d:",
> - __func__, ch);
> - coeff = &(hc->chan[ch].coeff[hc->chan[ch].coeff_count * 16]);
> - dtmf = 1;
> - for (co = 0; co < 8; co++) {
> - /* read W(n-1) coefficient */
> - addr = hc->DTMFbase + ((co << 7) | (ch << 2));
> - HFC_outb_nodebug(hc, R_RAM_ADDR0, addr);
> - HFC_outb_nodebug(hc, R_RAM_ADDR1, addr >> 8);
> - HFC_outb_nodebug(hc, R_RAM_ADDR2, (addr >> 16)
> - | V_ADDR_INC);
> - w_float = HFC_inb_nodebug(hc, R_RAM_DATA);
> - w_float |= (HFC_inb_nodebug(hc, R_RAM_DATA) << 8);
> - if (debug & DEBUG_HFCMULTI_DTMF)
> - printk(" %04x", w_float);
> -
> - /* decode float (see chip doc) */
> - mantissa = w_float & 0x0fff;
> - if (w_float & 0x8000)
> - mantissa |= 0xfffff000;
> - exponent = (w_float >> 12) & 0x7;
> - if (exponent) {
> - mantissa ^= 0x1000;
> - mantissa <<= (exponent - 1);
> - }
> -
> - /* store coefficient */
> - coeff[co << 1] = mantissa;
> -
> - /* read W(n) coefficient */
> - w_float = HFC_inb_nodebug(hc, R_RAM_DATA);
> - w_float |= (HFC_inb_nodebug(hc, R_RAM_DATA) << 8);
> - if (debug & DEBUG_HFCMULTI_DTMF)
> - printk(" %04x", w_float);
> -
> - /* decode float (see chip doc) */
> - mantissa = w_float & 0x0fff;
> - if (w_float & 0x8000)
> - mantissa |= 0xfffff000;
> - exponent = (w_float >> 12) & 0x7;
> - if (exponent) {
> - mantissa ^= 0x1000;
> - mantissa <<= (exponent - 1);
> - }
> -
> - /* store coefficient */
> - coeff[(co << 1) | 1] = mantissa;
> - }
> - if (debug & DEBUG_HFCMULTI_DTMF)
> - printk(" DTMF ready %08x %08x %08x %08x "
> - "%08x %08x %08x %08x\n",
> - coeff[0], coeff[1], coeff[2], coeff[3],
> - coeff[4], coeff[5], coeff[6], coeff[7]);
> - hc->chan[ch].coeff_count++;
> - if (hc->chan[ch].coeff_count == 8) {
> - hc->chan[ch].coeff_count = 0;
> - skb = mI_alloc_skb(512, GFP_ATOMIC);
> - if (!skb) {
> - printk(KERN_DEBUG "%s: No memory for skb\n",
> - __func__);
> - continue;
> - }
> - hh = mISDN_HEAD_P(skb);
> - hh->prim = PH_CONTROL_IND;
> - hh->id = DTMF_HFC_COEF;
> - skb_put_data(skb, hc->chan[ch].coeff, 512);
> - recv_Bchannel_skb(bch, skb);
> - }
> - }
> -
> - /* restart DTMF processing */
> - hc->dtmf = dtmf;
> - if (dtmf)
> - HFC_outb_nodebug(hc, R_DTMF, hc->hw.r_dtmf | V_RST_DTMF);
> -}
> -
> -
> -/*
> - * fill fifo as much as possible
> - */
> -
> -static void
> -hfcmulti_tx(struct hfc_multi *hc, int ch)
> -{
> - int i, ii, temp, tmp_len, len = 0;
> - int Zspace, z1, z2; /* must be int for calculation */
> - int Fspace, f1, f2;
> - u_char *d;
> - int *txpending, slot_tx;
> - struct bchannel *bch;
> - struct dchannel *dch;
> - struct sk_buff **sp = NULL;
> - int *idxp;
> -
> - bch = hc->chan[ch].bch;
> - dch = hc->chan[ch].dch;
> - if ((!dch) && (!bch))
> - return;
> -
> - txpending = &hc->chan[ch].txpending;
> - slot_tx = hc->chan[ch].slot_tx;
> - if (dch) {
> - if (!test_bit(FLG_ACTIVE, &dch->Flags))
> - return;
> - sp = &dch->tx_skb;
> - idxp = &dch->tx_idx;
> - } else {
> - if (!test_bit(FLG_ACTIVE, &bch->Flags))
> - return;
> - sp = &bch->tx_skb;
> - idxp = &bch->tx_idx;
> - }
> - if (*sp)
> - len = (*sp)->len;
> -
> - if ((!len) && *txpending != 1)
> - return; /* no data */
> -
> - if (test_bit(HFC_CHIP_B410P, &hc->chip) &&
> - (hc->chan[ch].protocol == ISDN_P_B_RAW) &&
> - (hc->chan[ch].slot_rx < 0) &&
> - (hc->chan[ch].slot_tx < 0))
> - HFC_outb_nodebug(hc, R_FIFO, 0x20 | (ch << 1));
> - else
> - HFC_outb_nodebug(hc, R_FIFO, ch << 1);
> - HFC_wait_nodebug(hc);
> -
> - if (*txpending == 2) {
> - /* reset fifo */
> - HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_RES_F);
> - HFC_wait_nodebug(hc);
> - HFC_outb(hc, A_SUBCH_CFG, 0);
> - *txpending = 1;
> - }
> -next_frame:
> - if (dch || test_bit(FLG_HDLC, &bch->Flags)) {
> - f1 = HFC_inb_nodebug(hc, A_F1);
> - f2 = HFC_inb_nodebug(hc, A_F2);
> - while (f2 != (temp = HFC_inb_nodebug(hc, A_F2))) {
> - if (debug & DEBUG_HFCMULTI_FIFO)
> - printk(KERN_DEBUG
> - "%s(card %d): reread f2 because %d!=%d\n",
> - __func__, hc->id + 1, temp, f2);
> - f2 = temp; /* repeat until F2 is equal */
> - }
> - Fspace = f2 - f1 - 1;
> - if (Fspace < 0)
> - Fspace += hc->Flen;
> - /*
> - * Old FIFO handling doesn't give us the current Z2 read
> - * pointer, so we cannot send the next frame before the fifo
> - * is empty. It makes no difference except for a slightly
> - * lower performance.
> - */
> - if (test_bit(HFC_CHIP_REVISION0, &hc->chip)) {
> - if (f1 != f2)
> - Fspace = 0;
> - else
> - Fspace = 1;
> - }
> - /* one frame only for ST D-channels, to allow resending */
> - if (hc->ctype != HFC_TYPE_E1 && dch) {
> - if (f1 != f2)
> - Fspace = 0;
> - }
> - /* F-counter full condition */
> - if (Fspace == 0)
> - return;
> - }
> - z1 = HFC_inw_nodebug(hc, A_Z1) - hc->Zmin;
> - z2 = HFC_inw_nodebug(hc, A_Z2) - hc->Zmin;
> - while (z2 != (temp = (HFC_inw_nodebug(hc, A_Z2) - hc->Zmin))) {
> - if (debug & DEBUG_HFCMULTI_FIFO)
> - printk(KERN_DEBUG "%s(card %d): reread z2 because "
> - "%d!=%d\n", __func__, hc->id + 1, temp, z2);
> - z2 = temp; /* repeat unti Z2 is equal */
> - }
> - hc->chan[ch].Zfill = z1 - z2;
> - if (hc->chan[ch].Zfill < 0)
> - hc->chan[ch].Zfill += hc->Zlen;
> - Zspace = z2 - z1;
> - if (Zspace <= 0)
> - Zspace += hc->Zlen;
> - Zspace -= 4; /* keep not too full, so pointers will not overrun */
> - /* fill transparent data only to maximum transparent load (minus 4) */
> - if (bch && test_bit(FLG_TRANSPARENT, &bch->Flags))
> - Zspace = Zspace - hc->Zlen + hc->max_trans;
> - if (Zspace <= 0) /* no space of 4 bytes */
> - return;
> -
> - /* if no data */
> - if (!len) {
> - if (z1 == z2) { /* empty */
> - /* if done with FIFO audio data during PCM connection */
> - if (bch && (!test_bit(FLG_HDLC, &bch->Flags)) &&
> - *txpending && slot_tx >= 0) {
> - if (debug & DEBUG_HFCMULTI_MODE)
> - printk(KERN_DEBUG
> - "%s: reconnecting PCM due to no "
> - "more FIFO data: channel %d "
> - "slot_tx %d\n",
> - __func__, ch, slot_tx);
> - /* connect slot */
> - if (hc->ctype == HFC_TYPE_XHFC)
> - HFC_outb(hc, A_CON_HDLC, 0xc0
> - | 0x07 << 2 | V_HDLC_TRP | V_IFF);
> - /* Enable FIFO, no interrupt */
> - else
> - HFC_outb(hc, A_CON_HDLC, 0xc0 | 0x00 |
> - V_HDLC_TRP | V_IFF);
> - HFC_outb_nodebug(hc, R_FIFO, ch << 1 | 1);
> - HFC_wait_nodebug(hc);
> - if (hc->ctype == HFC_TYPE_XHFC)
> - HFC_outb(hc, A_CON_HDLC, 0xc0
> - | 0x07 << 2 | V_HDLC_TRP | V_IFF);
> - /* Enable FIFO, no interrupt */
> - else
> - HFC_outb(hc, A_CON_HDLC, 0xc0 | 0x00 |
> - V_HDLC_TRP | V_IFF);
> - HFC_outb_nodebug(hc, R_FIFO, ch << 1);
> - HFC_wait_nodebug(hc);
> - }
> - *txpending = 0;
> - }
> - return; /* no data */
> - }
> -
> - /* "fill fifo if empty" feature */
> - if (bch && test_bit(FLG_FILLEMPTY, &bch->Flags)
> - && !test_bit(FLG_HDLC, &bch->Flags) && z2 == z1) {
> - if (debug & DEBUG_HFCMULTI_FILL)
> - printk(KERN_DEBUG "%s: buffer empty, so we have "
> - "underrun\n", __func__);
> - /* fill buffer, to prevent future underrun */
> - hc->write_fifo(hc, hc->silence_data, poll >> 1);
> - Zspace -= (poll >> 1);
> - }
> -
> - /* if audio data and connected slot */
> - if (bch && (!test_bit(FLG_HDLC, &bch->Flags)) && (!*txpending)
> - && slot_tx >= 0) {
> - if (debug & DEBUG_HFCMULTI_MODE)
> - printk(KERN_DEBUG "%s: disconnecting PCM due to "
> - "FIFO data: channel %d slot_tx %d\n",
> - __func__, ch, slot_tx);
> - /* disconnect slot */
> - if (hc->ctype == HFC_TYPE_XHFC)
> - HFC_outb(hc, A_CON_HDLC, 0x80
> - | 0x07 << 2 | V_HDLC_TRP | V_IFF);
> - /* Enable FIFO, no interrupt */
> - else
> - HFC_outb(hc, A_CON_HDLC, 0x80 | 0x00 |
> - V_HDLC_TRP | V_IFF);
> - HFC_outb_nodebug(hc, R_FIFO, ch << 1 | 1);
> - HFC_wait_nodebug(hc);
> - if (hc->ctype == HFC_TYPE_XHFC)
> - HFC_outb(hc, A_CON_HDLC, 0x80
> - | 0x07 << 2 | V_HDLC_TRP | V_IFF);
> - /* Enable FIFO, no interrupt */
> - else
> - HFC_outb(hc, A_CON_HDLC, 0x80 | 0x00 |
> - V_HDLC_TRP | V_IFF);
> - HFC_outb_nodebug(hc, R_FIFO, ch << 1);
> - HFC_wait_nodebug(hc);
> - }
> - *txpending = 1;
> -
> - /* show activity */
> - if (dch)
> - hc->activity_tx |= 1 << hc->chan[ch].port;
> -
> - /* fill fifo to what we have left */
> - ii = len;
> - if (dch || test_bit(FLG_HDLC, &bch->Flags))
> - temp = 1;
> - else
> - temp = 0;
> - i = *idxp;
> - d = (*sp)->data + i;
> - if (ii - i > Zspace)
> - ii = Zspace + i;
> - if (debug & DEBUG_HFCMULTI_FIFO)
> - printk(KERN_DEBUG "%s(card %d): fifo(%d) has %d bytes space "
> - "left (z1=%04x, z2=%04x) sending %d of %d bytes %s\n",
> - __func__, hc->id + 1, ch, Zspace, z1, z2, ii-i, len-i,
> - temp ? "HDLC" : "TRANS");
> -
> - /* Have to prep the audio data */
> - hc->write_fifo(hc, d, ii - i);
> - hc->chan[ch].Zfill += ii - i;
> - *idxp = ii;
> -
> - /* if not all data has been written */
> - if (ii != len) {
> - /* NOTE: fifo is started by the calling function */
> - return;
> - }
> -
> - /* if all data has been written, terminate frame */
> - if (dch || test_bit(FLG_HDLC, &bch->Flags)) {
> - /* increment f-counter */
> - HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_INC_F);
> - HFC_wait_nodebug(hc);
> - }
> -
> - tmp_len = (*sp)->len;
> - dev_kfree_skb(*sp);
> - /* check for next frame */
> - if (bch && get_next_bframe(bch)) {
> - len = tmp_len;
> - goto next_frame;
> - }
> - if (dch && get_next_dframe(dch)) {
> - len = tmp_len;
> - goto next_frame;
> - }
> -
> - /*
> - * now we have no more data, so in case of transparent,
> - * we set the last byte in fifo to 'silence' in case we will get
> - * no more data at all. this prevents sending an undefined value.
> - */
> - if (bch && test_bit(FLG_TRANSPARENT, &bch->Flags))
> - HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, hc->silence);
> -}
> -
> -
> -/* NOTE: only called if E1 card is in active state */
> -static void
> -hfcmulti_rx(struct hfc_multi *hc, int ch)
> -{
> - int temp;
> - int Zsize, z1, z2 = 0; /* = 0, to make GCC happy */
> - int f1 = 0, f2 = 0; /* = 0, to make GCC happy */
> - int again = 0;
> - struct bchannel *bch;
> - struct dchannel *dch = NULL;
> - struct sk_buff *skb, **sp = NULL;
> - int maxlen;
> -
> - bch = hc->chan[ch].bch;
> - if (bch) {
> - if (!test_bit(FLG_ACTIVE, &bch->Flags))
> - return;
> - } else if (hc->chan[ch].dch) {
> - dch = hc->chan[ch].dch;
> - if (!test_bit(FLG_ACTIVE, &dch->Flags))
> - return;
> - } else {
> - return;
> - }
> -next_frame:
> - /* on first AND before getting next valid frame, R_FIFO must be written
> - to. */
> - if (test_bit(HFC_CHIP_B410P, &hc->chip) &&
> - (hc->chan[ch].protocol == ISDN_P_B_RAW) &&
> - (hc->chan[ch].slot_rx < 0) &&
> - (hc->chan[ch].slot_tx < 0))
> - HFC_outb_nodebug(hc, R_FIFO, 0x20 | (ch << 1) | 1);
> - else
> - HFC_outb_nodebug(hc, R_FIFO, (ch << 1) | 1);
> - HFC_wait_nodebug(hc);
> -
> - /* ignore if rx is off BUT change fifo (above) to start pending TX */
> - if (hc->chan[ch].rx_off) {
> - if (bch)
> - bch->dropcnt += poll; /* not exact but fair enough */
> - return;
> - }
> -
> - if (dch || test_bit(FLG_HDLC, &bch->Flags)) {
> - f1 = HFC_inb_nodebug(hc, A_F1);
> - while (f1 != (temp = HFC_inb_nodebug(hc, A_F1))) {
> - if (debug & DEBUG_HFCMULTI_FIFO)
> - printk(KERN_DEBUG
> - "%s(card %d): reread f1 because %d!=%d\n",
> - __func__, hc->id + 1, temp, f1);
> - f1 = temp; /* repeat until F1 is equal */
> - }
> - f2 = HFC_inb_nodebug(hc, A_F2);
> - }
> - z1 = HFC_inw_nodebug(hc, A_Z1) - hc->Zmin;
> - while (z1 != (temp = (HFC_inw_nodebug(hc, A_Z1) - hc->Zmin))) {
> - if (debug & DEBUG_HFCMULTI_FIFO)
> - printk(KERN_DEBUG "%s(card %d): reread z2 because "
> - "%d!=%d\n", __func__, hc->id + 1, temp, z2);
> - z1 = temp; /* repeat until Z1 is equal */
> - }
> - z2 = HFC_inw_nodebug(hc, A_Z2) - hc->Zmin;
> - Zsize = z1 - z2;
> - if ((dch || test_bit(FLG_HDLC, &bch->Flags)) && f1 != f2)
> - /* complete hdlc frame */
> - Zsize++;
> - if (Zsize < 0)
> - Zsize += hc->Zlen;
> - /* if buffer is empty */
> - if (Zsize <= 0)
> - return;
> -
> - if (bch) {
> - maxlen = bchannel_get_rxbuf(bch, Zsize);
> - if (maxlen < 0) {
> - pr_warn("card%d.B%d: No bufferspace for %d bytes\n",
> - hc->id + 1, bch->nr, Zsize);
> - return;
> - }
> - sp = &bch->rx_skb;
> - maxlen = bch->maxlen;
> - } else { /* Dchannel */
> - sp = &dch->rx_skb;
> - maxlen = dch->maxlen + 3;
> - if (*sp == NULL) {
> - *sp = mI_alloc_skb(maxlen, GFP_ATOMIC);
> - if (*sp == NULL) {
> - pr_warn("card%d: No mem for dch rx_skb\n",
> - hc->id + 1);
> - return;
> - }
> - }
> - }
> - /* show activity */
> - if (dch)
> - hc->activity_rx |= 1 << hc->chan[ch].port;
> -
> - /* empty fifo with what we have */
> - if (dch || test_bit(FLG_HDLC, &bch->Flags)) {
> - if (debug & DEBUG_HFCMULTI_FIFO)
> - printk(KERN_DEBUG "%s(card %d): fifo(%d) reading %d "
> - "bytes (z1=%04x, z2=%04x) HDLC %s (f1=%d, f2=%d) "
> - "got=%d (again %d)\n", __func__, hc->id + 1, ch,
> - Zsize, z1, z2, (f1 == f2) ? "fragment" : "COMPLETE",
> - f1, f2, Zsize + (*sp)->len, again);
> - /* HDLC */
> - if ((Zsize + (*sp)->len) > maxlen) {
> - if (debug & DEBUG_HFCMULTI_FIFO)
> - printk(KERN_DEBUG
> - "%s(card %d): hdlc-frame too large.\n",
> - __func__, hc->id + 1);
> - skb_trim(*sp, 0);
> - HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_RES_F);
> - HFC_wait_nodebug(hc);
> - return;
> - }
> -
> - hc->read_fifo(hc, skb_put(*sp, Zsize), Zsize);
> -
> - if (f1 != f2) {
> - /* increment Z2,F2-counter */
> - HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_INC_F);
> - HFC_wait_nodebug(hc);
> - /* check size */
> - if ((*sp)->len < 4) {
> - if (debug & DEBUG_HFCMULTI_FIFO)
> - printk(KERN_DEBUG
> - "%s(card %d): Frame below minimum "
> - "size\n", __func__, hc->id + 1);
> - skb_trim(*sp, 0);
> - goto next_frame;
> - }
> - /* there is at least one complete frame, check crc */
> - if ((*sp)->data[(*sp)->len - 1]) {
> - if (debug & DEBUG_HFCMULTI_CRC)
> - printk(KERN_DEBUG
> - "%s: CRC-error\n", __func__);
> - skb_trim(*sp, 0);
> - goto next_frame;
> - }
> - skb_trim(*sp, (*sp)->len - 3);
> - if ((*sp)->len < MISDN_COPY_SIZE) {
> - skb = *sp;
> - *sp = mI_alloc_skb(skb->len, GFP_ATOMIC);
> - if (*sp) {
> - skb_put_data(*sp, skb->data, skb->len);
> - skb_trim(skb, 0);
> - } else {
> - printk(KERN_DEBUG "%s: No mem\n",
> - __func__);
> - *sp = skb;
> - skb = NULL;
> - }
> - } else {
> - skb = NULL;
> - }
> - if (debug & DEBUG_HFCMULTI_FIFO) {
> - printk(KERN_DEBUG "%s(card %d):",
> - __func__, hc->id + 1);
> - temp = 0;
> - while (temp < (*sp)->len)
> - printk(" %02x", (*sp)->data[temp++]);
> - printk("\n");
> - }
> - if (dch)
> - recv_Dchannel(dch);
> - else
> - recv_Bchannel(bch, MISDN_ID_ANY, false);
> - *sp = skb;
> - again++;
> - goto next_frame;
> - }
> - /* there is an incomplete frame */
> - } else {
> - /* transparent */
> - hc->read_fifo(hc, skb_put(*sp, Zsize), Zsize);
> - if (debug & DEBUG_HFCMULTI_FIFO)
> - printk(KERN_DEBUG
> - "%s(card %d): fifo(%d) reading %d bytes "
> - "(z1=%04x, z2=%04x) TRANS\n",
> - __func__, hc->id + 1, ch, Zsize, z1, z2);
> - /* only bch is transparent */
> - recv_Bchannel(bch, hc->chan[ch].Zfill, false);
> - }
> -}
> -
> -
> -/*
> - * Interrupt handler
> - */
> -static void
> -signal_state_up(struct dchannel *dch, int info, char *msg)
> -{
> - struct sk_buff *skb;
> - int id, data = info;
> -
> - if (debug & DEBUG_HFCMULTI_STATE)
> - printk(KERN_DEBUG "%s: %s\n", __func__, msg);
> -
> - id = TEI_SAPI | (GROUP_TEI << 8); /* manager address */
> -
> - skb = _alloc_mISDN_skb(MPH_INFORMATION_IND, id, sizeof(data), &data,
> - GFP_ATOMIC);
> - if (!skb)
> - return;
> - recv_Dchannel_skb(dch, skb);
> -}
> -
> -static inline void
> -handle_timer_irq(struct hfc_multi *hc)
> -{
> - int ch, temp;
> - struct dchannel *dch;
> - u_long flags;
> -
> - /* process queued resync jobs */
> - if (hc->e1_resync) {
> - /* lock, so e1_resync gets not changed */
> - spin_lock_irqsave(&HFClock, flags);
> - if (hc->e1_resync & 1) {
> - if (debug & DEBUG_HFCMULTI_PLXSD)
> - printk(KERN_DEBUG "Enable SYNC_I\n");
> - HFC_outb(hc, R_SYNC_CTRL, V_EXT_CLK_SYNC);
> - /* disable JATT, if RX_SYNC is set */
> - if (test_bit(HFC_CHIP_RX_SYNC, &hc->chip))
> - HFC_outb(hc, R_SYNC_OUT, V_SYNC_E1_RX);
> - }
> - if (hc->e1_resync & 2) {
> - if (debug & DEBUG_HFCMULTI_PLXSD)
> - printk(KERN_DEBUG "Enable jatt PLL\n");
> - HFC_outb(hc, R_SYNC_CTRL, V_SYNC_OFFS);
> - }
> - if (hc->e1_resync & 4) {
> - if (debug & DEBUG_HFCMULTI_PLXSD)
> - printk(KERN_DEBUG
> - "Enable QUARTZ for HFC-E1\n");
> - /* set jatt to quartz */
> - HFC_outb(hc, R_SYNC_CTRL, V_EXT_CLK_SYNC
> - | V_JATT_OFF);
> - /* switch to JATT, in case it is not already */
> - HFC_outb(hc, R_SYNC_OUT, 0);
> - }
> - hc->e1_resync = 0;
> - spin_unlock_irqrestore(&HFClock, flags);
> - }
> -
> - if (hc->ctype != HFC_TYPE_E1 || hc->e1_state == 1)
> - for (ch = 0; ch <= 31; ch++) {
> - if (hc->created[hc->chan[ch].port]) {
> - hfcmulti_tx(hc, ch);
> - /* fifo is started when switching to rx-fifo */
> - hfcmulti_rx(hc, ch);
> - if (hc->chan[ch].dch &&
> - hc->chan[ch].nt_timer > -1) {
> - dch = hc->chan[ch].dch;
> - if (!(--hc->chan[ch].nt_timer)) {
> - schedule_event(dch,
> - FLG_PHCHANGE);
> - if (debug &
> - DEBUG_HFCMULTI_STATE)
> - printk(KERN_DEBUG
> - "%s: nt_timer at "
> - "state %x\n",
> - __func__,
> - dch->state);
> - }
> - }
> - }
> - }
> - if (hc->ctype == HFC_TYPE_E1 && hc->created[0]) {
> - dch = hc->chan[hc->dnum[0]].dch;
> - /* LOS */
> - temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_SIG_LOS;
> - hc->chan[hc->dnum[0]].los = temp;
> - if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dnum[0]].cfg)) {
> - if (!temp && hc->chan[hc->dnum[0]].los)
> - signal_state_up(dch, L1_SIGNAL_LOS_ON,
> - "LOS detected");
> - if (temp && !hc->chan[hc->dnum[0]].los)
> - signal_state_up(dch, L1_SIGNAL_LOS_OFF,
> - "LOS gone");
> - }
> - if (test_bit(HFC_CFG_REPORT_AIS, &hc->chan[hc->dnum[0]].cfg)) {
> - /* AIS */
> - temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_AIS;
> - if (!temp && hc->chan[hc->dnum[0]].ais)
> - signal_state_up(dch, L1_SIGNAL_AIS_ON,
> - "AIS detected");
> - if (temp && !hc->chan[hc->dnum[0]].ais)
> - signal_state_up(dch, L1_SIGNAL_AIS_OFF,
> - "AIS gone");
> - hc->chan[hc->dnum[0]].ais = temp;
> - }
> - if (test_bit(HFC_CFG_REPORT_SLIP, &hc->chan[hc->dnum[0]].cfg)) {
> - /* SLIP */
> - temp = HFC_inb_nodebug(hc, R_SLIP) & V_FOSLIP_RX;
> - if (!temp && hc->chan[hc->dnum[0]].slip_rx)
> - signal_state_up(dch, L1_SIGNAL_SLIP_RX,
> - " bit SLIP detected RX");
> - hc->chan[hc->dnum[0]].slip_rx = temp;
> - temp = HFC_inb_nodebug(hc, R_SLIP) & V_FOSLIP_TX;
> - if (!temp && hc->chan[hc->dnum[0]].slip_tx)
> - signal_state_up(dch, L1_SIGNAL_SLIP_TX,
> - " bit SLIP detected TX");
> - hc->chan[hc->dnum[0]].slip_tx = temp;
> - }
> - if (test_bit(HFC_CFG_REPORT_RDI, &hc->chan[hc->dnum[0]].cfg)) {
> - /* RDI */
> - temp = HFC_inb_nodebug(hc, R_RX_SL0_0) & V_A;
> - if (!temp && hc->chan[hc->dnum[0]].rdi)
> - signal_state_up(dch, L1_SIGNAL_RDI_ON,
> - "RDI detected");
> - if (temp && !hc->chan[hc->dnum[0]].rdi)
> - signal_state_up(dch, L1_SIGNAL_RDI_OFF,
> - "RDI gone");
> - hc->chan[hc->dnum[0]].rdi = temp;
> - }
> - temp = HFC_inb_nodebug(hc, R_JATT_DIR);
> - switch (hc->chan[hc->dnum[0]].sync) {
> - case 0:
> - if ((temp & 0x60) == 0x60) {
> - if (debug & DEBUG_HFCMULTI_SYNC)
> - printk(KERN_DEBUG
> - "%s: (id=%d) E1 now "
> - "in clock sync\n",
> - __func__, hc->id);
> - HFC_outb(hc, R_RX_OFF,
> - hc->chan[hc->dnum[0]].jitter | V_RX_INIT);
> - HFC_outb(hc, R_TX_OFF,
> - hc->chan[hc->dnum[0]].jitter | V_RX_INIT);
> - hc->chan[hc->dnum[0]].sync = 1;
> - goto check_framesync;
> - }
> - break;
> - case 1:
> - if ((temp & 0x60) != 0x60) {
> - if (debug & DEBUG_HFCMULTI_SYNC)
> - printk(KERN_DEBUG
> - "%s: (id=%d) E1 "
> - "lost clock sync\n",
> - __func__, hc->id);
> - hc->chan[hc->dnum[0]].sync = 0;
> - break;
> - }
> - check_framesync:
> - temp = HFC_inb_nodebug(hc, R_SYNC_STA);
> - if (temp == 0x27) {
> - if (debug & DEBUG_HFCMULTI_SYNC)
> - printk(KERN_DEBUG
> - "%s: (id=%d) E1 "
> - "now in frame sync\n",
> - __func__, hc->id);
> - hc->chan[hc->dnum[0]].sync = 2;
> - }
> - break;
> - case 2:
> - if ((temp & 0x60) != 0x60) {
> - if (debug & DEBUG_HFCMULTI_SYNC)
> - printk(KERN_DEBUG
> - "%s: (id=%d) E1 lost "
> - "clock & frame sync\n",
> - __func__, hc->id);
> - hc->chan[hc->dnum[0]].sync = 0;
> - break;
> - }
> - temp = HFC_inb_nodebug(hc, R_SYNC_STA);
> - if (temp != 0x27) {
> - if (debug & DEBUG_HFCMULTI_SYNC)
> - printk(KERN_DEBUG
> - "%s: (id=%d) E1 "
> - "lost frame sync\n",
> - __func__, hc->id);
> - hc->chan[hc->dnum[0]].sync = 1;
> - }
> - break;
> - }
> - }
> -
> - if (test_bit(HFC_CHIP_WATCHDOG, &hc->chip))
> - hfcmulti_watchdog(hc);
> -
> - if (hc->leds)
> - hfcmulti_leds(hc);
> -}
> -
> -static void
> -ph_state_irq(struct hfc_multi *hc, u_char r_irq_statech)
> -{
> - struct dchannel *dch;
> - int ch;
> - int active;
> - u_char st_status, temp;
> -
> - /* state machine */
> - for (ch = 0; ch <= 31; ch++) {
> - if (hc->chan[ch].dch) {
> - dch = hc->chan[ch].dch;
> - if (r_irq_statech & 1) {
> - HFC_outb_nodebug(hc, R_ST_SEL,
> - hc->chan[ch].port);
> - /* undocumented: delay after R_ST_SEL */
> - udelay(1);
> - /* undocumented: status changes during read */
> - st_status = HFC_inb_nodebug(hc, A_ST_RD_STATE);
> - while (st_status != (temp =
> - HFC_inb_nodebug(hc, A_ST_RD_STATE))) {
> - if (debug & DEBUG_HFCMULTI_STATE)
> - printk(KERN_DEBUG "%s: reread "
> - "STATE because %d!=%d\n",
> - __func__, temp,
> - st_status);
> - st_status = temp; /* repeat */
> - }
> -
> - /* Speech Design TE-sync indication */
> - if (test_bit(HFC_CHIP_PLXSD, &hc->chip) &&
> - dch->dev.D.protocol == ISDN_P_TE_S0) {
> - if (st_status & V_FR_SYNC_ST)
> - hc->syncronized |=
> - (1 << hc->chan[ch].port);
> - else
> - hc->syncronized &=
> - ~(1 << hc->chan[ch].port);
> - }
> - dch->state = st_status & 0x0f;
> - if (dch->dev.D.protocol == ISDN_P_NT_S0)
> - active = 3;
> - else
> - active = 7;
> - if (dch->state == active) {
> - HFC_outb_nodebug(hc, R_FIFO,
> - (ch << 1) | 1);
> - HFC_wait_nodebug(hc);
> - HFC_outb_nodebug(hc,
> - R_INC_RES_FIFO, V_RES_F);
> - HFC_wait_nodebug(hc);
> - dch->tx_idx = 0;
> - }
> - schedule_event(dch, FLG_PHCHANGE);
> - if (debug & DEBUG_HFCMULTI_STATE)
> - printk(KERN_DEBUG
> - "%s: S/T newstate %x port %d\n",
> - __func__, dch->state,
> - hc->chan[ch].port);
> - }
> - r_irq_statech >>= 1;
> - }
> - }
> - if (test_bit(HFC_CHIP_PLXSD, &hc->chip))
> - plxsd_checksync(hc, 0);
> -}
> -
> -static void
> -fifo_irq(struct hfc_multi *hc, int block)
> -{
> - int ch, j;
> - struct dchannel *dch;
> - struct bchannel *bch;
> - u_char r_irq_fifo_bl;
> -
> - r_irq_fifo_bl = HFC_inb_nodebug(hc, R_IRQ_FIFO_BL0 + block);
> - j = 0;
> - while (j < 8) {
> - ch = (block << 2) + (j >> 1);
> - dch = hc->chan[ch].dch;
> - bch = hc->chan[ch].bch;
> - if (((!dch) && (!bch)) || (!hc->created[hc->chan[ch].port])) {
> - j += 2;
> - continue;
> - }
> - if (dch && (r_irq_fifo_bl & (1 << j)) &&
> - test_bit(FLG_ACTIVE, &dch->Flags)) {
> - hfcmulti_tx(hc, ch);
> - /* start fifo */
> - HFC_outb_nodebug(hc, R_FIFO, 0);
> - HFC_wait_nodebug(hc);
> - }
> - if (bch && (r_irq_fifo_bl & (1 << j)) &&
> - test_bit(FLG_ACTIVE, &bch->Flags)) {
> - hfcmulti_tx(hc, ch);
> - /* start fifo */
> - HFC_outb_nodebug(hc, R_FIFO, 0);
> - HFC_wait_nodebug(hc);
> - }
> - j++;
> - if (dch && (r_irq_fifo_bl & (1 << j)) &&
> - test_bit(FLG_ACTIVE, &dch->Flags)) {
> - hfcmulti_rx(hc, ch);
> - }
> - if (bch && (r_irq_fifo_bl & (1 << j)) &&
> - test_bit(FLG_ACTIVE, &bch->Flags)) {
> - hfcmulti_rx(hc, ch);
> - }
> - j++;
> - }
> -}
> -
> -#ifdef IRQ_DEBUG
> -int irqsem;
> -#endif
> -static irqreturn_t
> -hfcmulti_interrupt(int intno, void *dev_id)
> -{
> -#ifdef IRQCOUNT_DEBUG
> - static int iq1 = 0, iq2 = 0, iq3 = 0, iq4 = 0,
> - iq5 = 0, iq6 = 0, iqcnt = 0;
> -#endif
> - struct hfc_multi *hc = dev_id;
> - struct dchannel *dch;
> - u_char r_irq_statech, status, r_irq_misc, r_irq_oview;
> - int i;
> - void __iomem *plx_acc;
> - u_short wval;
> - u_char e1_syncsta, temp, temp2;
> - u_long flags;
> -
> - if (!hc) {
> - printk(KERN_ERR "HFC-multi: Spurious interrupt!\n");
> - return IRQ_NONE;
> - }
> -
> - spin_lock(&hc->lock);
> -
> -#ifdef IRQ_DEBUG
> - if (irqsem)
> - printk(KERN_ERR "irq for card %d during irq from "
> - "card %d, this is no bug.\n", hc->id + 1, irqsem);
> - irqsem = hc->id + 1;
> -#endif
> -#ifdef CONFIG_MISDN_HFCMULTI_8xx
> - if (hc->immap->im_cpm.cp_pbdat & hc->pb_irqmsk)
> - goto irq_notforus;
> -#endif
> - if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
> - spin_lock_irqsave(&plx_lock, flags);
> - plx_acc = hc->plx_membase + PLX_INTCSR;
> - wval = readw(plx_acc);
> - spin_unlock_irqrestore(&plx_lock, flags);
> - if (!(wval & PLX_INTCSR_LINTI1_STATUS))
> - goto irq_notforus;
> - }
> -
> - status = HFC_inb_nodebug(hc, R_STATUS);
> - r_irq_statech = HFC_inb_nodebug(hc, R_IRQ_STATECH);
> -#ifdef IRQCOUNT_DEBUG
> - if (r_irq_statech)
> - iq1++;
> - if (status & V_DTMF_STA)
> - iq2++;
> - if (status & V_LOST_STA)
> - iq3++;
> - if (status & V_EXT_IRQSTA)
> - iq4++;
> - if (status & V_MISC_IRQSTA)
> - iq5++;
> - if (status & V_FR_IRQSTA)
> - iq6++;
> - if (iqcnt++ > 5000) {
> - printk(KERN_ERR "iq1:%x iq2:%x iq3:%x iq4:%x iq5:%x iq6:%x\n",
> - iq1, iq2, iq3, iq4, iq5, iq6);
> - iqcnt = 0;
> - }
> -#endif
> -
> - if (!r_irq_statech &&
> - !(status & (V_DTMF_STA | V_LOST_STA | V_EXT_IRQSTA |
> - V_MISC_IRQSTA | V_FR_IRQSTA))) {
> - /* irq is not for us */
> - goto irq_notforus;
> - }
> - hc->irqcnt++;
> - if (r_irq_statech) {
> - if (hc->ctype != HFC_TYPE_E1)
> - ph_state_irq(hc, r_irq_statech);
> - }
> - if (status & V_LOST_STA) {
> - /* LOST IRQ */
> - HFC_outb(hc, R_INC_RES_FIFO, V_RES_LOST); /* clear irq! */
> - }
> - if (status & V_MISC_IRQSTA) {
> - /* misc IRQ */
> - r_irq_misc = HFC_inb_nodebug(hc, R_IRQ_MISC);
> - r_irq_misc &= hc->hw.r_irqmsk_misc; /* ignore disabled irqs */
> - if (r_irq_misc & V_STA_IRQ) {
> - if (hc->ctype == HFC_TYPE_E1) {
> - /* state machine */
> - dch = hc->chan[hc->dnum[0]].dch;
> - e1_syncsta = HFC_inb_nodebug(hc, R_SYNC_STA);
> - if (test_bit(HFC_CHIP_PLXSD, &hc->chip)
> - && hc->e1_getclock) {
> - if (e1_syncsta & V_FR_SYNC_E1)
> - hc->syncronized = 1;
> - else
> - hc->syncronized = 0;
> - }
> - /* undocumented: status changes during read */
> - temp = HFC_inb_nodebug(hc, R_E1_RD_STA);
> - while (temp != (temp2 =
> - HFC_inb_nodebug(hc, R_E1_RD_STA))) {
> - if (debug & DEBUG_HFCMULTI_STATE)
> - printk(KERN_DEBUG "%s: reread "
> - "STATE because %d!=%d\n",
> - __func__, temp, temp2);
> - temp = temp2; /* repeat */
> - }
> - /* broadcast state change to all fragments */
> - if (debug & DEBUG_HFCMULTI_STATE)
> - printk(KERN_DEBUG
> - "%s: E1 (id=%d) newstate %x\n",
> - __func__, hc->id, temp & 0x7);
> - for (i = 0; i < hc->ports; i++) {
> - dch = hc->chan[hc->dnum[i]].dch;
> - dch->state = temp & 0x7;
> - schedule_event(dch, FLG_PHCHANGE);
> - }
> -
> - if (test_bit(HFC_CHIP_PLXSD, &hc->chip))
> - plxsd_checksync(hc, 0);
> - }
> - }
> - if (r_irq_misc & V_TI_IRQ) {
> - if (hc->iclock_on)
> - mISDN_clock_update(hc->iclock, poll, NULL);
> - handle_timer_irq(hc);
> - }
> -
> - if (r_irq_misc & V_DTMF_IRQ)
> - hfcmulti_dtmf(hc);
> -
> - if (r_irq_misc & V_IRQ_PROC) {
> - static int irq_proc_cnt;
> - if (!irq_proc_cnt++)
> - printk(KERN_DEBUG "%s: got V_IRQ_PROC -"
> - " this should not happen\n", __func__);
> - }
> -
> - }
> - if (status & V_FR_IRQSTA) {
> - /* FIFO IRQ */
> - r_irq_oview = HFC_inb_nodebug(hc, R_IRQ_OVIEW);
> - for (i = 0; i < 8; i++) {
> - if (r_irq_oview & (1 << i))
> - fifo_irq(hc, i);
> - }
> - }
> -
> -#ifdef IRQ_DEBUG
> - irqsem = 0;
> -#endif
> - spin_unlock(&hc->lock);
> - return IRQ_HANDLED;
> -
> -irq_notforus:
> -#ifdef IRQ_DEBUG
> - irqsem = 0;
> -#endif
> - spin_unlock(&hc->lock);
> - return IRQ_NONE;
> -}
> -
> -
> -/*
> - * timer callback for D-chan busy resolution. Currently no function
> - */
> -
> -static void
> -hfcmulti_dbusy_timer(struct timer_list *t)
> -{
> -}
> -
> -
> -/*
> - * activate/deactivate hardware for selected channels and mode
> - *
> - * configure B-channel with the given protocol
> - * ch eqals to the HFC-channel (0-31)
> - * ch is the number of channel (0-4,4-7,8-11,12-15,16-19,20-23,24-27,28-31
> - * for S/T, 1-31 for E1)
> - * the hdlc interrupts will be set/unset
> - */
> -static int
> -mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
> - int bank_tx, int slot_rx, int bank_rx)
> -{
> - int flow_tx = 0, flow_rx = 0, routing = 0;
> - int oslot_tx, oslot_rx;
> - int conf;
> -
> - if (ch < 0 || ch > 31)
> - return -EINVAL;
> - oslot_tx = hc->chan[ch].slot_tx;
> - oslot_rx = hc->chan[ch].slot_rx;
> - conf = hc->chan[ch].conf;
> -
> - if (debug & DEBUG_HFCMULTI_MODE)
> - printk(KERN_DEBUG
> - "%s: card %d channel %d protocol %x slot old=%d new=%d "
> - "bank new=%d (TX) slot old=%d new=%d bank new=%d (RX)\n",
> - __func__, hc->id, ch, protocol, oslot_tx, slot_tx,
> - bank_tx, oslot_rx, slot_rx, bank_rx);
> -
> - if (oslot_tx >= 0 && slot_tx != oslot_tx) {
> - /* remove from slot */
> - if (debug & DEBUG_HFCMULTI_MODE)
> - printk(KERN_DEBUG "%s: remove from slot %d (TX)\n",
> - __func__, oslot_tx);
> - if (hc->slot_owner[oslot_tx << 1] == ch) {
> - HFC_outb(hc, R_SLOT, oslot_tx << 1);
> - HFC_outb(hc, A_SL_CFG, 0);
> - if (hc->ctype != HFC_TYPE_XHFC)
> - HFC_outb(hc, A_CONF, 0);
> - hc->slot_owner[oslot_tx << 1] = -1;
> - } else {
> - if (debug & DEBUG_HFCMULTI_MODE)
> - printk(KERN_DEBUG
> - "%s: we are not owner of this tx slot "
> - "anymore, channel %d is.\n",
> - __func__, hc->slot_owner[oslot_tx << 1]);
> - }
> - }
> -
> - if (oslot_rx >= 0 && slot_rx != oslot_rx) {
> - /* remove from slot */
> - if (debug & DEBUG_HFCMULTI_MODE)
> - printk(KERN_DEBUG
> - "%s: remove from slot %d (RX)\n",
> - __func__, oslot_rx);
> - if (hc->slot_owner[(oslot_rx << 1) | 1] == ch) {
> - HFC_outb(hc, R_SLOT, (oslot_rx << 1) | V_SL_DIR);
> - HFC_outb(hc, A_SL_CFG, 0);
> - hc->slot_owner[(oslot_rx << 1) | 1] = -1;
> - } else {
> - if (debug & DEBUG_HFCMULTI_MODE)
> - printk(KERN_DEBUG
> - "%s: we are not owner of this rx slot "
> - "anymore, channel %d is.\n",
> - __func__,
> - hc->slot_owner[(oslot_rx << 1) | 1]);
> - }
> - }
> -
> - if (slot_tx < 0) {
> - flow_tx = 0x80; /* FIFO->ST */
> - /* disable pcm slot */
> - hc->chan[ch].slot_tx = -1;
> - hc->chan[ch].bank_tx = 0;
> - } else {
> - /* set pcm slot */
> - if (hc->chan[ch].txpending)
> - flow_tx = 0x80; /* FIFO->ST */
> - else
> - flow_tx = 0xc0; /* PCM->ST */
> - /* put on slot */
> - routing = bank_tx ? 0xc0 : 0x80;
> - if (conf >= 0 || bank_tx > 1)
> - routing = 0x40; /* loop */
> - if (debug & DEBUG_HFCMULTI_MODE)
> - printk(KERN_DEBUG "%s: put channel %d to slot %d bank"
> - " %d flow %02x routing %02x conf %d (TX)\n",
> - __func__, ch, slot_tx, bank_tx,
> - flow_tx, routing, conf);
> - HFC_outb(hc, R_SLOT, slot_tx << 1);
> - HFC_outb(hc, A_SL_CFG, (ch << 1) | routing);
> - if (hc->ctype != HFC_TYPE_XHFC)
> - HFC_outb(hc, A_CONF,
> - (conf < 0) ? 0 : (conf | V_CONF_SL));
> - hc->slot_owner[slot_tx << 1] = ch;
> - hc->chan[ch].slot_tx = slot_tx;
> - hc->chan[ch].bank_tx = bank_tx;
> - }
> - if (slot_rx < 0) {
> - /* disable pcm slot */
> - flow_rx = 0x80; /* ST->FIFO */
> - hc->chan[ch].slot_rx = -1;
> - hc->chan[ch].bank_rx = 0;
> - } else {
> - /* set pcm slot */
> - if (hc->chan[ch].txpending)
> - flow_rx = 0x80; /* ST->FIFO */
> - else
> - flow_rx = 0xc0; /* ST->(FIFO,PCM) */
> - /* put on slot */
> - routing = bank_rx ? 0x80 : 0xc0; /* reversed */
> - if (conf >= 0 || bank_rx > 1)
> - routing = 0x40; /* loop */
> - if (debug & DEBUG_HFCMULTI_MODE)
> - printk(KERN_DEBUG "%s: put channel %d to slot %d bank"
> - " %d flow %02x routing %02x conf %d (RX)\n",
> - __func__, ch, slot_rx, bank_rx,
> - flow_rx, routing, conf);
> - HFC_outb(hc, R_SLOT, (slot_rx << 1) | V_SL_DIR);
> - HFC_outb(hc, A_SL_CFG, (ch << 1) | V_CH_DIR | routing);
> - hc->slot_owner[(slot_rx << 1) | 1] = ch;
> - hc->chan[ch].slot_rx = slot_rx;
> - hc->chan[ch].bank_rx = bank_rx;
> - }
> -
> - switch (protocol) {
> - case (ISDN_P_NONE):
> - /* disable TX fifo */
> - HFC_outb(hc, R_FIFO, ch << 1);
> - HFC_wait(hc);
> - HFC_outb(hc, A_CON_HDLC, flow_tx | 0x00 | V_IFF);
> - HFC_outb(hc, A_SUBCH_CFG, 0);
> - HFC_outb(hc, A_IRQ_MSK, 0);
> - HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
> - HFC_wait(hc);
> - /* disable RX fifo */
> - HFC_outb(hc, R_FIFO, (ch << 1) | 1);
> - HFC_wait(hc);
> - HFC_outb(hc, A_CON_HDLC, flow_rx | 0x00);
> - HFC_outb(hc, A_SUBCH_CFG, 0);
> - HFC_outb(hc, A_IRQ_MSK, 0);
> - HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
> - HFC_wait(hc);
> - if (hc->chan[ch].bch && hc->ctype != HFC_TYPE_E1) {
> - hc->hw.a_st_ctrl0[hc->chan[ch].port] &=
> - ((ch & 0x3) == 0) ? ~V_B1_EN : ~V_B2_EN;
> - HFC_outb(hc, R_ST_SEL, hc->chan[ch].port);
> - /* undocumented: delay after R_ST_SEL */
> - udelay(1);
> - HFC_outb(hc, A_ST_CTRL0,
> - hc->hw.a_st_ctrl0[hc->chan[ch].port]);
> - }
> - if (hc->chan[ch].bch) {
> - test_and_clear_bit(FLG_HDLC, &hc->chan[ch].bch->Flags);
> - test_and_clear_bit(FLG_TRANSPARENT,
> - &hc->chan[ch].bch->Flags);
> - }
> - break;
> - case (ISDN_P_B_RAW): /* B-channel */
> -
> - if (test_bit(HFC_CHIP_B410P, &hc->chip) &&
> - (hc->chan[ch].slot_rx < 0) &&
> - (hc->chan[ch].slot_tx < 0)) {
> -
> - printk(KERN_DEBUG
> - "Setting B-channel %d to echo cancelable "
> - "state on PCM slot %d\n", ch,
> - ((ch / 4) * 8) + ((ch % 4) * 4) + 1);
> - printk(KERN_DEBUG
> - "Enabling pass through for channel\n");
> - vpm_out(hc, ch, ((ch / 4) * 8) +
> - ((ch % 4) * 4) + 1, 0x01);
> - /* rx path */
> - /* S/T -> PCM */
> - HFC_outb(hc, R_FIFO, (ch << 1));
> - HFC_wait(hc);
> - HFC_outb(hc, A_CON_HDLC, 0xc0 | V_HDLC_TRP | V_IFF);
> - HFC_outb(hc, R_SLOT, (((ch / 4) * 8) +
> - ((ch % 4) * 4) + 1) << 1);
> - HFC_outb(hc, A_SL_CFG, 0x80 | (ch << 1));
> -
> - /* PCM -> FIFO */
> - HFC_outb(hc, R_FIFO, 0x20 | (ch << 1) | 1);
> - HFC_wait(hc);
> - HFC_outb(hc, A_CON_HDLC, 0x20 | V_HDLC_TRP | V_IFF);
> - HFC_outb(hc, A_SUBCH_CFG, 0);
> - HFC_outb(hc, A_IRQ_MSK, 0);
> - if (hc->chan[ch].protocol != protocol) {
> - HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
> - HFC_wait(hc);
> - }
> - HFC_outb(hc, R_SLOT, ((((ch / 4) * 8) +
> - ((ch % 4) * 4) + 1) << 1) | 1);
> - HFC_outb(hc, A_SL_CFG, 0x80 | 0x20 | (ch << 1) | 1);
> -
> - /* tx path */
> - /* PCM -> S/T */
> - HFC_outb(hc, R_FIFO, (ch << 1) | 1);
> - HFC_wait(hc);
> - HFC_outb(hc, A_CON_HDLC, 0xc0 | V_HDLC_TRP | V_IFF);
> - HFC_outb(hc, R_SLOT, ((((ch / 4) * 8) +
> - ((ch % 4) * 4)) << 1) | 1);
> - HFC_outb(hc, A_SL_CFG, 0x80 | 0x40 | (ch << 1) | 1);
> -
> - /* FIFO -> PCM */
> - HFC_outb(hc, R_FIFO, 0x20 | (ch << 1));
> - HFC_wait(hc);
> - HFC_outb(hc, A_CON_HDLC, 0x20 | V_HDLC_TRP | V_IFF);
> - HFC_outb(hc, A_SUBCH_CFG, 0);
> - HFC_outb(hc, A_IRQ_MSK, 0);
> - if (hc->chan[ch].protocol != protocol) {
> - HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
> - HFC_wait(hc);
> - }
> - /* tx silence */
> - HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, hc->silence);
> - HFC_outb(hc, R_SLOT, (((ch / 4) * 8) +
> - ((ch % 4) * 4)) << 1);
> - HFC_outb(hc, A_SL_CFG, 0x80 | 0x20 | (ch << 1));
> - } else {
> - /* enable TX fifo */
> - HFC_outb(hc, R_FIFO, ch << 1);
> - HFC_wait(hc);
> - if (hc->ctype == HFC_TYPE_XHFC)
> - HFC_outb(hc, A_CON_HDLC, flow_tx | 0x07 << 2 |
> - V_HDLC_TRP | V_IFF);
> - /* Enable FIFO, no interrupt */
> - else
> - HFC_outb(hc, A_CON_HDLC, flow_tx | 0x00 |
> - V_HDLC_TRP | V_IFF);
> - HFC_outb(hc, A_SUBCH_CFG, 0);
> - HFC_outb(hc, A_IRQ_MSK, 0);
> - if (hc->chan[ch].protocol != protocol) {
> - HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
> - HFC_wait(hc);
> - }
> - /* tx silence */
> - HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, hc->silence);
> - /* enable RX fifo */
> - HFC_outb(hc, R_FIFO, (ch << 1) | 1);
> - HFC_wait(hc);
> - if (hc->ctype == HFC_TYPE_XHFC)
> - HFC_outb(hc, A_CON_HDLC, flow_rx | 0x07 << 2 |
> - V_HDLC_TRP);
> - /* Enable FIFO, no interrupt*/
> - else
> - HFC_outb(hc, A_CON_HDLC, flow_rx | 0x00 |
> - V_HDLC_TRP);
> - HFC_outb(hc, A_SUBCH_CFG, 0);
> - HFC_outb(hc, A_IRQ_MSK, 0);
> - if (hc->chan[ch].protocol != protocol) {
> - HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
> - HFC_wait(hc);
> - }
> - }
> - if (hc->ctype != HFC_TYPE_E1) {
> - hc->hw.a_st_ctrl0[hc->chan[ch].port] |=
> - ((ch & 0x3) == 0) ? V_B1_EN : V_B2_EN;
> - HFC_outb(hc, R_ST_SEL, hc->chan[ch].port);
> - /* undocumented: delay after R_ST_SEL */
> - udelay(1);
> - HFC_outb(hc, A_ST_CTRL0,
> - hc->hw.a_st_ctrl0[hc->chan[ch].port]);
> - }
> - if (hc->chan[ch].bch)
> - test_and_set_bit(FLG_TRANSPARENT,
> - &hc->chan[ch].bch->Flags);
> - break;
> - case (ISDN_P_B_HDLC): /* B-channel */
> - case (ISDN_P_TE_S0): /* D-channel */
> - case (ISDN_P_NT_S0):
> - case (ISDN_P_TE_E1):
> - case (ISDN_P_NT_E1):
> - /* enable TX fifo */
> - HFC_outb(hc, R_FIFO, ch << 1);
> - HFC_wait(hc);
> - if (hc->ctype == HFC_TYPE_E1 || hc->chan[ch].bch) {
> - /* E1 or B-channel */
> - HFC_outb(hc, A_CON_HDLC, flow_tx | 0x04);
> - HFC_outb(hc, A_SUBCH_CFG, 0);
> - } else {
> - /* D-Channel without HDLC fill flags */
> - HFC_outb(hc, A_CON_HDLC, flow_tx | 0x04 | V_IFF);
> - HFC_outb(hc, A_SUBCH_CFG, 2);
> - }
> - HFC_outb(hc, A_IRQ_MSK, V_IRQ);
> - HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
> - HFC_wait(hc);
> - /* enable RX fifo */
> - HFC_outb(hc, R_FIFO, (ch << 1) | 1);
> - HFC_wait(hc);
> - HFC_outb(hc, A_CON_HDLC, flow_rx | 0x04);
> - if (hc->ctype == HFC_TYPE_E1 || hc->chan[ch].bch)
> - HFC_outb(hc, A_SUBCH_CFG, 0); /* full 8 bits */
> - else
> - HFC_outb(hc, A_SUBCH_CFG, 2); /* 2 bits dchannel */
> - HFC_outb(hc, A_IRQ_MSK, V_IRQ);
> - HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
> - HFC_wait(hc);
> - if (hc->chan[ch].bch) {
> - test_and_set_bit(FLG_HDLC, &hc->chan[ch].bch->Flags);
> - if (hc->ctype != HFC_TYPE_E1) {
> - hc->hw.a_st_ctrl0[hc->chan[ch].port] |=
> - ((ch & 0x3) == 0) ? V_B1_EN : V_B2_EN;
> - HFC_outb(hc, R_ST_SEL, hc->chan[ch].port);
> - /* undocumented: delay after R_ST_SEL */
> - udelay(1);
> - HFC_outb(hc, A_ST_CTRL0,
> - hc->hw.a_st_ctrl0[hc->chan[ch].port]);
> - }
> - }
> - break;
> - default:
> - printk(KERN_DEBUG "%s: protocol not known %x\n",
> - __func__, protocol);
> - hc->chan[ch].protocol = ISDN_P_NONE;
> - return -ENOPROTOOPT;
> - }
> - hc->chan[ch].protocol = protocol;
> - return 0;
> -}
> -
> -
> -/*
> - * connect/disconnect PCM
> - */
> -
> -static void
> -hfcmulti_pcm(struct hfc_multi *hc, int ch, int slot_tx, int bank_tx,
> - int slot_rx, int bank_rx)
> -{
> - if (slot_tx < 0 || slot_rx < 0 || bank_tx < 0 || bank_rx < 0) {
> - /* disable PCM */
> - mode_hfcmulti(hc, ch, hc->chan[ch].protocol, -1, 0, -1, 0);
> - return;
> - }
> -
> - /* enable pcm */
> - mode_hfcmulti(hc, ch, hc->chan[ch].protocol, slot_tx, bank_tx,
> - slot_rx, bank_rx);
> -}
> -
> -/*
> - * set/disable conference
> - */
> -
> -static void
> -hfcmulti_conf(struct hfc_multi *hc, int ch, int num)
> -{
> - if (num >= 0 && num <= 7)
> - hc->chan[ch].conf = num;
> - else
> - hc->chan[ch].conf = -1;
> - mode_hfcmulti(hc, ch, hc->chan[ch].protocol, hc->chan[ch].slot_tx,
> - hc->chan[ch].bank_tx, hc->chan[ch].slot_rx,
> - hc->chan[ch].bank_rx);
> -}
> -
> -
> -/*
> - * set/disable sample loop
> - */
> -
> -/* NOTE: this function is experimental and therefore disabled */
> -
> -/*
> - * Layer 1 callback function
> - */
> -static int
> -hfcm_l1callback(struct dchannel *dch, u_int cmd)
> -{
> - struct hfc_multi *hc = dch->hw;
> - struct sk_buff_head free_queue;
> - u_long flags;
> -
> - switch (cmd) {
> - case INFO3_P8:
> - case INFO3_P10:
> - break;
> - case HW_RESET_REQ:
> - /* start activation */
> - spin_lock_irqsave(&hc->lock, flags);
> - if (hc->ctype == HFC_TYPE_E1) {
> - if (debug & DEBUG_HFCMULTI_MSG)
> - printk(KERN_DEBUG
> - "%s: HW_RESET_REQ no BRI\n",
> - __func__);
> - } else {
> - HFC_outb(hc, R_ST_SEL, hc->chan[dch->slot].port);
> - /* undocumented: delay after R_ST_SEL */
> - udelay(1);
> - HFC_outb(hc, A_ST_WR_STATE, V_ST_LD_STA | 3); /* F3 */
> - udelay(6); /* wait at least 5,21us */
> - HFC_outb(hc, A_ST_WR_STATE, 3);
> - HFC_outb(hc, A_ST_WR_STATE, 3 | (V_ST_ACT * 3));
> - /* activate */
> - }
> - spin_unlock_irqrestore(&hc->lock, flags);
> - l1_event(dch->l1, HW_POWERUP_IND);
> - break;
> - case HW_DEACT_REQ:
> - __skb_queue_head_init(&free_queue);
> - /* start deactivation */
> - spin_lock_irqsave(&hc->lock, flags);
> - if (hc->ctype == HFC_TYPE_E1) {
> - if (debug & DEBUG_HFCMULTI_MSG)
> - printk(KERN_DEBUG
> - "%s: HW_DEACT_REQ no BRI\n",
> - __func__);
> - } else {
> - HFC_outb(hc, R_ST_SEL, hc->chan[dch->slot].port);
> - /* undocumented: delay after R_ST_SEL */
> - udelay(1);
> - HFC_outb(hc, A_ST_WR_STATE, V_ST_ACT * 2);
> - /* deactivate */
> - if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
> - hc->syncronized &=
> - ~(1 << hc->chan[dch->slot].port);
> - plxsd_checksync(hc, 0);
> - }
> - }
> - skb_queue_splice_init(&dch->squeue, &free_queue);
> - if (dch->tx_skb) {
> - __skb_queue_tail(&free_queue, dch->tx_skb);
> - dch->tx_skb = NULL;
> - }
> - dch->tx_idx = 0;
> - if (dch->rx_skb) {
> - __skb_queue_tail(&free_queue, dch->rx_skb);
> - dch->rx_skb = NULL;
> - }
> - test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
> - if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
> - timer_delete(&dch->timer);
> - spin_unlock_irqrestore(&hc->lock, flags);
> - __skb_queue_purge(&free_queue);
> - break;
> - case HW_POWERUP_REQ:
> - spin_lock_irqsave(&hc->lock, flags);
> - if (hc->ctype == HFC_TYPE_E1) {
> - if (debug & DEBUG_HFCMULTI_MSG)
> - printk(KERN_DEBUG
> - "%s: HW_POWERUP_REQ no BRI\n",
> - __func__);
> - } else {
> - HFC_outb(hc, R_ST_SEL, hc->chan[dch->slot].port);
> - /* undocumented: delay after R_ST_SEL */
> - udelay(1);
> - HFC_outb(hc, A_ST_WR_STATE, 3 | 0x10); /* activate */
> - udelay(6); /* wait at least 5,21us */
> - HFC_outb(hc, A_ST_WR_STATE, 3); /* activate */
> - }
> - spin_unlock_irqrestore(&hc->lock, flags);
> - break;
> - case PH_ACTIVATE_IND:
> - test_and_set_bit(FLG_ACTIVE, &dch->Flags);
> - _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
> - GFP_ATOMIC);
> - break;
> - case PH_DEACTIVATE_IND:
> - test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
> - _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
> - GFP_ATOMIC);
> - break;
> - default:
> - if (dch->debug & DEBUG_HW)
> - printk(KERN_DEBUG "%s: unknown command %x\n",
> - __func__, cmd);
> - return -1;
> - }
> - return 0;
> -}
> -
> -/*
> - * Layer2 -> Layer 1 Transfer
> - */
> -
> -static int
> -handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
> -{
> - struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
> - struct dchannel *dch = container_of(dev, struct dchannel, dev);
> - struct hfc_multi *hc = dch->hw;
> - struct mISDNhead *hh = mISDN_HEAD_P(skb);
> - int ret = -EINVAL;
> - unsigned int id;
> - u_long flags;
> -
> - switch (hh->prim) {
> - case PH_DATA_REQ:
> - if (skb->len < 1)
> - break;
> - spin_lock_irqsave(&hc->lock, flags);
> - ret = dchannel_senddata(dch, skb);
> - if (ret > 0) { /* direct TX */
> - id = hh->id; /* skb can be freed */
> - hfcmulti_tx(hc, dch->slot);
> - ret = 0;
> - /* start fifo */
> - HFC_outb(hc, R_FIFO, 0);
> - HFC_wait(hc);
> - spin_unlock_irqrestore(&hc->lock, flags);
> - queue_ch_frame(ch, PH_DATA_CNF, id, NULL);
> - } else
> - spin_unlock_irqrestore(&hc->lock, flags);
> - return ret;
> - case PH_ACTIVATE_REQ:
> - if (dch->dev.D.protocol != ISDN_P_TE_S0) {
> - spin_lock_irqsave(&hc->lock, flags);
> - ret = 0;
> - if (debug & DEBUG_HFCMULTI_MSG)
> - printk(KERN_DEBUG
> - "%s: PH_ACTIVATE port %d (0..%d)\n",
> - __func__, hc->chan[dch->slot].port,
> - hc->ports - 1);
> - /* start activation */
> - if (hc->ctype == HFC_TYPE_E1) {
> - ph_state_change(dch);
> - if (debug & DEBUG_HFCMULTI_STATE)
> - printk(KERN_DEBUG
> - "%s: E1 report state %x \n",
> - __func__, dch->state);
> - } else {
> - HFC_outb(hc, R_ST_SEL,
> - hc->chan[dch->slot].port);
> - /* undocumented: delay after R_ST_SEL */
> - udelay(1);
> - HFC_outb(hc, A_ST_WR_STATE, V_ST_LD_STA | 1);
> - /* G1 */
> - udelay(6); /* wait at least 5,21us */
> - HFC_outb(hc, A_ST_WR_STATE, 1);
> - HFC_outb(hc, A_ST_WR_STATE, 1 |
> - (V_ST_ACT * 3)); /* activate */
> - dch->state = 1;
> - }
> - spin_unlock_irqrestore(&hc->lock, flags);
> - } else
> - ret = l1_event(dch->l1, hh->prim);
> - break;
> - case PH_DEACTIVATE_REQ:
> - test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
> - if (dch->dev.D.protocol != ISDN_P_TE_S0) {
> - struct sk_buff_head free_queue;
> -
> - __skb_queue_head_init(&free_queue);
> - spin_lock_irqsave(&hc->lock, flags);
> - if (debug & DEBUG_HFCMULTI_MSG)
> - printk(KERN_DEBUG
> - "%s: PH_DEACTIVATE port %d (0..%d)\n",
> - __func__, hc->chan[dch->slot].port,
> - hc->ports - 1);
> - /* start deactivation */
> - if (hc->ctype == HFC_TYPE_E1) {
> - if (debug & DEBUG_HFCMULTI_MSG)
> - printk(KERN_DEBUG
> - "%s: PH_DEACTIVATE no BRI\n",
> - __func__);
> - } else {
> - HFC_outb(hc, R_ST_SEL,
> - hc->chan[dch->slot].port);
> - /* undocumented: delay after R_ST_SEL */
> - udelay(1);
> - HFC_outb(hc, A_ST_WR_STATE, V_ST_ACT * 2);
> - /* deactivate */
> - dch->state = 1;
> - }
> - skb_queue_splice_init(&dch->squeue, &free_queue);
> - if (dch->tx_skb) {
> - __skb_queue_tail(&free_queue, dch->tx_skb);
> - dch->tx_skb = NULL;
> - }
> - dch->tx_idx = 0;
> - if (dch->rx_skb) {
> - __skb_queue_tail(&free_queue, dch->rx_skb);
> - dch->rx_skb = NULL;
> - }
> - test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
> - if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
> - timer_delete(&dch->timer);
> -#ifdef FIXME
> - if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags))
> - dchannel_sched_event(&hc->dch, D_CLEARBUSY);
> -#endif
> - ret = 0;
> - spin_unlock_irqrestore(&hc->lock, flags);
> - __skb_queue_purge(&free_queue);
> - } else
> - ret = l1_event(dch->l1, hh->prim);
> - break;
> - }
> - if (!ret)
> - dev_kfree_skb(skb);
> - return ret;
> -}
> -
> -static void
> -deactivate_bchannel(struct bchannel *bch)
> -{
> - struct hfc_multi *hc = bch->hw;
> - u_long flags;
> -
> - spin_lock_irqsave(&hc->lock, flags);
> - mISDN_clear_bchannel(bch);
> - hc->chan[bch->slot].coeff_count = 0;
> - hc->chan[bch->slot].rx_off = 0;
> - hc->chan[bch->slot].conf = -1;
> - mode_hfcmulti(hc, bch->slot, ISDN_P_NONE, -1, 0, -1, 0);
> - spin_unlock_irqrestore(&hc->lock, flags);
> -}
> -
> -static int
> -handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb)
> -{
> - struct bchannel *bch = container_of(ch, struct bchannel, ch);
> - struct hfc_multi *hc = bch->hw;
> - int ret = -EINVAL;
> - struct mISDNhead *hh = mISDN_HEAD_P(skb);
> - unsigned long flags;
> -
> - switch (hh->prim) {
> - case PH_DATA_REQ:
> - if (!skb->len)
> - break;
> - spin_lock_irqsave(&hc->lock, flags);
> - ret = bchannel_senddata(bch, skb);
> - if (ret > 0) { /* direct TX */
> - hfcmulti_tx(hc, bch->slot);
> - ret = 0;
> - /* start fifo */
> - HFC_outb_nodebug(hc, R_FIFO, 0);
> - HFC_wait_nodebug(hc);
> - }
> - spin_unlock_irqrestore(&hc->lock, flags);
> - return ret;
> - case PH_ACTIVATE_REQ:
> - if (debug & DEBUG_HFCMULTI_MSG)
> - printk(KERN_DEBUG "%s: PH_ACTIVATE ch %d (0..32)\n",
> - __func__, bch->slot);
> - spin_lock_irqsave(&hc->lock, flags);
> - /* activate B-channel if not already activated */
> - if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags)) {
> - hc->chan[bch->slot].txpending = 0;
> - ret = mode_hfcmulti(hc, bch->slot,
> - ch->protocol,
> - hc->chan[bch->slot].slot_tx,
> - hc->chan[bch->slot].bank_tx,
> - hc->chan[bch->slot].slot_rx,
> - hc->chan[bch->slot].bank_rx);
> - if (!ret) {
> - if (ch->protocol == ISDN_P_B_RAW && !hc->dtmf
> - && test_bit(HFC_CHIP_DTMF, &hc->chip)) {
> - /* start decoder */
> - hc->dtmf = 1;
> - if (debug & DEBUG_HFCMULTI_DTMF)
> - printk(KERN_DEBUG
> - "%s: start dtmf decoder\n",
> - __func__);
> - HFC_outb(hc, R_DTMF, hc->hw.r_dtmf |
> - V_RST_DTMF);
> - }
> - }
> - } else
> - ret = 0;
> - spin_unlock_irqrestore(&hc->lock, flags);
> - if (!ret)
> - _queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0, NULL,
> - GFP_KERNEL);
> - break;
> - case PH_CONTROL_REQ:
> - spin_lock_irqsave(&hc->lock, flags);
> - switch (hh->id) {
> - case HFC_SPL_LOOP_ON: /* set sample loop */
> - if (debug & DEBUG_HFCMULTI_MSG)
> - printk(KERN_DEBUG
> - "%s: HFC_SPL_LOOP_ON (len = %d)\n",
> - __func__, skb->len);
> - ret = 0;
> - break;
> - case HFC_SPL_LOOP_OFF: /* set silence */
> - if (debug & DEBUG_HFCMULTI_MSG)
> - printk(KERN_DEBUG "%s: HFC_SPL_LOOP_OFF\n",
> - __func__);
> - ret = 0;
> - break;
> - default:
> - printk(KERN_ERR
> - "%s: unknown PH_CONTROL_REQ info %x\n",
> - __func__, hh->id);
> - ret = -EINVAL;
> - }
> - spin_unlock_irqrestore(&hc->lock, flags);
> - break;
> - case PH_DEACTIVATE_REQ:
> - deactivate_bchannel(bch); /* locked there */
> - _queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0, NULL,
> - GFP_KERNEL);
> - ret = 0;
> - break;
> - }
> - if (!ret)
> - dev_kfree_skb(skb);
> - return ret;
> -}
> -
> -/*
> - * bchannel control function
> - */
> -static int
> -channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
> -{
> - int ret = 0;
> - struct dsp_features *features =
> - (struct dsp_features *)(*((u_long *)&cq->p1));
> - struct hfc_multi *hc = bch->hw;
> - int slot_tx;
> - int bank_tx;
> - int slot_rx;
> - int bank_rx;
> - int num;
> -
> - switch (cq->op) {
> - case MISDN_CTRL_GETOP:
> - ret = mISDN_ctrl_bchannel(bch, cq);
> - cq->op |= MISDN_CTRL_HFC_OP | MISDN_CTRL_HW_FEATURES_OP;
> - break;
> - case MISDN_CTRL_RX_OFF: /* turn off / on rx stream */
> - ret = mISDN_ctrl_bchannel(bch, cq);
> - hc->chan[bch->slot].rx_off = !!cq->p1;
> - if (!hc->chan[bch->slot].rx_off) {
> - /* reset fifo on rx on */
> - HFC_outb_nodebug(hc, R_FIFO, (bch->slot << 1) | 1);
> - HFC_wait_nodebug(hc);
> - HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_RES_F);
> - HFC_wait_nodebug(hc);
> - }
> - if (debug & DEBUG_HFCMULTI_MSG)
> - printk(KERN_DEBUG "%s: RX_OFF request (nr=%d off=%d)\n",
> - __func__, bch->nr, hc->chan[bch->slot].rx_off);
> - break;
> - case MISDN_CTRL_FILL_EMPTY:
> - ret = mISDN_ctrl_bchannel(bch, cq);
> - hc->silence = bch->fill[0];
> - memset(hc->silence_data, hc->silence, sizeof(hc->silence_data));
> - break;
> - case MISDN_CTRL_HW_FEATURES: /* fill features structure */
> - if (debug & DEBUG_HFCMULTI_MSG)
> - printk(KERN_DEBUG "%s: HW_FEATURE request\n",
> - __func__);
> - /* create confirm */
> - features->hfc_id = hc->id;
> - if (test_bit(HFC_CHIP_DTMF, &hc->chip))
> - features->hfc_dtmf = 1;
> - if (test_bit(HFC_CHIP_CONF, &hc->chip))
> - features->hfc_conf = 1;
> - features->hfc_loops = 0;
> - if (test_bit(HFC_CHIP_B410P, &hc->chip)) {
> - features->hfc_echocanhw = 1;
> - } else {
> - features->pcm_id = hc->pcm;
> - features->pcm_slots = hc->slots;
> - features->pcm_banks = 2;
> - }
> - break;
> - case MISDN_CTRL_HFC_PCM_CONN: /* connect to pcm timeslot (0..N) */
> - slot_tx = cq->p1 & 0xff;
> - bank_tx = cq->p1 >> 8;
> - slot_rx = cq->p2 & 0xff;
> - bank_rx = cq->p2 >> 8;
> - if (debug & DEBUG_HFCMULTI_MSG)
> - printk(KERN_DEBUG
> - "%s: HFC_PCM_CONN slot %d bank %d (TX) "
> - "slot %d bank %d (RX)\n",
> - __func__, slot_tx, bank_tx,
> - slot_rx, bank_rx);
> - if (slot_tx < hc->slots && bank_tx <= 2 &&
> - slot_rx < hc->slots && bank_rx <= 2)
> - hfcmulti_pcm(hc, bch->slot,
> - slot_tx, bank_tx, slot_rx, bank_rx);
> - else {
> - printk(KERN_WARNING
> - "%s: HFC_PCM_CONN slot %d bank %d (TX) "
> - "slot %d bank %d (RX) out of range\n",
> - __func__, slot_tx, bank_tx,
> - slot_rx, bank_rx);
> - ret = -EINVAL;
> - }
> - break;
> - case MISDN_CTRL_HFC_PCM_DISC: /* release interface from pcm timeslot */
> - if (debug & DEBUG_HFCMULTI_MSG)
> - printk(KERN_DEBUG "%s: HFC_PCM_DISC\n",
> - __func__);
> - hfcmulti_pcm(hc, bch->slot, -1, 0, -1, 0);
> - break;
> - case MISDN_CTRL_HFC_CONF_JOIN: /* join conference (0..7) */
> - num = cq->p1 & 0xff;
> - if (debug & DEBUG_HFCMULTI_MSG)
> - printk(KERN_DEBUG "%s: HFC_CONF_JOIN conf %d\n",
> - __func__, num);
> - if (num <= 7)
> - hfcmulti_conf(hc, bch->slot, num);
> - else {
> - printk(KERN_WARNING
> - "%s: HW_CONF_JOIN conf %d out of range\n",
> - __func__, num);
> - ret = -EINVAL;
> - }
> - break;
> - case MISDN_CTRL_HFC_CONF_SPLIT: /* split conference */
> - if (debug & DEBUG_HFCMULTI_MSG)
> - printk(KERN_DEBUG "%s: HFC_CONF_SPLIT\n", __func__);
> - hfcmulti_conf(hc, bch->slot, -1);
> - break;
> - case MISDN_CTRL_HFC_ECHOCAN_ON:
> - if (debug & DEBUG_HFCMULTI_MSG)
> - printk(KERN_DEBUG "%s: HFC_ECHOCAN_ON\n", __func__);
> - if (test_bit(HFC_CHIP_B410P, &hc->chip))
> - vpm_echocan_on(hc, bch->slot, cq->p1);
> - else
> - ret = -EINVAL;
> - break;
> -
> - case MISDN_CTRL_HFC_ECHOCAN_OFF:
> - if (debug & DEBUG_HFCMULTI_MSG)
> - printk(KERN_DEBUG "%s: HFC_ECHOCAN_OFF\n",
> - __func__);
> - if (test_bit(HFC_CHIP_B410P, &hc->chip))
> - vpm_echocan_off(hc, bch->slot);
> - else
> - ret = -EINVAL;
> - break;
> - default:
> - ret = mISDN_ctrl_bchannel(bch, cq);
> - break;
> - }
> - return ret;
> -}
> -
> -static int
> -hfcm_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
> -{
> - struct bchannel *bch = container_of(ch, struct bchannel, ch);
> - struct hfc_multi *hc = bch->hw;
> - int err = -EINVAL;
> - u_long flags;
> -
> - if (bch->debug & DEBUG_HW)
> - printk(KERN_DEBUG "%s: cmd:%x %p\n",
> - __func__, cmd, arg);
> - switch (cmd) {
> - case CLOSE_CHANNEL:
> - test_and_clear_bit(FLG_OPEN, &bch->Flags);
> - deactivate_bchannel(bch); /* locked there */
> - ch->protocol = ISDN_P_NONE;
> - ch->peer = NULL;
> - module_put(THIS_MODULE);
> - err = 0;
> - break;
> - case CONTROL_CHANNEL:
> - spin_lock_irqsave(&hc->lock, flags);
> - err = channel_bctrl(bch, arg);
> - spin_unlock_irqrestore(&hc->lock, flags);
> - break;
> - default:
> - printk(KERN_WARNING "%s: unknown prim(%x)\n",
> - __func__, cmd);
> - }
> - return err;
> -}
> -
> -/*
> - * handle D-channel events
> - *
> - * handle state change event
> - */
> -static void
> -ph_state_change(struct dchannel *dch)
> -{
> - struct hfc_multi *hc;
> - int ch, i;
> -
> - if (!dch) {
> - printk(KERN_WARNING "%s: ERROR given dch is NULL\n", __func__);
> - return;
> - }
> - hc = dch->hw;
> - ch = dch->slot;
> -
> - if (hc->ctype == HFC_TYPE_E1) {
> - if (dch->dev.D.protocol == ISDN_P_TE_E1) {
> - if (debug & DEBUG_HFCMULTI_STATE)
> - printk(KERN_DEBUG
> - "%s: E1 TE (id=%d) newstate %x\n",
> - __func__, hc->id, dch->state);
> - } else {
> - if (debug & DEBUG_HFCMULTI_STATE)
> - printk(KERN_DEBUG
> - "%s: E1 NT (id=%d) newstate %x\n",
> - __func__, hc->id, dch->state);
> - }
> - switch (dch->state) {
> - case (1):
> - if (hc->e1_state != 1) {
> - for (i = 1; i <= 31; i++) {
> - /* reset fifos on e1 activation */
> - HFC_outb_nodebug(hc, R_FIFO,
> - (i << 1) | 1);
> - HFC_wait_nodebug(hc);
> - HFC_outb_nodebug(hc, R_INC_RES_FIFO,
> - V_RES_F);
> - HFC_wait_nodebug(hc);
> - }
> - }
> - test_and_set_bit(FLG_ACTIVE, &dch->Flags);
> - _queue_data(&dch->dev.D, PH_ACTIVATE_IND,
> - MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
> - break;
> -
> - default:
> - if (hc->e1_state != 1)
> - return;
> - test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
> - _queue_data(&dch->dev.D, PH_DEACTIVATE_IND,
> - MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
> - }
> - hc->e1_state = dch->state;
> - } else {
> - if (dch->dev.D.protocol == ISDN_P_TE_S0) {
> - if (debug & DEBUG_HFCMULTI_STATE)
> - printk(KERN_DEBUG
> - "%s: S/T TE newstate %x\n",
> - __func__, dch->state);
> - switch (dch->state) {
> - case (0):
> - l1_event(dch->l1, HW_RESET_IND);
> - break;
> - case (3):
> - l1_event(dch->l1, HW_DEACT_IND);
> - break;
> - case (5):
> - case (8):
> - l1_event(dch->l1, ANYSIGNAL);
> - break;
> - case (6):
> - l1_event(dch->l1, INFO2);
> - break;
> - case (7):
> - l1_event(dch->l1, INFO4_P8);
> - break;
> - }
> - } else {
> - if (debug & DEBUG_HFCMULTI_STATE)
> - printk(KERN_DEBUG "%s: S/T NT newstate %x\n",
> - __func__, dch->state);
> - switch (dch->state) {
> - case (2):
> - if (hc->chan[ch].nt_timer == 0) {
> - hc->chan[ch].nt_timer = -1;
> - HFC_outb(hc, R_ST_SEL,
> - hc->chan[ch].port);
> - /* undocumented: delay after R_ST_SEL */
> - udelay(1);
> - HFC_outb(hc, A_ST_WR_STATE, 4 |
> - V_ST_LD_STA); /* G4 */
> - udelay(6); /* wait at least 5,21us */
> - HFC_outb(hc, A_ST_WR_STATE, 4);
> - dch->state = 4;
> - } else {
> - /* one extra count for the next event */
> - hc->chan[ch].nt_timer =
> - nt_t1_count[poll_timer] + 1;
> - HFC_outb(hc, R_ST_SEL,
> - hc->chan[ch].port);
> - /* undocumented: delay after R_ST_SEL */
> - udelay(1);
> - /* allow G2 -> G3 transition */
> - HFC_outb(hc, A_ST_WR_STATE, 2 |
> - V_SET_G2_G3);
> - }
> - break;
> - case (1):
> - hc->chan[ch].nt_timer = -1;
> - test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
> - _queue_data(&dch->dev.D, PH_DEACTIVATE_IND,
> - MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
> - break;
> - case (4):
> - hc->chan[ch].nt_timer = -1;
> - break;
> - case (3):
> - hc->chan[ch].nt_timer = -1;
> - test_and_set_bit(FLG_ACTIVE, &dch->Flags);
> - _queue_data(&dch->dev.D, PH_ACTIVATE_IND,
> - MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
> - break;
> - }
> - }
> - }
> -}
> -
> -/*
> - * called for card mode init message
> - */
> -
> -static void
> -hfcmulti_initmode(struct dchannel *dch)
> -{
> - struct hfc_multi *hc = dch->hw;
> - u_char a_st_wr_state, r_e1_wr_sta;
> - int i, pt;
> -
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: entered\n", __func__);
> -
> - i = dch->slot;
> - pt = hc->chan[i].port;
> - if (hc->ctype == HFC_TYPE_E1) {
> - /* E1 */
> - hc->chan[hc->dnum[pt]].slot_tx = -1;
> - hc->chan[hc->dnum[pt]].slot_rx = -1;
> - hc->chan[hc->dnum[pt]].conf = -1;
> - if (hc->dnum[pt]) {
> - mode_hfcmulti(hc, dch->slot, dch->dev.D.protocol,
> - -1, 0, -1, 0);
> - timer_setup(&dch->timer, hfcmulti_dbusy_timer, 0);
> - }
> - for (i = 1; i <= 31; i++) {
> - if (!((1 << i) & hc->bmask[pt])) /* skip unused chan */
> - continue;
> - hc->chan[i].slot_tx = -1;
> - hc->chan[i].slot_rx = -1;
> - hc->chan[i].conf = -1;
> - mode_hfcmulti(hc, i, ISDN_P_NONE, -1, 0, -1, 0);
> - }
> - }
> - if (hc->ctype == HFC_TYPE_E1 && pt == 0) {
> - /* E1, port 0 */
> - dch = hc->chan[hc->dnum[0]].dch;
> - if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dnum[0]].cfg)) {
> - HFC_outb(hc, R_LOS0, 255); /* 2 ms */
> - HFC_outb(hc, R_LOS1, 255); /* 512 ms */
> - }
> - if (test_bit(HFC_CFG_OPTICAL, &hc->chan[hc->dnum[0]].cfg)) {
> - HFC_outb(hc, R_RX0, 0);
> - hc->hw.r_tx0 = 0 | V_OUT_EN;
> - } else {
> - HFC_outb(hc, R_RX0, 1);
> - hc->hw.r_tx0 = 1 | V_OUT_EN;
> - }
> - hc->hw.r_tx1 = V_ATX | V_NTRI;
> - HFC_outb(hc, R_TX0, hc->hw.r_tx0);
> - HFC_outb(hc, R_TX1, hc->hw.r_tx1);
> - HFC_outb(hc, R_TX_FR0, 0x00);
> - HFC_outb(hc, R_TX_FR1, 0xf8);
> -
> - if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dnum[0]].cfg))
> - HFC_outb(hc, R_TX_FR2, V_TX_MF | V_TX_E | V_NEG_E);
> -
> - HFC_outb(hc, R_RX_FR0, V_AUTO_RESYNC | V_AUTO_RECO | 0);
> -
> - if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dnum[0]].cfg))
> - HFC_outb(hc, R_RX_FR1, V_RX_MF | V_RX_MF_SYNC);
> -
> - if (dch->dev.D.protocol == ISDN_P_NT_E1) {
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: E1 port is NT-mode\n",
> - __func__);
> - r_e1_wr_sta = 0; /* G0 */
> - hc->e1_getclock = 0;
> - } else {
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: E1 port is TE-mode\n",
> - __func__);
> - r_e1_wr_sta = 0; /* F0 */
> - hc->e1_getclock = 1;
> - }
> - if (test_bit(HFC_CHIP_RX_SYNC, &hc->chip))
> - HFC_outb(hc, R_SYNC_OUT, V_SYNC_E1_RX);
> - else
> - HFC_outb(hc, R_SYNC_OUT, 0);
> - if (test_bit(HFC_CHIP_E1CLOCK_GET, &hc->chip))
> - hc->e1_getclock = 1;
> - if (test_bit(HFC_CHIP_E1CLOCK_PUT, &hc->chip))
> - hc->e1_getclock = 0;
> - if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip)) {
> - /* SLAVE (clock master) */
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG
> - "%s: E1 port is clock master "
> - "(clock from PCM)\n", __func__);
> - HFC_outb(hc, R_SYNC_CTRL, V_EXT_CLK_SYNC | V_PCM_SYNC);
> - } else {
> - if (hc->e1_getclock) {
> - /* MASTER (clock slave) */
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG
> - "%s: E1 port is clock slave "
> - "(clock to PCM)\n", __func__);
> - HFC_outb(hc, R_SYNC_CTRL, V_SYNC_OFFS);
> - } else {
> - /* MASTER (clock master) */
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: E1 port is "
> - "clock master "
> - "(clock from QUARTZ)\n",
> - __func__);
> - HFC_outb(hc, R_SYNC_CTRL, V_EXT_CLK_SYNC |
> - V_PCM_SYNC | V_JATT_OFF);
> - HFC_outb(hc, R_SYNC_OUT, 0);
> - }
> - }
> - HFC_outb(hc, R_JATT_ATT, 0x9c); /* undoc register */
> - HFC_outb(hc, R_PWM_MD, V_PWM0_MD);
> - HFC_outb(hc, R_PWM0, 0x50);
> - HFC_outb(hc, R_PWM1, 0xff);
> - /* state machine setup */
> - HFC_outb(hc, R_E1_WR_STA, r_e1_wr_sta | V_E1_LD_STA);
> - udelay(6); /* wait at least 5,21us */
> - HFC_outb(hc, R_E1_WR_STA, r_e1_wr_sta);
> - if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
> - hc->syncronized = 0;
> - plxsd_checksync(hc, 0);
> - }
> - }
> - if (hc->ctype != HFC_TYPE_E1) {
> - /* ST */
> - hc->chan[i].slot_tx = -1;
> - hc->chan[i].slot_rx = -1;
> - hc->chan[i].conf = -1;
> - mode_hfcmulti(hc, i, dch->dev.D.protocol, -1, 0, -1, 0);
> - timer_setup(&dch->timer, hfcmulti_dbusy_timer, 0);
> - hc->chan[i - 2].slot_tx = -1;
> - hc->chan[i - 2].slot_rx = -1;
> - hc->chan[i - 2].conf = -1;
> - mode_hfcmulti(hc, i - 2, ISDN_P_NONE, -1, 0, -1, 0);
> - hc->chan[i - 1].slot_tx = -1;
> - hc->chan[i - 1].slot_rx = -1;
> - hc->chan[i - 1].conf = -1;
> - mode_hfcmulti(hc, i - 1, ISDN_P_NONE, -1, 0, -1, 0);
> - /* select interface */
> - HFC_outb(hc, R_ST_SEL, pt);
> - /* undocumented: delay after R_ST_SEL */
> - udelay(1);
> - if (dch->dev.D.protocol == ISDN_P_NT_S0) {
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG
> - "%s: ST port %d is NT-mode\n",
> - __func__, pt);
> - /* clock delay */
> - HFC_outb(hc, A_ST_CLK_DLY, clockdelay_nt);
> - a_st_wr_state = 1; /* G1 */
> - hc->hw.a_st_ctrl0[pt] = V_ST_MD;
> - } else {
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG
> - "%s: ST port %d is TE-mode\n",
> - __func__, pt);
> - /* clock delay */
> - HFC_outb(hc, A_ST_CLK_DLY, clockdelay_te);
> - a_st_wr_state = 2; /* F2 */
> - hc->hw.a_st_ctrl0[pt] = 0;
> - }
> - if (!test_bit(HFC_CFG_NONCAP_TX, &hc->chan[i].cfg))
> - hc->hw.a_st_ctrl0[pt] |= V_TX_LI;
> - if (hc->ctype == HFC_TYPE_XHFC) {
> - hc->hw.a_st_ctrl0[pt] |= 0x40 /* V_ST_PU_CTRL */;
> - HFC_outb(hc, 0x35 /* A_ST_CTRL3 */,
> - 0x7c << 1 /* V_ST_PULSE */);
> - }
> - /* line setup */
> - HFC_outb(hc, A_ST_CTRL0, hc->hw.a_st_ctrl0[pt]);
> - /* disable E-channel */
> - if ((dch->dev.D.protocol == ISDN_P_NT_S0) ||
> - test_bit(HFC_CFG_DIS_ECHANNEL, &hc->chan[i].cfg))
> - HFC_outb(hc, A_ST_CTRL1, V_E_IGNO);
> - else
> - HFC_outb(hc, A_ST_CTRL1, 0);
> - /* enable B-channel receive */
> - HFC_outb(hc, A_ST_CTRL2, V_B1_RX_EN | V_B2_RX_EN);
> - /* state machine setup */
> - HFC_outb(hc, A_ST_WR_STATE, a_st_wr_state | V_ST_LD_STA);
> - udelay(6); /* wait at least 5,21us */
> - HFC_outb(hc, A_ST_WR_STATE, a_st_wr_state);
> - hc->hw.r_sci_msk |= 1 << pt;
> - /* state machine interrupts */
> - HFC_outb(hc, R_SCI_MSK, hc->hw.r_sci_msk);
> - /* unset sync on port */
> - if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
> - hc->syncronized &=
> - ~(1 << hc->chan[dch->slot].port);
> - plxsd_checksync(hc, 0);
> - }
> - }
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk("%s: done\n", __func__);
> -}
> -
> -
> -static int
> -open_dchannel(struct hfc_multi *hc, struct dchannel *dch,
> - struct channel_req *rq)
> -{
> - int err = 0;
> - u_long flags;
> -
> - if (debug & DEBUG_HW_OPEN)
> - printk(KERN_DEBUG "%s: dev(%d) open from %p\n", __func__,
> - dch->dev.id, __builtin_return_address(0));
> - if (rq->protocol == ISDN_P_NONE)
> - return -EINVAL;
> - if ((dch->dev.D.protocol != ISDN_P_NONE) &&
> - (dch->dev.D.protocol != rq->protocol)) {
> - if (debug & DEBUG_HFCMULTI_MODE)
> - printk(KERN_DEBUG "%s: change protocol %x to %x\n",
> - __func__, dch->dev.D.protocol, rq->protocol);
> - }
> - if ((dch->dev.D.protocol == ISDN_P_TE_S0) &&
> - (rq->protocol != ISDN_P_TE_S0))
> - l1_event(dch->l1, CLOSE_CHANNEL);
> - if (dch->dev.D.protocol != rq->protocol) {
> - if (rq->protocol == ISDN_P_TE_S0) {
> - err = create_l1(dch, hfcm_l1callback);
> - if (err)
> - return err;
> - }
> - dch->dev.D.protocol = rq->protocol;
> - spin_lock_irqsave(&hc->lock, flags);
> - hfcmulti_initmode(dch);
> - spin_unlock_irqrestore(&hc->lock, flags);
> - }
> - if (test_bit(FLG_ACTIVE, &dch->Flags))
> - _queue_data(&dch->dev.D, PH_ACTIVATE_IND, MISDN_ID_ANY,
> - 0, NULL, GFP_KERNEL);
> - rq->ch = &dch->dev.D;
> - if (!try_module_get(THIS_MODULE))
> - printk(KERN_WARNING "%s:cannot get module\n", __func__);
> - return 0;
> -}
> -
> -static int
> -open_bchannel(struct hfc_multi *hc, struct dchannel *dch,
> - struct channel_req *rq)
> -{
> - struct bchannel *bch;
> - int ch;
> -
> - if (!test_channelmap(rq->adr.channel, dch->dev.channelmap))
> - return -EINVAL;
> - if (rq->protocol == ISDN_P_NONE)
> - return -EINVAL;
> - if (hc->ctype == HFC_TYPE_E1)
> - ch = rq->adr.channel;
> - else
> - ch = (rq->adr.channel - 1) + (dch->slot - 2);
> - bch = hc->chan[ch].bch;
> - if (!bch) {
> - printk(KERN_ERR "%s:internal error ch %d has no bch\n",
> - __func__, ch);
> - return -EINVAL;
> - }
> - if (test_and_set_bit(FLG_OPEN, &bch->Flags))
> - return -EBUSY; /* b-channel can be only open once */
> - bch->ch.protocol = rq->protocol;
> - hc->chan[ch].rx_off = 0;
> - rq->ch = &bch->ch;
> - if (!try_module_get(THIS_MODULE))
> - printk(KERN_WARNING "%s:cannot get module\n", __func__);
> - return 0;
> -}
> -
> -/*
> - * device control function
> - */
> -static int
> -channel_dctrl(struct dchannel *dch, struct mISDN_ctrl_req *cq)
> -{
> - struct hfc_multi *hc = dch->hw;
> - int ret = 0;
> - int wd_mode, wd_cnt;
> -
> - switch (cq->op) {
> - case MISDN_CTRL_GETOP:
> - cq->op = MISDN_CTRL_HFC_OP | MISDN_CTRL_L1_TIMER3;
> - break;
> - case MISDN_CTRL_HFC_WD_INIT: /* init the watchdog */
> - wd_cnt = cq->p1 & 0xf;
> - wd_mode = !!(cq->p1 >> 4);
> - if (debug & DEBUG_HFCMULTI_MSG)
> - printk(KERN_DEBUG "%s: MISDN_CTRL_HFC_WD_INIT mode %s"
> - ", counter 0x%x\n", __func__,
> - wd_mode ? "AUTO" : "MANUAL", wd_cnt);
> - /* set the watchdog timer */
> - HFC_outb(hc, R_TI_WD, poll_timer | (wd_cnt << 4));
> - hc->hw.r_bert_wd_md = (wd_mode ? V_AUTO_WD_RES : 0);
> - if (hc->ctype == HFC_TYPE_XHFC)
> - hc->hw.r_bert_wd_md |= 0x40 /* V_WD_EN */;
> - /* init the watchdog register and reset the counter */
> - HFC_outb(hc, R_BERT_WD_MD, hc->hw.r_bert_wd_md | V_WD_RES);
> - if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
> - /* enable the watchdog output for Speech-Design */
> - HFC_outb(hc, R_GPIO_SEL, V_GPIO_SEL7);
> - HFC_outb(hc, R_GPIO_EN1, V_GPIO_EN15);
> - HFC_outb(hc, R_GPIO_OUT1, 0);
> - HFC_outb(hc, R_GPIO_OUT1, V_GPIO_OUT15);
> - }
> - break;
> - case MISDN_CTRL_HFC_WD_RESET: /* reset the watchdog counter */
> - if (debug & DEBUG_HFCMULTI_MSG)
> - printk(KERN_DEBUG "%s: MISDN_CTRL_HFC_WD_RESET\n",
> - __func__);
> - HFC_outb(hc, R_BERT_WD_MD, hc->hw.r_bert_wd_md | V_WD_RES);
> - break;
> - case MISDN_CTRL_L1_TIMER3:
> - ret = l1_event(dch->l1, HW_TIMER3_VALUE | (cq->p1 & 0xff));
> - break;
> - default:
> - printk(KERN_WARNING "%s: unknown Op %x\n",
> - __func__, cq->op);
> - ret = -EINVAL;
> - break;
> - }
> - return ret;
> -}
> -
> -static int
> -hfcm_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
> -{
> - struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
> - struct dchannel *dch = container_of(dev, struct dchannel, dev);
> - struct hfc_multi *hc = dch->hw;
> - struct channel_req *rq;
> - int err = 0;
> - u_long flags;
> -
> - if (dch->debug & DEBUG_HW)
> - printk(KERN_DEBUG "%s: cmd:%x %p\n",
> - __func__, cmd, arg);
> - switch (cmd) {
> - case OPEN_CHANNEL:
> - rq = arg;
> - switch (rq->protocol) {
> - case ISDN_P_TE_S0:
> - case ISDN_P_NT_S0:
> - if (hc->ctype == HFC_TYPE_E1) {
> - err = -EINVAL;
> - break;
> - }
> - err = open_dchannel(hc, dch, rq); /* locked there */
> - break;
> - case ISDN_P_TE_E1:
> - case ISDN_P_NT_E1:
> - if (hc->ctype != HFC_TYPE_E1) {
> - err = -EINVAL;
> - break;
> - }
> - err = open_dchannel(hc, dch, rq); /* locked there */
> - break;
> - default:
> - spin_lock_irqsave(&hc->lock, flags);
> - err = open_bchannel(hc, dch, rq);
> - spin_unlock_irqrestore(&hc->lock, flags);
> - }
> - break;
> - case CLOSE_CHANNEL:
> - if (debug & DEBUG_HW_OPEN)
> - printk(KERN_DEBUG "%s: dev(%d) close from %p\n",
> - __func__, dch->dev.id,
> - __builtin_return_address(0));
> - module_put(THIS_MODULE);
> - break;
> - case CONTROL_CHANNEL:
> - spin_lock_irqsave(&hc->lock, flags);
> - err = channel_dctrl(dch, arg);
> - spin_unlock_irqrestore(&hc->lock, flags);
> - break;
> - default:
> - if (dch->debug & DEBUG_HW)
> - printk(KERN_DEBUG "%s: unknown command %x\n",
> - __func__, cmd);
> - err = -EINVAL;
> - }
> - return err;
> -}
> -
> -static int
> -clockctl(void *priv, int enable)
> -{
> - struct hfc_multi *hc = priv;
> -
> - hc->iclock_on = enable;
> - return 0;
> -}
> -
> -/*
> - * initialize the card
> - */
> -
> -/*
> - * start timer irq, wait some time and check if we have interrupts.
> - * if not, reset chip and try again.
> - */
> -static int
> -init_card(struct hfc_multi *hc)
> -{
> - int err = -EIO;
> - u_long flags;
> - void __iomem *plx_acc;
> - u_long plx_flags;
> -
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: entered\n", __func__);
> -
> - spin_lock_irqsave(&hc->lock, flags);
> - /* set interrupts but leave global interrupt disabled */
> - hc->hw.r_irq_ctrl = V_FIFO_IRQ;
> - disable_hwirq(hc);
> - spin_unlock_irqrestore(&hc->lock, flags);
> -
> - if (request_irq(hc->irq, hfcmulti_interrupt, IRQF_SHARED,
> - "HFC-multi", hc)) {
> - printk(KERN_WARNING "mISDN: Could not get interrupt %d.\n",
> - hc->irq);
> - hc->irq = 0;
> - return -EIO;
> - }
> -
> - if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
> - spin_lock_irqsave(&plx_lock, plx_flags);
> - plx_acc = hc->plx_membase + PLX_INTCSR;
> - writew((PLX_INTCSR_PCIINT_ENABLE | PLX_INTCSR_LINTI1_ENABLE),
> - plx_acc); /* enable PCI & LINT1 irq */
> - spin_unlock_irqrestore(&plx_lock, plx_flags);
> - }
> -
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: IRQ %d count %d\n",
> - __func__, hc->irq, hc->irqcnt);
> - err = init_chip(hc);
> - if (err)
> - goto error;
> - /*
> - * Finally enable IRQ output
> - * this is only allowed, if an IRQ routine is already
> - * established for this HFC, so don't do that earlier
> - */
> - spin_lock_irqsave(&hc->lock, flags);
> - enable_hwirq(hc);
> - spin_unlock_irqrestore(&hc->lock, flags);
> - /* printk(KERN_DEBUG "no master irq set!!!\n"); */
> - set_current_state(TASK_UNINTERRUPTIBLE);
> - schedule_timeout((100 * HZ) / 1000); /* Timeout 100ms */
> - /* turn IRQ off until chip is completely initialized */
> - spin_lock_irqsave(&hc->lock, flags);
> - disable_hwirq(hc);
> - spin_unlock_irqrestore(&hc->lock, flags);
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: IRQ %d count %d\n",
> - __func__, hc->irq, hc->irqcnt);
> - if (hc->irqcnt) {
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: done\n", __func__);
> -
> - return 0;
> - }
> - if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip)) {
> - printk(KERN_INFO "ignoring missing interrupts\n");
> - return 0;
> - }
> -
> - printk(KERN_ERR "HFC PCI: IRQ(%d) getting no interrupts during init.\n",
> - hc->irq);
> -
> - err = -EIO;
> -
> -error:
> - if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
> - spin_lock_irqsave(&plx_lock, plx_flags);
> - plx_acc = hc->plx_membase + PLX_INTCSR;
> - writew(0x00, plx_acc); /*disable IRQs*/
> - spin_unlock_irqrestore(&plx_lock, plx_flags);
> - }
> -
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: free irq %d\n", __func__, hc->irq);
> - if (hc->irq) {
> - free_irq(hc->irq, hc);
> - hc->irq = 0;
> - }
> -
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: done (err=%d)\n", __func__, err);
> - return err;
> -}
> -
> -/*
> - * find pci device and set it up
> - */
> -
> -static int
> -setup_pci(struct hfc_multi *hc, struct pci_dev *pdev,
> - const struct pci_device_id *ent)
> -{
> - struct hm_map *m = (struct hm_map *)ent->driver_data;
> -
> - printk(KERN_INFO
> - "HFC-multi: card manufacturer: '%s' card name: '%s' clock: %s\n",
> - m->vendor_name, m->card_name, m->clock2 ? "double" : "normal");
> -
> - hc->pci_dev = pdev;
> - if (m->clock2)
> - test_and_set_bit(HFC_CHIP_CLOCK2, &hc->chip);
> -
> - if (ent->vendor == PCI_VENDOR_ID_DIGIUM &&
> - ent->device == PCI_DEVICE_ID_DIGIUM_HFC4S) {
> - test_and_set_bit(HFC_CHIP_B410P, &hc->chip);
> - test_and_set_bit(HFC_CHIP_PCM_MASTER, &hc->chip);
> - test_and_clear_bit(HFC_CHIP_PCM_SLAVE, &hc->chip);
> - hc->slots = 32;
> - }
> -
> - if (hc->pci_dev->irq <= 0) {
> - printk(KERN_WARNING "HFC-multi: No IRQ for PCI card found.\n");
> - return -EIO;
> - }
> - if (pci_enable_device(hc->pci_dev)) {
> - printk(KERN_WARNING "HFC-multi: Error enabling PCI card.\n");
> - return -EIO;
> - }
> - hc->leds = m->leds;
> - hc->ledstate = 0xAFFEAFFE;
> - hc->opticalsupport = m->opticalsupport;
> -
> - hc->pci_iobase = 0;
> - hc->pci_membase = NULL;
> - hc->plx_membase = NULL;
> -
> - /* set memory access methods */
> - if (m->io_mode) /* use mode from card config */
> - hc->io_mode = m->io_mode;
> - switch (hc->io_mode) {
> - case HFC_IO_MODE_PLXSD:
> - test_and_set_bit(HFC_CHIP_PLXSD, &hc->chip);
> - hc->slots = 128; /* required */
> - hc->HFC_outb = HFC_outb_pcimem;
> - hc->HFC_inb = HFC_inb_pcimem;
> - hc->HFC_inw = HFC_inw_pcimem;
> - hc->HFC_wait = HFC_wait_pcimem;
> - hc->read_fifo = read_fifo_pcimem;
> - hc->write_fifo = write_fifo_pcimem;
> - hc->plx_origmembase = hc->pci_dev->resource[0].start;
> - /* MEMBASE 1 is PLX PCI Bridge */
> -
> - if (!hc->plx_origmembase) {
> - printk(KERN_WARNING
> - "HFC-multi: No IO-Memory for PCI PLX bridge found\n");
> - pci_disable_device(hc->pci_dev);
> - return -EIO;
> - }
> -
> - hc->plx_membase = ioremap(hc->plx_origmembase, 0x80);
> - if (!hc->plx_membase) {
> - printk(KERN_WARNING
> - "HFC-multi: failed to remap plx address space. "
> - "(internal error)\n");
> - pci_disable_device(hc->pci_dev);
> - return -EIO;
> - }
> - printk(KERN_INFO
> - "HFC-multi: plx_membase:%#lx plx_origmembase:%#lx\n",
> - (u_long)hc->plx_membase, hc->plx_origmembase);
> -
> - hc->pci_origmembase = hc->pci_dev->resource[2].start;
> - /* MEMBASE 1 is PLX PCI Bridge */
> - if (!hc->pci_origmembase) {
> - printk(KERN_WARNING
> - "HFC-multi: No IO-Memory for PCI card found\n");
> - pci_disable_device(hc->pci_dev);
> - return -EIO;
> - }
> -
> - hc->pci_membase = ioremap(hc->pci_origmembase, 0x400);
> - if (!hc->pci_membase) {
> - printk(KERN_WARNING "HFC-multi: failed to remap io "
> - "address space. (internal error)\n");
> - pci_disable_device(hc->pci_dev);
> - return -EIO;
> - }
> -
> - printk(KERN_INFO
> - "card %d: defined at MEMBASE %#lx (%#lx) IRQ %d HZ %d "
> - "leds-type %d\n",
> - hc->id, (u_long)hc->pci_membase, hc->pci_origmembase,
> - hc->pci_dev->irq, HZ, hc->leds);
> - pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_MEMIO);
> - break;
> - case HFC_IO_MODE_PCIMEM:
> - hc->HFC_outb = HFC_outb_pcimem;
> - hc->HFC_inb = HFC_inb_pcimem;
> - hc->HFC_inw = HFC_inw_pcimem;
> - hc->HFC_wait = HFC_wait_pcimem;
> - hc->read_fifo = read_fifo_pcimem;
> - hc->write_fifo = write_fifo_pcimem;
> - hc->pci_origmembase = hc->pci_dev->resource[1].start;
> - if (!hc->pci_origmembase) {
> - printk(KERN_WARNING
> - "HFC-multi: No IO-Memory for PCI card found\n");
> - pci_disable_device(hc->pci_dev);
> - return -EIO;
> - }
> -
> - hc->pci_membase = ioremap(hc->pci_origmembase, 256);
> - if (!hc->pci_membase) {
> - printk(KERN_WARNING
> - "HFC-multi: failed to remap io address space. "
> - "(internal error)\n");
> - pci_disable_device(hc->pci_dev);
> - return -EIO;
> - }
> - printk(KERN_INFO "card %d: defined at MEMBASE %#lx (%#lx) IRQ "
> - "%d HZ %d leds-type %d\n", hc->id, (u_long)hc->pci_membase,
> - hc->pci_origmembase, hc->pci_dev->irq, HZ, hc->leds);
> - pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_MEMIO);
> - break;
> - case HFC_IO_MODE_REGIO:
> - hc->HFC_outb = HFC_outb_regio;
> - hc->HFC_inb = HFC_inb_regio;
> - hc->HFC_inw = HFC_inw_regio;
> - hc->HFC_wait = HFC_wait_regio;
> - hc->read_fifo = read_fifo_regio;
> - hc->write_fifo = write_fifo_regio;
> - hc->pci_iobase = (u_int) hc->pci_dev->resource[0].start;
> - if (!hc->pci_iobase) {
> - printk(KERN_WARNING
> - "HFC-multi: No IO for PCI card found\n");
> - pci_disable_device(hc->pci_dev);
> - return -EIO;
> - }
> -
> - if (!request_region(hc->pci_iobase, 8, "hfcmulti")) {
> - printk(KERN_WARNING "HFC-multi: failed to request "
> - "address space at 0x%08lx (internal error)\n",
> - hc->pci_iobase);
> - pci_disable_device(hc->pci_dev);
> - return -EIO;
> - }
> -
> - printk(KERN_INFO
> - "%s %s: defined at IOBASE %#x IRQ %d HZ %d leds-type %d\n",
> - m->vendor_name, m->card_name, (u_int) hc->pci_iobase,
> - hc->pci_dev->irq, HZ, hc->leds);
> - pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_REGIO);
> - break;
> - default:
> - printk(KERN_WARNING "HFC-multi: Invalid IO mode.\n");
> - pci_disable_device(hc->pci_dev);
> - return -EIO;
> - }
> -
> - pci_set_drvdata(hc->pci_dev, hc);
> -
> - /* At this point the needed PCI config is done */
> - /* fifos are still not enabled */
> - return 0;
> -}
> -
> -
> -/*
> - * remove port
> - */
> -
> -static void
> -release_port(struct hfc_multi *hc, struct dchannel *dch)
> -{
> - int pt, ci, i = 0;
> - u_long flags;
> - struct bchannel *pb;
> -
> - ci = dch->slot;
> - pt = hc->chan[ci].port;
> -
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: entered for port %d\n",
> - __func__, pt + 1);
> -
> - if (pt >= hc->ports) {
> - printk(KERN_WARNING "%s: ERROR port out of range (%d).\n",
> - __func__, pt + 1);
> - return;
> - }
> -
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: releasing port=%d\n",
> - __func__, pt + 1);
> -
> - if (dch->dev.D.protocol == ISDN_P_TE_S0)
> - l1_event(dch->l1, CLOSE_CHANNEL);
> -
> - hc->chan[ci].dch = NULL;
> -
> - if (hc->created[pt]) {
> - hc->created[pt] = 0;
> - mISDN_unregister_device(&dch->dev);
> - }
> -
> - spin_lock_irqsave(&hc->lock, flags);
> -
> - if (dch->timer.function) {
> - timer_delete(&dch->timer);
> - dch->timer.function = NULL;
> - }
> -
> - if (hc->ctype == HFC_TYPE_E1) { /* E1 */
> - /* remove sync */
> - if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
> - hc->syncronized = 0;
> - plxsd_checksync(hc, 1);
> - }
> - /* free channels */
> - for (i = 0; i <= 31; i++) {
> - if (!((1 << i) & hc->bmask[pt])) /* skip unused chan */
> - continue;
> - if (hc->chan[i].bch) {
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG
> - "%s: free port %d channel %d\n",
> - __func__, hc->chan[i].port + 1, i);
> - pb = hc->chan[i].bch;
> - hc->chan[i].bch = NULL;
> - spin_unlock_irqrestore(&hc->lock, flags);
> - mISDN_freebchannel(pb);
> - kfree(pb);
> - kfree(hc->chan[i].coeff);
> - spin_lock_irqsave(&hc->lock, flags);
> - }
> - }
> - } else {
> - /* remove sync */
> - if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
> - hc->syncronized &=
> - ~(1 << hc->chan[ci].port);
> - plxsd_checksync(hc, 1);
> - }
> - /* free channels */
> - if (hc->chan[ci - 2].bch) {
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG
> - "%s: free port %d channel %d\n",
> - __func__, hc->chan[ci - 2].port + 1,
> - ci - 2);
> - pb = hc->chan[ci - 2].bch;
> - hc->chan[ci - 2].bch = NULL;
> - spin_unlock_irqrestore(&hc->lock, flags);
> - mISDN_freebchannel(pb);
> - kfree(pb);
> - kfree(hc->chan[ci - 2].coeff);
> - spin_lock_irqsave(&hc->lock, flags);
> - }
> - if (hc->chan[ci - 1].bch) {
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG
> - "%s: free port %d channel %d\n",
> - __func__, hc->chan[ci - 1].port + 1,
> - ci - 1);
> - pb = hc->chan[ci - 1].bch;
> - hc->chan[ci - 1].bch = NULL;
> - spin_unlock_irqrestore(&hc->lock, flags);
> - mISDN_freebchannel(pb);
> - kfree(pb);
> - kfree(hc->chan[ci - 1].coeff);
> - spin_lock_irqsave(&hc->lock, flags);
> - }
> - }
> -
> - spin_unlock_irqrestore(&hc->lock, flags);
> -
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: free port %d channel D(%d)\n", __func__,
> - pt+1, ci);
> - mISDN_freedchannel(dch);
> - kfree(dch);
> -
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: done!\n", __func__);
> -}
> -
> -static void
> -release_card(struct hfc_multi *hc)
> -{
> - u_long flags;
> - int ch;
> -
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: release card (%d) entered\n",
> - __func__, hc->id);
> -
> - /* unregister clock source */
> - if (hc->iclock)
> - mISDN_unregister_clock(hc->iclock);
> -
> - /* disable and free irq */
> - spin_lock_irqsave(&hc->lock, flags);
> - disable_hwirq(hc);
> - spin_unlock_irqrestore(&hc->lock, flags);
> - udelay(1000);
> - if (hc->irq) {
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: free irq %d (hc=%p)\n",
> - __func__, hc->irq, hc);
> - free_irq(hc->irq, hc);
> - hc->irq = 0;
> -
> - }
> -
> - /* disable D-channels & B-channels */
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: disable all channels (d and b)\n",
> - __func__);
> - for (ch = 0; ch <= 31; ch++) {
> - if (hc->chan[ch].dch)
> - release_port(hc, hc->chan[ch].dch);
> - }
> -
> - /* dimm leds */
> - if (hc->leds)
> - hfcmulti_leds(hc);
> -
> - /* release hardware */
> - release_io_hfcmulti(hc);
> -
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: remove instance from list\n",
> - __func__);
> - list_del(&hc->list);
> -
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: delete instance\n", __func__);
> - if (hc == syncmaster)
> - syncmaster = NULL;
> - kfree(hc);
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: card successfully removed\n",
> - __func__);
> -}
> -
> -static void
> -init_e1_port_hw(struct hfc_multi *hc, struct hm_map *m)
> -{
> - /* set optical line type */
> - if (port[Port_cnt] & 0x001) {
> - if (!m->opticalsupport) {
> - printk(KERN_INFO
> - "This board has no optical "
> - "support\n");
> - } else {
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG
> - "%s: PORT set optical "
> - "interface: card(%d) "
> - "port(%d)\n",
> - __func__,
> - HFC_cnt + 1, 1);
> - test_and_set_bit(HFC_CFG_OPTICAL,
> - &hc->chan[hc->dnum[0]].cfg);
> - }
> - }
> - /* set LOS report */
> - if (port[Port_cnt] & 0x004) {
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: PORT set "
> - "LOS report: card(%d) port(%d)\n",
> - __func__, HFC_cnt + 1, 1);
> - test_and_set_bit(HFC_CFG_REPORT_LOS,
> - &hc->chan[hc->dnum[0]].cfg);
> - }
> - /* set AIS report */
> - if (port[Port_cnt] & 0x008) {
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: PORT set "
> - "AIS report: card(%d) port(%d)\n",
> - __func__, HFC_cnt + 1, 1);
> - test_and_set_bit(HFC_CFG_REPORT_AIS,
> - &hc->chan[hc->dnum[0]].cfg);
> - }
> - /* set SLIP report */
> - if (port[Port_cnt] & 0x010) {
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG
> - "%s: PORT set SLIP report: "
> - "card(%d) port(%d)\n",
> - __func__, HFC_cnt + 1, 1);
> - test_and_set_bit(HFC_CFG_REPORT_SLIP,
> - &hc->chan[hc->dnum[0]].cfg);
> - }
> - /* set RDI report */
> - if (port[Port_cnt] & 0x020) {
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG
> - "%s: PORT set RDI report: "
> - "card(%d) port(%d)\n",
> - __func__, HFC_cnt + 1, 1);
> - test_and_set_bit(HFC_CFG_REPORT_RDI,
> - &hc->chan[hc->dnum[0]].cfg);
> - }
> - /* set CRC-4 Mode */
> - if (!(port[Port_cnt] & 0x100)) {
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: PORT turn on CRC4 report:"
> - " card(%d) port(%d)\n",
> - __func__, HFC_cnt + 1, 1);
> - test_and_set_bit(HFC_CFG_CRC4,
> - &hc->chan[hc->dnum[0]].cfg);
> - } else {
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: PORT turn off CRC4"
> - " report: card(%d) port(%d)\n",
> - __func__, HFC_cnt + 1, 1);
> - }
> - /* set forced clock */
> - if (port[Port_cnt] & 0x0200) {
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: PORT force getting clock from "
> - "E1: card(%d) port(%d)\n",
> - __func__, HFC_cnt + 1, 1);
> - test_and_set_bit(HFC_CHIP_E1CLOCK_GET, &hc->chip);
> - } else
> - if (port[Port_cnt] & 0x0400) {
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: PORT force putting clock to "
> - "E1: card(%d) port(%d)\n",
> - __func__, HFC_cnt + 1, 1);
> - test_and_set_bit(HFC_CHIP_E1CLOCK_PUT, &hc->chip);
> - }
> - /* set JATT PLL */
> - if (port[Port_cnt] & 0x0800) {
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: PORT disable JATT PLL on "
> - "E1: card(%d) port(%d)\n",
> - __func__, HFC_cnt + 1, 1);
> - test_and_set_bit(HFC_CHIP_RX_SYNC, &hc->chip);
> - }
> - /* set elastic jitter buffer */
> - if (port[Port_cnt] & 0x3000) {
> - hc->chan[hc->dnum[0]].jitter = (port[Port_cnt]>>12) & 0x3;
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG
> - "%s: PORT set elastic "
> - "buffer to %d: card(%d) port(%d)\n",
> - __func__, hc->chan[hc->dnum[0]].jitter,
> - HFC_cnt + 1, 1);
> - } else
> - hc->chan[hc->dnum[0]].jitter = 2; /* default */
> -}
> -
> -static int
> -init_e1_port(struct hfc_multi *hc, struct hm_map *m, int pt)
> -{
> - struct dchannel *dch;
> - struct bchannel *bch;
> - int ch, ret = 0;
> - char name[MISDN_MAX_IDLEN];
> - int bcount = 0;
> -
> - dch = kzalloc_obj(struct dchannel);
> - if (!dch)
> - return -ENOMEM;
> - dch->debug = debug;
> - mISDN_initdchannel(dch, MAX_DFRAME_LEN_L1, ph_state_change);
> - dch->hw = hc;
> - dch->dev.Dprotocols = (1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1);
> - dch->dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
> - (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
> - dch->dev.D.send = handle_dmsg;
> - dch->dev.D.ctrl = hfcm_dctrl;
> - dch->slot = hc->dnum[pt];
> - hc->chan[hc->dnum[pt]].dch = dch;
> - hc->chan[hc->dnum[pt]].port = pt;
> - hc->chan[hc->dnum[pt]].nt_timer = -1;
> - for (ch = 1; ch <= 31; ch++) {
> - if (!((1 << ch) & hc->bmask[pt])) /* skip unused channel */
> - continue;
> - bch = kzalloc_obj(struct bchannel);
> - if (!bch) {
> - printk(KERN_ERR "%s: no memory for bchannel\n",
> - __func__);
> - ret = -ENOMEM;
> - goto free_chan;
> - }
> - hc->chan[ch].coeff = kzalloc(512, GFP_KERNEL);
> - if (!hc->chan[ch].coeff) {
> - printk(KERN_ERR "%s: no memory for coeffs\n",
> - __func__);
> - ret = -ENOMEM;
> - kfree(bch);
> - goto free_chan;
> - }
> - bch->nr = ch;
> - bch->slot = ch;
> - bch->debug = debug;
> - mISDN_initbchannel(bch, MAX_DATA_MEM, poll >> 1);
> - bch->hw = hc;
> - bch->ch.send = handle_bmsg;
> - bch->ch.ctrl = hfcm_bctrl;
> - bch->ch.nr = ch;
> - list_add(&bch->ch.list, &dch->dev.bchannels);
> - hc->chan[ch].bch = bch;
> - hc->chan[ch].port = pt;
> - set_channelmap(bch->nr, dch->dev.channelmap);
> - bcount++;
> - }
> - dch->dev.nrbchan = bcount;
> - if (pt == 0)
> - init_e1_port_hw(hc, m);
> - if (hc->ports > 1)
> - snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d-%d",
> - HFC_cnt + 1, pt+1);
> - else
> - snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d", HFC_cnt + 1);
> - ret = mISDN_register_device(&dch->dev, &hc->pci_dev->dev, name);
> - if (ret)
> - goto free_chan;
> - hc->created[pt] = 1;
> - return ret;
> -free_chan:
> - release_port(hc, dch);
> - return ret;
> -}
> -
> -static int
> -init_multi_port(struct hfc_multi *hc, int pt)
> -{
> - struct dchannel *dch;
> - struct bchannel *bch;
> - int ch, i, ret = 0;
> - char name[MISDN_MAX_IDLEN];
> -
> - dch = kzalloc_obj(struct dchannel);
> - if (!dch)
> - return -ENOMEM;
> - dch->debug = debug;
> - mISDN_initdchannel(dch, MAX_DFRAME_LEN_L1, ph_state_change);
> - dch->hw = hc;
> - dch->dev.Dprotocols = (1 << ISDN_P_TE_S0) | (1 << ISDN_P_NT_S0);
> - dch->dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
> - (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
> - dch->dev.D.send = handle_dmsg;
> - dch->dev.D.ctrl = hfcm_dctrl;
> - dch->dev.nrbchan = 2;
> - i = pt << 2;
> - dch->slot = i + 2;
> - hc->chan[i + 2].dch = dch;
> - hc->chan[i + 2].port = pt;
> - hc->chan[i + 2].nt_timer = -1;
> - for (ch = 0; ch < dch->dev.nrbchan; ch++) {
> - bch = kzalloc_obj(struct bchannel);
> - if (!bch) {
> - printk(KERN_ERR "%s: no memory for bchannel\n",
> - __func__);
> - ret = -ENOMEM;
> - goto free_chan;
> - }
> - hc->chan[i + ch].coeff = kzalloc(512, GFP_KERNEL);
> - if (!hc->chan[i + ch].coeff) {
> - printk(KERN_ERR "%s: no memory for coeffs\n",
> - __func__);
> - ret = -ENOMEM;
> - kfree(bch);
> - goto free_chan;
> - }
> - bch->nr = ch + 1;
> - bch->slot = i + ch;
> - bch->debug = debug;
> - mISDN_initbchannel(bch, MAX_DATA_MEM, poll >> 1);
> - bch->hw = hc;
> - bch->ch.send = handle_bmsg;
> - bch->ch.ctrl = hfcm_bctrl;
> - bch->ch.nr = ch + 1;
> - list_add(&bch->ch.list, &dch->dev.bchannels);
> - hc->chan[i + ch].bch = bch;
> - hc->chan[i + ch].port = pt;
> - set_channelmap(bch->nr, dch->dev.channelmap);
> - }
> - /* set master clock */
> - if (port[Port_cnt] & 0x001) {
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG
> - "%s: PROTOCOL set master clock: "
> - "card(%d) port(%d)\n",
> - __func__, HFC_cnt + 1, pt + 1);
> - if (dch->dev.D.protocol != ISDN_P_TE_S0) {
> - printk(KERN_ERR "Error: Master clock "
> - "for port(%d) of card(%d) is only"
> - " possible with TE-mode\n",
> - pt + 1, HFC_cnt + 1);
> - ret = -EINVAL;
> - goto free_chan;
> - }
> - if (hc->masterclk >= 0) {
> - printk(KERN_ERR "Error: Master clock "
> - "for port(%d) of card(%d) already "
> - "defined for port(%d)\n",
> - pt + 1, HFC_cnt + 1, hc->masterclk + 1);
> - ret = -EINVAL;
> - goto free_chan;
> - }
> - hc->masterclk = pt;
> - }
> - /* set transmitter line to non capacitive */
> - if (port[Port_cnt] & 0x002) {
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG
> - "%s: PROTOCOL set non capacitive "
> - "transmitter: card(%d) port(%d)\n",
> - __func__, HFC_cnt + 1, pt + 1);
> - test_and_set_bit(HFC_CFG_NONCAP_TX,
> - &hc->chan[i + 2].cfg);
> - }
> - /* disable E-channel */
> - if (port[Port_cnt] & 0x004) {
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG
> - "%s: PROTOCOL disable E-channel: "
> - "card(%d) port(%d)\n",
> - __func__, HFC_cnt + 1, pt + 1);
> - test_and_set_bit(HFC_CFG_DIS_ECHANNEL,
> - &hc->chan[i + 2].cfg);
> - }
> - if (hc->ctype == HFC_TYPE_XHFC) {
> - snprintf(name, MISDN_MAX_IDLEN - 1, "xhfc.%d-%d",
> - HFC_cnt + 1, pt + 1);
> - ret = mISDN_register_device(&dch->dev, NULL, name);
> - } else {
> - snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-%ds.%d-%d",
> - hc->ctype, HFC_cnt + 1, pt + 1);
> - ret = mISDN_register_device(&dch->dev, &hc->pci_dev->dev, name);
> - }
> - if (ret)
> - goto free_chan;
> - hc->created[pt] = 1;
> - return ret;
> -free_chan:
> - release_port(hc, dch);
> - return ret;
> -}
> -
> -static int
> -hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
> - const struct pci_device_id *ent)
> -{
> - int ret_err = 0;
> - int pt;
> - struct hfc_multi *hc;
> - u_long flags;
> - u_char dips = 0, pmj = 0; /* dip settings, port mode Jumpers */
> - int i, ch;
> - u_int maskcheck;
> -
> - if (HFC_cnt >= MAX_CARDS) {
> - printk(KERN_ERR "too many cards (max=%d).\n",
> - MAX_CARDS);
> - return -EINVAL;
> - }
> - if ((type[HFC_cnt] & 0xff) && (type[HFC_cnt] & 0xff) != m->type) {
> - printk(KERN_WARNING "HFC-MULTI: Card '%s:%s' type %d found but "
> - "type[%d] %d was supplied as module parameter\n",
> - m->vendor_name, m->card_name, m->type, HFC_cnt,
> - type[HFC_cnt] & 0xff);
> - printk(KERN_WARNING "HFC-MULTI: Load module without parameters "
> - "first, to see cards and their types.");
> - return -EINVAL;
> - }
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: Registering %s:%s chip type %d (0x%x)\n",
> - __func__, m->vendor_name, m->card_name, m->type,
> - type[HFC_cnt]);
> -
> - /* allocate card+fifo structure */
> - hc = kzalloc_obj(struct hfc_multi);
> - if (!hc) {
> - printk(KERN_ERR "No kmem for HFC-Multi card\n");
> - return -ENOMEM;
> - }
> - spin_lock_init(&hc->lock);
> - hc->mtyp = m;
> - hc->ctype = m->type;
> - hc->ports = m->ports;
> - hc->id = HFC_cnt;
> - hc->pcm = pcm[HFC_cnt];
> - hc->io_mode = iomode[HFC_cnt];
> - if (hc->ctype == HFC_TYPE_E1 && dmask[E1_cnt]) {
> - /* fragment card */
> - pt = 0;
> - maskcheck = 0;
> - for (ch = 0; ch <= 31; ch++) {
> - if (!((1 << ch) & dmask[E1_cnt]))
> - continue;
> - hc->dnum[pt] = ch;
> - hc->bmask[pt] = bmask[bmask_cnt++];
> - if ((maskcheck & hc->bmask[pt])
> - || (dmask[E1_cnt] & hc->bmask[pt])) {
> - printk(KERN_INFO
> - "HFC-E1 #%d has overlapping B-channels on fragment #%d\n",
> - E1_cnt + 1, pt);
> - kfree(hc);
> - return -EINVAL;
> - }
> - maskcheck |= hc->bmask[pt];
> - printk(KERN_INFO
> - "HFC-E1 #%d uses D-channel on slot %d and a B-channel map of 0x%08x\n",
> - E1_cnt + 1, ch, hc->bmask[pt]);
> - pt++;
> - }
> - hc->ports = pt;
> - }
> - if (hc->ctype == HFC_TYPE_E1 && !dmask[E1_cnt]) {
> - /* default card layout */
> - hc->dnum[0] = 16;
> - hc->bmask[0] = 0xfffefffe;
> - hc->ports = 1;
> - }
> -
> - /* set chip specific features */
> - hc->masterclk = -1;
> - if (type[HFC_cnt] & 0x100) {
> - test_and_set_bit(HFC_CHIP_ULAW, &hc->chip);
> - hc->silence = 0xff; /* ulaw silence */
> - } else
> - hc->silence = 0x2a; /* alaw silence */
> - if ((poll >> 1) > sizeof(hc->silence_data)) {
> - printk(KERN_ERR "HFCMULTI error: silence_data too small, "
> - "please fix\n");
> - kfree(hc);
> - return -EINVAL;
> - }
> - for (i = 0; i < (poll >> 1); i++)
> - hc->silence_data[i] = hc->silence;
> -
> - if (hc->ctype != HFC_TYPE_XHFC) {
> - if (!(type[HFC_cnt] & 0x200))
> - test_and_set_bit(HFC_CHIP_DTMF, &hc->chip);
> - test_and_set_bit(HFC_CHIP_CONF, &hc->chip);
> - }
> -
> - if (type[HFC_cnt] & 0x800)
> - test_and_set_bit(HFC_CHIP_PCM_SLAVE, &hc->chip);
> - if (type[HFC_cnt] & 0x1000) {
> - test_and_set_bit(HFC_CHIP_PCM_MASTER, &hc->chip);
> - test_and_clear_bit(HFC_CHIP_PCM_SLAVE, &hc->chip);
> - }
> - if (type[HFC_cnt] & 0x4000)
> - test_and_set_bit(HFC_CHIP_EXRAM_128, &hc->chip);
> - if (type[HFC_cnt] & 0x8000)
> - test_and_set_bit(HFC_CHIP_EXRAM_512, &hc->chip);
> - hc->slots = 32;
> - if (type[HFC_cnt] & 0x10000)
> - hc->slots = 64;
> - if (type[HFC_cnt] & 0x20000)
> - hc->slots = 128;
> - if (type[HFC_cnt] & 0x80000) {
> - test_and_set_bit(HFC_CHIP_WATCHDOG, &hc->chip);
> - hc->wdcount = 0;
> - hc->wdbyte = V_GPIO_OUT2;
> - printk(KERN_NOTICE "Watchdog enabled\n");
> - }
> -
> - if (pdev && ent)
> - /* setup pci, hc->slots may change due to PLXSD */
> - ret_err = setup_pci(hc, pdev, ent);
> - else
> -#ifdef CONFIG_MISDN_HFCMULTI_8xx
> - ret_err = setup_embedded(hc, m);
> -#else
> - {
> - printk(KERN_WARNING "Embedded IO Mode not selected\n");
> - ret_err = -EIO;
> - }
> -#endif
> - if (ret_err) {
> - if (hc == syncmaster)
> - syncmaster = NULL;
> - kfree(hc);
> - return ret_err;
> - }
> -
> - hc->HFC_outb_nodebug = hc->HFC_outb;
> - hc->HFC_inb_nodebug = hc->HFC_inb;
> - hc->HFC_inw_nodebug = hc->HFC_inw;
> - hc->HFC_wait_nodebug = hc->HFC_wait;
> -#ifdef HFC_REGISTER_DEBUG
> - hc->HFC_outb = HFC_outb_debug;
> - hc->HFC_inb = HFC_inb_debug;
> - hc->HFC_inw = HFC_inw_debug;
> - hc->HFC_wait = HFC_wait_debug;
> -#endif
> - /* create channels */
> - for (pt = 0; pt < hc->ports; pt++) {
> - if (Port_cnt >= MAX_PORTS) {
> - printk(KERN_ERR "too many ports (max=%d).\n",
> - MAX_PORTS);
> - ret_err = -EINVAL;
> - goto free_card;
> - }
> - if (hc->ctype == HFC_TYPE_E1)
> - ret_err = init_e1_port(hc, m, pt);
> - else
> - ret_err = init_multi_port(hc, pt);
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG
> - "%s: Registering D-channel, card(%d) port(%d) "
> - "result %d\n",
> - __func__, HFC_cnt + 1, pt + 1, ret_err);
> -
> - if (ret_err) {
> - while (pt) { /* release already registered ports */
> - pt--;
> - if (hc->ctype == HFC_TYPE_E1)
> - release_port(hc,
> - hc->chan[hc->dnum[pt]].dch);
> - else
> - release_port(hc,
> - hc->chan[(pt << 2) + 2].dch);
> - }
> - goto free_card;
> - }
> - if (hc->ctype != HFC_TYPE_E1)
> - Port_cnt++; /* for each S0 port */
> - }
> - if (hc->ctype == HFC_TYPE_E1) {
> - Port_cnt++; /* for each E1 port */
> - E1_cnt++;
> - }
> -
> - /* disp switches */
> - switch (m->dip_type) {
> - case DIP_4S:
> - /*
> - * Get DIP setting for beroNet 1S/2S/4S cards
> - * DIP Setting: (collect GPIO 13/14/15 (R_GPIO_IN1) +
> - * GPI 19/23 (R_GPI_IN2))
> - */
> - dips = ((~HFC_inb(hc, R_GPIO_IN1) & 0xE0) >> 5) |
> - ((~HFC_inb(hc, R_GPI_IN2) & 0x80) >> 3) |
> - (~HFC_inb(hc, R_GPI_IN2) & 0x08);
> -
> - /* Port mode (TE/NT) jumpers */
> - pmj = ((HFC_inb(hc, R_GPI_IN3) >> 4) & 0xf);
> -
> - if (test_bit(HFC_CHIP_B410P, &hc->chip))
> - pmj = ~pmj & 0xf;
> -
> - printk(KERN_INFO "%s: %s DIPs(0x%x) jumpers(0x%x)\n",
> - m->vendor_name, m->card_name, dips, pmj);
> - break;
> - case DIP_8S:
> - /*
> - * Get DIP Setting for beroNet 8S0+ cards
> - * Enable PCI auxbridge function
> - */
> - HFC_outb(hc, R_BRG_PCM_CFG, 1 | V_PCM_CLK);
> - /* prepare access to auxport */
> - outw(0x4000, hc->pci_iobase + 4);
> - /*
> - * some dummy reads are required to
> - * read valid DIP switch data
> - */
> - dips = inb(hc->pci_iobase);
> - dips = inb(hc->pci_iobase);
> - dips = inb(hc->pci_iobase);
> - dips = ~inb(hc->pci_iobase) & 0x3F;
> - outw(0x0, hc->pci_iobase + 4);
> - /* disable PCI auxbridge function */
> - HFC_outb(hc, R_BRG_PCM_CFG, V_PCM_CLK);
> - printk(KERN_INFO "%s: %s DIPs(0x%x)\n",
> - m->vendor_name, m->card_name, dips);
> - break;
> - case DIP_E1:
> - /*
> - * get DIP Setting for beroNet E1 cards
> - * DIP Setting: collect GPI 4/5/6/7 (R_GPI_IN0)
> - */
> - dips = (~HFC_inb(hc, R_GPI_IN0) & 0xF0) >> 4;
> - printk(KERN_INFO "%s: %s DIPs(0x%x)\n",
> - m->vendor_name, m->card_name, dips);
> - break;
> - }
> -
> - /* add to list */
> - spin_lock_irqsave(&HFClock, flags);
> - list_add_tail(&hc->list, &HFClist);
> - spin_unlock_irqrestore(&HFClock, flags);
> -
> - /* use as clock source */
> - if (clock == HFC_cnt + 1)
> - hc->iclock = mISDN_register_clock("HFCMulti", 0, clockctl, hc);
> -
> - /* initialize hardware */
> - hc->irq = (m->irq) ? : hc->pci_dev->irq;
> - ret_err = init_card(hc);
> - if (ret_err) {
> - printk(KERN_ERR "init card returns %d\n", ret_err);
> - release_card(hc);
> - return ret_err;
> - }
> -
> - /* start IRQ and return */
> - spin_lock_irqsave(&hc->lock, flags);
> - enable_hwirq(hc);
> - spin_unlock_irqrestore(&hc->lock, flags);
> - return 0;
> -
> -free_card:
> - release_io_hfcmulti(hc);
> - if (hc == syncmaster)
> - syncmaster = NULL;
> - kfree(hc);
> - return ret_err;
> -}
> -
> -static void hfc_remove_pci(struct pci_dev *pdev)
> -{
> - struct hfc_multi *card = pci_get_drvdata(pdev);
> - u_long flags;
> -
> - if (debug)
> - printk(KERN_INFO "removing hfc_multi card vendor:%x "
> - "device:%x subvendor:%x subdevice:%x\n",
> - pdev->vendor, pdev->device,
> - pdev->subsystem_vendor, pdev->subsystem_device);
> -
> - if (card) {
> - spin_lock_irqsave(&HFClock, flags);
> - release_card(card);
> - spin_unlock_irqrestore(&HFClock, flags);
> - } else {
> - if (debug)
> - printk(KERN_DEBUG "%s: drvdata already removed\n",
> - __func__);
> - }
> -}
> -
> -#define VENDOR_CCD "Cologne Chip AG"
> -#define VENDOR_BN "beroNet GmbH"
> -#define VENDOR_DIG "Digium Inc."
> -#define VENDOR_JH "Junghanns.NET GmbH"
> -#define VENDOR_PRIM "PrimuX"
> -
> -static const struct hm_map hfcm_map[] = {
> - /*0*/ {VENDOR_BN, "HFC-1S Card (mini PCI)", 4, 1, 1, 3, 0, DIP_4S, 0, 0},
> - /*1*/ {VENDOR_BN, "HFC-2S Card", 4, 2, 1, 3, 0, DIP_4S, 0, 0},
> - /*2*/ {VENDOR_BN, "HFC-2S Card (mini PCI)", 4, 2, 1, 3, 0, DIP_4S, 0, 0},
> - /*3*/ {VENDOR_BN, "HFC-4S Card", 4, 4, 1, 2, 0, DIP_4S, 0, 0},
> - /*4*/ {VENDOR_BN, "HFC-4S Card (mini PCI)", 4, 4, 1, 2, 0, 0, 0, 0},
> - /*5*/ {VENDOR_CCD, "HFC-4S Eval (old)", 4, 4, 0, 0, 0, 0, 0, 0},
> - /*6*/ {VENDOR_CCD, "HFC-4S IOB4ST", 4, 4, 1, 2, 0, DIP_4S, 0, 0},
> - /*7*/ {VENDOR_CCD, "HFC-4S", 4, 4, 1, 2, 0, 0, 0, 0},
> - /*8*/ {VENDOR_DIG, "HFC-4S Card", 4, 4, 0, 2, 0, 0, HFC_IO_MODE_REGIO, 0},
> - /*9*/ {VENDOR_CCD, "HFC-4S Swyx 4xS0 SX2 QuadBri", 4, 4, 1, 2, 0, 0, 0, 0},
> - /*10*/ {VENDOR_JH, "HFC-4S (junghanns 2.0)", 4, 4, 1, 2, 0, 0, 0, 0},
> - /*11*/ {VENDOR_PRIM, "HFC-2S Primux Card", 4, 2, 0, 0, 0, 0, 0, 0},
> -
> - /*12*/ {VENDOR_BN, "HFC-8S Card", 8, 8, 1, 0, 0, 0, 0, 0},
> - /*13*/ {VENDOR_BN, "HFC-8S Card (+)", 8, 8, 1, 8, 0, DIP_8S,
> - HFC_IO_MODE_REGIO, 0},
> - /*14*/ {VENDOR_CCD, "HFC-8S Eval (old)", 8, 8, 0, 0, 0, 0, 0, 0},
> - /*15*/ {VENDOR_CCD, "HFC-8S IOB4ST Recording", 8, 8, 1, 0, 0, 0, 0, 0},
> -
> - /*16*/ {VENDOR_CCD, "HFC-8S IOB8ST", 8, 8, 1, 0, 0, 0, 0, 0},
> - /*17*/ {VENDOR_CCD, "HFC-8S", 8, 8, 1, 0, 0, 0, 0, 0},
> - /*18*/ {VENDOR_CCD, "HFC-8S", 8, 8, 1, 0, 0, 0, 0, 0},
> -
> - /*19*/ {VENDOR_BN, "HFC-E1 Card", 1, 1, 0, 1, 0, DIP_E1, 0, 0},
> - /*20*/ {VENDOR_BN, "HFC-E1 Card (mini PCI)", 1, 1, 0, 1, 0, 0, 0, 0},
> - /*21*/ {VENDOR_BN, "HFC-E1+ Card (Dual)", 1, 1, 0, 1, 0, DIP_E1, 0, 0},
> - /*22*/ {VENDOR_BN, "HFC-E1 Card (Dual)", 1, 1, 0, 1, 0, DIP_E1, 0, 0},
> -
> - /*23*/ {VENDOR_CCD, "HFC-E1 Eval (old)", 1, 1, 0, 0, 0, 0, 0, 0},
> - /*24*/ {VENDOR_CCD, "HFC-E1 IOB1E1", 1, 1, 0, 1, 0, 0, 0, 0},
> - /*25*/ {VENDOR_CCD, "HFC-E1", 1, 1, 0, 1, 0, 0, 0, 0},
> -
> - /*26*/ {VENDOR_CCD, "HFC-4S Speech Design", 4, 4, 0, 0, 0, 0,
> - HFC_IO_MODE_PLXSD, 0},
> - /*27*/ {VENDOR_CCD, "HFC-E1 Speech Design", 1, 1, 0, 0, 0, 0,
> - HFC_IO_MODE_PLXSD, 0},
> - /*28*/ {VENDOR_CCD, "HFC-4S OpenVox", 4, 4, 1, 0, 0, 0, 0, 0},
> - /*29*/ {VENDOR_CCD, "HFC-2S OpenVox", 4, 2, 1, 0, 0, 0, 0, 0},
> - /*30*/ {VENDOR_CCD, "HFC-8S OpenVox", 8, 8, 1, 0, 0, 0, 0, 0},
> - /*31*/ {VENDOR_CCD, "XHFC-4S Speech Design", 5, 4, 0, 0, 0, 0,
> - HFC_IO_MODE_EMBSD, XHFC_IRQ},
> - /*32*/ {VENDOR_JH, "HFC-8S (junghanns)", 8, 8, 1, 0, 0, 0, 0, 0},
> - /*33*/ {VENDOR_BN, "HFC-2S Beronet Card PCIe", 4, 2, 1, 3, 0, DIP_4S, 0, 0},
> - /*34*/ {VENDOR_BN, "HFC-4S Beronet Card PCIe", 4, 4, 1, 2, 0, DIP_4S, 0, 0},
> -};
> -
> -#undef H
> -#define H(x) ((unsigned long)&hfcm_map[x])
> -static const struct pci_device_id hfmultipci_ids[] = {
> -
> - /* Cards with HFC-4S Chip */
> - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
> - PCI_SUBDEVICE_ID_CCD_BN1SM, 0, 0, H(0)}, /* BN1S mini PCI */
> - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
> - PCI_SUBDEVICE_ID_CCD_BN2S, 0, 0, H(1)}, /* BN2S */
> - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
> - PCI_SUBDEVICE_ID_CCD_BN2SM, 0, 0, H(2)}, /* BN2S mini PCI */
> - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
> - PCI_SUBDEVICE_ID_CCD_BN4S, 0, 0, H(3)}, /* BN4S */
> - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
> - PCI_SUBDEVICE_ID_CCD_BN4SM, 0, 0, H(4)}, /* BN4S mini PCI */
> - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
> - PCI_DEVICE_ID_CCD_HFC4S, 0, 0, H(5)}, /* Old Eval */
> - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
> - PCI_SUBDEVICE_ID_CCD_IOB4ST, 0, 0, H(6)}, /* IOB4ST */
> - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
> - PCI_SUBDEVICE_ID_CCD_HFC4S, 0, 0, H(7)}, /* 4S */
> - { PCI_VENDOR_ID_DIGIUM, PCI_DEVICE_ID_DIGIUM_HFC4S,
> - PCI_VENDOR_ID_DIGIUM, PCI_DEVICE_ID_DIGIUM_HFC4S, 0, 0, H(8)},
> - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
> - PCI_SUBDEVICE_ID_CCD_SWYX4S, 0, 0, H(9)}, /* 4S Swyx */
> - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
> - PCI_SUBDEVICE_ID_CCD_JH4S20, 0, 0, H(10)},
> - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
> - PCI_SUBDEVICE_ID_CCD_PMX2S, 0, 0, H(11)}, /* Primux */
> - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
> - PCI_SUBDEVICE_ID_CCD_OV4S, 0, 0, H(28)}, /* OpenVox 4 */
> - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
> - PCI_SUBDEVICE_ID_CCD_OV2S, 0, 0, H(29)}, /* OpenVox 2 */
> - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
> - 0xb761, 0, 0, H(33)}, /* BN2S PCIe */
> - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
> - 0xb762, 0, 0, H(34)}, /* BN4S PCIe */
> -
> - /* Cards with HFC-8S Chip */
> - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
> - PCI_SUBDEVICE_ID_CCD_BN8S, 0, 0, H(12)}, /* BN8S */
> - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
> - PCI_SUBDEVICE_ID_CCD_BN8SP, 0, 0, H(13)}, /* BN8S+ */
> - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
> - PCI_DEVICE_ID_CCD_HFC8S, 0, 0, H(14)}, /* old Eval */
> - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
> - PCI_SUBDEVICE_ID_CCD_IOB8STR, 0, 0, H(15)}, /* IOB8ST Recording */
> - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
> - PCI_SUBDEVICE_ID_CCD_IOB8ST, 0, 0, H(16)}, /* IOB8ST */
> - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
> - PCI_SUBDEVICE_ID_CCD_IOB8ST_1, 0, 0, H(17)}, /* IOB8ST */
> - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
> - PCI_SUBDEVICE_ID_CCD_HFC8S, 0, 0, H(18)}, /* 8S */
> - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
> - PCI_SUBDEVICE_ID_CCD_OV8S, 0, 0, H(30)}, /* OpenVox 8 */
> - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
> - PCI_SUBDEVICE_ID_CCD_JH8S, 0, 0, H(32)}, /* Junganns 8S */
> -
> -
> - /* Cards with HFC-E1 Chip */
> - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
> - PCI_SUBDEVICE_ID_CCD_BNE1, 0, 0, H(19)}, /* BNE1 */
> - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
> - PCI_SUBDEVICE_ID_CCD_BNE1M, 0, 0, H(20)}, /* BNE1 mini PCI */
> - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
> - PCI_SUBDEVICE_ID_CCD_BNE1DP, 0, 0, H(21)}, /* BNE1 + (Dual) */
> - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
> - PCI_SUBDEVICE_ID_CCD_BNE1D, 0, 0, H(22)}, /* BNE1 (Dual) */
> -
> - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
> - PCI_DEVICE_ID_CCD_HFCE1, 0, 0, H(23)}, /* Old Eval */
> - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
> - PCI_SUBDEVICE_ID_CCD_IOB1E1, 0, 0, H(24)}, /* IOB1E1 */
> - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
> - PCI_SUBDEVICE_ID_CCD_HFCE1, 0, 0, H(25)}, /* E1 */
> -
> - { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_VENDOR_ID_CCD,
> - PCI_SUBDEVICE_ID_CCD_SPD4S, 0, 0, H(26)}, /* PLX PCI Bridge */
> - { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_VENDOR_ID_CCD,
> - PCI_SUBDEVICE_ID_CCD_SPDE1, 0, 0, H(27)}, /* PLX PCI Bridge */
> -
> - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
> - PCI_SUBDEVICE_ID_CCD_JHSE1, 0, 0, H(25)}, /* Junghanns E1 */
> -
> - { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_HFC4S), 0 },
> - { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_HFC8S), 0 },
> - { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_HFCE1), 0 },
> - {0, }
> -};
> -#undef H
> -
> -MODULE_DEVICE_TABLE(pci, hfmultipci_ids);
> -
> -static int
> -hfcmulti_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
> -{
> - struct hm_map *m = (struct hm_map *)ent->driver_data;
> - int ret;
> -
> - if (m == NULL && ent->vendor == PCI_VENDOR_ID_CCD && (
> - ent->device == PCI_DEVICE_ID_CCD_HFC4S ||
> - ent->device == PCI_DEVICE_ID_CCD_HFC8S ||
> - ent->device == PCI_DEVICE_ID_CCD_HFCE1)) {
> - printk(KERN_ERR
> - "Unknown HFC multiport controller (vendor:%04x device:%04x "
> - "subvendor:%04x subdevice:%04x)\n", pdev->vendor,
> - pdev->device, pdev->subsystem_vendor,
> - pdev->subsystem_device);
> - printk(KERN_ERR
> - "Please contact the driver maintainer for support.\n");
> - return -ENODEV;
> - }
> - ret = hfcmulti_init(m, pdev, ent);
> - if (ret)
> - return ret;
> - HFC_cnt++;
> - printk(KERN_INFO "%d devices registered\n", HFC_cnt);
> - return 0;
> -}
> -
> -static struct pci_driver hfcmultipci_driver = {
> - .name = "hfc_multi",
> - .probe = hfcmulti_probe,
> - .remove = hfc_remove_pci,
> - .id_table = hfmultipci_ids,
> -};
> -
> -static void __exit
> -HFCmulti_cleanup(void)
> -{
> - struct hfc_multi *card, *next;
> -
> - /* get rid of all devices of this driver */
> - list_for_each_entry_safe(card, next, &HFClist, list)
> - release_card(card);
> - pci_unregister_driver(&hfcmultipci_driver);
> -}
> -
> -static int __init
> -HFCmulti_init(void)
> -{
> - int err;
> - int i, xhfc = 0;
> - struct hm_map m;
> -
> - printk(KERN_INFO "mISDN: HFC-multi driver %s\n", HFC_MULTI_VERSION);
> -
> -#ifdef IRQ_DEBUG
> - printk(KERN_DEBUG "%s: IRQ_DEBUG IS ENABLED!\n", __func__);
> -#endif
> -
> - if (debug & DEBUG_HFCMULTI_INIT)
> - printk(KERN_DEBUG "%s: init entered\n", __func__);
> -
> - switch (poll) {
> - case 0:
> - poll_timer = 6;
> - poll = 128;
> - break;
> - case 8:
> - poll_timer = 2;
> - break;
> - case 16:
> - poll_timer = 3;
> - break;
> - case 32:
> - poll_timer = 4;
> - break;
> - case 64:
> - poll_timer = 5;
> - break;
> - case 128:
> - poll_timer = 6;
> - break;
> - case 256:
> - poll_timer = 7;
> - break;
> - default:
> - printk(KERN_ERR
> - "%s: Wrong poll value (%d).\n", __func__, poll);
> - err = -EINVAL;
> - return err;
> -
> - }
> -
> - if (!clock)
> - clock = 1;
> -
> - /* Register the embedded devices.
> - * This should be done before the PCI cards registration */
> - switch (hwid) {
> - case HWID_MINIP4:
> - xhfc = 1;
> - m = hfcm_map[31];
> - break;
> - case HWID_MINIP8:
> - xhfc = 2;
> - m = hfcm_map[31];
> - break;
> - case HWID_MINIP16:
> - xhfc = 4;
> - m = hfcm_map[31];
> - break;
> - default:
> - xhfc = 0;
> - }
> -
> - for (i = 0; i < xhfc; ++i) {
> - err = hfcmulti_init(&m, NULL, NULL);
> - if (err) {
> - printk(KERN_ERR "error registering embedded driver: "
> - "%x\n", err);
> - return err;
> - }
> - HFC_cnt++;
> - printk(KERN_INFO "%d devices registered\n", HFC_cnt);
> - }
> -
> - /* Register the PCI cards */
> - err = pci_register_driver(&hfcmultipci_driver);
> - if (err < 0) {
> - printk(KERN_ERR "error registering pci driver: %x\n", err);
> - return err;
> - }
> -
> - return 0;
> -}
> -
> -
> -module_init(HFCmulti_init);
> -module_exit(HFCmulti_cleanup);
> diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c
> deleted file mode 100644
> index 554a1c640321..000000000000
> --- a/drivers/isdn/hardware/mISDN/hfcpci.c
> +++ /dev/null
> @@ -1,2360 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-or-later
> -/*
> - *
> - * hfcpci.c low level driver for CCD's hfc-pci based cards
> - *
> - * Author Werner Cornelius (werner@isdn4linux.de)
> - * based on existing driver for CCD hfc ISA cards
> - * type approval valid for HFC-S PCI A based card
> - *
> - * Copyright 1999 by Werner Cornelius (werner@isdn-development.de)
> - * Copyright 2008 by Karsten Keil <kkeil@novell.com>
> - *
> - * Module options:
> - *
> - * debug:
> - * NOTE: only one poll value must be given for all cards
> - * See hfc_pci.h for debug flags.
> - *
> - * poll:
> - * NOTE: only one poll value must be given for all cards
> - * Give the number of samples for each fifo process.
> - * By default 128 is used. Decrease to reduce delay, increase to
> - * reduce cpu load. If unsure, don't mess with it!
> - * A value of 128 will use controller's interrupt. Other values will
> - * use kernel timer, because the controller will not allow lower values
> - * than 128.
> - * Also note that the value depends on the kernel timer frequency.
> - * If kernel uses a frequency of 1000 Hz, steps of 8 samples are possible.
> - * If the kernel uses 100 Hz, steps of 80 samples are possible.
> - * If the kernel uses 300 Hz, steps of about 26 samples are possible.
> - */
> -
> -#include <linux/interrupt.h>
> -#include <linux/module.h>
> -#include <linux/pci.h>
> -#include <linux/delay.h>
> -#include <linux/mISDNhw.h>
> -#include <linux/slab.h>
> -
> -#include "hfc_pci.h"
> -
> -static void hfcpci_softirq(struct timer_list *unused);
> -static const char *hfcpci_revision = "2.0";
> -
> -static int HFC_cnt;
> -static uint debug;
> -static uint poll, tics;
> -static DEFINE_TIMER(hfc_tl, hfcpci_softirq);
> -static unsigned long hfc_jiffies;
> -
> -MODULE_AUTHOR("Karsten Keil");
> -MODULE_DESCRIPTION("mISDN driver for CCD's hfc-pci based cards");
> -MODULE_LICENSE("GPL");
> -module_param(debug, uint, S_IRUGO | S_IWUSR);
> -module_param(poll, uint, S_IRUGO | S_IWUSR);
> -
> -enum {
> - HFC_CCD_2BD0,
> - HFC_CCD_B000,
> - HFC_CCD_B006,
> - HFC_CCD_B007,
> - HFC_CCD_B008,
> - HFC_CCD_B009,
> - HFC_CCD_B00A,
> - HFC_CCD_B00B,
> - HFC_CCD_B00C,
> - HFC_CCD_B100,
> - HFC_CCD_B700,
> - HFC_CCD_B701,
> - HFC_ASUS_0675,
> - HFC_BERKOM_A1T,
> - HFC_BERKOM_TCONCEPT,
> - HFC_ANIGMA_MC145575,
> - HFC_ZOLTRIX_2BD0,
> - HFC_DIGI_DF_M_IOM2_E,
> - HFC_DIGI_DF_M_E,
> - HFC_DIGI_DF_M_IOM2_A,
> - HFC_DIGI_DF_M_A,
> - HFC_ABOCOM_2BD1,
> - HFC_SITECOM_DC105V2,
> -};
> -
> -struct hfcPCI_hw {
> - unsigned char cirm;
> - unsigned char ctmt;
> - unsigned char clkdel;
> - unsigned char states;
> - unsigned char conn;
> - unsigned char mst_m;
> - unsigned char int_m1;
> - unsigned char int_m2;
> - unsigned char sctrl;
> - unsigned char sctrl_r;
> - unsigned char sctrl_e;
> - unsigned char trm;
> - unsigned char fifo_en;
> - unsigned char bswapped;
> - unsigned char protocol;
> - int nt_timer;
> - unsigned char __iomem *pci_io; /* start of PCI IO memory */
> - dma_addr_t dmahandle;
> - void *fifos; /* FIFO memory */
> - int last_bfifo_cnt[2];
> - /* marker saving last b-fifo frame count */
> - struct timer_list timer;
> -};
> -
> -#define HFC_CFG_MASTER 1
> -#define HFC_CFG_SLAVE 2
> -#define HFC_CFG_PCM 3
> -#define HFC_CFG_2HFC 4
> -#define HFC_CFG_SLAVEHFC 5
> -#define HFC_CFG_NEG_F0 6
> -#define HFC_CFG_SW_DD_DU 7
> -
> -#define FLG_HFC_TIMER_T1 16
> -#define FLG_HFC_TIMER_T3 17
> -
> -#define NT_T1_COUNT 1120 /* number of 3.125ms interrupts (3.5s) */
> -#define NT_T3_COUNT 31 /* number of 3.125ms interrupts (97 ms) */
> -#define CLKDEL_TE 0x0e /* CLKDEL in TE mode */
> -#define CLKDEL_NT 0x6c /* CLKDEL in NT mode */
> -
> -
> -struct hfc_pci {
> - u_char subtype;
> - u_char chanlimit;
> - u_char initdone;
> - u_long cfg;
> - u_int irq;
> - u_int irqcnt;
> - struct pci_dev *pdev;
> - struct hfcPCI_hw hw;
> - spinlock_t lock; /* card lock */
> - struct dchannel dch;
> - struct bchannel bch[2];
> -};
> -
> -/* Interface functions */
> -static void
> -enable_hwirq(struct hfc_pci *hc)
> -{
> - hc->hw.int_m2 |= HFCPCI_IRQ_ENABLE;
> - Write_hfc(hc, HFCPCI_INT_M2, hc->hw.int_m2);
> -}
> -
> -static void
> -disable_hwirq(struct hfc_pci *hc)
> -{
> - hc->hw.int_m2 &= ~((u_char)HFCPCI_IRQ_ENABLE);
> - Write_hfc(hc, HFCPCI_INT_M2, hc->hw.int_m2);
> -}
> -
> -/*
> - * free hardware resources used by driver
> - */
> -static void
> -release_io_hfcpci(struct hfc_pci *hc)
> -{
> - /* disable memory mapped ports + busmaster */
> - pci_write_config_word(hc->pdev, PCI_COMMAND, 0);
> - timer_delete(&hc->hw.timer);
> - dma_free_coherent(&hc->pdev->dev, 0x8000, hc->hw.fifos,
> - hc->hw.dmahandle);
> - iounmap(hc->hw.pci_io);
> -}
> -
> -/*
> - * set mode (NT or TE)
> - */
> -static void
> -hfcpci_setmode(struct hfc_pci *hc)
> -{
> - if (hc->hw.protocol == ISDN_P_NT_S0) {
> - hc->hw.clkdel = CLKDEL_NT; /* ST-Bit delay for NT-Mode */
> - hc->hw.sctrl |= SCTRL_MODE_NT; /* NT-MODE */
> - hc->hw.states = 1; /* G1 */
> - } else {
> - hc->hw.clkdel = CLKDEL_TE; /* ST-Bit delay for TE-Mode */
> - hc->hw.sctrl &= ~SCTRL_MODE_NT; /* TE-MODE */
> - hc->hw.states = 2; /* F2 */
> - }
> - Write_hfc(hc, HFCPCI_CLKDEL, hc->hw.clkdel);
> - Write_hfc(hc, HFCPCI_STATES, HFCPCI_LOAD_STATE | hc->hw.states);
> - udelay(10);
> - Write_hfc(hc, HFCPCI_STATES, hc->hw.states | 0x40); /* Deactivate */
> - Write_hfc(hc, HFCPCI_SCTRL, hc->hw.sctrl);
> -}
> -
> -/*
> - * function called to reset the HFC PCI chip. A complete software reset of chip
> - * and fifos is done.
> - */
> -static void
> -reset_hfcpci(struct hfc_pci *hc)
> -{
> - u_char val;
> - int cnt = 0;
> -
> - printk(KERN_DEBUG "reset_hfcpci: entered\n");
> - val = Read_hfc(hc, HFCPCI_CHIP_ID);
> - printk(KERN_INFO "HFC_PCI: resetting HFC ChipId(%x)\n", val);
> - /* enable memory mapped ports, disable busmaster */
> - pci_write_config_word(hc->pdev, PCI_COMMAND, PCI_ENA_MEMIO);
> - disable_hwirq(hc);
> - /* enable memory ports + busmaster */
> - pci_write_config_word(hc->pdev, PCI_COMMAND,
> - PCI_ENA_MEMIO + PCI_ENA_MASTER);
> - val = Read_hfc(hc, HFCPCI_STATUS);
> - printk(KERN_DEBUG "HFC-PCI status(%x) before reset\n", val);
> - hc->hw.cirm = HFCPCI_RESET; /* Reset On */
> - Write_hfc(hc, HFCPCI_CIRM, hc->hw.cirm);
> - set_current_state(TASK_UNINTERRUPTIBLE);
> - mdelay(10); /* Timeout 10ms */
> - hc->hw.cirm = 0; /* Reset Off */
> - Write_hfc(hc, HFCPCI_CIRM, hc->hw.cirm);
> - val = Read_hfc(hc, HFCPCI_STATUS);
> - printk(KERN_DEBUG "HFC-PCI status(%x) after reset\n", val);
> - while (cnt < 50000) { /* max 50000 us */
> - udelay(5);
> - cnt += 5;
> - val = Read_hfc(hc, HFCPCI_STATUS);
> - if (!(val & 2))
> - break;
> - }
> - printk(KERN_DEBUG "HFC-PCI status(%x) after %dus\n", val, cnt);
> -
> - hc->hw.fifo_en = 0x30; /* only D fifos enabled */
> -
> - hc->hw.bswapped = 0; /* no exchange */
> - hc->hw.ctmt = HFCPCI_TIM3_125 | HFCPCI_AUTO_TIMER;
> - hc->hw.trm = HFCPCI_BTRANS_THRESMASK; /* no echo connect , threshold */
> - hc->hw.sctrl = 0x40; /* set tx_lo mode, error in datasheet ! */
> - hc->hw.sctrl_r = 0;
> - hc->hw.sctrl_e = HFCPCI_AUTO_AWAKE; /* S/T Auto awake */
> - hc->hw.mst_m = 0;
> - if (test_bit(HFC_CFG_MASTER, &hc->cfg))
> - hc->hw.mst_m |= HFCPCI_MASTER; /* HFC Master Mode */
> - if (test_bit(HFC_CFG_NEG_F0, &hc->cfg))
> - hc->hw.mst_m |= HFCPCI_F0_NEGATIV;
> - Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en);
> - Write_hfc(hc, HFCPCI_TRM, hc->hw.trm);
> - Write_hfc(hc, HFCPCI_SCTRL_E, hc->hw.sctrl_e);
> - Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt);
> -
> - hc->hw.int_m1 = HFCPCI_INTS_DTRANS | HFCPCI_INTS_DREC |
> - HFCPCI_INTS_L1STATE | HFCPCI_INTS_TIMER;
> - Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
> -
> - /* Clear already pending ints */
> - val = Read_hfc(hc, HFCPCI_INT_S1);
> -
> - /* set NT/TE mode */
> - hfcpci_setmode(hc);
> -
> - Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
> - Write_hfc(hc, HFCPCI_SCTRL_R, hc->hw.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
> - */
> - if (test_bit(HFC_CFG_PCM, &hc->cfg)) {
> - /* set data flow directions: connect B1,B2: HFC to/from PCM */
> - hc->hw.conn = 0x09;
> - } else {
> - hc->hw.conn = 0x36; /* set data flow directions */
> - if (test_bit(HFC_CFG_SW_DD_DU, &hc->cfg)) {
> - Write_hfc(hc, HFCPCI_B1_SSL, 0xC0);
> - Write_hfc(hc, HFCPCI_B2_SSL, 0xC1);
> - Write_hfc(hc, HFCPCI_B1_RSL, 0xC0);
> - Write_hfc(hc, HFCPCI_B2_RSL, 0xC1);
> - } else {
> - Write_hfc(hc, HFCPCI_B1_SSL, 0x80);
> - Write_hfc(hc, HFCPCI_B2_SSL, 0x81);
> - Write_hfc(hc, HFCPCI_B1_RSL, 0x80);
> - Write_hfc(hc, HFCPCI_B2_RSL, 0x81);
> - }
> - }
> - Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn);
> - val = Read_hfc(hc, HFCPCI_INT_S2);
> -}
> -
> -/*
> - * Timer function called when kernel timer expires
> - */
> -static void
> -hfcpci_Timer(struct timer_list *t)
> -{
> - struct hfc_pci *hc = timer_container_of(hc, t, hw.timer);
> - hc->hw.timer.expires = jiffies + 75;
> - /* WD RESET */
> -/*
> - * WriteReg(hc, HFCD_DATA, HFCD_CTMT, hc->hw.ctmt | 0x80);
> - * add_timer(&hc->hw.timer);
> - */
> -}
> -
> -
> -/*
> - * select a b-channel entry matching and active
> - */
> -static struct bchannel *
> -Sel_BCS(struct hfc_pci *hc, int channel)
> -{
> - if (test_bit(FLG_ACTIVE, &hc->bch[0].Flags) &&
> - (hc->bch[0].nr & channel))
> - return &hc->bch[0];
> - else if (test_bit(FLG_ACTIVE, &hc->bch[1].Flags) &&
> - (hc->bch[1].nr & channel))
> - return &hc->bch[1];
> - else
> - return NULL;
> -}
> -
> -/*
> - * clear the desired B-channel rx fifo
> - */
> -static void
> -hfcpci_clear_fifo_rx(struct hfc_pci *hc, int fifo)
> -{
> - u_char fifo_state;
> - struct bzfifo *bzr;
> -
> - if (fifo) {
> - bzr = &((union fifo_area *)(hc->hw.fifos))->b_chans.rxbz_b2;
> - fifo_state = hc->hw.fifo_en & HFCPCI_FIFOEN_B2RX;
> - } else {
> - bzr = &((union fifo_area *)(hc->hw.fifos))->b_chans.rxbz_b1;
> - fifo_state = hc->hw.fifo_en & HFCPCI_FIFOEN_B1RX;
> - }
> - if (fifo_state)
> - hc->hw.fifo_en ^= fifo_state;
> - Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en);
> - hc->hw.last_bfifo_cnt[fifo] = 0;
> - bzr->f1 = MAX_B_FRAMES;
> - bzr->f2 = bzr->f1; /* init F pointers to remain constant */
> - bzr->za[MAX_B_FRAMES].z1 = cpu_to_le16(B_FIFO_SIZE + B_SUB_VAL - 1);
> - bzr->za[MAX_B_FRAMES].z2 = cpu_to_le16(
> - le16_to_cpu(bzr->za[MAX_B_FRAMES].z1));
> - if (fifo_state)
> - hc->hw.fifo_en |= fifo_state;
> - Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en);
> -}
> -
> -/*
> - * clear the desired B-channel tx fifo
> - */
> -static void hfcpci_clear_fifo_tx(struct hfc_pci *hc, int fifo)
> -{
> - u_char fifo_state;
> - struct bzfifo *bzt;
> -
> - if (fifo) {
> - bzt = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b2;
> - fifo_state = hc->hw.fifo_en & HFCPCI_FIFOEN_B2TX;
> - } else {
> - bzt = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b1;
> - fifo_state = hc->hw.fifo_en & HFCPCI_FIFOEN_B1TX;
> - }
> - if (fifo_state)
> - hc->hw.fifo_en ^= fifo_state;
> - Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en);
> - if (hc->bch[fifo].debug & DEBUG_HW_BCHANNEL)
> - printk(KERN_DEBUG "hfcpci_clear_fifo_tx%d f1(%x) f2(%x) "
> - "z1(%x) z2(%x) state(%x)\n",
> - fifo, bzt->f1, bzt->f2,
> - le16_to_cpu(bzt->za[MAX_B_FRAMES].z1),
> - le16_to_cpu(bzt->za[MAX_B_FRAMES].z2),
> - fifo_state);
> - bzt->f2 = MAX_B_FRAMES;
> - bzt->f1 = bzt->f2; /* init F pointers to remain constant */
> - bzt->za[MAX_B_FRAMES].z1 = cpu_to_le16(B_FIFO_SIZE + B_SUB_VAL - 1);
> - bzt->za[MAX_B_FRAMES].z2 = cpu_to_le16(B_FIFO_SIZE + B_SUB_VAL - 2);
> - if (fifo_state)
> - hc->hw.fifo_en |= fifo_state;
> - Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en);
> - if (hc->bch[fifo].debug & DEBUG_HW_BCHANNEL)
> - printk(KERN_DEBUG
> - "hfcpci_clear_fifo_tx%d f1(%x) f2(%x) z1(%x) z2(%x)\n",
> - fifo, bzt->f1, bzt->f2,
> - le16_to_cpu(bzt->za[MAX_B_FRAMES].z1),
> - le16_to_cpu(bzt->za[MAX_B_FRAMES].z2));
> -}
> -
> -/*
> - * read a complete B-frame out of the buffer
> - */
> -static void
> -hfcpci_empty_bfifo(struct bchannel *bch, struct bzfifo *bz,
> - u_char *bdata, int count)
> -{
> - u_char *ptr, *ptr1, new_f2;
> - int maxlen, new_z2;
> - struct zt *zp;
> -
> - if ((bch->debug & DEBUG_HW_BCHANNEL) && !(bch->debug & DEBUG_HW_BFIFO))
> - printk(KERN_DEBUG "hfcpci_empty_fifo\n");
> - zp = &bz->za[bz->f2]; /* point to Z-Regs */
> - new_z2 = le16_to_cpu(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 > MAX_DATA_SIZE + 3) || (count < 4) ||
> - (*(bdata + (le16_to_cpu(zp->z1) - B_SUB_VAL)))) {
> - if (bch->debug & DEBUG_HW)
> - printk(KERN_DEBUG "hfcpci_empty_fifo: incoming packet "
> - "invalid length %d or crc\n", count);
> -#ifdef ERROR_STATISTIC
> - bch->err_inv++;
> -#endif
> - bz->za[new_f2].z2 = cpu_to_le16(new_z2);
> - bz->f2 = new_f2; /* next buffer */
> - } else {
> - bch->rx_skb = mI_alloc_skb(count - 3, GFP_ATOMIC);
> - if (!bch->rx_skb) {
> - printk(KERN_WARNING "HFCPCI: receive out of memory\n");
> - return;
> - }
> - count -= 3;
> - ptr = skb_put(bch->rx_skb, count);
> -
> - if (le16_to_cpu(zp->z2) + count <= B_FIFO_SIZE + B_SUB_VAL)
> - maxlen = count; /* complete transfer */
> - else
> - maxlen = B_FIFO_SIZE + B_SUB_VAL -
> - le16_to_cpu(zp->z2); /* maximum */
> -
> - ptr1 = bdata + (le16_to_cpu(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 = cpu_to_le16(new_z2);
> - bz->f2 = new_f2; /* next buffer */
> - recv_Bchannel(bch, MISDN_ID_ANY, false);
> - }
> -}
> -
> -/*
> - * D-channel receive procedure
> - */
> -static int
> -receive_dmsg(struct hfc_pci *hc)
> -{
> - struct dchannel *dch = &hc->dch;
> - int maxlen;
> - int rcnt, total;
> - int count = 5;
> - u_char *ptr, *ptr1;
> - struct dfifo *df;
> - struct zt *zp;
> -
> - df = &((union fifo_area *)(hc->hw.fifos))->d_chan.d_rx;
> - while (((df->f1 & D_FREG_MASK) != (df->f2 & D_FREG_MASK)) && count--) {
> - zp = &df->za[df->f2 & D_FREG_MASK];
> - rcnt = le16_to_cpu(zp->z1) - le16_to_cpu(zp->z2);
> - if (rcnt < 0)
> - rcnt += D_FIFO_SIZE;
> - rcnt++;
> - if (dch->debug & DEBUG_HW_DCHANNEL)
> - printk(KERN_DEBUG
> - "hfcpci recd f1(%d) f2(%d) z1(%x) z2(%x) cnt(%d)\n",
> - df->f1, df->f2,
> - le16_to_cpu(zp->z1),
> - le16_to_cpu(zp->z2),
> - rcnt);
> -
> - if ((rcnt > MAX_DFRAME_LEN + 3) || (rcnt < 4) ||
> - (df->data[le16_to_cpu(zp->z1)])) {
> - if (dch->debug & DEBUG_HW)
> - printk(KERN_DEBUG
> - "empty_fifo hfcpci packet inv. len "
> - "%d or crc %d\n",
> - rcnt,
> - df->data[le16_to_cpu(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 =
> - cpu_to_le16((le16_to_cpu(zp->z2) + rcnt) &
> - (D_FIFO_SIZE - 1));
> - } else {
> - dch->rx_skb = mI_alloc_skb(rcnt - 3, GFP_ATOMIC);
> - if (!dch->rx_skb) {
> - printk(KERN_WARNING
> - "HFC-PCI: D receive out of memory\n");
> - break;
> - }
> - total = rcnt;
> - rcnt -= 3;
> - ptr = skb_put(dch->rx_skb, rcnt);
> -
> - if (le16_to_cpu(zp->z2) + rcnt <= D_FIFO_SIZE)
> - maxlen = rcnt; /* complete transfer */
> - else
> - maxlen = D_FIFO_SIZE - le16_to_cpu(zp->z2);
> - /* maximum */
> -
> - ptr1 = df->data + le16_to_cpu(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 = cpu_to_le16((
> - le16_to_cpu(zp->z2) + total) & (D_FIFO_SIZE - 1));
> - recv_Dchannel(dch);
> - }
> - }
> - return 1;
> -}
> -
> -/*
> - * check for transparent receive data and read max one 'poll' size if avail
> - */
> -static void
> -hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *rxbz,
> - struct bzfifo *txbz, u_char *bdata)
> -{
> - __le16 *z1r, *z2r, *z1t, *z2t;
> - int new_z2, fcnt_rx, fcnt_tx, maxlen;
> - u_char *ptr, *ptr1;
> -
> - z1r = &rxbz->za[MAX_B_FRAMES].z1; /* pointer to z reg */
> - z2r = z1r + 1;
> - z1t = &txbz->za[MAX_B_FRAMES].z1;
> - z2t = z1t + 1;
> -
> - fcnt_rx = le16_to_cpu(*z1r) - le16_to_cpu(*z2r);
> - if (!fcnt_rx)
> - return; /* no data avail */
> -
> - if (fcnt_rx <= 0)
> - fcnt_rx += B_FIFO_SIZE; /* bytes actually buffered */
> - new_z2 = le16_to_cpu(*z2r) + fcnt_rx; /* new position in fifo */
> - if (new_z2 >= (B_FIFO_SIZE + B_SUB_VAL))
> - new_z2 -= B_FIFO_SIZE; /* buffer wrap */
> -
> - fcnt_tx = le16_to_cpu(*z2t) - le16_to_cpu(*z1t);
> - if (fcnt_tx <= 0)
> - fcnt_tx += B_FIFO_SIZE;
> - /* fcnt_tx contains available bytes in tx-fifo */
> - fcnt_tx = B_FIFO_SIZE - fcnt_tx;
> - /* remaining bytes to send (bytes in tx-fifo) */
> -
> - if (test_bit(FLG_RX_OFF, &bch->Flags)) {
> - bch->dropcnt += fcnt_rx;
> - *z2r = cpu_to_le16(new_z2);
> - return;
> - }
> - maxlen = bchannel_get_rxbuf(bch, fcnt_rx);
> - if (maxlen < 0) {
> - pr_warn("B%d: No bufferspace for %d bytes\n", bch->nr, fcnt_rx);
> - } else {
> - ptr = skb_put(bch->rx_skb, fcnt_rx);
> - if (le16_to_cpu(*z2r) + fcnt_rx <= B_FIFO_SIZE + B_SUB_VAL)
> - maxlen = fcnt_rx; /* complete transfer */
> - else
> - maxlen = B_FIFO_SIZE + B_SUB_VAL - le16_to_cpu(*z2r);
> - /* maximum */
> -
> - ptr1 = bdata + (le16_to_cpu(*z2r) - B_SUB_VAL);
> - /* start of data */
> - memcpy(ptr, ptr1, maxlen); /* copy data */
> - fcnt_rx -= maxlen;
> -
> - if (fcnt_rx) { /* rest remaining */
> - ptr += maxlen;
> - ptr1 = bdata; /* start of buffer */
> - memcpy(ptr, ptr1, fcnt_rx); /* rest */
> - }
> - recv_Bchannel(bch, fcnt_tx, false); /* bch, id, !force */
> - }
> - *z2r = cpu_to_le16(new_z2); /* new position */
> -}
> -
> -/*
> - * B-channel main receive routine
> - */
> -static void
> -main_rec_hfcpci(struct bchannel *bch)
> -{
> - struct hfc_pci *hc = bch->hw;
> - int rcnt, real_fifo;
> - int receive = 0, count = 5;
> - struct bzfifo *txbz, *rxbz;
> - u_char *bdata;
> - struct zt *zp;
> -
> - if ((bch->nr & 2) && (!hc->hw.bswapped)) {
> - rxbz = &((union fifo_area *)(hc->hw.fifos))->b_chans.rxbz_b2;
> - txbz = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b2;
> - bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.rxdat_b2;
> - real_fifo = 1;
> - } else {
> - rxbz = &((union fifo_area *)(hc->hw.fifos))->b_chans.rxbz_b1;
> - txbz = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b1;
> - bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.rxdat_b1;
> - real_fifo = 0;
> - }
> -Begin:
> - count--;
> - if (rxbz->f1 != rxbz->f2) {
> - if (bch->debug & DEBUG_HW_BCHANNEL)
> - printk(KERN_DEBUG "hfcpci rec ch(%x) f1(%d) f2(%d)\n",
> - bch->nr, rxbz->f1, rxbz->f2);
> - zp = &rxbz->za[rxbz->f2];
> -
> - rcnt = le16_to_cpu(zp->z1) - le16_to_cpu(zp->z2);
> - if (rcnt < 0)
> - rcnt += B_FIFO_SIZE;
> - rcnt++;
> - if (bch->debug & DEBUG_HW_BCHANNEL)
> - printk(KERN_DEBUG
> - "hfcpci rec ch(%x) z1(%x) z2(%x) cnt(%d)\n",
> - bch->nr, le16_to_cpu(zp->z1),
> - le16_to_cpu(zp->z2), rcnt);
> - hfcpci_empty_bfifo(bch, rxbz, bdata, rcnt);
> - rcnt = rxbz->f1 - rxbz->f2;
> - if (rcnt < 0)
> - rcnt += MAX_B_FRAMES + 1;
> - if (hc->hw.last_bfifo_cnt[real_fifo] > rcnt + 1) {
> - rcnt = 0;
> - hfcpci_clear_fifo_rx(hc, real_fifo);
> - }
> - hc->hw.last_bfifo_cnt[real_fifo] = rcnt;
> - if (rcnt > 1)
> - receive = 1;
> - else
> - receive = 0;
> - } else if (test_bit(FLG_TRANSPARENT, &bch->Flags)) {
> - hfcpci_empty_fifo_trans(bch, rxbz, txbz, bdata);
> - return;
> - } else
> - receive = 0;
> - if (count && receive)
> - goto Begin;
> -
> -}
> -
> -/*
> - * D-channel send routine
> - */
> -static void
> -hfcpci_fill_dfifo(struct hfc_pci *hc)
> -{
> - struct dchannel *dch = &hc->dch;
> - int fcnt;
> - int count, new_z1, maxlen;
> - struct dfifo *df;
> - u_char *src, *dst, new_f1;
> -
> - if ((dch->debug & DEBUG_HW_DCHANNEL) && !(dch->debug & DEBUG_HW_DFIFO))
> - printk(KERN_DEBUG "%s\n", __func__);
> -
> - if (!dch->tx_skb)
> - return;
> - count = dch->tx_skb->len - dch->tx_idx;
> - if (count <= 0)
> - return;
> - df = &((union fifo_area *) (hc->hw.fifos))->d_chan.d_tx;
> -
> - if (dch->debug & DEBUG_HW_DFIFO)
> - printk(KERN_DEBUG "%s:f1(%d) f2(%d) z1(f1)(%x)\n", __func__,
> - df->f1, df->f2,
> - le16_to_cpu(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 (dch->debug & DEBUG_HW_DCHANNEL)
> - printk(KERN_DEBUG
> - "hfcpci_fill_Dfifo more as 14 frames\n");
> -#ifdef ERROR_STATISTIC
> - cs->err_tx++;
> -#endif
> - return;
> - }
> - /* now determine free bytes in FIFO buffer */
> - maxlen = le16_to_cpu(df->za[df->f2 & D_FREG_MASK].z2) -
> - le16_to_cpu(df->za[df->f1 & D_FREG_MASK].z1) - 1;
> - if (maxlen <= 0)
> - maxlen += D_FIFO_SIZE; /* count now contains available bytes */
> -
> - if (dch->debug & DEBUG_HW_DCHANNEL)
> - printk(KERN_DEBUG "hfcpci_fill_Dfifo count(%d/%d)\n",
> - count, maxlen);
> - if (count > maxlen) {
> - if (dch->debug & DEBUG_HW_DCHANNEL)
> - printk(KERN_DEBUG "hfcpci_fill_Dfifo no fifo mem\n");
> - return;
> - }
> - new_z1 = (le16_to_cpu(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 = dch->tx_skb->data + dch->tx_idx; /* source pointer */
> - dst = df->data + le16_to_cpu(df->za[df->f1 & D_FREG_MASK].z1);
> - maxlen = D_FIFO_SIZE - le16_to_cpu(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 = cpu_to_le16(new_z1);
> - /* for next buffer */
> - df->za[df->f1 & D_FREG_MASK].z1 = cpu_to_le16(new_z1);
> - /* new pos actual buffer */
> - df->f1 = new_f1; /* next frame */
> - dch->tx_idx = dch->tx_skb->len;
> -}
> -
> -/*
> - * B-channel send routine
> - */
> -static void
> -hfcpci_fill_fifo(struct bchannel *bch)
> -{
> - struct hfc_pci *hc = bch->hw;
> - int maxlen, fcnt;
> - int count, new_z1;
> - struct bzfifo *bz;
> - u_char *bdata;
> - u_char new_f1, *src, *dst;
> - __le16 *z1t, *z2t;
> -
> - if ((bch->debug & DEBUG_HW_BCHANNEL) && !(bch->debug & DEBUG_HW_BFIFO))
> - printk(KERN_DEBUG "%s\n", __func__);
> - if ((!bch->tx_skb) || bch->tx_skb->len == 0) {
> - if (!test_bit(FLG_FILLEMPTY, &bch->Flags) &&
> - !test_bit(FLG_TRANSPARENT, &bch->Flags))
> - return;
> - count = HFCPCI_FILLEMPTY;
> - } else {
> - count = bch->tx_skb->len - bch->tx_idx;
> - }
> - if ((bch->nr & 2) && (!hc->hw.bswapped)) {
> - bz = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b2;
> - bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.txdat_b2;
> - } else {
> - bz = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b1;
> - bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.txdat_b1;
> - }
> -
> - if (test_bit(FLG_TRANSPARENT, &bch->Flags)) {
> - z1t = &bz->za[MAX_B_FRAMES].z1;
> - z2t = z1t + 1;
> - if (bch->debug & DEBUG_HW_BCHANNEL)
> - printk(KERN_DEBUG "hfcpci_fill_fifo_trans ch(%x) "
> - "cnt(%d) z1(%x) z2(%x)\n", bch->nr, count,
> - le16_to_cpu(*z1t), le16_to_cpu(*z2t));
> - fcnt = le16_to_cpu(*z2t) - le16_to_cpu(*z1t);
> - if (fcnt <= 0)
> - fcnt += B_FIFO_SIZE;
> - if (test_bit(FLG_FILLEMPTY, &bch->Flags)) {
> - /* fcnt contains available bytes in fifo */
> - if (count > fcnt)
> - count = fcnt;
> - new_z1 = le16_to_cpu(*z1t) + count;
> - /* new buffer Position */
> - if (new_z1 >= (B_FIFO_SIZE + B_SUB_VAL))
> - new_z1 -= B_FIFO_SIZE; /* buffer wrap */
> - dst = bdata + (le16_to_cpu(*z1t) - B_SUB_VAL);
> - maxlen = (B_FIFO_SIZE + B_SUB_VAL) - le16_to_cpu(*z1t);
> - /* end of fifo */
> - if (bch->debug & DEBUG_HW_BFIFO)
> - printk(KERN_DEBUG "hfcpci_FFt fillempty "
> - "fcnt(%d) maxl(%d) nz1(%x) dst(%p)\n",
> - fcnt, maxlen, new_z1, dst);
> - if (maxlen > count)
> - maxlen = count; /* limit size */
> - memset(dst, bch->fill[0], maxlen); /* first copy */
> - count -= maxlen; /* remaining bytes */
> - if (count) {
> - dst = bdata; /* start of buffer */
> - memset(dst, bch->fill[0], count);
> - }
> - *z1t = cpu_to_le16(new_z1); /* now send data */
> - return;
> - }
> - /* fcnt contains available bytes in fifo */
> - fcnt = B_FIFO_SIZE - fcnt;
> - /* remaining bytes to send (bytes in fifo) */
> -
> - next_t_frame:
> - count = bch->tx_skb->len - bch->tx_idx;
> - /* maximum fill shall be poll*2 */
> - if (count > (poll << 1) - fcnt)
> - count = (poll << 1) - fcnt;
> - if (count <= 0)
> - return;
> - /* data is suitable for fifo */
> - new_z1 = le16_to_cpu(*z1t) + count;
> - /* new buffer Position */
> - if (new_z1 >= (B_FIFO_SIZE + B_SUB_VAL))
> - new_z1 -= B_FIFO_SIZE; /* buffer wrap */
> - src = bch->tx_skb->data + bch->tx_idx;
> - /* source pointer */
> - dst = bdata + (le16_to_cpu(*z1t) - B_SUB_VAL);
> - maxlen = (B_FIFO_SIZE + B_SUB_VAL) - le16_to_cpu(*z1t);
> - /* end of fifo */
> - if (bch->debug & DEBUG_HW_BFIFO)
> - printk(KERN_DEBUG "hfcpci_FFt fcnt(%d) "
> - "maxl(%d) nz1(%x) dst(%p)\n",
> - fcnt, maxlen, new_z1, dst);
> - fcnt += count;
> - bch->tx_idx += count;
> - 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);
> - }
> - *z1t = cpu_to_le16(new_z1); /* now send data */
> - if (bch->tx_idx < bch->tx_skb->len)
> - return;
> - dev_kfree_skb_any(bch->tx_skb);
> - if (get_next_bframe(bch))
> - goto next_t_frame;
> - return;
> - }
> - if (bch->debug & DEBUG_HW_BCHANNEL)
> - printk(KERN_DEBUG
> - "%s: ch(%x) f1(%d) f2(%d) z1(f1)(%x)\n",
> - __func__, bch->nr, 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 (bch->debug & DEBUG_HW_BCHANNEL)
> - printk(KERN_DEBUG
> - "hfcpci_fill_Bfifo more as 14 frames\n");
> - return;
> - }
> - /* now determine free bytes in FIFO buffer */
> - maxlen = le16_to_cpu(bz->za[bz->f2].z2) -
> - le16_to_cpu(bz->za[bz->f1].z1) - 1;
> - if (maxlen <= 0)
> - maxlen += B_FIFO_SIZE; /* count now contains available bytes */
> -
> - if (bch->debug & DEBUG_HW_BCHANNEL)
> - printk(KERN_DEBUG "hfcpci_fill_fifo ch(%x) count(%d/%d)\n",
> - bch->nr, count, maxlen);
> -
> - if (maxlen < count) {
> - if (bch->debug & DEBUG_HW_BCHANNEL)
> - printk(KERN_DEBUG "hfcpci_fill_fifo no fifo mem\n");
> - return;
> - }
> - new_z1 = le16_to_cpu(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 = bch->tx_skb->data + bch->tx_idx; /* source pointer */
> - dst = bdata + (le16_to_cpu(bz->za[bz->f1].z1) - B_SUB_VAL);
> - maxlen = (B_FIFO_SIZE + B_SUB_VAL) - le16_to_cpu(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);
> - }
> - bz->za[new_f1].z1 = cpu_to_le16(new_z1); /* for next buffer */
> - bz->f1 = new_f1; /* next frame */
> - dev_kfree_skb_any(bch->tx_skb);
> - get_next_bframe(bch);
> -}
> -
> -
> -
> -/*
> - * handle L1 state changes TE
> - */
> -
> -static void
> -ph_state_te(struct dchannel *dch)
> -{
> - if (dch->debug)
> - printk(KERN_DEBUG "%s: TE newstate %x\n",
> - __func__, dch->state);
> - switch (dch->state) {
> - case 0:
> - l1_event(dch->l1, HW_RESET_IND);
> - break;
> - case 3:
> - l1_event(dch->l1, HW_DEACT_IND);
> - break;
> - case 5:
> - case 8:
> - l1_event(dch->l1, ANYSIGNAL);
> - break;
> - case 6:
> - l1_event(dch->l1, INFO2);
> - break;
> - case 7:
> - l1_event(dch->l1, INFO4_P8);
> - break;
> - }
> -}
> -
> -/*
> - * handle L1 state changes NT
> - */
> -
> -static void
> -handle_nt_timer3(struct dchannel *dch) {
> - struct hfc_pci *hc = dch->hw;
> -
> - test_and_clear_bit(FLG_HFC_TIMER_T3, &dch->Flags);
> - hc->hw.int_m1 &= ~HFCPCI_INTS_TIMER;
> - Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
> - hc->hw.nt_timer = 0;
> - test_and_set_bit(FLG_ACTIVE, &dch->Flags);
> - if (test_bit(HFC_CFG_MASTER, &hc->cfg))
> - hc->hw.mst_m |= HFCPCI_MASTER;
> - Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
> - _queue_data(&dch->dev.D, PH_ACTIVATE_IND,
> - MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
> -}
> -
> -static void
> -ph_state_nt(struct dchannel *dch)
> -{
> - struct hfc_pci *hc = dch->hw;
> -
> - if (dch->debug)
> - printk(KERN_DEBUG "%s: NT newstate %x\n",
> - __func__, dch->state);
> - switch (dch->state) {
> - case 2:
> - if (hc->hw.nt_timer < 0) {
> - hc->hw.nt_timer = 0;
> - test_and_clear_bit(FLG_HFC_TIMER_T3, &dch->Flags);
> - test_and_clear_bit(FLG_HFC_TIMER_T1, &dch->Flags);
> - hc->hw.int_m1 &= ~HFCPCI_INTS_TIMER;
> - Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
> - /* Clear already pending ints */
> - (void) Read_hfc(hc, HFCPCI_INT_S1);
> - Write_hfc(hc, HFCPCI_STATES, 4 | HFCPCI_LOAD_STATE);
> - udelay(10);
> - Write_hfc(hc, HFCPCI_STATES, 4);
> - dch->state = 4;
> - } else if (hc->hw.nt_timer == 0) {
> - hc->hw.int_m1 |= HFCPCI_INTS_TIMER;
> - Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
> - hc->hw.nt_timer = NT_T1_COUNT;
> - hc->hw.ctmt &= ~HFCPCI_AUTO_TIMER;
> - hc->hw.ctmt |= HFCPCI_TIM3_125;
> - Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt |
> - HFCPCI_CLTIMER);
> - test_and_clear_bit(FLG_HFC_TIMER_T3, &dch->Flags);
> - test_and_set_bit(FLG_HFC_TIMER_T1, &dch->Flags);
> - /* allow G2 -> G3 transition */
> - Write_hfc(hc, HFCPCI_STATES, 2 | HFCPCI_NT_G2_G3);
> - } else {
> - Write_hfc(hc, HFCPCI_STATES, 2 | HFCPCI_NT_G2_G3);
> - }
> - break;
> - case 1:
> - hc->hw.nt_timer = 0;
> - test_and_clear_bit(FLG_HFC_TIMER_T3, &dch->Flags);
> - test_and_clear_bit(FLG_HFC_TIMER_T1, &dch->Flags);
> - hc->hw.int_m1 &= ~HFCPCI_INTS_TIMER;
> - Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
> - test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
> - hc->hw.mst_m &= ~HFCPCI_MASTER;
> - Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
> - test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
> - _queue_data(&dch->dev.D, PH_DEACTIVATE_IND,
> - MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
> - break;
> - case 4:
> - hc->hw.nt_timer = 0;
> - test_and_clear_bit(FLG_HFC_TIMER_T3, &dch->Flags);
> - test_and_clear_bit(FLG_HFC_TIMER_T1, &dch->Flags);
> - hc->hw.int_m1 &= ~HFCPCI_INTS_TIMER;
> - Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
> - break;
> - case 3:
> - if (!test_and_set_bit(FLG_HFC_TIMER_T3, &dch->Flags)) {
> - if (!test_and_clear_bit(FLG_L2_ACTIVATED,
> - &dch->Flags)) {
> - handle_nt_timer3(dch);
> - break;
> - }
> - test_and_clear_bit(FLG_HFC_TIMER_T1, &dch->Flags);
> - hc->hw.int_m1 |= HFCPCI_INTS_TIMER;
> - Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
> - hc->hw.nt_timer = NT_T3_COUNT;
> - hc->hw.ctmt &= ~HFCPCI_AUTO_TIMER;
> - hc->hw.ctmt |= HFCPCI_TIM3_125;
> - Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt |
> - HFCPCI_CLTIMER);
> - }
> - break;
> - }
> -}
> -
> -static void
> -ph_state(struct dchannel *dch)
> -{
> - struct hfc_pci *hc = dch->hw;
> -
> - if (hc->hw.protocol == ISDN_P_NT_S0) {
> - if (test_bit(FLG_HFC_TIMER_T3, &dch->Flags) &&
> - hc->hw.nt_timer < 0)
> - handle_nt_timer3(dch);
> - else
> - ph_state_nt(dch);
> - } else
> - ph_state_te(dch);
> -}
> -
> -/*
> - * Layer 1 callback function
> - */
> -static int
> -hfc_l1callback(struct dchannel *dch, u_int cmd)
> -{
> - struct hfc_pci *hc = dch->hw;
> -
> - switch (cmd) {
> - case INFO3_P8:
> - case INFO3_P10:
> - if (test_bit(HFC_CFG_MASTER, &hc->cfg))
> - hc->hw.mst_m |= HFCPCI_MASTER;
> - Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
> - break;
> - case HW_RESET_REQ:
> - Write_hfc(hc, HFCPCI_STATES, HFCPCI_LOAD_STATE | 3);
> - /* HFC ST 3 */
> - udelay(6);
> - Write_hfc(hc, HFCPCI_STATES, 3); /* HFC ST 2 */
> - if (test_bit(HFC_CFG_MASTER, &hc->cfg))
> - hc->hw.mst_m |= HFCPCI_MASTER;
> - Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
> - Write_hfc(hc, HFCPCI_STATES, HFCPCI_ACTIVATE |
> - HFCPCI_DO_ACTION);
> - l1_event(dch->l1, HW_POWERUP_IND);
> - break;
> - case HW_DEACT_REQ:
> - hc->hw.mst_m &= ~HFCPCI_MASTER;
> - Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
> - skb_queue_purge(&dch->squeue);
> - if (dch->tx_skb) {
> - dev_kfree_skb(dch->tx_skb);
> - dch->tx_skb = NULL;
> - }
> - dch->tx_idx = 0;
> - if (dch->rx_skb) {
> - dev_kfree_skb(dch->rx_skb);
> - dch->rx_skb = NULL;
> - }
> - test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
> - if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
> - timer_delete(&dch->timer);
> - break;
> - case HW_POWERUP_REQ:
> - Write_hfc(hc, HFCPCI_STATES, HFCPCI_DO_ACTION);
> - break;
> - case PH_ACTIVATE_IND:
> - test_and_set_bit(FLG_ACTIVE, &dch->Flags);
> - _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
> - GFP_ATOMIC);
> - break;
> - case PH_DEACTIVATE_IND:
> - test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
> - _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
> - GFP_ATOMIC);
> - break;
> - default:
> - if (dch->debug & DEBUG_HW)
> - printk(KERN_DEBUG "%s: unknown command %x\n",
> - __func__, cmd);
> - return -1;
> - }
> - return 0;
> -}
> -
> -/*
> - * Interrupt handler
> - */
> -static inline void
> -tx_birq(struct bchannel *bch)
> -{
> - if (bch->tx_skb && bch->tx_idx < bch->tx_skb->len)
> - hfcpci_fill_fifo(bch);
> - else {
> - dev_kfree_skb_any(bch->tx_skb);
> - if (get_next_bframe(bch))
> - hfcpci_fill_fifo(bch);
> - }
> -}
> -
> -static inline void
> -tx_dirq(struct dchannel *dch)
> -{
> - if (dch->tx_skb && dch->tx_idx < dch->tx_skb->len)
> - hfcpci_fill_dfifo(dch->hw);
> - else {
> - dev_kfree_skb(dch->tx_skb);
> - if (get_next_dframe(dch))
> - hfcpci_fill_dfifo(dch->hw);
> - }
> -}
> -
> -static irqreturn_t
> -hfcpci_int(int intno, void *dev_id)
> -{
> - struct hfc_pci *hc = dev_id;
> - u_char exval;
> - struct bchannel *bch;
> - u_char val, stat;
> -
> - spin_lock(&hc->lock);
> - if (!(hc->hw.int_m2 & 0x08)) {
> - spin_unlock(&hc->lock);
> - return IRQ_NONE; /* not initialised */
> - }
> - stat = Read_hfc(hc, HFCPCI_STATUS);
> - if (HFCPCI_ANYINT & stat) {
> - val = Read_hfc(hc, HFCPCI_INT_S1);
> - if (hc->dch.debug & DEBUG_HW_DCHANNEL)
> - printk(KERN_DEBUG
> - "HFC-PCI: stat(%02x) s1(%02x)\n", stat, val);
> - } else {
> - /* shared */
> - spin_unlock(&hc->lock);
> - return IRQ_NONE;
> - }
> - hc->irqcnt++;
> -
> - if (hc->dch.debug & DEBUG_HW_DCHANNEL)
> - printk(KERN_DEBUG "HFC-PCI irq %x\n", val);
> - val &= hc->hw.int_m1;
> - if (val & 0x40) { /* state machine irq */
> - exval = Read_hfc(hc, HFCPCI_STATES) & 0xf;
> - if (hc->dch.debug & DEBUG_HW_DCHANNEL)
> - printk(KERN_DEBUG "ph_state chg %d->%d\n",
> - hc->dch.state, exval);
> - hc->dch.state = exval;
> - schedule_event(&hc->dch, FLG_PHCHANGE);
> - val &= ~0x40;
> - }
> - if (val & 0x80) { /* timer irq */
> - if (hc->hw.protocol == ISDN_P_NT_S0) {
> - if ((--hc->hw.nt_timer) < 0)
> - schedule_event(&hc->dch, FLG_PHCHANGE);
> - }
> - val &= ~0x80;
> - Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt | HFCPCI_CLTIMER);
> - }
> - if (val & 0x08) { /* B1 rx */
> - bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1);
> - if (bch)
> - main_rec_hfcpci(bch);
> - else if (hc->dch.debug)
> - printk(KERN_DEBUG "hfcpci spurious 0x08 IRQ\n");
> - }
> - if (val & 0x10) { /* B2 rx */
> - bch = Sel_BCS(hc, 2);
> - if (bch)
> - main_rec_hfcpci(bch);
> - else if (hc->dch.debug)
> - printk(KERN_DEBUG "hfcpci spurious 0x10 IRQ\n");
> - }
> - if (val & 0x01) { /* B1 tx */
> - bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1);
> - if (bch)
> - tx_birq(bch);
> - else if (hc->dch.debug)
> - printk(KERN_DEBUG "hfcpci spurious 0x01 IRQ\n");
> - }
> - if (val & 0x02) { /* B2 tx */
> - bch = Sel_BCS(hc, 2);
> - if (bch)
> - tx_birq(bch);
> - else if (hc->dch.debug)
> - printk(KERN_DEBUG "hfcpci spurious 0x02 IRQ\n");
> - }
> - if (val & 0x20) /* D rx */
> - receive_dmsg(hc);
> - if (val & 0x04) { /* D tx */
> - if (test_and_clear_bit(FLG_BUSY_TIMER, &hc->dch.Flags))
> - timer_delete(&hc->dch.timer);
> - tx_dirq(&hc->dch);
> - }
> - spin_unlock(&hc->lock);
> - return IRQ_HANDLED;
> -}
> -
> -/*
> - * timer callback for D-chan busy resolution. Currently no function
> - */
> -static void
> -hfcpci_dbusy_timer(struct timer_list *t)
> -{
> -}
> -
> -/*
> - * activate/deactivate hardware for selected channels and mode
> - */
> -static int
> -mode_hfcpci(struct bchannel *bch, int bc, int protocol)
> -{
> - struct hfc_pci *hc = bch->hw;
> - int fifo2;
> - u_char rx_slot = 0, tx_slot = 0, pcm_mode;
> -
> - if (bch->debug & DEBUG_HW_BCHANNEL)
> - printk(KERN_DEBUG
> - "HFCPCI bchannel protocol %x-->%x ch %x-->%x\n",
> - bch->state, protocol, bch->nr, bc);
> -
> - fifo2 = bc;
> - pcm_mode = (bc >> 24) & 0xff;
> - if (pcm_mode) { /* PCM SLOT USE */
> - if (!test_bit(HFC_CFG_PCM, &hc->cfg))
> - printk(KERN_WARNING
> - "%s: pcm channel id without HFC_CFG_PCM\n",
> - __func__);
> - rx_slot = (bc >> 8) & 0xff;
> - tx_slot = (bc >> 16) & 0xff;
> - bc = bc & 0xff;
> - } else if (test_bit(HFC_CFG_PCM, &hc->cfg) && (protocol > ISDN_P_NONE))
> - printk(KERN_WARNING "%s: no pcm channel id but HFC_CFG_PCM\n",
> - __func__);
> - if (hc->chanlimit > 1) {
> - hc->hw.bswapped = 0; /* B1 and B2 normal mode */
> - hc->hw.sctrl_e &= ~0x80;
> - } else {
> - if (bc & 2) {
> - if (protocol != ISDN_P_NONE) {
> - hc->hw.bswapped = 1; /* B1 and B2 exchanged */
> - hc->hw.sctrl_e |= 0x80;
> - } else {
> - hc->hw.bswapped = 0; /* B1 and B2 normal mode */
> - hc->hw.sctrl_e &= ~0x80;
> - }
> - fifo2 = 1;
> - } else {
> - hc->hw.bswapped = 0; /* B1 and B2 normal mode */
> - hc->hw.sctrl_e &= ~0x80;
> - }
> - }
> - switch (protocol) {
> - case (-1): /* used for init */
> - bch->state = -1;
> - bch->nr = bc;
> - fallthrough;
> - case (ISDN_P_NONE):
> - if (bch->state == ISDN_P_NONE)
> - return 0;
> - if (bc & 2) {
> - hc->hw.sctrl &= ~SCTRL_B2_ENA;
> - hc->hw.sctrl_r &= ~SCTRL_B2_ENA;
> - } else {
> - hc->hw.sctrl &= ~SCTRL_B1_ENA;
> - hc->hw.sctrl_r &= ~SCTRL_B1_ENA;
> - }
> - if (fifo2 & 2) {
> - hc->hw.fifo_en &= ~HFCPCI_FIFOEN_B2;
> - hc->hw.int_m1 &= ~(HFCPCI_INTS_B2TRANS |
> - HFCPCI_INTS_B2REC);
> - } else {
> - hc->hw.fifo_en &= ~HFCPCI_FIFOEN_B1;
> - hc->hw.int_m1 &= ~(HFCPCI_INTS_B1TRANS |
> - HFCPCI_INTS_B1REC);
> - }
> -#ifdef REVERSE_BITORDER
> - if (bch->nr & 2)
> - hc->hw.cirm &= 0x7f;
> - else
> - hc->hw.cirm &= 0xbf;
> -#endif
> - bch->state = ISDN_P_NONE;
> - bch->nr = bc;
> - test_and_clear_bit(FLG_HDLC, &bch->Flags);
> - test_and_clear_bit(FLG_TRANSPARENT, &bch->Flags);
> - break;
> - case (ISDN_P_B_RAW):
> - bch->state = protocol;
> - bch->nr = bc;
> - hfcpci_clear_fifo_rx(hc, (fifo2 & 2) ? 1 : 0);
> - hfcpci_clear_fifo_tx(hc, (fifo2 & 2) ? 1 : 0);
> - if (bc & 2) {
> - hc->hw.sctrl |= SCTRL_B2_ENA;
> - hc->hw.sctrl_r |= SCTRL_B2_ENA;
> -#ifdef REVERSE_BITORDER
> - hc->hw.cirm |= 0x80;
> -#endif
> - } else {
> - hc->hw.sctrl |= SCTRL_B1_ENA;
> - hc->hw.sctrl_r |= SCTRL_B1_ENA;
> -#ifdef REVERSE_BITORDER
> - hc->hw.cirm |= 0x40;
> -#endif
> - }
> - if (fifo2 & 2) {
> - hc->hw.fifo_en |= HFCPCI_FIFOEN_B2;
> - if (!tics)
> - hc->hw.int_m1 |= (HFCPCI_INTS_B2TRANS |
> - HFCPCI_INTS_B2REC);
> - hc->hw.ctmt |= 2;
> - hc->hw.conn &= ~0x18;
> - } else {
> - hc->hw.fifo_en |= HFCPCI_FIFOEN_B1;
> - if (!tics)
> - hc->hw.int_m1 |= (HFCPCI_INTS_B1TRANS |
> - HFCPCI_INTS_B1REC);
> - hc->hw.ctmt |= 1;
> - hc->hw.conn &= ~0x03;
> - }
> - test_and_set_bit(FLG_TRANSPARENT, &bch->Flags);
> - break;
> - case (ISDN_P_B_HDLC):
> - bch->state = protocol;
> - bch->nr = bc;
> - hfcpci_clear_fifo_rx(hc, (fifo2 & 2) ? 1 : 0);
> - hfcpci_clear_fifo_tx(hc, (fifo2 & 2) ? 1 : 0);
> - if (bc & 2) {
> - hc->hw.sctrl |= SCTRL_B2_ENA;
> - hc->hw.sctrl_r |= SCTRL_B2_ENA;
> - } else {
> - hc->hw.sctrl |= SCTRL_B1_ENA;
> - hc->hw.sctrl_r |= SCTRL_B1_ENA;
> - }
> - if (fifo2 & 2) {
> - hc->hw.last_bfifo_cnt[1] = 0;
> - hc->hw.fifo_en |= HFCPCI_FIFOEN_B2;
> - hc->hw.int_m1 |= (HFCPCI_INTS_B2TRANS |
> - HFCPCI_INTS_B2REC);
> - hc->hw.ctmt &= ~2;
> - hc->hw.conn &= ~0x18;
> - } else {
> - hc->hw.last_bfifo_cnt[0] = 0;
> - hc->hw.fifo_en |= HFCPCI_FIFOEN_B1;
> - hc->hw.int_m1 |= (HFCPCI_INTS_B1TRANS |
> - HFCPCI_INTS_B1REC);
> - hc->hw.ctmt &= ~1;
> - hc->hw.conn &= ~0x03;
> - }
> - test_and_set_bit(FLG_HDLC, &bch->Flags);
> - break;
> - default:
> - printk(KERN_DEBUG "prot not known %x\n", protocol);
> - return -ENOPROTOOPT;
> - }
> - if (test_bit(HFC_CFG_PCM, &hc->cfg)) {
> - if ((protocol == ISDN_P_NONE) ||
> - (protocol == -1)) { /* init case */
> - rx_slot = 0;
> - tx_slot = 0;
> - } else {
> - if (test_bit(HFC_CFG_SW_DD_DU, &hc->cfg)) {
> - rx_slot |= 0xC0;
> - tx_slot |= 0xC0;
> - } else {
> - rx_slot |= 0x80;
> - tx_slot |= 0x80;
> - }
> - }
> - if (bc & 2) {
> - hc->hw.conn &= 0xc7;
> - hc->hw.conn |= 0x08;
> - printk(KERN_DEBUG "%s: Write_hfc: B2_SSL 0x%x\n",
> - __func__, tx_slot);
> - printk(KERN_DEBUG "%s: Write_hfc: B2_RSL 0x%x\n",
> - __func__, rx_slot);
> - Write_hfc(hc, HFCPCI_B2_SSL, tx_slot);
> - Write_hfc(hc, HFCPCI_B2_RSL, rx_slot);
> - } else {
> - hc->hw.conn &= 0xf8;
> - hc->hw.conn |= 0x01;
> - printk(KERN_DEBUG "%s: Write_hfc: B1_SSL 0x%x\n",
> - __func__, tx_slot);
> - printk(KERN_DEBUG "%s: Write_hfc: B1_RSL 0x%x\n",
> - __func__, rx_slot);
> - Write_hfc(hc, HFCPCI_B1_SSL, tx_slot);
> - Write_hfc(hc, HFCPCI_B1_RSL, rx_slot);
> - }
> - }
> - Write_hfc(hc, HFCPCI_SCTRL_E, hc->hw.sctrl_e);
> - Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
> - Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en);
> - Write_hfc(hc, HFCPCI_SCTRL, hc->hw.sctrl);
> - Write_hfc(hc, HFCPCI_SCTRL_R, hc->hw.sctrl_r);
> - Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt);
> - Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn);
> -#ifdef REVERSE_BITORDER
> - Write_hfc(hc, HFCPCI_CIRM, hc->hw.cirm);
> -#endif
> - return 0;
> -}
> -
> -static int
> -set_hfcpci_rxtest(struct bchannel *bch, int protocol, int chan)
> -{
> - struct hfc_pci *hc = bch->hw;
> -
> - if (bch->debug & DEBUG_HW_BCHANNEL)
> - printk(KERN_DEBUG
> - "HFCPCI bchannel test rx protocol %x-->%x ch %x-->%x\n",
> - bch->state, protocol, bch->nr, chan);
> - if (bch->nr != chan) {
> - printk(KERN_DEBUG
> - "HFCPCI rxtest wrong channel parameter %x/%x\n",
> - bch->nr, chan);
> - return -EINVAL;
> - }
> - switch (protocol) {
> - case (ISDN_P_B_RAW):
> - bch->state = protocol;
> - hfcpci_clear_fifo_rx(hc, (chan & 2) ? 1 : 0);
> - if (chan & 2) {
> - hc->hw.sctrl_r |= SCTRL_B2_ENA;
> - hc->hw.fifo_en |= HFCPCI_FIFOEN_B2RX;
> - if (!tics)
> - hc->hw.int_m1 |= HFCPCI_INTS_B2REC;
> - hc->hw.ctmt |= 2;
> - hc->hw.conn &= ~0x18;
> -#ifdef REVERSE_BITORDER
> - hc->hw.cirm |= 0x80;
> -#endif
> - } else {
> - hc->hw.sctrl_r |= SCTRL_B1_ENA;
> - hc->hw.fifo_en |= HFCPCI_FIFOEN_B1RX;
> - if (!tics)
> - hc->hw.int_m1 |= HFCPCI_INTS_B1REC;
> - hc->hw.ctmt |= 1;
> - hc->hw.conn &= ~0x03;
> -#ifdef REVERSE_BITORDER
> - hc->hw.cirm |= 0x40;
> -#endif
> - }
> - break;
> - case (ISDN_P_B_HDLC):
> - bch->state = protocol;
> - hfcpci_clear_fifo_rx(hc, (chan & 2) ? 1 : 0);
> - if (chan & 2) {
> - hc->hw.sctrl_r |= SCTRL_B2_ENA;
> - hc->hw.last_bfifo_cnt[1] = 0;
> - hc->hw.fifo_en |= HFCPCI_FIFOEN_B2RX;
> - hc->hw.int_m1 |= HFCPCI_INTS_B2REC;
> - hc->hw.ctmt &= ~2;
> - hc->hw.conn &= ~0x18;
> - } else {
> - hc->hw.sctrl_r |= SCTRL_B1_ENA;
> - hc->hw.last_bfifo_cnt[0] = 0;
> - hc->hw.fifo_en |= HFCPCI_FIFOEN_B1RX;
> - hc->hw.int_m1 |= HFCPCI_INTS_B1REC;
> - hc->hw.ctmt &= ~1;
> - hc->hw.conn &= ~0x03;
> - }
> - break;
> - default:
> - printk(KERN_DEBUG "prot not known %x\n", protocol);
> - return -ENOPROTOOPT;
> - }
> - Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
> - Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en);
> - Write_hfc(hc, HFCPCI_SCTRL_R, hc->hw.sctrl_r);
> - Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt);
> - Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn);
> -#ifdef REVERSE_BITORDER
> - Write_hfc(hc, HFCPCI_CIRM, hc->hw.cirm);
> -#endif
> - return 0;
> -}
> -
> -static void
> -deactivate_bchannel(struct bchannel *bch)
> -{
> - struct hfc_pci *hc = bch->hw;
> - u_long flags;
> -
> - spin_lock_irqsave(&hc->lock, flags);
> - mISDN_clear_bchannel(bch);
> - mode_hfcpci(bch, bch->nr, ISDN_P_NONE);
> - spin_unlock_irqrestore(&hc->lock, flags);
> -}
> -
> -/*
> - * Layer 1 B-channel hardware access
> - */
> -static int
> -channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
> -{
> - return mISDN_ctrl_bchannel(bch, cq);
> -}
> -static int
> -hfc_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
> -{
> - struct bchannel *bch = container_of(ch, struct bchannel, ch);
> - struct hfc_pci *hc = bch->hw;
> - int ret = -EINVAL;
> - u_long flags;
> -
> - if (bch->debug & DEBUG_HW)
> - printk(KERN_DEBUG "%s: cmd:%x %p\n", __func__, cmd, arg);
> - switch (cmd) {
> - case HW_TESTRX_RAW:
> - spin_lock_irqsave(&hc->lock, flags);
> - ret = set_hfcpci_rxtest(bch, ISDN_P_B_RAW, (int)(long)arg);
> - spin_unlock_irqrestore(&hc->lock, flags);
> - break;
> - case HW_TESTRX_HDLC:
> - spin_lock_irqsave(&hc->lock, flags);
> - ret = set_hfcpci_rxtest(bch, ISDN_P_B_HDLC, (int)(long)arg);
> - spin_unlock_irqrestore(&hc->lock, flags);
> - break;
> - case HW_TESTRX_OFF:
> - spin_lock_irqsave(&hc->lock, flags);
> - mode_hfcpci(bch, bch->nr, ISDN_P_NONE);
> - spin_unlock_irqrestore(&hc->lock, flags);
> - ret = 0;
> - break;
> - case CLOSE_CHANNEL:
> - test_and_clear_bit(FLG_OPEN, &bch->Flags);
> - deactivate_bchannel(bch);
> - ch->protocol = ISDN_P_NONE;
> - ch->peer = NULL;
> - module_put(THIS_MODULE);
> - ret = 0;
> - break;
> - case CONTROL_CHANNEL:
> - ret = channel_bctrl(bch, arg);
> - break;
> - default:
> - printk(KERN_WARNING "%s: unknown prim(%x)\n",
> - __func__, cmd);
> - }
> - return ret;
> -}
> -
> -/*
> - * Layer2 -> Layer 1 Dchannel data
> - */
> -static int
> -hfcpci_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb)
> -{
> - struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
> - struct dchannel *dch = container_of(dev, struct dchannel, dev);
> - struct hfc_pci *hc = dch->hw;
> - int ret = -EINVAL;
> - struct mISDNhead *hh = mISDN_HEAD_P(skb);
> - unsigned int id;
> - u_long flags;
> -
> - switch (hh->prim) {
> - case PH_DATA_REQ:
> - spin_lock_irqsave(&hc->lock, flags);
> - ret = dchannel_senddata(dch, skb);
> - if (ret > 0) { /* direct TX */
> - id = hh->id; /* skb can be freed */
> - hfcpci_fill_dfifo(dch->hw);
> - ret = 0;
> - spin_unlock_irqrestore(&hc->lock, flags);
> - queue_ch_frame(ch, PH_DATA_CNF, id, NULL);
> - } else
> - spin_unlock_irqrestore(&hc->lock, flags);
> - return ret;
> - case PH_ACTIVATE_REQ:
> - spin_lock_irqsave(&hc->lock, flags);
> - if (hc->hw.protocol == ISDN_P_NT_S0) {
> - ret = 0;
> - if (test_bit(HFC_CFG_MASTER, &hc->cfg))
> - hc->hw.mst_m |= HFCPCI_MASTER;
> - Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
> - if (test_bit(FLG_ACTIVE, &dch->Flags)) {
> - spin_unlock_irqrestore(&hc->lock, flags);
> - _queue_data(&dch->dev.D, PH_ACTIVATE_IND,
> - MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
> - break;
> - }
> - test_and_set_bit(FLG_L2_ACTIVATED, &dch->Flags);
> - Write_hfc(hc, HFCPCI_STATES, HFCPCI_ACTIVATE |
> - HFCPCI_DO_ACTION | 1);
> - } else
> - ret = l1_event(dch->l1, hh->prim);
> - spin_unlock_irqrestore(&hc->lock, flags);
> - break;
> - case PH_DEACTIVATE_REQ:
> - test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
> - spin_lock_irqsave(&hc->lock, flags);
> - if (hc->hw.protocol == ISDN_P_NT_S0) {
> - struct sk_buff_head free_queue;
> -
> - __skb_queue_head_init(&free_queue);
> - /* prepare deactivation */
> - Write_hfc(hc, HFCPCI_STATES, 0x40);
> - skb_queue_splice_init(&dch->squeue, &free_queue);
> - if (dch->tx_skb) {
> - __skb_queue_tail(&free_queue, dch->tx_skb);
> - dch->tx_skb = NULL;
> - }
> - dch->tx_idx = 0;
> - if (dch->rx_skb) {
> - __skb_queue_tail(&free_queue, dch->rx_skb);
> - dch->rx_skb = NULL;
> - }
> - test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
> - if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
> - timer_delete(&dch->timer);
> -#ifdef FIXME
> - if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags))
> - dchannel_sched_event(&hc->dch, D_CLEARBUSY);
> -#endif
> - hc->hw.mst_m &= ~HFCPCI_MASTER;
> - Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
> - ret = 0;
> - spin_unlock_irqrestore(&hc->lock, flags);
> - __skb_queue_purge(&free_queue);
> - } else {
> - ret = l1_event(dch->l1, hh->prim);
> - spin_unlock_irqrestore(&hc->lock, flags);
> - }
> - break;
> - }
> - if (!ret)
> - dev_kfree_skb(skb);
> - return ret;
> -}
> -
> -/*
> - * Layer2 -> Layer 1 Bchannel data
> - */
> -static int
> -hfcpci_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)
> -{
> - struct bchannel *bch = container_of(ch, struct bchannel, ch);
> - struct hfc_pci *hc = bch->hw;
> - int ret = -EINVAL;
> - struct mISDNhead *hh = mISDN_HEAD_P(skb);
> - unsigned long flags;
> -
> - switch (hh->prim) {
> - case PH_DATA_REQ:
> - spin_lock_irqsave(&hc->lock, flags);
> - ret = bchannel_senddata(bch, skb);
> - if (ret > 0) { /* direct TX */
> - hfcpci_fill_fifo(bch);
> - ret = 0;
> - }
> - spin_unlock_irqrestore(&hc->lock, flags);
> - return ret;
> - case PH_ACTIVATE_REQ:
> - spin_lock_irqsave(&hc->lock, flags);
> - if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags))
> - ret = mode_hfcpci(bch, bch->nr, ch->protocol);
> - else
> - ret = 0;
> - spin_unlock_irqrestore(&hc->lock, flags);
> - if (!ret)
> - _queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
> - NULL, GFP_KERNEL);
> - break;
> - case PH_DEACTIVATE_REQ:
> - deactivate_bchannel(bch);
> - _queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
> - NULL, GFP_KERNEL);
> - ret = 0;
> - break;
> - }
> - if (!ret)
> - dev_kfree_skb(skb);
> - return ret;
> -}
> -
> -/*
> - * called for card init message
> - */
> -
> -static void
> -inithfcpci(struct hfc_pci *hc)
> -{
> - printk(KERN_DEBUG "inithfcpci: entered\n");
> - timer_setup(&hc->dch.timer, hfcpci_dbusy_timer, 0);
> - hc->chanlimit = 2;
> - mode_hfcpci(&hc->bch[0], 1, -1);
> - mode_hfcpci(&hc->bch[1], 2, -1);
> -}
> -
> -
> -static int
> -init_card(struct hfc_pci *hc)
> -{
> - int cnt = 3;
> - u_long flags;
> -
> - printk(KERN_DEBUG "init_card: entered\n");
> -
> -
> - spin_lock_irqsave(&hc->lock, flags);
> - disable_hwirq(hc);
> - spin_unlock_irqrestore(&hc->lock, flags);
> - if (request_irq(hc->irq, hfcpci_int, IRQF_SHARED, "HFC PCI", hc)) {
> - printk(KERN_WARNING
> - "mISDN: couldn't get interrupt %d\n", hc->irq);
> - return -EIO;
> - }
> - spin_lock_irqsave(&hc->lock, flags);
> - reset_hfcpci(hc);
> - while (cnt) {
> - inithfcpci(hc);
> - /*
> - * Finally enable IRQ output
> - * this is only allowed, if an IRQ routine is already
> - * established for this HFC, so don't do that earlier
> - */
> - enable_hwirq(hc);
> - spin_unlock_irqrestore(&hc->lock, flags);
> - /* Timeout 80ms */
> - set_current_state(TASK_UNINTERRUPTIBLE);
> - schedule_timeout((80 * HZ) / 1000);
> - printk(KERN_INFO "HFC PCI: IRQ %d count %d\n",
> - hc->irq, hc->irqcnt);
> - /* now switch timer interrupt off */
> - spin_lock_irqsave(&hc->lock, flags);
> - hc->hw.int_m1 &= ~HFCPCI_INTS_TIMER;
> - Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
> - /* reinit mode reg */
> - Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
> - if (!hc->irqcnt) {
> - printk(KERN_WARNING
> - "HFC PCI: IRQ(%d) getting no interrupts "
> - "during init %d\n", hc->irq, 4 - cnt);
> - if (cnt == 1)
> - break;
> - else {
> - reset_hfcpci(hc);
> - cnt--;
> - }
> - } else {
> - spin_unlock_irqrestore(&hc->lock, flags);
> - hc->initdone = 1;
> - return 0;
> - }
> - }
> - disable_hwirq(hc);
> - spin_unlock_irqrestore(&hc->lock, flags);
> - free_irq(hc->irq, hc);
> - return -EIO;
> -}
> -
> -static int
> -channel_ctrl(struct hfc_pci *hc, struct mISDN_ctrl_req *cq)
> -{
> - int ret = 0;
> - u_char slot;
> -
> - switch (cq->op) {
> - case MISDN_CTRL_GETOP:
> - cq->op = MISDN_CTRL_LOOP | MISDN_CTRL_CONNECT |
> - MISDN_CTRL_DISCONNECT | MISDN_CTRL_L1_TIMER3;
> - break;
> - case MISDN_CTRL_LOOP:
> - /* channel 0 disabled loop */
> - if (cq->channel < 0 || cq->channel > 2) {
> - ret = -EINVAL;
> - break;
> - }
> - if (cq->channel & 1) {
> - if (test_bit(HFC_CFG_SW_DD_DU, &hc->cfg))
> - slot = 0xC0;
> - else
> - slot = 0x80;
> - printk(KERN_DEBUG "%s: Write_hfc: B1_SSL/RSL 0x%x\n",
> - __func__, slot);
> - Write_hfc(hc, HFCPCI_B1_SSL, slot);
> - Write_hfc(hc, HFCPCI_B1_RSL, slot);
> - hc->hw.conn = (hc->hw.conn & ~7) | 6;
> - Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn);
> - }
> - if (cq->channel & 2) {
> - if (test_bit(HFC_CFG_SW_DD_DU, &hc->cfg))
> - slot = 0xC1;
> - else
> - slot = 0x81;
> - printk(KERN_DEBUG "%s: Write_hfc: B2_SSL/RSL 0x%x\n",
> - __func__, slot);
> - Write_hfc(hc, HFCPCI_B2_SSL, slot);
> - Write_hfc(hc, HFCPCI_B2_RSL, slot);
> - hc->hw.conn = (hc->hw.conn & ~0x38) | 0x30;
> - Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn);
> - }
> - if (cq->channel & 3)
> - hc->hw.trm |= 0x80; /* enable IOM-loop */
> - else {
> - hc->hw.conn = (hc->hw.conn & ~0x3f) | 0x09;
> - Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn);
> - hc->hw.trm &= 0x7f; /* disable IOM-loop */
> - }
> - Write_hfc(hc, HFCPCI_TRM, hc->hw.trm);
> - break;
> - case MISDN_CTRL_CONNECT:
> - if (cq->channel == cq->p1) {
> - ret = -EINVAL;
> - break;
> - }
> - if (cq->channel < 1 || cq->channel > 2 ||
> - cq->p1 < 1 || cq->p1 > 2) {
> - ret = -EINVAL;
> - break;
> - }
> - if (test_bit(HFC_CFG_SW_DD_DU, &hc->cfg))
> - slot = 0xC0;
> - else
> - slot = 0x80;
> - printk(KERN_DEBUG "%s: Write_hfc: B1_SSL/RSL 0x%x\n",
> - __func__, slot);
> - Write_hfc(hc, HFCPCI_B1_SSL, slot);
> - Write_hfc(hc, HFCPCI_B2_RSL, slot);
> - if (test_bit(HFC_CFG_SW_DD_DU, &hc->cfg))
> - slot = 0xC1;
> - else
> - slot = 0x81;
> - printk(KERN_DEBUG "%s: Write_hfc: B2_SSL/RSL 0x%x\n",
> - __func__, slot);
> - Write_hfc(hc, HFCPCI_B2_SSL, slot);
> - Write_hfc(hc, HFCPCI_B1_RSL, slot);
> - hc->hw.conn = (hc->hw.conn & ~0x3f) | 0x36;
> - Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn);
> - hc->hw.trm |= 0x80;
> - Write_hfc(hc, HFCPCI_TRM, hc->hw.trm);
> - break;
> - case MISDN_CTRL_DISCONNECT:
> - hc->hw.conn = (hc->hw.conn & ~0x3f) | 0x09;
> - Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn);
> - hc->hw.trm &= 0x7f; /* disable IOM-loop */
> - break;
> - case MISDN_CTRL_L1_TIMER3:
> - ret = l1_event(hc->dch.l1, HW_TIMER3_VALUE | (cq->p1 & 0xff));
> - break;
> - default:
> - printk(KERN_WARNING "%s: unknown Op %x\n",
> - __func__, cq->op);
> - ret = -EINVAL;
> - break;
> - }
> - return ret;
> -}
> -
> -static int
> -open_dchannel(struct hfc_pci *hc, struct mISDNchannel *ch,
> - struct channel_req *rq)
> -{
> - int err = 0;
> -
> - if (debug & DEBUG_HW_OPEN)
> - printk(KERN_DEBUG "%s: dev(%d) open from %p\n", __func__,
> - hc->dch.dev.id, __builtin_return_address(0));
> - if (rq->protocol == ISDN_P_NONE)
> - return -EINVAL;
> - if (rq->adr.channel == 1) {
> - /* TODO: E-Channel */
> - return -EINVAL;
> - }
> - if (!hc->initdone) {
> - if (rq->protocol == ISDN_P_TE_S0) {
> - err = create_l1(&hc->dch, hfc_l1callback);
> - if (err)
> - return err;
> - }
> - hc->hw.protocol = rq->protocol;
> - ch->protocol = rq->protocol;
> - err = init_card(hc);
> - if (err)
> - return err;
> - } else {
> - if (rq->protocol != ch->protocol) {
> - if (hc->hw.protocol == ISDN_P_TE_S0)
> - l1_event(hc->dch.l1, CLOSE_CHANNEL);
> - if (rq->protocol == ISDN_P_TE_S0) {
> - err = create_l1(&hc->dch, hfc_l1callback);
> - if (err)
> - return err;
> - }
> - hc->hw.protocol = rq->protocol;
> - ch->protocol = rq->protocol;
> - hfcpci_setmode(hc);
> - }
> - }
> -
> - if (((ch->protocol == ISDN_P_NT_S0) && (hc->dch.state == 3)) ||
> - ((ch->protocol == ISDN_P_TE_S0) && (hc->dch.state == 7))) {
> - _queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY,
> - 0, NULL, GFP_KERNEL);
> - }
> - rq->ch = ch;
> - if (!try_module_get(THIS_MODULE))
> - printk(KERN_WARNING "%s:cannot get module\n", __func__);
> - return 0;
> -}
> -
> -static int
> -open_bchannel(struct hfc_pci *hc, struct channel_req *rq)
> -{
> - struct bchannel *bch;
> -
> - if (rq->adr.channel == 0 || rq->adr.channel > 2)
> - return -EINVAL;
> - if (rq->protocol == ISDN_P_NONE)
> - return -EINVAL;
> - bch = &hc->bch[rq->adr.channel - 1];
> - if (test_and_set_bit(FLG_OPEN, &bch->Flags))
> - return -EBUSY; /* b-channel can be only open once */
> - bch->ch.protocol = rq->protocol;
> - rq->ch = &bch->ch; /* TODO: E-channel */
> - if (!try_module_get(THIS_MODULE))
> - printk(KERN_WARNING "%s:cannot get module\n", __func__);
> - return 0;
> -}
> -
> -/*
> - * device control function
> - */
> -static int
> -hfc_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
> -{
> - struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
> - struct dchannel *dch = container_of(dev, struct dchannel, dev);
> - struct hfc_pci *hc = dch->hw;
> - struct channel_req *rq;
> - int err = 0;
> -
> - if (dch->debug & DEBUG_HW)
> - printk(KERN_DEBUG "%s: cmd:%x %p\n",
> - __func__, cmd, arg);
> - switch (cmd) {
> - case OPEN_CHANNEL:
> - rq = arg;
> - if ((rq->protocol == ISDN_P_TE_S0) ||
> - (rq->protocol == ISDN_P_NT_S0))
> - err = open_dchannel(hc, ch, rq);
> - else
> - err = open_bchannel(hc, rq);
> - break;
> - case CLOSE_CHANNEL:
> - if (debug & DEBUG_HW_OPEN)
> - printk(KERN_DEBUG "%s: dev(%d) close from %p\n",
> - __func__, hc->dch.dev.id,
> - __builtin_return_address(0));
> - module_put(THIS_MODULE);
> - break;
> - case CONTROL_CHANNEL:
> - err = channel_ctrl(hc, arg);
> - break;
> - default:
> - if (dch->debug & DEBUG_HW)
> - printk(KERN_DEBUG "%s: unknown command %x\n",
> - __func__, cmd);
> - return -EINVAL;
> - }
> - return err;
> -}
> -
> -static int
> -setup_hw(struct hfc_pci *hc)
> -{
> - void *buffer;
> -
> - printk(KERN_INFO "mISDN: HFC-PCI driver %s\n", hfcpci_revision);
> - hc->hw.cirm = 0;
> - hc->dch.state = 0;
> - pci_set_master(hc->pdev);
> - if (!hc->irq) {
> - printk(KERN_WARNING "HFC-PCI: No IRQ for PCI card found\n");
> - return -EINVAL;
> - }
> - hc->hw.pci_io =
> - (char __iomem *)(unsigned long)hc->pdev->resource[1].start;
> -
> - if (!hc->hw.pci_io) {
> - printk(KERN_WARNING "HFC-PCI: No IO-Mem for PCI card found\n");
> - return -ENOMEM;
> - }
> - /* Allocate memory for FIFOS */
> - /* the memory needs to be on a 32k boundary within the first 4G */
> - if (dma_set_mask(&hc->pdev->dev, 0xFFFF8000)) {
> - printk(KERN_WARNING
> - "HFC-PCI: No usable DMA configuration!\n");
> - return -EIO;
> - }
> - buffer = dma_alloc_coherent(&hc->pdev->dev, 0x8000, &hc->hw.dmahandle,
> - GFP_KERNEL);
> - /* We silently assume the address is okay if nonzero */
> - if (!buffer) {
> - printk(KERN_WARNING
> - "HFC-PCI: Error allocating memory for FIFO!\n");
> - return -ENOMEM;
> - }
> - hc->hw.fifos = buffer;
> - pci_write_config_dword(hc->pdev, 0x80, hc->hw.dmahandle);
> - hc->hw.pci_io = ioremap((ulong) hc->hw.pci_io, 256);
> - if (unlikely(!hc->hw.pci_io)) {
> - printk(KERN_WARNING
> - "HFC-PCI: Error in ioremap for PCI!\n");
> - dma_free_coherent(&hc->pdev->dev, 0x8000, hc->hw.fifos,
> - hc->hw.dmahandle);
> - return -ENOMEM;
> - }
> -
> - printk(KERN_INFO
> - "HFC-PCI: defined at mem %#lx fifo %p(%pad) IRQ %d HZ %d\n",
> - (u_long) hc->hw.pci_io, hc->hw.fifos,
> - &hc->hw.dmahandle, hc->irq, HZ);
> -
> - /* enable memory mapped ports, disable busmaster */
> - pci_write_config_word(hc->pdev, PCI_COMMAND, PCI_ENA_MEMIO);
> - hc->hw.int_m2 = 0;
> - disable_hwirq(hc);
> - hc->hw.int_m1 = 0;
> - Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
> - /* At this point the needed PCI config is done */
> - /* fifos are still not enabled */
> - timer_setup(&hc->hw.timer, hfcpci_Timer, 0);
> - /* default PCM master */
> - test_and_set_bit(HFC_CFG_MASTER, &hc->cfg);
> - return 0;
> -}
> -
> -static void
> -release_card(struct hfc_pci *hc) {
> - u_long flags;
> -
> - spin_lock_irqsave(&hc->lock, flags);
> - hc->hw.int_m2 = 0; /* interrupt output off ! */
> - disable_hwirq(hc);
> - mode_hfcpci(&hc->bch[0], 1, ISDN_P_NONE);
> - mode_hfcpci(&hc->bch[1], 2, ISDN_P_NONE);
> - if (hc->dch.timer.function != NULL) {
> - timer_delete(&hc->dch.timer);
> - hc->dch.timer.function = NULL;
> - }
> - spin_unlock_irqrestore(&hc->lock, flags);
> - if (hc->hw.protocol == ISDN_P_TE_S0)
> - l1_event(hc->dch.l1, CLOSE_CHANNEL);
> - if (hc->initdone)
> - free_irq(hc->irq, hc);
> - release_io_hfcpci(hc); /* must release after free_irq! */
> - mISDN_unregister_device(&hc->dch.dev);
> - mISDN_freebchannel(&hc->bch[1]);
> - mISDN_freebchannel(&hc->bch[0]);
> - mISDN_freedchannel(&hc->dch);
> - pci_set_drvdata(hc->pdev, NULL);
> - kfree(hc);
> -}
> -
> -static int
> -setup_card(struct hfc_pci *card)
> -{
> - int err = -EINVAL;
> - u_int i;
> - char name[MISDN_MAX_IDLEN];
> -
> - card->dch.debug = debug;
> - spin_lock_init(&card->lock);
> - mISDN_initdchannel(&card->dch, MAX_DFRAME_LEN_L1, ph_state);
> - card->dch.hw = card;
> - card->dch.dev.Dprotocols = (1 << ISDN_P_TE_S0) | (1 << ISDN_P_NT_S0);
> - card->dch.dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
> - (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
> - card->dch.dev.D.send = hfcpci_l2l1D;
> - card->dch.dev.D.ctrl = hfc_dctrl;
> - card->dch.dev.nrbchan = 2;
> - for (i = 0; i < 2; i++) {
> - card->bch[i].nr = i + 1;
> - set_channelmap(i + 1, card->dch.dev.channelmap);
> - card->bch[i].debug = debug;
> - mISDN_initbchannel(&card->bch[i], MAX_DATA_MEM, poll >> 1);
> - card->bch[i].hw = card;
> - card->bch[i].ch.send = hfcpci_l2l1B;
> - card->bch[i].ch.ctrl = hfc_bctrl;
> - card->bch[i].ch.nr = i + 1;
> - list_add(&card->bch[i].ch.list, &card->dch.dev.bchannels);
> - }
> - err = setup_hw(card);
> - if (err)
> - goto error;
> - snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-pci.%d", HFC_cnt + 1);
> - err = mISDN_register_device(&card->dch.dev, &card->pdev->dev, name);
> - if (err)
> - goto error;
> - HFC_cnt++;
> - printk(KERN_INFO "HFC %d cards installed\n", HFC_cnt);
> - return 0;
> -error:
> - mISDN_freebchannel(&card->bch[1]);
> - mISDN_freebchannel(&card->bch[0]);
> - mISDN_freedchannel(&card->dch);
> - kfree(card);
> - return err;
> -}
> -
> -/* private data in the PCI devices list */
> -struct _hfc_map {
> - u_int subtype;
> - u_int flag;
> - char *name;
> -};
> -
> -static const struct _hfc_map hfc_map[] =
> -{
> - {HFC_CCD_2BD0, 0, "CCD/Billion/Asuscom 2BD0"},
> - {HFC_CCD_B000, 0, "Billion B000"},
> - {HFC_CCD_B006, 0, "Billion B006"},
> - {HFC_CCD_B007, 0, "Billion B007"},
> - {HFC_CCD_B008, 0, "Billion B008"},
> - {HFC_CCD_B009, 0, "Billion B009"},
> - {HFC_CCD_B00A, 0, "Billion B00A"},
> - {HFC_CCD_B00B, 0, "Billion B00B"},
> - {HFC_CCD_B00C, 0, "Billion B00C"},
> - {HFC_CCD_B100, 0, "Seyeon B100"},
> - {HFC_CCD_B700, 0, "Primux II S0 B700"},
> - {HFC_CCD_B701, 0, "Primux II S0 NT B701"},
> - {HFC_ABOCOM_2BD1, 0, "Abocom/Magitek 2BD1"},
> - {HFC_ASUS_0675, 0, "Asuscom/Askey 675"},
> - {HFC_BERKOM_TCONCEPT, 0, "German telekom T-Concept"},
> - {HFC_BERKOM_A1T, 0, "German telekom A1T"},
> - {HFC_ANIGMA_MC145575, 0, "Motorola MC145575"},
> - {HFC_ZOLTRIX_2BD0, 0, "Zoltrix 2BD0"},
> - {HFC_DIGI_DF_M_IOM2_E, 0,
> - "Digi International DataFire Micro V IOM2 (Europe)"},
> - {HFC_DIGI_DF_M_E, 0,
> - "Digi International DataFire Micro V (Europe)"},
> - {HFC_DIGI_DF_M_IOM2_A, 0,
> - "Digi International DataFire Micro V IOM2 (North America)"},
> - {HFC_DIGI_DF_M_A, 0,
> - "Digi International DataFire Micro V (North America)"},
> - {HFC_SITECOM_DC105V2, 0, "Sitecom Connectivity DC-105 ISDN TA"},
> - {},
> -};
> -
> -static const struct pci_device_id hfc_ids[] =
> -{
> - { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_2BD0),
> - (unsigned long) &hfc_map[0] },
> - { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B000),
> - (unsigned long) &hfc_map[1] },
> - { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B006),
> - (unsigned long) &hfc_map[2] },
> - { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B007),
> - (unsigned long) &hfc_map[3] },
> - { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B008),
> - (unsigned long) &hfc_map[4] },
> - { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B009),
> - (unsigned long) &hfc_map[5] },
> - { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B00A),
> - (unsigned long) &hfc_map[6] },
> - { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B00B),
> - (unsigned long) &hfc_map[7] },
> - { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B00C),
> - (unsigned long) &hfc_map[8] },
> - { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B100),
> - (unsigned long) &hfc_map[9] },
> - { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B700),
> - (unsigned long) &hfc_map[10] },
> - { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B701),
> - (unsigned long) &hfc_map[11] },
> - { PCI_VDEVICE(ABOCOM, PCI_DEVICE_ID_ABOCOM_2BD1),
> - (unsigned long) &hfc_map[12] },
> - { PCI_VDEVICE(ASUSTEK, PCI_DEVICE_ID_ASUSTEK_0675),
> - (unsigned long) &hfc_map[13] },
> - { PCI_VDEVICE(BERKOM, PCI_DEVICE_ID_BERKOM_T_CONCEPT),
> - (unsigned long) &hfc_map[14] },
> - { PCI_VDEVICE(BERKOM, PCI_DEVICE_ID_BERKOM_A1T),
> - (unsigned long) &hfc_map[15] },
> - { PCI_VDEVICE(ANIGMA, PCI_DEVICE_ID_ANIGMA_MC145575),
> - (unsigned long) &hfc_map[16] },
> - { PCI_VDEVICE(ZOLTRIX, PCI_DEVICE_ID_ZOLTRIX_2BD0),
> - (unsigned long) &hfc_map[17] },
> - { PCI_VDEVICE(DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_E),
> - (unsigned long) &hfc_map[18] },
> - { PCI_VDEVICE(DIGI, PCI_DEVICE_ID_DIGI_DF_M_E),
> - (unsigned long) &hfc_map[19] },
> - { PCI_VDEVICE(DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_A),
> - (unsigned long) &hfc_map[20] },
> - { PCI_VDEVICE(DIGI, PCI_DEVICE_ID_DIGI_DF_M_A),
> - (unsigned long) &hfc_map[21] },
> - { PCI_VDEVICE(SITECOM, PCI_DEVICE_ID_SITECOM_DC105V2),
> - (unsigned long) &hfc_map[22] },
> - {},
> -};
> -
> -static int
> -hfc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
> -{
> - int err = -ENOMEM;
> - struct hfc_pci *card;
> - struct _hfc_map *m = (struct _hfc_map *)ent->driver_data;
> -
> - card = kzalloc_obj(struct hfc_pci);
> - if (!card) {
> - printk(KERN_ERR "No kmem for HFC card\n");
> - return err;
> - }
> - card->pdev = pdev;
> - card->subtype = m->subtype;
> - err = pci_enable_device(pdev);
> - if (err) {
> - kfree(card);
> - return err;
> - }
> -
> - printk(KERN_INFO "mISDN_hfcpci: found adapter %s at %s\n",
> - m->name, pci_name(pdev));
> -
> - card->irq = pdev->irq;
> - pci_set_drvdata(pdev, card);
> - err = setup_card(card);
> - if (err)
> - pci_set_drvdata(pdev, NULL);
> - return err;
> -}
> -
> -static void
> -hfc_remove_pci(struct pci_dev *pdev)
> -{
> - struct hfc_pci *card = pci_get_drvdata(pdev);
> -
> - if (card)
> - release_card(card);
> - else
> - if (debug)
> - printk(KERN_DEBUG "%s: drvdata already removed\n",
> - __func__);
> -}
> -
> -
> -static struct pci_driver hfc_driver = {
> - .name = "hfcpci",
> - .probe = hfc_probe,
> - .remove = hfc_remove_pci,
> - .id_table = hfc_ids,
> -};
> -
> -static int
> -_hfcpci_softirq(struct device *dev, void *unused)
> -{
> - struct hfc_pci *hc = dev_get_drvdata(dev);
> - struct bchannel *bch;
> - if (hc == NULL)
> - return 0;
> -
> - if (hc->hw.int_m2 & HFCPCI_IRQ_ENABLE) {
> - spin_lock_irq(&hc->lock);
> - bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1);
> - if (bch && bch->state == ISDN_P_B_RAW) { /* B1 rx&tx */
> - main_rec_hfcpci(bch);
> - tx_birq(bch);
> - }
> - bch = Sel_BCS(hc, hc->hw.bswapped ? 1 : 2);
> - if (bch && bch->state == ISDN_P_B_RAW) { /* B2 rx&tx */
> - main_rec_hfcpci(bch);
> - tx_birq(bch);
> - }
> - spin_unlock_irq(&hc->lock);
> - }
> - return 0;
> -}
> -
> -static void
> -hfcpci_softirq(struct timer_list *unused)
> -{
> - WARN_ON_ONCE(driver_for_each_device(&hfc_driver.driver, NULL, NULL,
> - _hfcpci_softirq) != 0);
> -
> - /* if next event would be in the past ... */
> - if ((s32)(hfc_jiffies + tics - jiffies) <= 0)
> - hfc_jiffies = jiffies + 1;
> - else
> - hfc_jiffies += tics;
> - mod_timer(&hfc_tl, hfc_jiffies);
> -}
> -
> -static int __init
> -HFC_init(void)
> -{
> - int err;
> -
> - if (!poll)
> - poll = HFCPCI_BTRANS_THRESHOLD;
> -
> - if (poll != HFCPCI_BTRANS_THRESHOLD) {
> - tics = (poll * HZ) / 8000;
> - if (tics < 1)
> - tics = 1;
> - poll = (tics * 8000) / HZ;
> - if (poll > 256 || poll < 8) {
> - printk(KERN_ERR "%s: Wrong poll value %d not in range "
> - "of 8..256.\n", __func__, poll);
> - err = -EINVAL;
> - return err;
> - }
> - }
> - if (poll != HFCPCI_BTRANS_THRESHOLD) {
> - printk(KERN_INFO "%s: Using alternative poll value of %d\n",
> - __func__, poll);
> - hfc_jiffies = jiffies + tics;
> - mod_timer(&hfc_tl, hfc_jiffies);
> - } else
> - tics = 0; /* indicate the use of controller's timer */
> -
> - err = pci_register_driver(&hfc_driver);
> - if (err) {
> - if (timer_pending(&hfc_tl))
> - timer_delete(&hfc_tl);
> - }
> -
> - return err;
> -}
> -
> -static void __exit
> -HFC_cleanup(void)
> -{
> - timer_delete_sync(&hfc_tl);
> -
> - pci_unregister_driver(&hfc_driver);
> -}
> -
> -module_init(HFC_init);
> -module_exit(HFC_cleanup);
> -
> -MODULE_DEVICE_TABLE(pci, hfc_ids);
> diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.c b/drivers/isdn/hardware/mISDN/hfcsusb.c
> deleted file mode 100644
> index 227babe83879..000000000000
> --- a/drivers/isdn/hardware/mISDN/hfcsusb.c
> +++ /dev/null
> @@ -1,2157 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-or-later
> -/* hfcsusb.c
> - * mISDN driver for Colognechip HFC-S USB chip
> - *
> - * Copyright 2001 by Peter Sprenger (sprenger@moving-bytes.de)
> - * Copyright 2008 by Martin Bachem (info@bachem-it.com)
> - *
> - * module params
> - * debug=<n>, default=0, with n=0xHHHHGGGG
> - * H - l1 driver flags described in hfcsusb.h
> - * G - common mISDN debug flags described at mISDNhw.h
> - *
> - * poll=<n>, default 128
> - * n : burst size of PH_DATA_IND at transparent rx data
> - *
> - * Revision: 0.3.3 (socket), 2008-11-05
> - */
> -
> -#include <linux/module.h>
> -#include <linux/delay.h>
> -#include <linux/usb.h>
> -#include <linux/mISDNhw.h>
> -#include <linux/slab.h>
> -#include "hfcsusb.h"
> -
> -static unsigned int debug;
> -static int poll = DEFAULT_TRANSP_BURST_SZ;
> -
> -static LIST_HEAD(HFClist);
> -static DEFINE_RWLOCK(HFClock);
> -
> -
> -MODULE_AUTHOR("Martin Bachem");
> -MODULE_DESCRIPTION("mISDN driver for Colognechip HFC-S USB chip");
> -MODULE_LICENSE("GPL");
> -module_param(debug, uint, S_IRUGO | S_IWUSR);
> -module_param(poll, int, 0);
> -
> -static int hfcsusb_cnt;
> -
> -/* some function prototypes */
> -static void hfcsusb_ph_command(struct hfcsusb *hw, u_char command);
> -static void release_hw(struct hfcsusb *hw);
> -static void reset_hfcsusb(struct hfcsusb *hw);
> -static void setPortMode(struct hfcsusb *hw);
> -static void hfcsusb_start_endpoint(struct hfcsusb *hw, int channel);
> -static void hfcsusb_stop_endpoint(struct hfcsusb *hw, int channel);
> -static int hfcsusb_setup_bch(struct bchannel *bch, int protocol);
> -static void deactivate_bchannel(struct bchannel *bch);
> -static int hfcsusb_ph_info(struct hfcsusb *hw);
> -
> -/* start next background transfer for control channel */
> -static void
> -ctrl_start_transfer(struct hfcsusb *hw)
> -{
> - if (debug & DBG_HFC_CALL_TRACE)
> - printk(KERN_DEBUG "%s: %s\n", hw->name, __func__);
> -
> - if (hw->ctrl_cnt) {
> - hw->ctrl_urb->pipe = hw->ctrl_out_pipe;
> - hw->ctrl_urb->setup_packet = (u_char *)&hw->ctrl_write;
> - hw->ctrl_urb->transfer_buffer = NULL;
> - hw->ctrl_urb->transfer_buffer_length = 0;
> - hw->ctrl_write.wIndex =
> - cpu_to_le16(hw->ctrl_buff[hw->ctrl_out_idx].hfcs_reg);
> - hw->ctrl_write.wValue =
> - cpu_to_le16(hw->ctrl_buff[hw->ctrl_out_idx].reg_val);
> -
> - usb_submit_urb(hw->ctrl_urb, GFP_ATOMIC);
> - }
> -}
> -
> -/*
> - * queue a control transfer request to write HFC-S USB
> - * chip register using CTRL resuest queue
> - */
> -static int write_reg(struct hfcsusb *hw, __u8 reg, __u8 val)
> -{
> - struct ctrl_buf *buf;
> -
> - if (debug & DBG_HFC_CALL_TRACE)
> - printk(KERN_DEBUG "%s: %s reg(0x%02x) val(0x%02x)\n",
> - hw->name, __func__, reg, val);
> -
> - spin_lock(&hw->ctrl_lock);
> - if (hw->ctrl_cnt >= HFC_CTRL_BUFSIZE) {
> - spin_unlock(&hw->ctrl_lock);
> - return 1;
> - }
> - buf = &hw->ctrl_buff[hw->ctrl_in_idx];
> - buf->hfcs_reg = reg;
> - buf->reg_val = val;
> - if (++hw->ctrl_in_idx >= HFC_CTRL_BUFSIZE)
> - hw->ctrl_in_idx = 0;
> - if (++hw->ctrl_cnt == 1)
> - ctrl_start_transfer(hw);
> - spin_unlock(&hw->ctrl_lock);
> -
> - return 0;
> -}
> -
> -/* control completion routine handling background control cmds */
> -static void
> -ctrl_complete(struct urb *urb)
> -{
> - struct hfcsusb *hw = (struct hfcsusb *) urb->context;
> -
> - if (debug & DBG_HFC_CALL_TRACE)
> - printk(KERN_DEBUG "%s: %s\n", hw->name, __func__);
> -
> - urb->dev = hw->dev;
> - if (hw->ctrl_cnt) {
> - hw->ctrl_cnt--; /* decrement actual count */
> - if (++hw->ctrl_out_idx >= HFC_CTRL_BUFSIZE)
> - hw->ctrl_out_idx = 0; /* pointer wrap */
> -
> - ctrl_start_transfer(hw); /* start next transfer */
> - }
> -}
> -
> -/* handle LED bits */
> -static void
> -set_led_bit(struct hfcsusb *hw, signed short led_bits, int set_on)
> -{
> - if (set_on) {
> - if (led_bits < 0)
> - hw->led_state &= ~abs(led_bits);
> - else
> - hw->led_state |= led_bits;
> - } else {
> - if (led_bits < 0)
> - hw->led_state |= abs(led_bits);
> - else
> - hw->led_state &= ~led_bits;
> - }
> -}
> -
> -/* handle LED requests */
> -static void
> -handle_led(struct hfcsusb *hw, int event)
> -{
> - struct hfcsusb_vdata *driver_info = (struct hfcsusb_vdata *)
> - hfcsusb_idtab[hw->vend_idx].driver_info;
> - __u8 tmpled;
> -
> - if (driver_info->led_scheme == LED_OFF)
> - return;
> - tmpled = hw->led_state;
> -
> - switch (event) {
> - case LED_POWER_ON:
> - set_led_bit(hw, driver_info->led_bits[0], 1);
> - set_led_bit(hw, driver_info->led_bits[1], 0);
> - set_led_bit(hw, driver_info->led_bits[2], 0);
> - set_led_bit(hw, driver_info->led_bits[3], 0);
> - break;
> - case LED_POWER_OFF:
> - set_led_bit(hw, driver_info->led_bits[0], 0);
> - set_led_bit(hw, driver_info->led_bits[1], 0);
> - set_led_bit(hw, driver_info->led_bits[2], 0);
> - set_led_bit(hw, driver_info->led_bits[3], 0);
> - break;
> - case LED_S0_ON:
> - set_led_bit(hw, driver_info->led_bits[1], 1);
> - break;
> - case LED_S0_OFF:
> - set_led_bit(hw, driver_info->led_bits[1], 0);
> - break;
> - case LED_B1_ON:
> - set_led_bit(hw, driver_info->led_bits[2], 1);
> - break;
> - case LED_B1_OFF:
> - set_led_bit(hw, driver_info->led_bits[2], 0);
> - break;
> - case LED_B2_ON:
> - set_led_bit(hw, driver_info->led_bits[3], 1);
> - break;
> - case LED_B2_OFF:
> - set_led_bit(hw, driver_info->led_bits[3], 0);
> - break;
> - }
> -
> - if (hw->led_state != tmpled) {
> - if (debug & DBG_HFC_CALL_TRACE)
> - printk(KERN_DEBUG "%s: %s reg(0x%02x) val(x%02x)\n",
> - hw->name, __func__,
> - HFCUSB_P_DATA, hw->led_state);
> -
> - write_reg(hw, HFCUSB_P_DATA, hw->led_state);
> - }
> -}
> -
> -/*
> - * Layer2 -> Layer 1 Bchannel data
> - */
> -static int
> -hfcusb_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)
> -{
> - struct bchannel *bch = container_of(ch, struct bchannel, ch);
> - struct hfcsusb *hw = bch->hw;
> - int ret = -EINVAL;
> - struct mISDNhead *hh = mISDN_HEAD_P(skb);
> - u_long flags;
> -
> - if (debug & DBG_HFC_CALL_TRACE)
> - printk(KERN_DEBUG "%s: %s\n", hw->name, __func__);
> -
> - switch (hh->prim) {
> - case PH_DATA_REQ:
> - spin_lock_irqsave(&hw->lock, flags);
> - ret = bchannel_senddata(bch, skb);
> - spin_unlock_irqrestore(&hw->lock, flags);
> - if (debug & DBG_HFC_CALL_TRACE)
> - printk(KERN_DEBUG "%s: %s PH_DATA_REQ ret(%i)\n",
> - hw->name, __func__, ret);
> - if (ret > 0)
> - ret = 0;
> - return ret;
> - case PH_ACTIVATE_REQ:
> - if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags)) {
> - hfcsusb_start_endpoint(hw, bch->nr - 1);
> - ret = hfcsusb_setup_bch(bch, ch->protocol);
> - } else
> - ret = 0;
> - if (!ret)
> - _queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY,
> - 0, NULL, GFP_KERNEL);
> - break;
> - case PH_DEACTIVATE_REQ:
> - deactivate_bchannel(bch);
> - _queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY,
> - 0, NULL, GFP_KERNEL);
> - ret = 0;
> - break;
> - }
> - if (!ret)
> - dev_kfree_skb(skb);
> - return ret;
> -}
> -
> -/*
> - * send full D/B channel status information
> - * as MPH_INFORMATION_IND
> - */
> -static int
> -hfcsusb_ph_info(struct hfcsusb *hw)
> -{
> - struct ph_info *phi;
> - struct dchannel *dch = &hw->dch;
> - int i;
> -
> - phi = kzalloc_flex(*phi, bch, dch->dev.nrbchan, GFP_ATOMIC);
> - if (!phi)
> - return -ENOMEM;
> -
> - phi->dch.ch.protocol = hw->protocol;
> - phi->dch.ch.Flags = dch->Flags;
> - phi->dch.state = dch->state;
> - phi->dch.num_bch = dch->dev.nrbchan;
> - for (i = 0; i < dch->dev.nrbchan; i++) {
> - phi->bch[i].protocol = hw->bch[i].ch.protocol;
> - phi->bch[i].Flags = hw->bch[i].Flags;
> - }
> - _queue_data(&dch->dev.D, MPH_INFORMATION_IND, MISDN_ID_ANY,
> - struct_size(phi, bch, dch->dev.nrbchan), phi, GFP_ATOMIC);
> - kfree(phi);
> -
> - return 0;
> -}
> -
> -/*
> - * Layer2 -> Layer 1 Dchannel data
> - */
> -static int
> -hfcusb_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb)
> -{
> - struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
> - struct dchannel *dch = container_of(dev, struct dchannel, dev);
> - struct mISDNhead *hh = mISDN_HEAD_P(skb);
> - struct hfcsusb *hw = dch->hw;
> - int ret = -EINVAL;
> - u_long flags;
> -
> - switch (hh->prim) {
> - case PH_DATA_REQ:
> - if (debug & DBG_HFC_CALL_TRACE)
> - printk(KERN_DEBUG "%s: %s: PH_DATA_REQ\n",
> - hw->name, __func__);
> -
> - spin_lock_irqsave(&hw->lock, flags);
> - ret = dchannel_senddata(dch, skb);
> - spin_unlock_irqrestore(&hw->lock, flags);
> - if (ret > 0) {
> - ret = 0;
> - queue_ch_frame(ch, PH_DATA_CNF, hh->id, NULL);
> - }
> - break;
> -
> - case PH_ACTIVATE_REQ:
> - if (debug & DBG_HFC_CALL_TRACE)
> - printk(KERN_DEBUG "%s: %s: PH_ACTIVATE_REQ %s\n",
> - hw->name, __func__,
> - (hw->protocol == ISDN_P_NT_S0) ? "NT" : "TE");
> -
> - if (hw->protocol == ISDN_P_NT_S0) {
> - ret = 0;
> - if (test_bit(FLG_ACTIVE, &dch->Flags)) {
> - _queue_data(&dch->dev.D,
> - PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
> - NULL, GFP_ATOMIC);
> - } else {
> - hfcsusb_ph_command(hw,
> - HFC_L1_ACTIVATE_NT);
> - test_and_set_bit(FLG_L2_ACTIVATED,
> - &dch->Flags);
> - }
> - } else {
> - hfcsusb_ph_command(hw, HFC_L1_ACTIVATE_TE);
> - ret = l1_event(dch->l1, hh->prim);
> - }
> - break;
> -
> - case PH_DEACTIVATE_REQ:
> - if (debug & DBG_HFC_CALL_TRACE)
> - printk(KERN_DEBUG "%s: %s: PH_DEACTIVATE_REQ\n",
> - hw->name, __func__);
> - test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
> -
> - if (hw->protocol == ISDN_P_NT_S0) {
> - struct sk_buff_head free_queue;
> -
> - __skb_queue_head_init(&free_queue);
> - hfcsusb_ph_command(hw, HFC_L1_DEACTIVATE_NT);
> - spin_lock_irqsave(&hw->lock, flags);
> - skb_queue_splice_init(&dch->squeue, &free_queue);
> - if (dch->tx_skb) {
> - __skb_queue_tail(&free_queue, dch->tx_skb);
> - dch->tx_skb = NULL;
> - }
> - dch->tx_idx = 0;
> - if (dch->rx_skb) {
> - __skb_queue_tail(&free_queue, dch->rx_skb);
> - dch->rx_skb = NULL;
> - }
> - test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
> - spin_unlock_irqrestore(&hw->lock, flags);
> - __skb_queue_purge(&free_queue);
> -#ifdef FIXME
> - if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags))
> - dchannel_sched_event(&hc->dch, D_CLEARBUSY);
> -#endif
> - ret = 0;
> - } else
> - ret = l1_event(dch->l1, hh->prim);
> - break;
> - case MPH_INFORMATION_REQ:
> - ret = hfcsusb_ph_info(hw);
> - break;
> - }
> -
> - return ret;
> -}
> -
> -/*
> - * Layer 1 callback function
> - */
> -static int
> -hfc_l1callback(struct dchannel *dch, u_int cmd)
> -{
> - struct hfcsusb *hw = dch->hw;
> -
> - if (debug & DBG_HFC_CALL_TRACE)
> - printk(KERN_DEBUG "%s: %s cmd 0x%x\n",
> - hw->name, __func__, cmd);
> -
> - switch (cmd) {
> - case INFO3_P8:
> - case INFO3_P10:
> - case HW_RESET_REQ:
> - case HW_POWERUP_REQ:
> - break;
> -
> - case HW_DEACT_REQ:
> - skb_queue_purge(&dch->squeue);
> - if (dch->tx_skb) {
> - dev_kfree_skb(dch->tx_skb);
> - dch->tx_skb = NULL;
> - }
> - dch->tx_idx = 0;
> - if (dch->rx_skb) {
> - dev_kfree_skb(dch->rx_skb);
> - dch->rx_skb = NULL;
> - }
> - test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
> - break;
> - case PH_ACTIVATE_IND:
> - test_and_set_bit(FLG_ACTIVE, &dch->Flags);
> - _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
> - GFP_ATOMIC);
> - break;
> - case PH_DEACTIVATE_IND:
> - test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
> - _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
> - GFP_ATOMIC);
> - break;
> - default:
> - if (dch->debug & DEBUG_HW)
> - printk(KERN_DEBUG "%s: %s: unknown cmd %x\n",
> - hw->name, __func__, cmd);
> - return -1;
> - }
> - return hfcsusb_ph_info(hw);
> -}
> -
> -static int
> -open_dchannel(struct hfcsusb *hw, struct mISDNchannel *ch,
> - struct channel_req *rq)
> -{
> - int err = 0;
> -
> - if (debug & DEBUG_HW_OPEN)
> - printk(KERN_DEBUG "%s: %s: dev(%d) open addr(%i) from %p\n",
> - hw->name, __func__, hw->dch.dev.id, rq->adr.channel,
> - __builtin_return_address(0));
> - if (rq->protocol == ISDN_P_NONE)
> - return -EINVAL;
> -
> - test_and_clear_bit(FLG_ACTIVE, &hw->dch.Flags);
> - test_and_clear_bit(FLG_ACTIVE, &hw->ech.Flags);
> - hfcsusb_start_endpoint(hw, HFC_CHAN_D);
> -
> - /* E-Channel logging */
> - if (rq->adr.channel == 1) {
> - if (hw->fifos[HFCUSB_PCM_RX].pipe) {
> - hfcsusb_start_endpoint(hw, HFC_CHAN_E);
> - set_bit(FLG_ACTIVE, &hw->ech.Flags);
> - _queue_data(&hw->ech.dev.D, PH_ACTIVATE_IND,
> - MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
> - } else
> - return -EINVAL;
> - }
> -
> - if (!hw->initdone) {
> - hw->protocol = rq->protocol;
> - if (rq->protocol == ISDN_P_TE_S0) {
> - err = create_l1(&hw->dch, hfc_l1callback);
> - if (err)
> - return err;
> - }
> - setPortMode(hw);
> - ch->protocol = rq->protocol;
> - hw->initdone = 1;
> - } else {
> - if (rq->protocol != ch->protocol)
> - return -EPROTONOSUPPORT;
> - }
> -
> - if (((ch->protocol == ISDN_P_NT_S0) && (hw->dch.state == 3)) ||
> - ((ch->protocol == ISDN_P_TE_S0) && (hw->dch.state == 7)))
> - _queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY,
> - 0, NULL, GFP_KERNEL);
> - rq->ch = ch;
> - if (!try_module_get(THIS_MODULE))
> - printk(KERN_WARNING "%s: %s: cannot get module\n",
> - hw->name, __func__);
> - return 0;
> -}
> -
> -static int
> -open_bchannel(struct hfcsusb *hw, struct channel_req *rq)
> -{
> - struct bchannel *bch;
> -
> - if (rq->adr.channel == 0 || rq->adr.channel > 2)
> - return -EINVAL;
> - if (rq->protocol == ISDN_P_NONE)
> - return -EINVAL;
> -
> - if (debug & DBG_HFC_CALL_TRACE)
> - printk(KERN_DEBUG "%s: %s B%i\n",
> - hw->name, __func__, rq->adr.channel);
> -
> - bch = &hw->bch[rq->adr.channel - 1];
> - if (test_and_set_bit(FLG_OPEN, &bch->Flags))
> - return -EBUSY; /* b-channel can be only open once */
> - bch->ch.protocol = rq->protocol;
> - rq->ch = &bch->ch;
> -
> - if (!try_module_get(THIS_MODULE))
> - printk(KERN_WARNING "%s: %s:cannot get module\n",
> - hw->name, __func__);
> - return 0;
> -}
> -
> -static int
> -channel_ctrl(struct hfcsusb *hw, struct mISDN_ctrl_req *cq)
> -{
> - int ret = 0;
> -
> - if (debug & DBG_HFC_CALL_TRACE)
> - printk(KERN_DEBUG "%s: %s op(0x%x) channel(0x%x)\n",
> - hw->name, __func__, (cq->op), (cq->channel));
> -
> - switch (cq->op) {
> - case MISDN_CTRL_GETOP:
> - cq->op = MISDN_CTRL_LOOP | MISDN_CTRL_CONNECT |
> - MISDN_CTRL_DISCONNECT;
> - break;
> - default:
> - printk(KERN_WARNING "%s: %s: unknown Op %x\n",
> - hw->name, __func__, cq->op);
> - ret = -EINVAL;
> - break;
> - }
> - return ret;
> -}
> -
> -/*
> - * device control function
> - */
> -static int
> -hfc_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
> -{
> - struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
> - struct dchannel *dch = container_of(dev, struct dchannel, dev);
> - struct hfcsusb *hw = dch->hw;
> - struct channel_req *rq;
> - int err = 0;
> -
> - if (dch->debug & DEBUG_HW)
> - printk(KERN_DEBUG "%s: %s: cmd:%x %p\n",
> - hw->name, __func__, cmd, arg);
> - switch (cmd) {
> - case OPEN_CHANNEL:
> - rq = arg;
> - if ((rq->protocol == ISDN_P_TE_S0) ||
> - (rq->protocol == ISDN_P_NT_S0))
> - err = open_dchannel(hw, ch, rq);
> - else
> - err = open_bchannel(hw, rq);
> - if (!err)
> - hw->open++;
> - break;
> - case CLOSE_CHANNEL:
> - hw->open--;
> - if (debug & DEBUG_HW_OPEN)
> - printk(KERN_DEBUG
> - "%s: %s: dev(%d) close from %p (open %d)\n",
> - hw->name, __func__, hw->dch.dev.id,
> - __builtin_return_address(0), hw->open);
> - if (!hw->open) {
> - hfcsusb_stop_endpoint(hw, HFC_CHAN_D);
> - if (hw->fifos[HFCUSB_PCM_RX].pipe)
> - hfcsusb_stop_endpoint(hw, HFC_CHAN_E);
> - handle_led(hw, LED_POWER_ON);
> - }
> - module_put(THIS_MODULE);
> - break;
> - case CONTROL_CHANNEL:
> - err = channel_ctrl(hw, arg);
> - break;
> - default:
> - if (dch->debug & DEBUG_HW)
> - printk(KERN_DEBUG "%s: %s: unknown command %x\n",
> - hw->name, __func__, cmd);
> - return -EINVAL;
> - }
> - return err;
> -}
> -
> -/*
> - * S0 TE state change event handler
> - */
> -static void
> -ph_state_te(struct dchannel *dch)
> -{
> - struct hfcsusb *hw = dch->hw;
> -
> - if (debug & DEBUG_HW) {
> - if (dch->state <= HFC_MAX_TE_LAYER1_STATE)
> - printk(KERN_DEBUG "%s: %s: %s\n", hw->name, __func__,
> - HFC_TE_LAYER1_STATES[dch->state]);
> - else
> - printk(KERN_DEBUG "%s: %s: TE F%d\n",
> - hw->name, __func__, dch->state);
> - }
> -
> - switch (dch->state) {
> - case 0:
> - l1_event(dch->l1, HW_RESET_IND);
> - break;
> - case 3:
> - l1_event(dch->l1, HW_DEACT_IND);
> - break;
> - case 5:
> - case 8:
> - l1_event(dch->l1, ANYSIGNAL);
> - break;
> - case 6:
> - l1_event(dch->l1, INFO2);
> - break;
> - case 7:
> - l1_event(dch->l1, INFO4_P8);
> - break;
> - }
> - if (dch->state == 7)
> - handle_led(hw, LED_S0_ON);
> - else
> - handle_led(hw, LED_S0_OFF);
> -}
> -
> -/*
> - * S0 NT state change event handler
> - */
> -static void
> -ph_state_nt(struct dchannel *dch)
> -{
> - struct hfcsusb *hw = dch->hw;
> -
> - if (debug & DEBUG_HW) {
> - if (dch->state <= HFC_MAX_NT_LAYER1_STATE)
> - printk(KERN_DEBUG "%s: %s: %s\n",
> - hw->name, __func__,
> - HFC_NT_LAYER1_STATES[dch->state]);
> -
> - else
> - printk(KERN_INFO DRIVER_NAME "%s: %s: NT G%d\n",
> - hw->name, __func__, dch->state);
> - }
> -
> - switch (dch->state) {
> - case (1):
> - test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
> - test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
> - hw->nt_timer = 0;
> - hw->timers &= ~NT_ACTIVATION_TIMER;
> - handle_led(hw, LED_S0_OFF);
> - break;
> -
> - case (2):
> - if (hw->nt_timer < 0) {
> - hw->nt_timer = 0;
> - hw->timers &= ~NT_ACTIVATION_TIMER;
> - hfcsusb_ph_command(dch->hw, HFC_L1_DEACTIVATE_NT);
> - } else {
> - hw->timers |= NT_ACTIVATION_TIMER;
> - hw->nt_timer = NT_T1_COUNT;
> - /* allow G2 -> G3 transition */
> - write_reg(hw, HFCUSB_STATES, 2 | HFCUSB_NT_G2_G3);
> - }
> - break;
> - case (3):
> - hw->nt_timer = 0;
> - hw->timers &= ~NT_ACTIVATION_TIMER;
> - test_and_set_bit(FLG_ACTIVE, &dch->Flags);
> - _queue_data(&dch->dev.D, PH_ACTIVATE_IND,
> - MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
> - handle_led(hw, LED_S0_ON);
> - break;
> - case (4):
> - hw->nt_timer = 0;
> - hw->timers &= ~NT_ACTIVATION_TIMER;
> - break;
> - default:
> - break;
> - }
> - hfcsusb_ph_info(hw);
> -}
> -
> -static void
> -ph_state(struct dchannel *dch)
> -{
> - struct hfcsusb *hw = dch->hw;
> -
> - if (hw->protocol == ISDN_P_NT_S0)
> - ph_state_nt(dch);
> - else if (hw->protocol == ISDN_P_TE_S0)
> - ph_state_te(dch);
> -}
> -
> -/*
> - * disable/enable BChannel for desired protocol
> - */
> -static int
> -hfcsusb_setup_bch(struct bchannel *bch, int protocol)
> -{
> - struct hfcsusb *hw = bch->hw;
> - __u8 conhdlc, sctrl, sctrl_r;
> -
> - if (debug & DEBUG_HW)
> - printk(KERN_DEBUG "%s: %s: protocol %x-->%x B%d\n",
> - hw->name, __func__, bch->state, protocol,
> - bch->nr);
> -
> - /* setup val for CON_HDLC */
> - conhdlc = 0;
> - if (protocol > ISDN_P_NONE)
> - conhdlc = 8; /* enable FIFO */
> -
> - switch (protocol) {
> - case (-1): /* used for init */
> - bch->state = -1;
> - fallthrough;
> - case (ISDN_P_NONE):
> - if (bch->state == ISDN_P_NONE)
> - return 0; /* already in idle state */
> - bch->state = ISDN_P_NONE;
> - clear_bit(FLG_HDLC, &bch->Flags);
> - clear_bit(FLG_TRANSPARENT, &bch->Flags);
> - break;
> - case (ISDN_P_B_RAW):
> - conhdlc |= 2;
> - bch->state = protocol;
> - set_bit(FLG_TRANSPARENT, &bch->Flags);
> - break;
> - case (ISDN_P_B_HDLC):
> - bch->state = protocol;
> - set_bit(FLG_HDLC, &bch->Flags);
> - break;
> - default:
> - if (debug & DEBUG_HW)
> - printk(KERN_DEBUG "%s: %s: prot not known %x\n",
> - hw->name, __func__, protocol);
> - return -ENOPROTOOPT;
> - }
> -
> - if (protocol >= ISDN_P_NONE) {
> - write_reg(hw, HFCUSB_FIFO, (bch->nr == 1) ? 0 : 2);
> - write_reg(hw, HFCUSB_CON_HDLC, conhdlc);
> - write_reg(hw, HFCUSB_INC_RES_F, 2);
> - write_reg(hw, HFCUSB_FIFO, (bch->nr == 1) ? 1 : 3);
> - write_reg(hw, HFCUSB_CON_HDLC, conhdlc);
> - write_reg(hw, HFCUSB_INC_RES_F, 2);
> -
> - sctrl = 0x40 + ((hw->protocol == ISDN_P_TE_S0) ? 0x00 : 0x04);
> - sctrl_r = 0x0;
> - if (test_bit(FLG_ACTIVE, &hw->bch[0].Flags)) {
> - sctrl |= 1;
> - sctrl_r |= 1;
> - }
> - if (test_bit(FLG_ACTIVE, &hw->bch[1].Flags)) {
> - sctrl |= 2;
> - sctrl_r |= 2;
> - }
> - write_reg(hw, HFCUSB_SCTRL, sctrl);
> - write_reg(hw, HFCUSB_SCTRL_R, sctrl_r);
> -
> - if (protocol > ISDN_P_NONE)
> - handle_led(hw, (bch->nr == 1) ? LED_B1_ON : LED_B2_ON);
> - else
> - handle_led(hw, (bch->nr == 1) ? LED_B1_OFF :
> - LED_B2_OFF);
> - }
> - return hfcsusb_ph_info(hw);
> -}
> -
> -static void
> -hfcsusb_ph_command(struct hfcsusb *hw, u_char command)
> -{
> - if (debug & DEBUG_HW)
> - printk(KERN_DEBUG "%s: %s: %x\n",
> - hw->name, __func__, command);
> -
> - switch (command) {
> - case HFC_L1_ACTIVATE_TE:
> - /* force sending sending INFO1 */
> - write_reg(hw, HFCUSB_STATES, 0x14);
> - /* start l1 activation */
> - write_reg(hw, HFCUSB_STATES, 0x04);
> - break;
> -
> - case HFC_L1_FORCE_DEACTIVATE_TE:
> - write_reg(hw, HFCUSB_STATES, 0x10);
> - write_reg(hw, HFCUSB_STATES, 0x03);
> - break;
> -
> - case HFC_L1_ACTIVATE_NT:
> - if (hw->dch.state == 3)
> - _queue_data(&hw->dch.dev.D, PH_ACTIVATE_IND,
> - MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
> - else
> - write_reg(hw, HFCUSB_STATES, HFCUSB_ACTIVATE |
> - HFCUSB_DO_ACTION | HFCUSB_NT_G2_G3);
> - break;
> -
> - case HFC_L1_DEACTIVATE_NT:
> - write_reg(hw, HFCUSB_STATES,
> - HFCUSB_DO_ACTION);
> - break;
> - }
> -}
> -
> -/*
> - * Layer 1 B-channel hardware access
> - */
> -static int
> -channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
> -{
> - return mISDN_ctrl_bchannel(bch, cq);
> -}
> -
> -/* collect data from incoming interrupt or isochron USB data */
> -static void
> -hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
> - int finish)
> -{
> - struct hfcsusb *hw = fifo->hw;
> - struct sk_buff *rx_skb = NULL;
> - int maxlen = 0;
> - int fifon = fifo->fifonum;
> - int i;
> - int hdlc = 0;
> - unsigned long flags;
> -
> - if (debug & DBG_HFC_CALL_TRACE)
> - printk(KERN_DEBUG "%s: %s: fifo(%i) len(%i) "
> - "dch(%p) bch(%p) ech(%p)\n",
> - hw->name, __func__, fifon, len,
> - fifo->dch, fifo->bch, fifo->ech);
> -
> - if (!len)
> - return;
> -
> - if ((!!fifo->dch + !!fifo->bch + !!fifo->ech) != 1) {
> - printk(KERN_DEBUG "%s: %s: undefined channel\n",
> - hw->name, __func__);
> - return;
> - }
> -
> - spin_lock_irqsave(&hw->lock, flags);
> - if (fifo->dch) {
> - rx_skb = fifo->dch->rx_skb;
> - maxlen = fifo->dch->maxlen;
> - hdlc = 1;
> - }
> - if (fifo->bch) {
> - if (test_bit(FLG_RX_OFF, &fifo->bch->Flags)) {
> - fifo->bch->dropcnt += len;
> - spin_unlock_irqrestore(&hw->lock, flags);
> - return;
> - }
> - maxlen = bchannel_get_rxbuf(fifo->bch, len);
> - rx_skb = fifo->bch->rx_skb;
> - if (maxlen < 0) {
> - if (rx_skb)
> - skb_trim(rx_skb, 0);
> - pr_warn("%s.B%d: No bufferspace for %d bytes\n",
> - hw->name, fifo->bch->nr, len);
> - spin_unlock_irqrestore(&hw->lock, flags);
> - return;
> - }
> - maxlen = fifo->bch->maxlen;
> - hdlc = test_bit(FLG_HDLC, &fifo->bch->Flags);
> - }
> - if (fifo->ech) {
> - rx_skb = fifo->ech->rx_skb;
> - maxlen = fifo->ech->maxlen;
> - hdlc = 1;
> - }
> -
> - if (fifo->dch || fifo->ech) {
> - if (!rx_skb) {
> - rx_skb = mI_alloc_skb(maxlen, GFP_ATOMIC);
> - if (rx_skb) {
> - if (fifo->dch)
> - fifo->dch->rx_skb = rx_skb;
> - if (fifo->ech)
> - fifo->ech->rx_skb = rx_skb;
> - skb_trim(rx_skb, 0);
> - } else {
> - printk(KERN_DEBUG "%s: %s: No mem for rx_skb\n",
> - hw->name, __func__);
> - spin_unlock_irqrestore(&hw->lock, flags);
> - return;
> - }
> - }
> - /* D/E-Channel SKB range check */
> - if ((rx_skb->len + len) >= MAX_DFRAME_LEN_L1) {
> - printk(KERN_DEBUG "%s: %s: sbk mem exceeded "
> - "for fifo(%d) HFCUSB_D_RX\n",
> - hw->name, __func__, fifon);
> - skb_trim(rx_skb, 0);
> - spin_unlock_irqrestore(&hw->lock, flags);
> - return;
> - }
> - }
> -
> - skb_put_data(rx_skb, data, len);
> -
> - if (hdlc) {
> - /* we have a complete hdlc packet */
> - if (finish) {
> - if ((rx_skb->len > 3) &&
> - (!(rx_skb->data[rx_skb->len - 1]))) {
> - if (debug & DBG_HFC_FIFO_VERBOSE) {
> - printk(KERN_DEBUG "%s: %s: fifon(%i)"
> - " new RX len(%i): ",
> - hw->name, __func__, fifon,
> - rx_skb->len);
> - i = 0;
> - while (i < rx_skb->len)
> - printk("%02x ",
> - rx_skb->data[i++]);
> - printk("\n");
> - }
> -
> - /* remove CRC & status */
> - skb_trim(rx_skb, rx_skb->len - 3);
> -
> - if (fifo->dch)
> - recv_Dchannel(fifo->dch);
> - if (fifo->bch)
> - recv_Bchannel(fifo->bch, MISDN_ID_ANY,
> - 0);
> - if (fifo->ech)
> - recv_Echannel(fifo->ech,
> - &hw->dch);
> - } else {
> - if (debug & DBG_HFC_FIFO_VERBOSE) {
> - printk(KERN_DEBUG
> - "%s: CRC or minlen ERROR fifon(%i) "
> - "RX len(%i): ",
> - hw->name, fifon, rx_skb->len);
> - i = 0;
> - while (i < rx_skb->len)
> - printk("%02x ",
> - rx_skb->data[i++]);
> - printk("\n");
> - }
> - skb_trim(rx_skb, 0);
> - }
> - }
> - } else {
> - /* deliver transparent data to layer2 */
> - recv_Bchannel(fifo->bch, MISDN_ID_ANY, false);
> - }
> - spin_unlock_irqrestore(&hw->lock, flags);
> -}
> -
> -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_bulk_urb(urb, dev, pipe, buf, packet_size * num_packets,
> - complete, context);
> -
> - urb->number_of_packets = num_packets;
> - urb->transfer_flags = URB_ISO_ASAP;
> - urb->actual_length = 0;
> - urb->interval = interval;
> -
> - 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;
> - }
> -}
> -
> -/* receive completion routine for all ISO tx fifos */
> -static void
> -rx_iso_complete(struct urb *urb)
> -{
> - struct iso_urb *context_iso_urb = (struct iso_urb *) urb->context;
> - struct usb_fifo *fifo = context_iso_urb->owner_fifo;
> - struct hfcsusb *hw = fifo->hw;
> - int k, len, errcode, offset, num_isoc_packets, fifon, maxlen,
> - status, iso_status, i;
> - __u8 *buf;
> - static __u8 eof[8];
> - __u8 s0_state;
> - unsigned long flags;
> -
> - fifon = fifo->fifonum;
> - status = urb->status;
> -
> - spin_lock_irqsave(&hw->lock, flags);
> - if (fifo->stop_gracefull) {
> - fifo->stop_gracefull = 0;
> - fifo->active = 0;
> - spin_unlock_irqrestore(&hw->lock, flags);
> - return;
> - }
> - spin_unlock_irqrestore(&hw->lock, flags);
> -
> - /*
> - * ISO transfer only partially completed,
> - * look at individual frame status for details
> - */
> - if (status == -EXDEV) {
> - if (debug & DEBUG_HW)
> - printk(KERN_DEBUG "%s: %s: with -EXDEV "
> - "urb->status %d, fifonum %d\n",
> - hw->name, __func__, status, fifon);
> -
> - /* clear status, so go on with ISO transfers */
> - status = 0;
> - }
> -
> - s0_state = 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 && (debug & DBG_HFC_FIFO_VERBOSE)) {
> - printk(KERN_DEBUG "%s: %s: "
> - "ISO packet %i, status: %i\n",
> - hw->name, __func__, k, iso_status);
> - }
> -
> - /* USB data log for every D ISO in */
> - if ((fifon == HFCUSB_D_RX) &&
> - (debug & DBG_HFC_USB_VERBOSE)) {
> - printk(KERN_DEBUG
> - "%s: %s: %d (%d/%d) len(%d) ",
> - hw->name, __func__, urb->start_frame,
> - k, num_isoc_packets - 1,
> - len);
> - for (i = 0; i < len; i++)
> - printk("%x ", buf[i]);
> - printk("\n");
> - }
> -
> - if (!iso_status) {
> - if (fifo->last_urblen != maxlen) {
> - /*
> - * save fifo fill-level threshold bits
> - * to use them later in TX ISO URB
> - * completions
> - */
> - hw->threshold_mask = buf[1];
> -
> - if (fifon == HFCUSB_D_RX)
> - s0_state = (buf[0] >> 4);
> -
> - eof[fifon] = buf[0] & 1;
> - if (len > 2)
> - hfcsusb_rx_frame(fifo, buf + 2,
> - len - 2, (len < maxlen)
> - ? eof[fifon] : 0);
> - } else
> - hfcsusb_rx_frame(fifo, buf, len,
> - (len < maxlen) ?
> - eof[fifon] : 0);
> - fifo->last_urblen = len;
> - }
> - }
> -
> - /* signal S0 layer1 state change */
> - if ((s0_state) && (hw->initdone) &&
> - (s0_state != hw->dch.state)) {
> - hw->dch.state = s0_state;
> - schedule_event(&hw->dch, FLG_PHCHANGE);
> - }
> -
> - fill_isoc_urb(urb, fifo->hw->dev, fifo->pipe,
> - context_iso_urb->buffer, num_isoc_packets,
> - fifo->usb_packet_maxlen, fifo->intervall,
> - (usb_complete_t)rx_iso_complete, urb->context);
> - errcode = usb_submit_urb(urb, GFP_ATOMIC);
> - if (errcode < 0) {
> - if (debug & DEBUG_HW)
> - printk(KERN_DEBUG "%s: %s: error submitting "
> - "ISO URB: %d\n",
> - hw->name, __func__, errcode);
> - }
> - } else {
> - if (status && (debug & DBG_HFC_URB_INFO))
> - printk(KERN_DEBUG "%s: %s: rx_iso_complete : "
> - "urb->status %d, fifonum %d\n",
> - hw->name, __func__, status, fifon);
> - }
> -}
> -
> -/* receive completion routine for all interrupt rx fifos */
> -static void
> -rx_int_complete(struct urb *urb)
> -{
> - int len, status, i;
> - __u8 *buf, maxlen, fifon;
> - struct usb_fifo *fifo = (struct usb_fifo *) urb->context;
> - struct hfcsusb *hw = fifo->hw;
> - static __u8 eof[8];
> - unsigned long flags;
> -
> - spin_lock_irqsave(&hw->lock, flags);
> - if (fifo->stop_gracefull) {
> - fifo->stop_gracefull = 0;
> - fifo->active = 0;
> - spin_unlock_irqrestore(&hw->lock, flags);
> - return;
> - }
> - spin_unlock_irqrestore(&hw->lock, flags);
> -
> - fifon = fifo->fifonum;
> - if ((!fifo->active) || (urb->status)) {
> - if (debug & DBG_HFC_URB_ERROR)
> - printk(KERN_DEBUG
> - "%s: %s: RX-Fifo %i is going down (%i)\n",
> - hw->name, __func__, fifon, urb->status);
> -
> - fifo->urb->interval = 0; /* cancel automatic rescheduling */
> - return;
> - }
> - len = urb->actual_length;
> - buf = fifo->buffer;
> - maxlen = fifo->usb_packet_maxlen;
> -
> - /* USB data log for every D INT in */
> - if ((fifon == HFCUSB_D_RX) && (debug & DBG_HFC_USB_VERBOSE)) {
> - printk(KERN_DEBUG "%s: %s: D RX INT len(%d) ",
> - hw->name, __func__, len);
> - for (i = 0; i < len; i++)
> - printk("%02x ", buf[i]);
> - printk("\n");
> - }
> -
> - if (fifo->last_urblen != fifo->usb_packet_maxlen) {
> - /* the threshold mask is in the 2nd status byte */
> - hw->threshold_mask = buf[1];
> -
> - /* signal S0 layer1 state change */
> - if (hw->initdone && ((buf[0] >> 4) != hw->dch.state)) {
> - hw->dch.state = (buf[0] >> 4);
> - schedule_event(&hw->dch, FLG_PHCHANGE);
> - }
> -
> - eof[fifon] = buf[0] & 1;
> - /* if we have more than the 2 status bytes -> collect data */
> - if (len > 2)
> - hfcsusb_rx_frame(fifo, buf + 2,
> - urb->actual_length - 2,
> - (len < maxlen) ? eof[fifon] : 0);
> - } else {
> - hfcsusb_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) {
> - if (debug & DEBUG_HW)
> - printk(KERN_DEBUG "%s: %s: error resubmitting USB\n",
> - hw->name, __func__);
> - }
> -}
> -
> -/* transmit completion routine for all ISO tx fifos */
> -static void
> -tx_iso_complete(struct urb *urb)
> -{
> - struct iso_urb *context_iso_urb = (struct iso_urb *) urb->context;
> - struct usb_fifo *fifo = context_iso_urb->owner_fifo;
> - struct hfcsusb *hw = fifo->hw;
> - struct sk_buff *tx_skb;
> - int k, tx_offset, num_isoc_packets, sink, remain, current_len,
> - errcode, hdlc, i;
> - int *tx_idx;
> - int frame_complete, fifon, status, fillempty = 0;
> - __u8 threshbit, *p;
> - unsigned long flags;
> -
> - spin_lock_irqsave(&hw->lock, flags);
> - if (fifo->stop_gracefull) {
> - fifo->stop_gracefull = 0;
> - fifo->active = 0;
> - spin_unlock_irqrestore(&hw->lock, flags);
> - return;
> - }
> -
> - if (fifo->dch) {
> - tx_skb = fifo->dch->tx_skb;
> - tx_idx = &fifo->dch->tx_idx;
> - hdlc = 1;
> - } else if (fifo->bch) {
> - tx_skb = fifo->bch->tx_skb;
> - tx_idx = &fifo->bch->tx_idx;
> - hdlc = test_bit(FLG_HDLC, &fifo->bch->Flags);
> - if (!tx_skb && !hdlc &&
> - test_bit(FLG_FILLEMPTY, &fifo->bch->Flags))
> - fillempty = 1;
> - } else {
> - printk(KERN_DEBUG "%s: %s: neither BCH nor DCH\n",
> - hw->name, __func__);
> - spin_unlock_irqrestore(&hw->lock, flags);
> - return;
> - }
> -
> - fifon = fifo->fifonum;
> - status = urb->status;
> -
> - tx_offset = 0;
> -
> - /*
> - * ISO transfer only partially completed,
> - * look at individual frame status for details
> - */
> - if (status == -EXDEV) {
> - if (debug & DBG_HFC_URB_ERROR)
> - printk(KERN_DEBUG "%s: %s: "
> - "-EXDEV (%i) fifon (%d)\n",
> - hw->name, __func__, status, fifon);
> -
> - /* clear status, so go on with ISO transfers */
> - status = 0;
> - }
> -
> - if (fifo->active && !status) {
> - /* is FifoFull-threshold set for our channel? */
> - threshbit = (hw->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->hw->dev, fifo->pipe,
> - context_iso_urb->buffer, num_isoc_packets,
> - fifo->usb_packet_maxlen, fifo->intervall,
> - (usb_complete_t)tx_iso_complete, urb->context);
> - memset(context_iso_urb->buffer, 0,
> - sizeof(context_iso_urb->buffer));
> - frame_complete = 0;
> -
> - for (k = 0; k < num_isoc_packets; ++k) {
> - /* analyze tx success of previous ISO packets */
> - if (debug & DBG_HFC_URB_ERROR) {
> - errcode = urb->iso_frame_desc[k].status;
> - if (errcode) {
> - printk(KERN_DEBUG "%s: %s: "
> - "ISO packet %i, status: %i\n",
> - hw->name, __func__, k, errcode);
> - }
> - }
> -
> - /* Generate next ISO Packets */
> - if (tx_skb)
> - remain = tx_skb->len - *tx_idx;
> - else if (fillempty)
> - remain = 15; /* > not complete */
> - else
> - remain = 0;
> -
> - if (remain > 0) {
> - fifo->bit_line -= sink;
> - current_len = (0 - fifo->bit_line) / 8;
> - if (current_len > 14)
> - current_len = 14;
> - if (current_len < 0)
> - current_len = 0;
> - if (remain < current_len)
> - current_len = remain;
> -
> - /* 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 == remain) {
> - if (hdlc) {
> - /* signal 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;
> - }
> -
> - /* copy tx data to iso-urb buffer */
> - p = context_iso_urb->buffer + tx_offset + 1;
> - if (fillempty) {
> - memset(p, fifo->bch->fill[0],
> - current_len);
> - } else {
> - memcpy(p, (tx_skb->data + *tx_idx),
> - current_len);
> - *tx_idx += current_len;
> - }
> - urb->iso_frame_desc[k].offset = tx_offset;
> - urb->iso_frame_desc[k].length = current_len + 1;
> -
> - /* USB data log for every D ISO out */
> - if ((fifon == HFCUSB_D_RX) && !fillempty &&
> - (debug & DBG_HFC_USB_VERBOSE)) {
> - printk(KERN_DEBUG
> - "%s: %s (%d/%d) offs(%d) len(%d) ",
> - hw->name, __func__,
> - k, num_isoc_packets - 1,
> - urb->iso_frame_desc[k].offset,
> - urb->iso_frame_desc[k].length);
> -
> - for (i = urb->iso_frame_desc[k].offset;
> - i < (urb->iso_frame_desc[k].offset
> - + urb->iso_frame_desc[k].length);
> - i++)
> - printk("%x ",
> - context_iso_urb->buffer[i]);
> -
> - printk(" skb->len(%i) tx-idx(%d)\n",
> - tx_skb->len, *tx_idx);
> - }
> -
> - tx_offset += (current_len + 1);
> - } else {
> - urb->iso_frame_desc[k].offset = tx_offset++;
> - urb->iso_frame_desc[k].length = 1;
> - /* we lower data margin every msec */
> - fifo->bit_line -= sink;
> - if (fifo->bit_line < BITLINE_INF)
> - fifo->bit_line = BITLINE_INF;
> - }
> -
> - if (frame_complete) {
> - frame_complete = 0;
> -
> - if (debug & DBG_HFC_FIFO_VERBOSE) {
> - printk(KERN_DEBUG "%s: %s: "
> - "fifon(%i) new TX len(%i): ",
> - hw->name, __func__,
> - fifon, tx_skb->len);
> - i = 0;
> - while (i < tx_skb->len)
> - printk("%02x ",
> - tx_skb->data[i++]);
> - printk("\n");
> - }
> -
> - dev_consume_skb_irq(tx_skb);
> - tx_skb = NULL;
> - if (fifo->dch && get_next_dframe(fifo->dch))
> - tx_skb = fifo->dch->tx_skb;
> - else if (fifo->bch &&
> - get_next_bframe(fifo->bch))
> - tx_skb = fifo->bch->tx_skb;
> - }
> - }
> - errcode = usb_submit_urb(urb, GFP_ATOMIC);
> - if (errcode < 0) {
> - if (debug & DEBUG_HW)
> - printk(KERN_DEBUG
> - "%s: %s: error submitting ISO URB: %d \n",
> - hw->name, __func__, errcode);
> - }
> -
> - /*
> - * abuse DChannel tx iso completion to trigger NT mode state
> - * changes tx_iso_complete is assumed to be called every
> - * fifo->intervall (ms)
> - */
> - if ((fifon == HFCUSB_D_TX) && (hw->protocol == ISDN_P_NT_S0)
> - && (hw->timers & NT_ACTIVATION_TIMER)) {
> - if ((--hw->nt_timer) < 0)
> - schedule_event(&hw->dch, FLG_PHCHANGE);
> - }
> -
> - } else {
> - if (status && (debug & DBG_HFC_URB_ERROR))
> - printk(KERN_DEBUG "%s: %s: urb->status %s (%i)"
> - "fifonum=%d\n",
> - hw->name, __func__,
> - symbolic(urb_errlist, status), status, fifon);
> - }
> - spin_unlock_irqrestore(&hw->lock, flags);
> -}
> -
> -/*
> - * allocs urbs and start isoc transfer with two pending urbs to avoid
> - * gaps in the transfer chain
> - */
> -static int
> -start_isoc_chain(struct usb_fifo *fifo, int num_packets_per_urb,
> - usb_complete_t complete, int packet_size)
> -{
> - struct hfcsusb *hw = fifo->hw;
> - int i, k, errcode;
> -
> - if (debug)
> - printk(KERN_DEBUG "%s: %s: fifo %i\n",
> - hw->name, __func__, fifo->fifonum);
> -
> - /* allocate Memory for Iso out Urbs */
> - for (i = 0; i < 2; i++) {
> - if (!(fifo->iso[i].urb)) {
> - fifo->iso[i].urb =
> - usb_alloc_urb(num_packets_per_urb, GFP_KERNEL);
> - if (!(fifo->iso[i].urb)) {
> - printk(KERN_DEBUG
> - "%s: %s: alloc urb for fifo %i failed",
> - hw->name, __func__, fifo->fifonum);
> - continue;
> - }
> - fifo->iso[i].owner_fifo = (struct usb_fifo *) fifo;
> - fifo->iso[i].indx = i;
> -
> - /* Init the first iso */
> - if (ISO_BUFFER_SIZE >=
> - (fifo->usb_packet_maxlen *
> - num_packets_per_urb)) {
> - fill_isoc_urb(fifo->iso[i].urb,
> - fifo->hw->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));
> -
> - for (k = 0; k < num_packets_per_urb; k++) {
> - fifo->iso[i].urb->
> - iso_frame_desc[k].offset =
> - k * packet_size;
> - fifo->iso[i].urb->
> - iso_frame_desc[k].length =
> - packet_size;
> - }
> - } else {
> - printk(KERN_DEBUG
> - "%s: %s: ISO Buffer size to small!\n",
> - hw->name, __func__);
> - }
> - }
> - fifo->bit_line = BITLINE_INF;
> -
> - errcode = usb_submit_urb(fifo->iso[i].urb, GFP_KERNEL);
> - fifo->active = (errcode >= 0) ? 1 : 0;
> - fifo->stop_gracefull = 0;
> - if (errcode < 0) {
> - printk(KERN_DEBUG "%s: %s: %s URB nr:%d\n",
> - hw->name, __func__,
> - symbolic(urb_errlist, errcode), i);
> - }
> - }
> - return fifo->active;
> -}
> -
> -static void
> -stop_iso_gracefull(struct usb_fifo *fifo)
> -{
> - struct hfcsusb *hw = fifo->hw;
> - int i, timeout;
> - u_long flags;
> -
> - for (i = 0; i < 2; i++) {
> - spin_lock_irqsave(&hw->lock, flags);
> - if (debug)
> - printk(KERN_DEBUG "%s: %s for fifo %i.%i\n",
> - hw->name, __func__, fifo->fifonum, i);
> - fifo->stop_gracefull = 1;
> - spin_unlock_irqrestore(&hw->lock, flags);
> - }
> -
> - for (i = 0; i < 2; i++) {
> - timeout = 3;
> - while (fifo->stop_gracefull && timeout--)
> - schedule_timeout_interruptible((HZ / 1000) * 16);
> - if (debug && fifo->stop_gracefull)
> - printk(KERN_DEBUG "%s: ERROR %s for fifo %i.%i\n",
> - hw->name, __func__, fifo->fifonum, i);
> - }
> -}
> -
> -static void
> -stop_int_gracefull(struct usb_fifo *fifo)
> -{
> - struct hfcsusb *hw = fifo->hw;
> - int timeout;
> - u_long flags;
> -
> - spin_lock_irqsave(&hw->lock, flags);
> - if (debug)
> - printk(KERN_DEBUG "%s: %s for fifo %i\n",
> - hw->name, __func__, fifo->fifonum);
> - fifo->stop_gracefull = 1;
> - spin_unlock_irqrestore(&hw->lock, flags);
> -
> - timeout = 3;
> - while (fifo->stop_gracefull && timeout--)
> - schedule_timeout_interruptible((HZ / 1000) * 3);
> - if (debug && fifo->stop_gracefull)
> - printk(KERN_DEBUG "%s: ERROR %s for fifo %i\n",
> - hw->name, __func__, fifo->fifonum);
> -}
> -
> -/* start the interrupt transfer for the given fifo */
> -static void
> -start_int_fifo(struct usb_fifo *fifo)
> -{
> - struct hfcsusb *hw = fifo->hw;
> - int errcode;
> -
> - if (debug)
> - printk(KERN_DEBUG "%s: %s: INT IN fifo:%d\n",
> - hw->name, __func__, fifo->fifonum);
> -
> - if (!fifo->urb) {
> - fifo->urb = usb_alloc_urb(0, GFP_KERNEL);
> - if (!fifo->urb)
> - return;
> - }
> - usb_fill_int_urb(fifo->urb, fifo->hw->dev, fifo->pipe,
> - fifo->buffer, fifo->usb_packet_maxlen,
> - (usb_complete_t)rx_int_complete, fifo, fifo->intervall);
> - fifo->active = 1;
> - fifo->stop_gracefull = 0;
> - errcode = usb_submit_urb(fifo->urb, GFP_KERNEL);
> - if (errcode) {
> - printk(KERN_DEBUG "%s: %s: submit URB: status:%i\n",
> - hw->name, __func__, errcode);
> - fifo->active = 0;
> - }
> -}
> -
> -static void
> -setPortMode(struct hfcsusb *hw)
> -{
> - if (debug & DEBUG_HW)
> - printk(KERN_DEBUG "%s: %s %s\n", hw->name, __func__,
> - (hw->protocol == ISDN_P_TE_S0) ? "TE" : "NT");
> -
> - if (hw->protocol == ISDN_P_TE_S0) {
> - write_reg(hw, HFCUSB_SCTRL, 0x40);
> - write_reg(hw, HFCUSB_SCTRL_E, 0x00);
> - write_reg(hw, HFCUSB_CLKDEL, CLKDEL_TE);
> - write_reg(hw, HFCUSB_STATES, 3 | 0x10);
> - write_reg(hw, HFCUSB_STATES, 3);
> - } else {
> - write_reg(hw, HFCUSB_SCTRL, 0x44);
> - write_reg(hw, HFCUSB_SCTRL_E, 0x09);
> - write_reg(hw, HFCUSB_CLKDEL, CLKDEL_NT);
> - write_reg(hw, HFCUSB_STATES, 1 | 0x10);
> - write_reg(hw, HFCUSB_STATES, 1);
> - }
> -}
> -
> -static void
> -reset_hfcsusb(struct hfcsusb *hw)
> -{
> - struct usb_fifo *fifo;
> - int i;
> -
> - if (debug & DEBUG_HW)
> - printk(KERN_DEBUG "%s: %s\n", hw->name, __func__);
> -
> - /* do Chip reset */
> - write_reg(hw, HFCUSB_CIRM, 8);
> -
> - /* aux = output, reset off */
> - write_reg(hw, HFCUSB_CIRM, 0x10);
> -
> - /* set USB_SIZE to match the wMaxPacketSize for INT or BULK transfers */
> - write_reg(hw, HFCUSB_USB_SIZE, (hw->packet_size / 8) |
> - ((hw->packet_size / 8) << 4));
> -
> - /* set USB_SIZE_I to match the wMaxPacketSize for ISO transfers */
> - write_reg(hw, HFCUSB_USB_SIZE_I, hw->iso_packet_size);
> -
> - /* enable PCM/GCI master mode */
> - write_reg(hw, HFCUSB_MST_MODE1, 0); /* set default values */
> - write_reg(hw, HFCUSB_MST_MODE0, 1); /* enable master mode */
> -
> - /* init the fifos */
> - write_reg(hw, HFCUSB_F_THRES,
> - (HFCUSB_TX_THRESHOLD / 8) | ((HFCUSB_RX_THRESHOLD / 8) << 4));
> -
> - fifo = hw->fifos;
> - for (i = 0; i < HFCUSB_NUM_FIFOS; i++) {
> - write_reg(hw, HFCUSB_FIFO, i); /* select the desired fifo */
> - 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_reg(hw, HFCUSB_HDLC_PAR, ((i <= HFCUSB_B2_RX) ? 0 : 2));
> -
> - /* enable all fifos */
> - if (i == HFCUSB_D_TX)
> - write_reg(hw, HFCUSB_CON_HDLC,
> - (hw->protocol == ISDN_P_NT_S0) ? 0x08 : 0x09);
> - else
> - write_reg(hw, HFCUSB_CON_HDLC, 0x08);
> - write_reg(hw, HFCUSB_INC_RES_F, 2); /* reset the fifo */
> - }
> -
> - write_reg(hw, HFCUSB_SCTRL_R, 0); /* disable both B receivers */
> - handle_led(hw, LED_POWER_ON);
> -}
> -
> -/* start USB data pipes dependand on device's endpoint configuration */
> -static void
> -hfcsusb_start_endpoint(struct hfcsusb *hw, int channel)
> -{
> - /* quick check if endpoint already running */
> - if ((channel == HFC_CHAN_D) && (hw->fifos[HFCUSB_D_RX].active))
> - return;
> - if ((channel == HFC_CHAN_B1) && (hw->fifos[HFCUSB_B1_RX].active))
> - return;
> - if ((channel == HFC_CHAN_B2) && (hw->fifos[HFCUSB_B2_RX].active))
> - return;
> - if ((channel == HFC_CHAN_E) && (hw->fifos[HFCUSB_PCM_RX].active))
> - return;
> -
> - /* start rx endpoints using USB INT IN method */
> - if (hw->cfg_used == CNF_3INT3ISO || hw->cfg_used == CNF_4INT3ISO)
> - start_int_fifo(hw->fifos + channel * 2 + 1);
> -
> - /* start rx endpoints using USB ISO IN method */
> - if (hw->cfg_used == CNF_3ISO3ISO || hw->cfg_used == CNF_4ISO3ISO) {
> - switch (channel) {
> - case HFC_CHAN_D:
> - start_isoc_chain(hw->fifos + HFCUSB_D_RX,
> - ISOC_PACKETS_D,
> - (usb_complete_t)rx_iso_complete,
> - 16);
> - break;
> - case HFC_CHAN_E:
> - start_isoc_chain(hw->fifos + HFCUSB_PCM_RX,
> - ISOC_PACKETS_D,
> - (usb_complete_t)rx_iso_complete,
> - 16);
> - break;
> - case HFC_CHAN_B1:
> - start_isoc_chain(hw->fifos + HFCUSB_B1_RX,
> - ISOC_PACKETS_B,
> - (usb_complete_t)rx_iso_complete,
> - 16);
> - break;
> - case HFC_CHAN_B2:
> - start_isoc_chain(hw->fifos + HFCUSB_B2_RX,
> - ISOC_PACKETS_B,
> - (usb_complete_t)rx_iso_complete,
> - 16);
> - break;
> - }
> - }
> -
> - /* start tx endpoints using USB ISO OUT method */
> - switch (channel) {
> - case HFC_CHAN_D:
> - start_isoc_chain(hw->fifos + HFCUSB_D_TX,
> - ISOC_PACKETS_B,
> - (usb_complete_t)tx_iso_complete, 1);
> - break;
> - case HFC_CHAN_B1:
> - start_isoc_chain(hw->fifos + HFCUSB_B1_TX,
> - ISOC_PACKETS_D,
> - (usb_complete_t)tx_iso_complete, 1);
> - break;
> - case HFC_CHAN_B2:
> - start_isoc_chain(hw->fifos + HFCUSB_B2_TX,
> - ISOC_PACKETS_B,
> - (usb_complete_t)tx_iso_complete, 1);
> - break;
> - }
> -}
> -
> -/* stop USB data pipes dependand on device's endpoint configuration */
> -static void
> -hfcsusb_stop_endpoint(struct hfcsusb *hw, int channel)
> -{
> - /* quick check if endpoint currently running */
> - if ((channel == HFC_CHAN_D) && (!hw->fifos[HFCUSB_D_RX].active))
> - return;
> - if ((channel == HFC_CHAN_B1) && (!hw->fifos[HFCUSB_B1_RX].active))
> - return;
> - if ((channel == HFC_CHAN_B2) && (!hw->fifos[HFCUSB_B2_RX].active))
> - return;
> - if ((channel == HFC_CHAN_E) && (!hw->fifos[HFCUSB_PCM_RX].active))
> - return;
> -
> - /* rx endpoints using USB INT IN method */
> - if (hw->cfg_used == CNF_3INT3ISO || hw->cfg_used == CNF_4INT3ISO)
> - stop_int_gracefull(hw->fifos + channel * 2 + 1);
> -
> - /* rx endpoints using USB ISO IN method */
> - if (hw->cfg_used == CNF_3ISO3ISO || hw->cfg_used == CNF_4ISO3ISO)
> - stop_iso_gracefull(hw->fifos + channel * 2 + 1);
> -
> - /* tx endpoints using USB ISO OUT method */
> - if (channel != HFC_CHAN_E)
> - stop_iso_gracefull(hw->fifos + channel * 2);
> -}
> -
> -
> -/* Hardware Initialization */
> -static int
> -setup_hfcsusb(struct hfcsusb *hw)
> -{
> - void *dmabuf = kmalloc_obj(u_char);
> - u_char b;
> - int ret;
> -
> - if (debug & DBG_HFC_CALL_TRACE)
> - printk(KERN_DEBUG "%s: %s\n", hw->name, __func__);
> -
> - if (!dmabuf)
> - return -ENOMEM;
> -
> - ret = read_reg_atomic(hw, HFCUSB_CHIP_ID, dmabuf);
> -
> - memcpy(&b, dmabuf, sizeof(u_char));
> - kfree(dmabuf);
> -
> - /* check the chip id */
> - if (ret != 1) {
> - printk(KERN_DEBUG "%s: %s: cannot read chip id\n",
> - hw->name, __func__);
> - return 1;
> - }
> - if (b != HFCUSB_CHIPID) {
> - printk(KERN_DEBUG "%s: %s: Invalid chip id 0x%02x\n",
> - hw->name, __func__, b);
> - return 1;
> - }
> -
> - /* first set the needed config, interface and alternate */
> - (void) usb_set_interface(hw->dev, hw->if_used, hw->alt_used);
> -
> - hw->led_state = 0;
> -
> - /* init the background machinery for control requests */
> - hw->ctrl_read.bRequestType = 0xc0;
> - hw->ctrl_read.bRequest = 1;
> - hw->ctrl_read.wLength = cpu_to_le16(1);
> - hw->ctrl_write.bRequestType = 0x40;
> - hw->ctrl_write.bRequest = 0;
> - hw->ctrl_write.wLength = 0;
> - usb_fill_control_urb(hw->ctrl_urb, hw->dev, hw->ctrl_out_pipe,
> - (u_char *)&hw->ctrl_write, NULL, 0,
> - (usb_complete_t)ctrl_complete, hw);
> -
> - reset_hfcsusb(hw);
> - return 0;
> -}
> -
> -static void
> -release_hw(struct hfcsusb *hw)
> -{
> - if (debug & DBG_HFC_CALL_TRACE)
> - printk(KERN_DEBUG "%s: %s\n", hw->name, __func__);
> -
> - /*
> - * stop all endpoints gracefully
> - * TODO: mISDN_core should generate CLOSE_CHANNEL
> - * signals after calling mISDN_unregister_device()
> - */
> - hfcsusb_stop_endpoint(hw, HFC_CHAN_D);
> - hfcsusb_stop_endpoint(hw, HFC_CHAN_B1);
> - hfcsusb_stop_endpoint(hw, HFC_CHAN_B2);
> - if (hw->fifos[HFCUSB_PCM_RX].pipe)
> - hfcsusb_stop_endpoint(hw, HFC_CHAN_E);
> - if (hw->protocol == ISDN_P_TE_S0)
> - l1_event(hw->dch.l1, CLOSE_CHANNEL);
> -
> - mISDN_unregister_device(&hw->dch.dev);
> - mISDN_freebchannel(&hw->bch[1]);
> - mISDN_freebchannel(&hw->bch[0]);
> - mISDN_freedchannel(&hw->dch);
> -
> - if (hw->ctrl_urb) {
> - usb_kill_urb(hw->ctrl_urb);
> - usb_free_urb(hw->ctrl_urb);
> - hw->ctrl_urb = NULL;
> - }
> -
> - if (hw->intf)
> - usb_set_intfdata(hw->intf, NULL);
> - list_del(&hw->list);
> - kfree(hw);
> - hw = NULL;
> -}
> -
> -static void
> -deactivate_bchannel(struct bchannel *bch)
> -{
> - struct hfcsusb *hw = bch->hw;
> - u_long flags;
> -
> - if (bch->debug & DEBUG_HW)
> - printk(KERN_DEBUG "%s: %s: bch->nr(%i)\n",
> - hw->name, __func__, bch->nr);
> -
> - spin_lock_irqsave(&hw->lock, flags);
> - mISDN_clear_bchannel(bch);
> - spin_unlock_irqrestore(&hw->lock, flags);
> - hfcsusb_setup_bch(bch, ISDN_P_NONE);
> - hfcsusb_stop_endpoint(hw, bch->nr - 1);
> -}
> -
> -/*
> - * Layer 1 B-channel hardware access
> - */
> -static int
> -hfc_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
> -{
> - struct bchannel *bch = container_of(ch, struct bchannel, ch);
> - int ret = -EINVAL;
> -
> - if (bch->debug & DEBUG_HW)
> - printk(KERN_DEBUG "%s: cmd:%x %p\n", __func__, cmd, arg);
> -
> - switch (cmd) {
> - case HW_TESTRX_RAW:
> - case HW_TESTRX_HDLC:
> - case HW_TESTRX_OFF:
> - ret = -EINVAL;
> - break;
> -
> - case CLOSE_CHANNEL:
> - test_and_clear_bit(FLG_OPEN, &bch->Flags);
> - deactivate_bchannel(bch);
> - ch->protocol = ISDN_P_NONE;
> - ch->peer = NULL;
> - module_put(THIS_MODULE);
> - ret = 0;
> - break;
> - case CONTROL_CHANNEL:
> - ret = channel_bctrl(bch, arg);
> - break;
> - default:
> - printk(KERN_WARNING "%s: unknown prim(%x)\n",
> - __func__, cmd);
> - }
> - return ret;
> -}
> -
> -static int
> -setup_instance(struct hfcsusb *hw, struct device *parent)
> -{
> - u_long flags;
> - int err, i;
> -
> - if (debug & DBG_HFC_CALL_TRACE)
> - printk(KERN_DEBUG "%s: %s\n", hw->name, __func__);
> -
> - spin_lock_init(&hw->ctrl_lock);
> - spin_lock_init(&hw->lock);
> -
> - mISDN_initdchannel(&hw->dch, MAX_DFRAME_LEN_L1, ph_state);
> - hw->dch.debug = debug & 0xFFFF;
> - hw->dch.hw = hw;
> - hw->dch.dev.Dprotocols = (1 << ISDN_P_TE_S0) | (1 << ISDN_P_NT_S0);
> - hw->dch.dev.D.send = hfcusb_l2l1D;
> - hw->dch.dev.D.ctrl = hfc_dctrl;
> -
> - /* enable E-Channel logging */
> - if (hw->fifos[HFCUSB_PCM_RX].pipe)
> - mISDN_initdchannel(&hw->ech, MAX_DFRAME_LEN_L1, NULL);
> -
> - hw->dch.dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
> - (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
> - hw->dch.dev.nrbchan = 2;
> - for (i = 0; i < 2; i++) {
> - hw->bch[i].nr = i + 1;
> - set_channelmap(i + 1, hw->dch.dev.channelmap);
> - hw->bch[i].debug = debug;
> - mISDN_initbchannel(&hw->bch[i], MAX_DATA_MEM, poll >> 1);
> - hw->bch[i].hw = hw;
> - hw->bch[i].ch.send = hfcusb_l2l1B;
> - hw->bch[i].ch.ctrl = hfc_bctrl;
> - hw->bch[i].ch.nr = i + 1;
> - list_add(&hw->bch[i].ch.list, &hw->dch.dev.bchannels);
> - }
> -
> - hw->fifos[HFCUSB_B1_TX].bch = &hw->bch[0];
> - hw->fifos[HFCUSB_B1_RX].bch = &hw->bch[0];
> - hw->fifos[HFCUSB_B2_TX].bch = &hw->bch[1];
> - hw->fifos[HFCUSB_B2_RX].bch = &hw->bch[1];
> - hw->fifos[HFCUSB_D_TX].dch = &hw->dch;
> - hw->fifos[HFCUSB_D_RX].dch = &hw->dch;
> - hw->fifos[HFCUSB_PCM_RX].ech = &hw->ech;
> - hw->fifos[HFCUSB_PCM_TX].ech = &hw->ech;
> -
> - err = setup_hfcsusb(hw);
> - if (err)
> - goto out;
> -
> - snprintf(hw->name, MISDN_MAX_IDLEN - 1, "%s.%d", DRIVER_NAME,
> - hfcsusb_cnt + 1);
> - printk(KERN_INFO "%s: registered as '%s'\n",
> - DRIVER_NAME, hw->name);
> -
> - err = mISDN_register_device(&hw->dch.dev, parent, hw->name);
> - if (err)
> - goto out;
> -
> - hfcsusb_cnt++;
> - write_lock_irqsave(&HFClock, flags);
> - list_add_tail(&hw->list, &HFClist);
> - write_unlock_irqrestore(&HFClock, flags);
> - return 0;
> -
> -out:
> - mISDN_freebchannel(&hw->bch[1]);
> - mISDN_freebchannel(&hw->bch[0]);
> - mISDN_freedchannel(&hw->dch);
> - return err;
> -}
> -
> -static int
> -hfcsusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
> -{
> - int err;
> - struct hfcsusb *hw;
> - struct usb_device *dev = interface_to_usbdev(intf);
> - struct usb_host_interface *iface = intf->cur_altsetting;
> - struct usb_host_interface *iface_used = NULL;
> - struct usb_host_endpoint *ep;
> - struct hfcsusb_vdata *driver_info;
> - int ifnum = iface->desc.bInterfaceNumber, i, idx, alt_idx,
> - probe_alt_setting, vend_idx, cfg_used, *vcf, attr, cfg_found,
> - ep_addr, cmptbl[16], small_match, iso_packet_size, packet_size,
> - alt_used = 0;
> -
> - vend_idx = 0xffff;
> - for (i = 0; hfcsusb_idtab[i].idVendor; i++) {
> - if ((le16_to_cpu(dev->descriptor.idVendor)
> - == hfcsusb_idtab[i].idVendor) &&
> - (le16_to_cpu(dev->descriptor.idProduct)
> - == hfcsusb_idtab[i].idProduct)) {
> - vend_idx = i;
> - continue;
> - }
> - }
> -
> - printk(KERN_DEBUG
> - "%s: interface(%d) actalt(%d) minor(%d) vend_idx(%d)\n",
> - __func__, ifnum, iface->desc.bAlternateSetting,
> - intf->minor, vend_idx);
> -
> - if (vend_idx == 0xffff) {
> - printk(KERN_WARNING
> - "%s: no valid vendor found in USB descriptor\n",
> - __func__);
> - return -EIO;
> - }
> - /* if vendor and product ID is OK, start probing alternate settings */
> - alt_idx = 0;
> - small_match = -1;
> -
> - /* 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;
> -
> - while (validconf[cfg_used][0]) {
> - cfg_found = 1;
> - vcf = validconf[cfg_used];
> - 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 (idx > 15)
> - return -EIO;
> -
> - if (ep_addr & 0x80)
> - idx++;
> - attr = ep->desc.bmAttributes;
> -
> - if (cmptbl[idx] != EP_NOP) {
> - 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;
> -
> - if (attr == USB_ENDPOINT_XFER_INT &&
> - ep->desc.bInterval < vcf[17]) {
> - cfg_found = 0;
> - }
> - }
> - ep++;
> - }
> -
> - for (i = 0; i < 16; i++)
> - if (cmptbl[i] != EP_NOP && cmptbl[i] != EP_NUL)
> - cfg_found = 0;
> -
> - if (cfg_found) {
> - if (small_match < cfg_used) {
> - small_match = cfg_used;
> - alt_used = probe_alt_setting;
> - iface_used = iface;
> - }
> - }
> - cfg_used++;
> - }
> - alt_idx++;
> - } /* (alt_idx < intf->num_altsetting) */
> -
> - /* not found a valid USB Ta Endpoint config */
> - if (small_match == -1)
> - return -EIO;
> -
> - iface = iface_used;
> - hw = kzalloc_obj(struct hfcsusb);
> - if (!hw)
> - return -ENOMEM; /* got no mem */
> - snprintf(hw->name, MISDN_MAX_IDLEN - 1, "%s", DRIVER_NAME);
> -
> - ep = iface->endpoint;
> - vcf = validconf[small_match];
> -
> - for (i = 0; i < iface->desc.bNumEndpoints; i++) {
> - struct usb_fifo *f;
> -
> - ep_addr = ep->desc.bEndpointAddress;
> - /* get endpoint base */
> - idx = ((ep_addr & 0x7f) - 1) * 2;
> - if (ep_addr & 0x80)
> - idx++;
> - f = &hw->fifos[idx & 7];
> -
> - /* init Endpoints */
> - if (vcf[idx] == EP_NOP || vcf[idx] == EP_NUL) {
> - ep++;
> - continue;
> - }
> - switch (ep->desc.bmAttributes) {
> - case USB_ENDPOINT_XFER_INT:
> - f->pipe = usb_rcvintpipe(dev,
> - ep->desc.bEndpointAddress);
> - f->usb_transfer_mode = USB_INT;
> - packet_size = le16_to_cpu(ep->desc.wMaxPacketSize);
> - break;
> - case USB_ENDPOINT_XFER_BULK:
> - if (ep_addr & 0x80)
> - f->pipe = usb_rcvbulkpipe(dev,
> - ep->desc.bEndpointAddress);
> - else
> - f->pipe = usb_sndbulkpipe(dev,
> - ep->desc.bEndpointAddress);
> - f->usb_transfer_mode = USB_BULK;
> - packet_size = le16_to_cpu(ep->desc.wMaxPacketSize);
> - break;
> - case USB_ENDPOINT_XFER_ISOC:
> - if (ep_addr & 0x80)
> - f->pipe = usb_rcvisocpipe(dev,
> - ep->desc.bEndpointAddress);
> - else
> - f->pipe = usb_sndisocpipe(dev,
> - ep->desc.bEndpointAddress);
> - f->usb_transfer_mode = USB_ISOC;
> - iso_packet_size = le16_to_cpu(ep->desc.wMaxPacketSize);
> - break;
> - default:
> - f->pipe = 0;
> - }
> -
> - if (f->pipe) {
> - f->fifonum = idx & 7;
> - f->hw = hw;
> - f->usb_packet_maxlen =
> - le16_to_cpu(ep->desc.wMaxPacketSize);
> - f->intervall = ep->desc.bInterval;
> - }
> - ep++;
> - }
> - hw->dev = dev; /* save device */
> - hw->if_used = ifnum; /* save used interface */
> - hw->alt_used = alt_used; /* and alternate config */
> - hw->ctrl_paksize = dev->descriptor.bMaxPacketSize0; /* control size */
> - hw->cfg_used = vcf[16]; /* store used config */
> - hw->vend_idx = vend_idx; /* store found vendor */
> - hw->packet_size = packet_size;
> - hw->iso_packet_size = iso_packet_size;
> -
> - /* create the control pipes needed for register access */
> - hw->ctrl_in_pipe = usb_rcvctrlpipe(hw->dev, 0);
> - hw->ctrl_out_pipe = usb_sndctrlpipe(hw->dev, 0);
> -
> - driver_info = (struct hfcsusb_vdata *)
> - hfcsusb_idtab[vend_idx].driver_info;
> -
> - hw->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL);
> - if (!hw->ctrl_urb) {
> - pr_warn("%s: No memory for control urb\n",
> - driver_info->vend_name);
> - err = -ENOMEM;
> - goto err_free_hw;
> - }
> -
> - pr_info("%s: %s: detected \"%s\" (%s, if=%d alt=%d)\n",
> - hw->name, __func__, driver_info->vend_name,
> - conf_str[small_match], ifnum, alt_used);
> -
> - if (setup_instance(hw, dev->dev.parent)) {
> - err = -EIO;
> - goto err_free_urb;
> - }
> -
> - hw->intf = intf;
> - usb_set_intfdata(hw->intf, hw);
> - return 0;
> -
> -err_free_urb:
> - usb_free_urb(hw->ctrl_urb);
> -err_free_hw:
> - kfree(hw);
> - return err;
> -}
> -
> -/* function called when an active device is removed */
> -static void
> -hfcsusb_disconnect(struct usb_interface *intf)
> -{
> - struct hfcsusb *hw = usb_get_intfdata(intf);
> - struct hfcsusb *next;
> - int cnt = 0;
> -
> - printk(KERN_INFO "%s: device disconnected\n", hw->name);
> -
> - handle_led(hw, LED_POWER_OFF);
> - release_hw(hw);
> -
> - list_for_each_entry_safe(hw, next, &HFClist, list)
> - cnt++;
> - if (!cnt)
> - hfcsusb_cnt = 0;
> -
> - usb_set_intfdata(intf, NULL);
> -}
> -
> -static struct usb_driver hfcsusb_drv = {
> - .name = DRIVER_NAME,
> - .id_table = hfcsusb_idtab,
> - .probe = hfcsusb_probe,
> - .disconnect = hfcsusb_disconnect,
> - .disable_hub_initiated_lpm = 1,
> -};
> -
> -module_usb_driver(hfcsusb_drv);
> diff --git a/drivers/isdn/hardware/mISDN/isdnhdlc.c b/drivers/isdn/hardware/mISDN/isdnhdlc.c
> deleted file mode 100644
> index 985367e6711d..000000000000
> --- a/drivers/isdn/hardware/mISDN/isdnhdlc.c
> +++ /dev/null
> @@ -1,617 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-or-later
> -/*
> - * isdnhdlc.c -- General purpose ISDN HDLC decoder.
> - *
> - * Copyright (C)
> - * 2009 Karsten Keil <keil@b1-systems.de>
> - * 2002 Wolfgang Mües <wolfgang@iksw-muees.de>
> - * 2001 Frode Isaksen <fisaksen@bewan.com>
> - * 2001 Kai Germaschewski <kai.germaschewski@gmx.de>
> - */
> -
> -#include <linux/module.h>
> -#include <linux/init.h>
> -#include <linux/crc-ccitt.h>
> -#include <linux/bitrev.h>
> -#include "isdnhdlc.h"
> -
> -/*-------------------------------------------------------------------*/
> -
> -MODULE_AUTHOR("Wolfgang Mües <wolfgang@iksw-muees.de>, "
> - "Frode Isaksen <fisaksen@bewan.com>, "
> - "Kai Germaschewski <kai.germaschewski@gmx.de>");
> -MODULE_DESCRIPTION("General purpose ISDN HDLC decoder");
> -MODULE_LICENSE("GPL");
> -
> -/*-------------------------------------------------------------------*/
> -
> -enum {
> - HDLC_FAST_IDLE, HDLC_GET_FLAG_B0, HDLC_GETFLAG_B1A6, HDLC_GETFLAG_B7,
> - HDLC_GET_DATA, HDLC_FAST_FLAG
> -};
> -
> -enum {
> - HDLC_SEND_DATA, HDLC_SEND_CRC1, HDLC_SEND_FAST_FLAG,
> - HDLC_SEND_FIRST_FLAG, HDLC_SEND_CRC2, HDLC_SEND_CLOSING_FLAG,
> - HDLC_SEND_IDLE1, HDLC_SEND_FAST_IDLE, HDLC_SENDFLAG_B0,
> - HDLC_SENDFLAG_B1A6, HDLC_SENDFLAG_B7, STOPPED, HDLC_SENDFLAG_ONE
> -};
> -
> -void isdnhdlc_rcv_init(struct isdnhdlc_vars *hdlc, u32 features)
> -{
> - memset(hdlc, 0, sizeof(struct isdnhdlc_vars));
> - hdlc->state = HDLC_GET_DATA;
> - if (features & HDLC_56KBIT)
> - hdlc->do_adapt56 = 1;
> - if (features & HDLC_BITREVERSE)
> - hdlc->do_bitreverse = 1;
> -}
> -EXPORT_SYMBOL(isdnhdlc_out_init);
> -
> -void isdnhdlc_out_init(struct isdnhdlc_vars *hdlc, u32 features)
> -{
> - memset(hdlc, 0, sizeof(struct isdnhdlc_vars));
> - if (features & HDLC_DCHANNEL) {
> - hdlc->dchannel = 1;
> - hdlc->state = HDLC_SEND_FIRST_FLAG;
> - } else {
> - hdlc->dchannel = 0;
> - hdlc->state = HDLC_SEND_FAST_FLAG;
> - hdlc->ffvalue = 0x7e;
> - }
> - hdlc->cbin = 0x7e;
> - if (features & HDLC_56KBIT) {
> - hdlc->do_adapt56 = 1;
> - hdlc->state = HDLC_SENDFLAG_B0;
> - } else
> - hdlc->data_bits = 8;
> - if (features & HDLC_BITREVERSE)
> - hdlc->do_bitreverse = 1;
> -}
> -EXPORT_SYMBOL(isdnhdlc_rcv_init);
> -
> -static int
> -check_frame(struct isdnhdlc_vars *hdlc)
> -{
> - int status;
> -
> - if (hdlc->dstpos < 2) /* too small - framing error */
> - status = -HDLC_FRAMING_ERROR;
> - else if (hdlc->crc != 0xf0b8) /* crc error */
> - status = -HDLC_CRC_ERROR;
> - else {
> - /* remove CRC */
> - hdlc->dstpos -= 2;
> - /* good frame */
> - status = hdlc->dstpos;
> - }
> - return status;
> -}
> -
> -/*
> - isdnhdlc_decode - decodes HDLC frames from a transparent bit stream.
> -
> - The source buffer is scanned for valid HDLC frames looking for
> - flags (01111110) to indicate the start of a frame. If the start of
> - the frame is found, the bit stuffing is removed (0 after 5 1's).
> - When a new flag is found, the complete frame has been received
> - and the CRC is checked.
> - If a valid frame is found, the function returns the frame length
> - excluding the CRC with the bit HDLC_END_OF_FRAME set.
> - If the beginning of a valid frame is found, the function returns
> - the length.
> - If a framing error is found (too many 1s and not a flag) the function
> - returns the length with the bit HDLC_FRAMING_ERROR set.
> - If a CRC error is found the function returns the length with the
> - bit HDLC_CRC_ERROR set.
> - If the frame length exceeds the destination buffer size, the function
> - returns the length with the bit HDLC_LENGTH_ERROR set.
> -
> - src - source buffer
> - slen - source buffer length
> - count - number of bytes removed (decoded) from the source buffer
> - dst _ destination buffer
> - dsize - destination buffer size
> - returns - number of decoded bytes in the destination buffer and status
> - flag.
> -*/
> -int isdnhdlc_decode(struct isdnhdlc_vars *hdlc, const u8 *src, int slen,
> - int *count, u8 *dst, int dsize)
> -{
> - int status = 0;
> -
> - static const unsigned char fast_flag[] = {
> - 0x00, 0x00, 0x00, 0x20, 0x30, 0x38, 0x3c, 0x3e, 0x3f
> - };
> -
> - static const unsigned char fast_flag_value[] = {
> - 0x00, 0x7e, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f
> - };
> -
> - static const unsigned char fast_abort[] = {
> - 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff
> - };
> -
> -#define handle_fast_flag(h) \
> - do { \
> - if (h->cbin == fast_flag[h->bit_shift]) { \
> - h->ffvalue = fast_flag_value[h->bit_shift]; \
> - h->state = HDLC_FAST_FLAG; \
> - h->ffbit_shift = h->bit_shift; \
> - h->bit_shift = 1; \
> - } else { \
> - h->state = HDLC_GET_DATA; \
> - h->data_received = 0; \
> - } \
> - } while (0)
> -
> -#define handle_abort(h) \
> - do { \
> - h->shift_reg = fast_abort[h->ffbit_shift - 1]; \
> - h->hdlc_bits1 = h->ffbit_shift - 2; \
> - if (h->hdlc_bits1 < 0) \
> - h->hdlc_bits1 = 0; \
> - h->data_bits = h->ffbit_shift - 1; \
> - h->state = HDLC_GET_DATA; \
> - h->data_received = 0; \
> - } while (0)
> -
> - *count = slen;
> -
> - while (slen > 0) {
> - if (hdlc->bit_shift == 0) {
> - /* the code is for bitreverse streams */
> - if (hdlc->do_bitreverse == 0)
> - hdlc->cbin = bitrev8(*src++);
> - else
> - hdlc->cbin = *src++;
> - slen--;
> - hdlc->bit_shift = 8;
> - if (hdlc->do_adapt56)
> - hdlc->bit_shift--;
> - }
> -
> - switch (hdlc->state) {
> - case STOPPED:
> - return 0;
> - case HDLC_FAST_IDLE:
> - if (hdlc->cbin == 0xff) {
> - hdlc->bit_shift = 0;
> - break;
> - }
> - hdlc->state = HDLC_GET_FLAG_B0;
> - hdlc->hdlc_bits1 = 0;
> - hdlc->bit_shift = 8;
> - break;
> - case HDLC_GET_FLAG_B0:
> - if (!(hdlc->cbin & 0x80)) {
> - hdlc->state = HDLC_GETFLAG_B1A6;
> - hdlc->hdlc_bits1 = 0;
> - } else {
> - if ((!hdlc->do_adapt56) &&
> - (++hdlc->hdlc_bits1 >= 8) &&
> - (hdlc->bit_shift == 1))
> - hdlc->state = HDLC_FAST_IDLE;
> - }
> - hdlc->cbin <<= 1;
> - hdlc->bit_shift--;
> - break;
> - case HDLC_GETFLAG_B1A6:
> - if (hdlc->cbin & 0x80) {
> - hdlc->hdlc_bits1++;
> - if (hdlc->hdlc_bits1 == 6)
> - hdlc->state = HDLC_GETFLAG_B7;
> - } else
> - hdlc->hdlc_bits1 = 0;
> - hdlc->cbin <<= 1;
> - hdlc->bit_shift--;
> - break;
> - case HDLC_GETFLAG_B7:
> - if (hdlc->cbin & 0x80) {
> - hdlc->state = HDLC_GET_FLAG_B0;
> - } else {
> - hdlc->state = HDLC_GET_DATA;
> - hdlc->crc = 0xffff;
> - hdlc->shift_reg = 0;
> - hdlc->hdlc_bits1 = 0;
> - hdlc->data_bits = 0;
> - hdlc->data_received = 0;
> - }
> - hdlc->cbin <<= 1;
> - hdlc->bit_shift--;
> - break;
> - case HDLC_GET_DATA:
> - if (hdlc->cbin & 0x80) {
> - hdlc->hdlc_bits1++;
> - switch (hdlc->hdlc_bits1) {
> - case 6:
> - break;
> - case 7:
> - if (hdlc->data_received)
> - /* bad frame */
> - status = -HDLC_FRAMING_ERROR;
> - if (!hdlc->do_adapt56) {
> - if (hdlc->cbin == fast_abort
> - [hdlc->bit_shift + 1]) {
> - hdlc->state =
> - HDLC_FAST_IDLE;
> - hdlc->bit_shift = 1;
> - break;
> - }
> - } else
> - hdlc->state = HDLC_GET_FLAG_B0;
> - break;
> - default:
> - hdlc->shift_reg >>= 1;
> - hdlc->shift_reg |= 0x80;
> - hdlc->data_bits++;
> - break;
> - }
> - } else {
> - switch (hdlc->hdlc_bits1) {
> - case 5:
> - break;
> - case 6:
> - if (hdlc->data_received)
> - status = check_frame(hdlc);
> - hdlc->crc = 0xffff;
> - hdlc->shift_reg = 0;
> - hdlc->data_bits = 0;
> - if (!hdlc->do_adapt56)
> - handle_fast_flag(hdlc);
> - else {
> - hdlc->state = HDLC_GET_DATA;
> - hdlc->data_received = 0;
> - }
> - break;
> - default:
> - hdlc->shift_reg >>= 1;
> - hdlc->data_bits++;
> - break;
> - }
> - hdlc->hdlc_bits1 = 0;
> - }
> - if (status) {
> - hdlc->dstpos = 0;
> - *count -= slen;
> - hdlc->cbin <<= 1;
> - hdlc->bit_shift--;
> - return status;
> - }
> - if (hdlc->data_bits == 8) {
> - hdlc->data_bits = 0;
> - hdlc->data_received = 1;
> - hdlc->crc = crc_ccitt_byte(hdlc->crc,
> - hdlc->shift_reg);
> -
> - /* good byte received */
> - if (hdlc->dstpos < dsize)
> - dst[hdlc->dstpos++] = hdlc->shift_reg;
> - else {
> - /* frame too long */
> - status = -HDLC_LENGTH_ERROR;
> - hdlc->dstpos = 0;
> - }
> - }
> - hdlc->cbin <<= 1;
> - hdlc->bit_shift--;
> - break;
> - case HDLC_FAST_FLAG:
> - if (hdlc->cbin == hdlc->ffvalue) {
> - hdlc->bit_shift = 0;
> - break;
> - } else {
> - if (hdlc->cbin == 0xff) {
> - hdlc->state = HDLC_FAST_IDLE;
> - hdlc->bit_shift = 0;
> - } else if (hdlc->ffbit_shift == 8) {
> - hdlc->state = HDLC_GETFLAG_B7;
> - break;
> - } else
> - handle_abort(hdlc);
> - }
> - break;
> - default:
> - break;
> - }
> - }
> - *count -= slen;
> - return 0;
> -}
> -EXPORT_SYMBOL(isdnhdlc_decode);
> -/*
> - isdnhdlc_encode - encodes HDLC frames to a transparent bit stream.
> -
> - The bit stream starts with a beginning flag (01111110). After
> - that each byte is added to the bit stream with bit stuffing added
> - (0 after 5 1's).
> - When the last byte has been removed from the source buffer, the
> - CRC (2 bytes is added) and the frame terminates with the ending flag.
> - For the dchannel, the idle character (all 1's) is also added at the end.
> - If this function is called with empty source buffer (slen=0), flags or
> - idle character will be generated.
> -
> - src - source buffer
> - slen - source buffer length
> - count - number of bytes removed (encoded) from source buffer
> - dst _ destination buffer
> - dsize - destination buffer size
> - returns - number of encoded bytes in the destination buffer
> -*/
> -int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const u8 *src, u16 slen,
> - int *count, u8 *dst, int dsize)
> -{
> - static const unsigned char xfast_flag_value[] = {
> - 0x7e, 0x3f, 0x9f, 0xcf, 0xe7, 0xf3, 0xf9, 0xfc, 0x7e
> - };
> -
> - int len = 0;
> -
> - *count = slen;
> -
> - /* special handling for one byte frames */
> - if ((slen == 1) && (hdlc->state == HDLC_SEND_FAST_FLAG))
> - hdlc->state = HDLC_SENDFLAG_ONE;
> - while (dsize > 0) {
> - if (hdlc->bit_shift == 0) {
> - if (slen && !hdlc->do_closing) {
> - hdlc->shift_reg = *src++;
> - slen--;
> - if (slen == 0)
> - /* closing sequence, CRC + flag(s) */
> - hdlc->do_closing = 1;
> - hdlc->bit_shift = 8;
> - } else {
> - if (hdlc->state == HDLC_SEND_DATA) {
> - if (hdlc->data_received) {
> - hdlc->state = HDLC_SEND_CRC1;
> - hdlc->crc ^= 0xffff;
> - hdlc->bit_shift = 8;
> - hdlc->shift_reg =
> - hdlc->crc & 0xff;
> - } else if (!hdlc->do_adapt56)
> - hdlc->state =
> - HDLC_SEND_FAST_FLAG;
> - else
> - hdlc->state =
> - HDLC_SENDFLAG_B0;
> - }
> -
> - }
> - }
> -
> - switch (hdlc->state) {
> - case STOPPED:
> - while (dsize--)
> - *dst++ = 0xff;
> - return dsize;
> - case HDLC_SEND_FAST_FLAG:
> - hdlc->do_closing = 0;
> - if (slen == 0) {
> - /* the code is for bitreverse streams */
> - if (hdlc->do_bitreverse == 0)
> - *dst++ = bitrev8(hdlc->ffvalue);
> - else
> - *dst++ = hdlc->ffvalue;
> - len++;
> - dsize--;
> - break;
> - }
> - fallthrough;
> - case HDLC_SENDFLAG_ONE:
> - if (hdlc->bit_shift == 8) {
> - hdlc->cbin = hdlc->ffvalue >>
> - (8 - hdlc->data_bits);
> - hdlc->state = HDLC_SEND_DATA;
> - hdlc->crc = 0xffff;
> - hdlc->hdlc_bits1 = 0;
> - hdlc->data_received = 1;
> - }
> - break;
> - case HDLC_SENDFLAG_B0:
> - hdlc->do_closing = 0;
> - hdlc->cbin <<= 1;
> - hdlc->data_bits++;
> - hdlc->hdlc_bits1 = 0;
> - hdlc->state = HDLC_SENDFLAG_B1A6;
> - break;
> - case HDLC_SENDFLAG_B1A6:
> - hdlc->cbin <<= 1;
> - hdlc->data_bits++;
> - hdlc->cbin++;
> - if (++hdlc->hdlc_bits1 == 6)
> - hdlc->state = HDLC_SENDFLAG_B7;
> - break;
> - case HDLC_SENDFLAG_B7:
> - hdlc->cbin <<= 1;
> - hdlc->data_bits++;
> - if (slen == 0) {
> - hdlc->state = HDLC_SENDFLAG_B0;
> - break;
> - }
> - if (hdlc->bit_shift == 8) {
> - hdlc->state = HDLC_SEND_DATA;
> - hdlc->crc = 0xffff;
> - hdlc->hdlc_bits1 = 0;
> - hdlc->data_received = 1;
> - }
> - break;
> - case HDLC_SEND_FIRST_FLAG:
> - hdlc->data_received = 1;
> - if (hdlc->data_bits == 8) {
> - hdlc->state = HDLC_SEND_DATA;
> - hdlc->crc = 0xffff;
> - hdlc->hdlc_bits1 = 0;
> - break;
> - }
> - hdlc->cbin <<= 1;
> - hdlc->data_bits++;
> - if (hdlc->shift_reg & 0x01)
> - hdlc->cbin++;
> - hdlc->shift_reg >>= 1;
> - hdlc->bit_shift--;
> - if (hdlc->bit_shift == 0) {
> - hdlc->state = HDLC_SEND_DATA;
> - hdlc->crc = 0xffff;
> - hdlc->hdlc_bits1 = 0;
> - }
> - break;
> - case HDLC_SEND_DATA:
> - hdlc->cbin <<= 1;
> - hdlc->data_bits++;
> - if (hdlc->hdlc_bits1 == 5) {
> - hdlc->hdlc_bits1 = 0;
> - break;
> - }
> - if (hdlc->bit_shift == 8)
> - hdlc->crc = crc_ccitt_byte(hdlc->crc,
> - hdlc->shift_reg);
> - if (hdlc->shift_reg & 0x01) {
> - hdlc->hdlc_bits1++;
> - hdlc->cbin++;
> - hdlc->shift_reg >>= 1;
> - hdlc->bit_shift--;
> - } else {
> - hdlc->hdlc_bits1 = 0;
> - hdlc->shift_reg >>= 1;
> - hdlc->bit_shift--;
> - }
> - break;
> - case HDLC_SEND_CRC1:
> - hdlc->cbin <<= 1;
> - hdlc->data_bits++;
> - if (hdlc->hdlc_bits1 == 5) {
> - hdlc->hdlc_bits1 = 0;
> - break;
> - }
> - if (hdlc->shift_reg & 0x01) {
> - hdlc->hdlc_bits1++;
> - hdlc->cbin++;
> - hdlc->shift_reg >>= 1;
> - hdlc->bit_shift--;
> - } else {
> - hdlc->hdlc_bits1 = 0;
> - hdlc->shift_reg >>= 1;
> - hdlc->bit_shift--;
> - }
> - if (hdlc->bit_shift == 0) {
> - hdlc->shift_reg = (hdlc->crc >> 8);
> - hdlc->state = HDLC_SEND_CRC2;
> - hdlc->bit_shift = 8;
> - }
> - break;
> - case HDLC_SEND_CRC2:
> - hdlc->cbin <<= 1;
> - hdlc->data_bits++;
> - if (hdlc->hdlc_bits1 == 5) {
> - hdlc->hdlc_bits1 = 0;
> - break;
> - }
> - if (hdlc->shift_reg & 0x01) {
> - hdlc->hdlc_bits1++;
> - hdlc->cbin++;
> - hdlc->shift_reg >>= 1;
> - hdlc->bit_shift--;
> - } else {
> - hdlc->hdlc_bits1 = 0;
> - hdlc->shift_reg >>= 1;
> - hdlc->bit_shift--;
> - }
> - if (hdlc->bit_shift == 0) {
> - hdlc->shift_reg = 0x7e;
> - hdlc->state = HDLC_SEND_CLOSING_FLAG;
> - hdlc->bit_shift = 8;
> - }
> - break;
> - case HDLC_SEND_CLOSING_FLAG:
> - hdlc->cbin <<= 1;
> - hdlc->data_bits++;
> - if (hdlc->hdlc_bits1 == 5) {
> - hdlc->hdlc_bits1 = 0;
> - break;
> - }
> - if (hdlc->shift_reg & 0x01)
> - hdlc->cbin++;
> - hdlc->shift_reg >>= 1;
> - hdlc->bit_shift--;
> - if (hdlc->bit_shift == 0) {
> - hdlc->ffvalue =
> - xfast_flag_value[hdlc->data_bits];
> - if (hdlc->dchannel) {
> - hdlc->ffvalue = 0x7e;
> - hdlc->state = HDLC_SEND_IDLE1;
> - hdlc->bit_shift = 8-hdlc->data_bits;
> - if (hdlc->bit_shift == 0)
> - hdlc->state =
> - HDLC_SEND_FAST_IDLE;
> - } else {
> - if (!hdlc->do_adapt56) {
> - hdlc->state =
> - HDLC_SEND_FAST_FLAG;
> - hdlc->data_received = 0;
> - } else {
> - hdlc->state = HDLC_SENDFLAG_B0;
> - hdlc->data_received = 0;
> - }
> - /* Finished this frame, send flags */
> - if (dsize > 1)
> - dsize = 1;
> - }
> - }
> - break;
> - case HDLC_SEND_IDLE1:
> - hdlc->do_closing = 0;
> - hdlc->cbin <<= 1;
> - hdlc->cbin++;
> - hdlc->data_bits++;
> - hdlc->bit_shift--;
> - if (hdlc->bit_shift == 0) {
> - hdlc->state = HDLC_SEND_FAST_IDLE;
> - hdlc->bit_shift = 0;
> - }
> - break;
> - case HDLC_SEND_FAST_IDLE:
> - hdlc->do_closing = 0;
> - hdlc->cbin = 0xff;
> - hdlc->data_bits = 8;
> - if (hdlc->bit_shift == 8) {
> - hdlc->cbin = 0x7e;
> - hdlc->state = HDLC_SEND_FIRST_FLAG;
> - } else {
> - /* the code is for bitreverse streams */
> - if (hdlc->do_bitreverse == 0)
> - *dst++ = bitrev8(hdlc->cbin);
> - else
> - *dst++ = hdlc->cbin;
> - hdlc->bit_shift = 0;
> - hdlc->data_bits = 0;
> - len++;
> - dsize = 0;
> - }
> - break;
> - default:
> - break;
> - }
> - if (hdlc->do_adapt56) {
> - if (hdlc->data_bits == 7) {
> - hdlc->cbin <<= 1;
> - hdlc->cbin++;
> - hdlc->data_bits++;
> - }
> - }
> - if (hdlc->data_bits == 8) {
> - /* the code is for bitreverse streams */
> - if (hdlc->do_bitreverse == 0)
> - *dst++ = bitrev8(hdlc->cbin);
> - else
> - *dst++ = hdlc->cbin;
> - hdlc->data_bits = 0;
> - len++;
> - dsize--;
> - }
> - }
> - *count -= slen;
> -
> - return len;
> -}
> -EXPORT_SYMBOL(isdnhdlc_encode);
> diff --git a/drivers/isdn/hardware/mISDN/mISDNinfineon.c b/drivers/isdn/hardware/mISDN/mISDNinfineon.c
> deleted file mode 100644
> index aaa639ad5526..000000000000
> --- a/drivers/isdn/hardware/mISDN/mISDNinfineon.c
> +++ /dev/null
> @@ -1,1168 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * mISDNinfineon.c
> - * Support for cards based on following Infineon ISDN chipsets
> - * - ISAC + HSCX
> - * - IPAC and IPAC-X
> - * - ISAC-SX + HSCX
> - *
> - * Supported cards:
> - * - Dialogic Diva 2.0
> - * - Dialogic Diva 2.0U
> - * - Dialogic Diva 2.01
> - * - Dialogic Diva 2.02
> - * - Sedlbauer Speedwin
> - * - HST Saphir3
> - * - Develo (former ELSA) Microlink PCI (Quickstep 1000)
> - * - Develo (former ELSA) Quickstep 3000
> - * - Berkom Scitel BRIX Quadro
> - * - Dr.Neuhaus (Sagem) Niccy
> - *
> - * Author Karsten Keil <keil@isdn4linux.de>
> - *
> - * Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
> - */
> -
> -#include <linux/interrupt.h>
> -#include <linux/module.h>
> -#include <linux/pci.h>
> -#include <linux/delay.h>
> -#include <linux/mISDNhw.h>
> -#include <linux/slab.h>
> -#include "ipac.h"
> -
> -#define INFINEON_REV "1.0"
> -
> -static int inf_cnt;
> -static u32 debug;
> -static u32 irqloops = 4;
> -
> -enum inf_types {
> - INF_NONE,
> - INF_DIVA20,
> - INF_DIVA20U,
> - INF_DIVA201,
> - INF_DIVA202,
> - INF_SPEEDWIN,
> - INF_SAPHIR3,
> - INF_QS1000,
> - INF_QS3000,
> - INF_NICCY,
> - INF_SCT_1,
> - INF_SCT_2,
> - INF_SCT_3,
> - INF_SCT_4,
> - INF_GAZEL_R685,
> - INF_GAZEL_R753
> -};
> -
> -enum addr_mode {
> - AM_NONE = 0,
> - AM_IO,
> - AM_MEMIO,
> - AM_IND_IO,
> -};
> -
> -struct inf_cinfo {
> - enum inf_types typ;
> - const char *full;
> - const char *name;
> - enum addr_mode cfg_mode;
> - enum addr_mode addr_mode;
> - u8 cfg_bar;
> - u8 addr_bar;
> - void *irqfunc;
> -};
> -
> -struct _ioaddr {
> - enum addr_mode mode;
> - union {
> - void __iomem *p;
> - struct _ioport io;
> - } a;
> -};
> -
> -struct _iohandle {
> - enum addr_mode mode;
> - resource_size_t size;
> - resource_size_t start;
> - void __iomem *p;
> -};
> -
> -struct inf_hw {
> - struct list_head list;
> - struct pci_dev *pdev;
> - const struct inf_cinfo *ci;
> - char name[MISDN_MAX_IDLEN];
> - u32 irq;
> - u32 irqcnt;
> - struct _iohandle cfg;
> - struct _iohandle addr;
> - struct _ioaddr isac;
> - struct _ioaddr hscx;
> - spinlock_t lock; /* HW access lock */
> - struct ipac_hw ipac;
> - struct inf_hw *sc[3]; /* slave cards */
> -};
> -
> -
> -#define PCI_SUBVENDOR_HST_SAPHIR3 0x52
> -#define PCI_SUBVENDOR_SEDLBAUER_PCI 0x53
> -#define PCI_SUB_ID_SEDLBAUER 0x01
> -
> -static struct pci_device_id infineon_ids[] = {
> - { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA20), INF_DIVA20 },
> - { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA20_U), INF_DIVA20U },
> - { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA201), INF_DIVA201 },
> - { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA202), INF_DIVA202 },
> - { PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
> - PCI_SUBVENDOR_SEDLBAUER_PCI, PCI_SUB_ID_SEDLBAUER, 0, 0,
> - INF_SPEEDWIN },
> - { PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
> - PCI_SUBVENDOR_HST_SAPHIR3, PCI_SUB_ID_SEDLBAUER, 0, 0, INF_SAPHIR3 },
> - { PCI_VDEVICE(ELSA, PCI_DEVICE_ID_ELSA_MICROLINK), INF_QS1000 },
> - { PCI_VDEVICE(ELSA, PCI_DEVICE_ID_ELSA_QS3000), INF_QS3000 },
> - { PCI_VDEVICE(SATSAGEM, PCI_DEVICE_ID_SATSAGEM_NICCY), INF_NICCY },
> - { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
> - PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_SCITEL_QUADRO, 0, 0,
> - INF_SCT_1 },
> - { PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_R685), INF_GAZEL_R685 },
> - { PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_R753), INF_GAZEL_R753 },
> - { PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_DJINN_ITOO), INF_GAZEL_R753 },
> - { PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_OLITEC), INF_GAZEL_R753 },
> - { }
> -};
> -MODULE_DEVICE_TABLE(pci, infineon_ids);
> -
> -/* PCI interface specific defines */
> -/* Diva 2.0/2.0U */
> -#define DIVA_HSCX_PORT 0x00
> -#define DIVA_HSCX_ALE 0x04
> -#define DIVA_ISAC_PORT 0x08
> -#define DIVA_ISAC_ALE 0x0C
> -#define DIVA_PCI_CTRL 0x10
> -
> -/* DIVA_PCI_CTRL bits */
> -#define DIVA_IRQ_BIT 0x01
> -#define DIVA_RESET_BIT 0x08
> -#define DIVA_EEPROM_CLK 0x40
> -#define DIVA_LED_A 0x10
> -#define DIVA_LED_B 0x20
> -#define DIVA_IRQ_CLR 0x80
> -
> -/* Diva 2.01/2.02 */
> -/* Siemens PITA */
> -#define PITA_ICR_REG 0x00
> -#define PITA_INT0_STATUS 0x02
> -
> -#define PITA_MISC_REG 0x1c
> -#define PITA_PARA_SOFTRESET 0x01000000
> -#define PITA_SER_SOFTRESET 0x02000000
> -#define PITA_PARA_MPX_MODE 0x04000000
> -#define PITA_INT0_ENABLE 0x00020000
> -
> -/* TIGER 100 Registers */
> -#define TIGER_RESET_ADDR 0x00
> -#define TIGER_EXTERN_RESET 0x01
> -#define TIGER_AUX_CTRL 0x02
> -#define TIGER_AUX_DATA 0x03
> -#define TIGER_AUX_IRQMASK 0x05
> -#define TIGER_AUX_STATUS 0x07
> -
> -/* Tiger AUX BITs */
> -#define TIGER_IOMASK 0xdd /* 1 and 5 are inputs */
> -#define TIGER_IRQ_BIT 0x02
> -
> -#define TIGER_IPAC_ALE 0xC0
> -#define TIGER_IPAC_PORT 0xC8
> -
> -/* ELSA (now Develo) PCI cards */
> -#define ELSA_IRQ_ADDR 0x4c
> -#define ELSA_IRQ_MASK 0x04
> -#define QS1000_IRQ_OFF 0x01
> -#define QS3000_IRQ_OFF 0x03
> -#define QS1000_IRQ_ON 0x41
> -#define QS3000_IRQ_ON 0x43
> -
> -/* Dr Neuhaus/Sagem Niccy */
> -#define NICCY_ISAC_PORT 0x00
> -#define NICCY_HSCX_PORT 0x01
> -#define NICCY_ISAC_ALE 0x02
> -#define NICCY_HSCX_ALE 0x03
> -
> -#define NICCY_IRQ_CTRL_REG 0x38
> -#define NICCY_IRQ_ENABLE 0x001f00
> -#define NICCY_IRQ_DISABLE 0xff0000
> -#define NICCY_IRQ_BIT 0x800000
> -
> -
> -/* Scitel PLX */
> -#define SCT_PLX_IRQ_ADDR 0x4c
> -#define SCT_PLX_RESET_ADDR 0x50
> -#define SCT_PLX_IRQ_ENABLE 0x41
> -#define SCT_PLX_RESET_BIT 0x04
> -
> -/* Gazel */
> -#define GAZEL_IPAC_DATA_PORT 0x04
> -/* Gazel PLX */
> -#define GAZEL_CNTRL 0x50
> -#define GAZEL_RESET 0x04
> -#define GAZEL_RESET_9050 0x40000000
> -#define GAZEL_INCSR 0x4C
> -#define GAZEL_ISAC_EN 0x08
> -#define GAZEL_INT_ISAC 0x20
> -#define GAZEL_HSCX_EN 0x01
> -#define GAZEL_INT_HSCX 0x04
> -#define GAZEL_PCI_EN 0x40
> -#define GAZEL_IPAC_EN 0x03
> -
> -
> -static LIST_HEAD(Cards);
> -static DEFINE_RWLOCK(card_lock); /* protect Cards */
> -
> -static void
> -_set_debug(struct inf_hw *card)
> -{
> - card->ipac.isac.dch.debug = debug;
> - card->ipac.hscx[0].bch.debug = debug;
> - card->ipac.hscx[1].bch.debug = debug;
> -}
> -
> -static int
> -set_debug(const char *val, const struct kernel_param *kp)
> -{
> - int ret;
> - struct inf_hw *card;
> -
> - ret = param_set_uint(val, kp);
> - if (!ret) {
> - read_lock(&card_lock);
> - list_for_each_entry(card, &Cards, list)
> - _set_debug(card);
> - read_unlock(&card_lock);
> - }
> - return ret;
> -}
> -
> -MODULE_AUTHOR("Karsten Keil");
> -MODULE_DESCRIPTION("mISDN driver for cards based on Infineon ISDN chipsets");
> -MODULE_LICENSE("GPL v2");
> -MODULE_VERSION(INFINEON_REV);
> -module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR);
> -MODULE_PARM_DESC(debug, "infineon debug mask");
> -module_param(irqloops, uint, S_IRUGO | S_IWUSR);
> -MODULE_PARM_DESC(irqloops, "infineon maximal irqloops (default 4)");
> -
> -/* Interface functions */
> -
> -IOFUNC_IO(ISAC, inf_hw, isac.a.io)
> -IOFUNC_IO(IPAC, inf_hw, hscx.a.io)
> -IOFUNC_IND(ISAC, inf_hw, isac.a.io)
> -IOFUNC_IND(IPAC, inf_hw, hscx.a.io)
> -IOFUNC_MEMIO(ISAC, inf_hw, u32, isac.a.p)
> -IOFUNC_MEMIO(IPAC, inf_hw, u32, hscx.a.p)
> -
> -static irqreturn_t
> -diva_irq(int intno, void *dev_id)
> -{
> - struct inf_hw *hw = dev_id;
> - u8 val;
> -
> - spin_lock(&hw->lock);
> - val = inb((u32)hw->cfg.start + DIVA_PCI_CTRL);
> - if (!(val & DIVA_IRQ_BIT)) { /* for us or shared ? */
> - spin_unlock(&hw->lock);
> - return IRQ_NONE; /* shared */
> - }
> - hw->irqcnt++;
> - mISDNipac_irq(&hw->ipac, irqloops);
> - spin_unlock(&hw->lock);
> - return IRQ_HANDLED;
> -}
> -
> -static irqreturn_t
> -diva20x_irq(int intno, void *dev_id)
> -{
> - struct inf_hw *hw = dev_id;
> - u8 val;
> -
> - spin_lock(&hw->lock);
> - val = readb(hw->cfg.p);
> - if (!(val & PITA_INT0_STATUS)) { /* for us or shared ? */
> - spin_unlock(&hw->lock);
> - return IRQ_NONE; /* shared */
> - }
> - hw->irqcnt++;
> - mISDNipac_irq(&hw->ipac, irqloops);
> - writeb(PITA_INT0_STATUS, hw->cfg.p); /* ACK PITA INT0 */
> - spin_unlock(&hw->lock);
> - return IRQ_HANDLED;
> -}
> -
> -static irqreturn_t
> -tiger_irq(int intno, void *dev_id)
> -{
> - struct inf_hw *hw = dev_id;
> - u8 val;
> -
> - spin_lock(&hw->lock);
> - val = inb((u32)hw->cfg.start + TIGER_AUX_STATUS);
> - if (val & TIGER_IRQ_BIT) { /* for us or shared ? */
> - spin_unlock(&hw->lock);
> - return IRQ_NONE; /* shared */
> - }
> - hw->irqcnt++;
> - mISDNipac_irq(&hw->ipac, irqloops);
> - spin_unlock(&hw->lock);
> - return IRQ_HANDLED;
> -}
> -
> -static irqreturn_t
> -elsa_irq(int intno, void *dev_id)
> -{
> - struct inf_hw *hw = dev_id;
> - u8 val;
> -
> - spin_lock(&hw->lock);
> - val = inb((u32)hw->cfg.start + ELSA_IRQ_ADDR);
> - if (!(val & ELSA_IRQ_MASK)) {
> - spin_unlock(&hw->lock);
> - return IRQ_NONE; /* shared */
> - }
> - hw->irqcnt++;
> - mISDNipac_irq(&hw->ipac, irqloops);
> - spin_unlock(&hw->lock);
> - return IRQ_HANDLED;
> -}
> -
> -static irqreturn_t
> -niccy_irq(int intno, void *dev_id)
> -{
> - struct inf_hw *hw = dev_id;
> - u32 val;
> -
> - spin_lock(&hw->lock);
> - val = inl((u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
> - if (!(val & NICCY_IRQ_BIT)) { /* for us or shared ? */
> - spin_unlock(&hw->lock);
> - return IRQ_NONE; /* shared */
> - }
> - outl(val, (u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
> - hw->irqcnt++;
> - mISDNipac_irq(&hw->ipac, irqloops);
> - spin_unlock(&hw->lock);
> - return IRQ_HANDLED;
> -}
> -
> -static irqreturn_t
> -gazel_irq(int intno, void *dev_id)
> -{
> - struct inf_hw *hw = dev_id;
> - irqreturn_t ret;
> -
> - spin_lock(&hw->lock);
> - ret = mISDNipac_irq(&hw->ipac, irqloops);
> - spin_unlock(&hw->lock);
> - return ret;
> -}
> -
> -static irqreturn_t
> -ipac_irq(int intno, void *dev_id)
> -{
> - struct inf_hw *hw = dev_id;
> - u8 val;
> -
> - spin_lock(&hw->lock);
> - val = hw->ipac.read_reg(hw, IPAC_ISTA);
> - if (!(val & 0x3f)) {
> - spin_unlock(&hw->lock);
> - return IRQ_NONE; /* shared */
> - }
> - hw->irqcnt++;
> - mISDNipac_irq(&hw->ipac, irqloops);
> - spin_unlock(&hw->lock);
> - return IRQ_HANDLED;
> -}
> -
> -static void
> -enable_hwirq(struct inf_hw *hw)
> -{
> - u16 w;
> - u32 val;
> -
> - switch (hw->ci->typ) {
> - case INF_DIVA201:
> - case INF_DIVA202:
> - writel(PITA_INT0_ENABLE, hw->cfg.p);
> - break;
> - case INF_SPEEDWIN:
> - case INF_SAPHIR3:
> - outb(TIGER_IRQ_BIT, (u32)hw->cfg.start + TIGER_AUX_IRQMASK);
> - break;
> - case INF_QS1000:
> - outb(QS1000_IRQ_ON, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
> - break;
> - case INF_QS3000:
> - outb(QS3000_IRQ_ON, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
> - break;
> - case INF_NICCY:
> - val = inl((u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
> - val |= NICCY_IRQ_ENABLE;
> - outl(val, (u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
> - break;
> - case INF_SCT_1:
> - w = inw((u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
> - w |= SCT_PLX_IRQ_ENABLE;
> - outw(w, (u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
> - break;
> - case INF_GAZEL_R685:
> - outb(GAZEL_ISAC_EN + GAZEL_HSCX_EN + GAZEL_PCI_EN,
> - (u32)hw->cfg.start + GAZEL_INCSR);
> - break;
> - case INF_GAZEL_R753:
> - outb(GAZEL_IPAC_EN + GAZEL_PCI_EN,
> - (u32)hw->cfg.start + GAZEL_INCSR);
> - break;
> - default:
> - break;
> - }
> -}
> -
> -static void
> -disable_hwirq(struct inf_hw *hw)
> -{
> - u16 w;
> - u32 val;
> -
> - switch (hw->ci->typ) {
> - case INF_DIVA201:
> - case INF_DIVA202:
> - writel(0, hw->cfg.p);
> - break;
> - case INF_SPEEDWIN:
> - case INF_SAPHIR3:
> - outb(0, (u32)hw->cfg.start + TIGER_AUX_IRQMASK);
> - break;
> - case INF_QS1000:
> - outb(QS1000_IRQ_OFF, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
> - break;
> - case INF_QS3000:
> - outb(QS3000_IRQ_OFF, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
> - break;
> - case INF_NICCY:
> - val = inl((u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
> - val &= NICCY_IRQ_DISABLE;
> - outl(val, (u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
> - break;
> - case INF_SCT_1:
> - w = inw((u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
> - w &= (~SCT_PLX_IRQ_ENABLE);
> - outw(w, (u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
> - break;
> - case INF_GAZEL_R685:
> - case INF_GAZEL_R753:
> - outb(0, (u32)hw->cfg.start + GAZEL_INCSR);
> - break;
> - default:
> - break;
> - }
> -}
> -
> -static void
> -ipac_chip_reset(struct inf_hw *hw)
> -{
> - hw->ipac.write_reg(hw, IPAC_POTA2, 0x20);
> - mdelay(5);
> - hw->ipac.write_reg(hw, IPAC_POTA2, 0x00);
> - mdelay(5);
> - hw->ipac.write_reg(hw, IPAC_CONF, hw->ipac.conf);
> - hw->ipac.write_reg(hw, IPAC_MASK, 0xc0);
> -}
> -
> -static void
> -reset_inf(struct inf_hw *hw)
> -{
> - u16 w;
> - u32 val;
> -
> - if (debug & DEBUG_HW)
> - pr_notice("%s: resetting card\n", hw->name);
> - switch (hw->ci->typ) {
> - case INF_DIVA20:
> - case INF_DIVA20U:
> - outb(0, (u32)hw->cfg.start + DIVA_PCI_CTRL);
> - mdelay(10);
> - outb(DIVA_RESET_BIT, (u32)hw->cfg.start + DIVA_PCI_CTRL);
> - mdelay(10);
> - /* Workaround PCI9060 */
> - outb(9, (u32)hw->cfg.start + 0x69);
> - outb(DIVA_RESET_BIT | DIVA_LED_A,
> - (u32)hw->cfg.start + DIVA_PCI_CTRL);
> - break;
> - case INF_DIVA201:
> - writel(PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE,
> - hw->cfg.p + PITA_MISC_REG);
> - mdelay(1);
> - writel(PITA_PARA_MPX_MODE, hw->cfg.p + PITA_MISC_REG);
> - mdelay(10);
> - break;
> - case INF_DIVA202:
> - writel(PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE,
> - hw->cfg.p + PITA_MISC_REG);
> - mdelay(1);
> - writel(PITA_PARA_MPX_MODE | PITA_SER_SOFTRESET,
> - hw->cfg.p + PITA_MISC_REG);
> - mdelay(10);
> - break;
> - case INF_SPEEDWIN:
> - case INF_SAPHIR3:
> - ipac_chip_reset(hw);
> - hw->ipac.write_reg(hw, IPAC_ACFG, 0xff);
> - hw->ipac.write_reg(hw, IPAC_AOE, 0x00);
> - hw->ipac.write_reg(hw, IPAC_PCFG, 0x12);
> - break;
> - case INF_QS1000:
> - case INF_QS3000:
> - ipac_chip_reset(hw);
> - hw->ipac.write_reg(hw, IPAC_ACFG, 0x00);
> - hw->ipac.write_reg(hw, IPAC_AOE, 0x3c);
> - hw->ipac.write_reg(hw, IPAC_ATX, 0xff);
> - break;
> - case INF_NICCY:
> - break;
> - case INF_SCT_1:
> - w = inw((u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
> - w &= (~SCT_PLX_RESET_BIT);
> - outw(w, (u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
> - mdelay(10);
> - w = inw((u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
> - w |= SCT_PLX_RESET_BIT;
> - outw(w, (u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
> - mdelay(10);
> - break;
> - case INF_GAZEL_R685:
> - val = inl((u32)hw->cfg.start + GAZEL_CNTRL);
> - val |= (GAZEL_RESET_9050 + GAZEL_RESET);
> - outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
> - val &= ~(GAZEL_RESET_9050 + GAZEL_RESET);
> - mdelay(4);
> - outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
> - mdelay(10);
> - hw->ipac.isac.adf2 = 0x87;
> - hw->ipac.hscx[0].slot = 0x1f;
> - hw->ipac.hscx[1].slot = 0x23;
> - break;
> - case INF_GAZEL_R753:
> - val = inl((u32)hw->cfg.start + GAZEL_CNTRL);
> - val |= (GAZEL_RESET_9050 + GAZEL_RESET);
> - outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
> - val &= ~(GAZEL_RESET_9050 + GAZEL_RESET);
> - mdelay(4);
> - outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
> - mdelay(10);
> - ipac_chip_reset(hw);
> - hw->ipac.write_reg(hw, IPAC_ACFG, 0xff);
> - hw->ipac.write_reg(hw, IPAC_AOE, 0x00);
> - hw->ipac.conf = 0x01; /* IOM off */
> - break;
> - default:
> - return;
> - }
> - enable_hwirq(hw);
> -}
> -
> -static int
> -inf_ctrl(struct inf_hw *hw, u32 cmd, u_long arg)
> -{
> - int ret = 0;
> -
> - switch (cmd) {
> - case HW_RESET_REQ:
> - reset_inf(hw);
> - break;
> - default:
> - pr_info("%s: %s unknown command %x %lx\n",
> - hw->name, __func__, cmd, arg);
> - ret = -EINVAL;
> - break;
> - }
> - return ret;
> -}
> -
> -static int
> -init_irq(struct inf_hw *hw)
> -{
> - int ret, cnt = 3;
> - u_long flags;
> -
> - if (!hw->ci->irqfunc)
> - return -EINVAL;
> - ret = request_irq(hw->irq, hw->ci->irqfunc, IRQF_SHARED, hw->name, hw);
> - if (ret) {
> - pr_info("%s: couldn't get interrupt %d\n", hw->name, hw->irq);
> - return ret;
> - }
> - while (cnt--) {
> - spin_lock_irqsave(&hw->lock, flags);
> - reset_inf(hw);
> - ret = hw->ipac.init(&hw->ipac);
> - if (ret) {
> - spin_unlock_irqrestore(&hw->lock, flags);
> - pr_info("%s: ISAC init failed with %d\n",
> - hw->name, ret);
> - break;
> - }
> - spin_unlock_irqrestore(&hw->lock, flags);
> - msleep_interruptible(10);
> - if (debug & DEBUG_HW)
> - pr_notice("%s: IRQ %d count %d\n", hw->name,
> - hw->irq, hw->irqcnt);
> - if (!hw->irqcnt) {
> - pr_info("%s: IRQ(%d) got no requests during init %d\n",
> - hw->name, hw->irq, 3 - cnt);
> - } else
> - return 0;
> - }
> - free_irq(hw->irq, hw);
> - return -EIO;
> -}
> -
> -static void
> -release_io(struct inf_hw *hw)
> -{
> - if (hw->cfg.mode) {
> - if (hw->cfg.mode == AM_MEMIO) {
> - release_mem_region(hw->cfg.start, hw->cfg.size);
> - if (hw->cfg.p)
> - iounmap(hw->cfg.p);
> - } else
> - release_region(hw->cfg.start, hw->cfg.size);
> - hw->cfg.mode = AM_NONE;
> - }
> - if (hw->addr.mode) {
> - if (hw->addr.mode == AM_MEMIO) {
> - release_mem_region(hw->addr.start, hw->addr.size);
> - if (hw->addr.p)
> - iounmap(hw->addr.p);
> - } else
> - release_region(hw->addr.start, hw->addr.size);
> - hw->addr.mode = AM_NONE;
> - }
> -}
> -
> -static int
> -setup_io(struct inf_hw *hw)
> -{
> - int err = 0;
> -
> - if (hw->ci->cfg_mode) {
> - hw->cfg.start = pci_resource_start(hw->pdev, hw->ci->cfg_bar);
> - hw->cfg.size = pci_resource_len(hw->pdev, hw->ci->cfg_bar);
> - if (hw->ci->cfg_mode == AM_MEMIO) {
> - if (!request_mem_region(hw->cfg.start, hw->cfg.size,
> - hw->name))
> - err = -EBUSY;
> - } else {
> - if (!request_region(hw->cfg.start, hw->cfg.size,
> - hw->name))
> - err = -EBUSY;
> - }
> - if (err) {
> - pr_info("mISDN: %s config port %lx (%lu bytes)"
> - "already in use\n", hw->name,
> - (ulong)hw->cfg.start, (ulong)hw->cfg.size);
> - return err;
> - }
> - hw->cfg.mode = hw->ci->cfg_mode;
> - if (hw->ci->cfg_mode == AM_MEMIO) {
> - hw->cfg.p = ioremap(hw->cfg.start, hw->cfg.size);
> - if (!hw->cfg.p)
> - return -ENOMEM;
> - }
> - if (debug & DEBUG_HW)
> - pr_notice("%s: IO cfg %lx (%lu bytes) mode%d\n",
> - hw->name, (ulong)hw->cfg.start,
> - (ulong)hw->cfg.size, hw->ci->cfg_mode);
> -
> - }
> - if (hw->ci->addr_mode) {
> - hw->addr.start = pci_resource_start(hw->pdev, hw->ci->addr_bar);
> - hw->addr.size = pci_resource_len(hw->pdev, hw->ci->addr_bar);
> - if (hw->ci->addr_mode == AM_MEMIO) {
> - if (!request_mem_region(hw->addr.start, hw->addr.size,
> - hw->name))
> - err = -EBUSY;
> - } else {
> - if (!request_region(hw->addr.start, hw->addr.size,
> - hw->name))
> - err = -EBUSY;
> - }
> - if (err) {
> - pr_info("mISDN: %s address port %lx (%lu bytes)"
> - "already in use\n", hw->name,
> - (ulong)hw->addr.start, (ulong)hw->addr.size);
> - return err;
> - }
> - hw->addr.mode = hw->ci->addr_mode;
> - if (hw->ci->addr_mode == AM_MEMIO) {
> - hw->addr.p = ioremap(hw->addr.start, hw->addr.size);
> - if (!hw->addr.p)
> - return -ENOMEM;
> - }
> - if (debug & DEBUG_HW)
> - pr_notice("%s: IO addr %lx (%lu bytes) mode%d\n",
> - hw->name, (ulong)hw->addr.start,
> - (ulong)hw->addr.size, hw->ci->addr_mode);
> -
> - }
> -
> - switch (hw->ci->typ) {
> - case INF_DIVA20:
> - case INF_DIVA20U:
> - hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX;
> - hw->isac.mode = hw->cfg.mode;
> - hw->isac.a.io.ale = (u32)hw->cfg.start + DIVA_ISAC_ALE;
> - hw->isac.a.io.port = (u32)hw->cfg.start + DIVA_ISAC_PORT;
> - hw->hscx.mode = hw->cfg.mode;
> - hw->hscx.a.io.ale = (u32)hw->cfg.start + DIVA_HSCX_ALE;
> - hw->hscx.a.io.port = (u32)hw->cfg.start + DIVA_HSCX_PORT;
> - break;
> - case INF_DIVA201:
> - hw->ipac.type = IPAC_TYPE_IPAC;
> - hw->ipac.isac.off = 0x80;
> - hw->isac.mode = hw->addr.mode;
> - hw->isac.a.p = hw->addr.p;
> - hw->hscx.mode = hw->addr.mode;
> - hw->hscx.a.p = hw->addr.p;
> - break;
> - case INF_DIVA202:
> - hw->ipac.type = IPAC_TYPE_IPACX;
> - hw->isac.mode = hw->addr.mode;
> - hw->isac.a.p = hw->addr.p;
> - hw->hscx.mode = hw->addr.mode;
> - hw->hscx.a.p = hw->addr.p;
> - break;
> - case INF_SPEEDWIN:
> - case INF_SAPHIR3:
> - hw->ipac.type = IPAC_TYPE_IPAC;
> - hw->ipac.isac.off = 0x80;
> - hw->isac.mode = hw->cfg.mode;
> - hw->isac.a.io.ale = (u32)hw->cfg.start + TIGER_IPAC_ALE;
> - hw->isac.a.io.port = (u32)hw->cfg.start + TIGER_IPAC_PORT;
> - hw->hscx.mode = hw->cfg.mode;
> - hw->hscx.a.io.ale = (u32)hw->cfg.start + TIGER_IPAC_ALE;
> - hw->hscx.a.io.port = (u32)hw->cfg.start + TIGER_IPAC_PORT;
> - outb(0xff, (ulong)hw->cfg.start);
> - mdelay(1);
> - outb(0x00, (ulong)hw->cfg.start);
> - mdelay(1);
> - outb(TIGER_IOMASK, (ulong)hw->cfg.start + TIGER_AUX_CTRL);
> - break;
> - case INF_QS1000:
> - case INF_QS3000:
> - hw->ipac.type = IPAC_TYPE_IPAC;
> - hw->ipac.isac.off = 0x80;
> - hw->isac.a.io.ale = (u32)hw->addr.start;
> - hw->isac.a.io.port = (u32)hw->addr.start + 1;
> - hw->isac.mode = hw->addr.mode;
> - hw->hscx.a.io.ale = (u32)hw->addr.start;
> - hw->hscx.a.io.port = (u32)hw->addr.start + 1;
> - hw->hscx.mode = hw->addr.mode;
> - break;
> - case INF_NICCY:
> - hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX;
> - hw->isac.mode = hw->addr.mode;
> - hw->isac.a.io.ale = (u32)hw->addr.start + NICCY_ISAC_ALE;
> - hw->isac.a.io.port = (u32)hw->addr.start + NICCY_ISAC_PORT;
> - hw->hscx.mode = hw->addr.mode;
> - hw->hscx.a.io.ale = (u32)hw->addr.start + NICCY_HSCX_ALE;
> - hw->hscx.a.io.port = (u32)hw->addr.start + NICCY_HSCX_PORT;
> - break;
> - case INF_SCT_1:
> - hw->ipac.type = IPAC_TYPE_IPAC;
> - hw->ipac.isac.off = 0x80;
> - hw->isac.a.io.ale = (u32)hw->addr.start;
> - hw->isac.a.io.port = hw->isac.a.io.ale + 4;
> - hw->isac.mode = hw->addr.mode;
> - hw->hscx.a.io.ale = hw->isac.a.io.ale;
> - hw->hscx.a.io.port = hw->isac.a.io.port;
> - hw->hscx.mode = hw->addr.mode;
> - break;
> - case INF_SCT_2:
> - hw->ipac.type = IPAC_TYPE_IPAC;
> - hw->ipac.isac.off = 0x80;
> - hw->isac.a.io.ale = (u32)hw->addr.start + 0x08;
> - hw->isac.a.io.port = hw->isac.a.io.ale + 4;
> - hw->isac.mode = hw->addr.mode;
> - hw->hscx.a.io.ale = hw->isac.a.io.ale;
> - hw->hscx.a.io.port = hw->isac.a.io.port;
> - hw->hscx.mode = hw->addr.mode;
> - break;
> - case INF_SCT_3:
> - hw->ipac.type = IPAC_TYPE_IPAC;
> - hw->ipac.isac.off = 0x80;
> - hw->isac.a.io.ale = (u32)hw->addr.start + 0x10;
> - hw->isac.a.io.port = hw->isac.a.io.ale + 4;
> - hw->isac.mode = hw->addr.mode;
> - hw->hscx.a.io.ale = hw->isac.a.io.ale;
> - hw->hscx.a.io.port = hw->isac.a.io.port;
> - hw->hscx.mode = hw->addr.mode;
> - break;
> - case INF_SCT_4:
> - hw->ipac.type = IPAC_TYPE_IPAC;
> - hw->ipac.isac.off = 0x80;
> - hw->isac.a.io.ale = (u32)hw->addr.start + 0x20;
> - hw->isac.a.io.port = hw->isac.a.io.ale + 4;
> - hw->isac.mode = hw->addr.mode;
> - hw->hscx.a.io.ale = hw->isac.a.io.ale;
> - hw->hscx.a.io.port = hw->isac.a.io.port;
> - hw->hscx.mode = hw->addr.mode;
> - break;
> - case INF_GAZEL_R685:
> - hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX;
> - hw->ipac.isac.off = 0x80;
> - hw->isac.mode = hw->addr.mode;
> - hw->isac.a.io.port = (u32)hw->addr.start;
> - hw->hscx.mode = hw->addr.mode;
> - hw->hscx.a.io.port = hw->isac.a.io.port;
> - break;
> - case INF_GAZEL_R753:
> - hw->ipac.type = IPAC_TYPE_IPAC;
> - hw->ipac.isac.off = 0x80;
> - hw->isac.mode = hw->addr.mode;
> - hw->isac.a.io.ale = (u32)hw->addr.start;
> - hw->isac.a.io.port = (u32)hw->addr.start + GAZEL_IPAC_DATA_PORT;
> - hw->hscx.mode = hw->addr.mode;
> - hw->hscx.a.io.ale = hw->isac.a.io.ale;
> - hw->hscx.a.io.port = hw->isac.a.io.port;
> - break;
> - default:
> - return -EINVAL;
> - }
> - switch (hw->isac.mode) {
> - case AM_MEMIO:
> - ASSIGN_FUNC_IPAC(MIO, hw->ipac);
> - break;
> - case AM_IND_IO:
> - ASSIGN_FUNC_IPAC(IND, hw->ipac);
> - break;
> - case AM_IO:
> - ASSIGN_FUNC_IPAC(IO, hw->ipac);
> - break;
> - default:
> - return -EINVAL;
> - }
> - return 0;
> -}
> -
> -static void
> -release_card(struct inf_hw *card) {
> - ulong flags;
> - int i;
> -
> - spin_lock_irqsave(&card->lock, flags);
> - disable_hwirq(card);
> - spin_unlock_irqrestore(&card->lock, flags);
> - card->ipac.isac.release(&card->ipac.isac);
> - free_irq(card->irq, card);
> - mISDN_unregister_device(&card->ipac.isac.dch.dev);
> - release_io(card);
> - write_lock_irqsave(&card_lock, flags);
> - list_del(&card->list);
> - write_unlock_irqrestore(&card_lock, flags);
> - switch (card->ci->typ) {
> - case INF_SCT_2:
> - case INF_SCT_3:
> - case INF_SCT_4:
> - break;
> - case INF_SCT_1:
> - for (i = 0; i < 3; i++) {
> - if (card->sc[i])
> - release_card(card->sc[i]);
> - card->sc[i] = NULL;
> - }
> - fallthrough;
> - default:
> - pci_disable_device(card->pdev);
> - pci_set_drvdata(card->pdev, NULL);
> - break;
> - }
> - kfree(card);
> - inf_cnt--;
> -}
> -
> -static int
> -setup_instance(struct inf_hw *card)
> -{
> - int err;
> - ulong flags;
> -
> - snprintf(card->name, MISDN_MAX_IDLEN - 1, "%s.%d", card->ci->name,
> - inf_cnt + 1);
> - write_lock_irqsave(&card_lock, flags);
> - list_add_tail(&card->list, &Cards);
> - write_unlock_irqrestore(&card_lock, flags);
> -
> - _set_debug(card);
> - card->ipac.isac.name = card->name;
> - card->ipac.name = card->name;
> - card->ipac.owner = THIS_MODULE;
> - spin_lock_init(&card->lock);
> - card->ipac.isac.hwlock = &card->lock;
> - card->ipac.hwlock = &card->lock;
> - card->ipac.ctrl = (void *)&inf_ctrl;
> -
> - err = setup_io(card);
> - if (err)
> - goto error_setup;
> -
> - card->ipac.isac.dch.dev.Bprotocols =
> - mISDNipac_init(&card->ipac, card);
> -
> - if (card->ipac.isac.dch.dev.Bprotocols == 0)
> - goto error_setup;
> -
> - err = mISDN_register_device(&card->ipac.isac.dch.dev,
> - &card->pdev->dev, card->name);
> - if (err)
> - goto error;
> -
> - err = init_irq(card);
> - if (!err) {
> - inf_cnt++;
> - pr_notice("Infineon %d cards installed\n", inf_cnt);
> - return 0;
> - }
> - mISDN_unregister_device(&card->ipac.isac.dch.dev);
> -error:
> - card->ipac.release(&card->ipac);
> -error_setup:
> - release_io(card);
> - write_lock_irqsave(&card_lock, flags);
> - list_del(&card->list);
> - write_unlock_irqrestore(&card_lock, flags);
> - return err;
> -}
> -
> -static const struct inf_cinfo inf_card_info[] = {
> - {
> - INF_DIVA20,
> - "Dialogic Diva 2.0",
> - "diva20",
> - AM_IND_IO, AM_NONE, 2, 0,
> - &diva_irq
> - },
> - {
> - INF_DIVA20U,
> - "Dialogic Diva 2.0U",
> - "diva20U",
> - AM_IND_IO, AM_NONE, 2, 0,
> - &diva_irq
> - },
> - {
> - INF_DIVA201,
> - "Dialogic Diva 2.01",
> - "diva201",
> - AM_MEMIO, AM_MEMIO, 0, 1,
> - &diva20x_irq
> - },
> - {
> - INF_DIVA202,
> - "Dialogic Diva 2.02",
> - "diva202",
> - AM_MEMIO, AM_MEMIO, 0, 1,
> - &diva20x_irq
> - },
> - {
> - INF_SPEEDWIN,
> - "Sedlbauer SpeedWin PCI",
> - "speedwin",
> - AM_IND_IO, AM_NONE, 0, 0,
> - &tiger_irq
> - },
> - {
> - INF_SAPHIR3,
> - "HST Saphir 3",
> - "saphir",
> - AM_IND_IO, AM_NONE, 0, 0,
> - &tiger_irq
> - },
> - {
> - INF_QS1000,
> - "Develo Microlink PCI",
> - "qs1000",
> - AM_IO, AM_IND_IO, 1, 3,
> - &elsa_irq
> - },
> - {
> - INF_QS3000,
> - "Develo QuickStep 3000",
> - "qs3000",
> - AM_IO, AM_IND_IO, 1, 3,
> - &elsa_irq
> - },
> - {
> - INF_NICCY,
> - "Sagem NICCY",
> - "niccy",
> - AM_IO, AM_IND_IO, 0, 1,
> - &niccy_irq
> - },
> - {
> - INF_SCT_1,
> - "SciTel Quadro",
> - "p1_scitel",
> - AM_IO, AM_IND_IO, 1, 5,
> - &ipac_irq
> - },
> - {
> - INF_SCT_2,
> - "SciTel Quadro",
> - "p2_scitel",
> - AM_NONE, AM_IND_IO, 0, 4,
> - &ipac_irq
> - },
> - {
> - INF_SCT_3,
> - "SciTel Quadro",
> - "p3_scitel",
> - AM_NONE, AM_IND_IO, 0, 3,
> - &ipac_irq
> - },
> - {
> - INF_SCT_4,
> - "SciTel Quadro",
> - "p4_scitel",
> - AM_NONE, AM_IND_IO, 0, 2,
> - &ipac_irq
> - },
> - {
> - INF_GAZEL_R685,
> - "Gazel R685",
> - "gazel685",
> - AM_IO, AM_IO, 1, 2,
> - &gazel_irq
> - },
> - {
> - INF_GAZEL_R753,
> - "Gazel R753",
> - "gazel753",
> - AM_IO, AM_IND_IO, 1, 2,
> - &ipac_irq
> - },
> - {
> - INF_NONE,
> - }
> -};
> -
> -static const struct inf_cinfo *
> -get_card_info(enum inf_types typ)
> -{
> - const struct inf_cinfo *ci = inf_card_info;
> -
> - while (ci->typ != INF_NONE) {
> - if (ci->typ == typ)
> - return ci;
> - ci++;
> - }
> - return NULL;
> -}
> -
> -static int
> -inf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
> -{
> - int err = -ENOMEM;
> - struct inf_hw *card;
> -
> - card = kzalloc_obj(struct inf_hw);
> - if (!card) {
> - pr_info("No memory for Infineon ISDN card\n");
> - return err;
> - }
> - card->pdev = pdev;
> - err = pci_enable_device(pdev);
> - if (err) {
> - kfree(card);
> - return err;
> - }
> - card->ci = get_card_info(ent->driver_data);
> - if (!card->ci) {
> - pr_info("mISDN: do not have information about adapter at %s\n",
> - pci_name(pdev));
> - kfree(card);
> - pci_disable_device(pdev);
> - return -EINVAL;
> - } else
> - pr_notice("mISDN: found adapter %s at %s\n",
> - card->ci->full, pci_name(pdev));
> -
> - card->irq = pdev->irq;
> - pci_set_drvdata(pdev, card);
> - err = setup_instance(card);
> - if (err) {
> - pci_disable_device(pdev);
> - kfree(card);
> - pci_set_drvdata(pdev, NULL);
> - } else if (ent->driver_data == INF_SCT_1) {
> - int i;
> - struct inf_hw *sc;
> -
> - for (i = 1; i < 4; i++) {
> - sc = kzalloc_obj(struct inf_hw);
> - if (!sc) {
> - release_card(card);
> - pci_disable_device(pdev);
> - return -ENOMEM;
> - }
> - sc->irq = card->irq;
> - sc->pdev = card->pdev;
> - sc->ci = card->ci + i;
> - err = setup_instance(sc);
> - if (err) {
> - pci_disable_device(pdev);
> - kfree(sc);
> - release_card(card);
> - break;
> - } else
> - card->sc[i - 1] = sc;
> - }
> - }
> - return err;
> -}
> -
> -static void
> -inf_remove(struct pci_dev *pdev)
> -{
> - struct inf_hw *card = pci_get_drvdata(pdev);
> -
> - if (card)
> - release_card(card);
> - else
> - pr_debug("%s: drvdata already removed\n", __func__);
> -}
> -
> -static struct pci_driver infineon_driver = {
> - .name = "ISDN Infineon pci",
> - .probe = inf_probe,
> - .remove = inf_remove,
> - .id_table = infineon_ids,
> -};
> -
> -static int __init
> -infineon_init(void)
> -{
> - int err;
> -
> - pr_notice("Infineon ISDN Driver Rev. %s\n", INFINEON_REV);
> - err = pci_register_driver(&infineon_driver);
> - return err;
> -}
> -
> -static void __exit
> -infineon_cleanup(void)
> -{
> - pci_unregister_driver(&infineon_driver);
> -}
> -
> -module_init(infineon_init);
> -module_exit(infineon_cleanup);
> diff --git a/drivers/isdn/hardware/mISDN/mISDNipac.c b/drivers/isdn/hardware/mISDN/mISDNipac.c
> deleted file mode 100644
> index a34ea6058960..000000000000
> --- a/drivers/isdn/hardware/mISDN/mISDNipac.c
> +++ /dev/null
> @@ -1,1636 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * isac.c ISAC specific routines
> - *
> - * Author Karsten Keil <keil@isdn4linux.de>
> - *
> - * Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
> - */
> -
> -#include <linux/irqreturn.h>
> -#include <linux/slab.h>
> -#include <linux/module.h>
> -#include <linux/mISDNhw.h>
> -#include "ipac.h"
> -
> -
> -#define DBUSY_TIMER_VALUE 80
> -#define ARCOFI_USE 1
> -
> -#define ISAC_REV "2.0"
> -
> -MODULE_AUTHOR("Karsten Keil");
> -MODULE_VERSION(ISAC_REV);
> -MODULE_DESCRIPTION("mISDN driver for ISAC specific functions");
> -MODULE_LICENSE("GPL v2");
> -
> -#define ReadISAC(is, o) (is->read_reg(is->dch.hw, o + is->off))
> -#define WriteISAC(is, o, v) (is->write_reg(is->dch.hw, o + is->off, v))
> -#define ReadHSCX(h, o) (h->ip->read_reg(h->ip->hw, h->off + o))
> -#define WriteHSCX(h, o, v) (h->ip->write_reg(h->ip->hw, h->off + o, v))
> -#define ReadIPAC(ip, o) (ip->read_reg(ip->hw, o))
> -#define WriteIPAC(ip, o, v) (ip->write_reg(ip->hw, o, v))
> -
> -static inline void
> -ph_command(struct isac_hw *isac, u8 command)
> -{
> - pr_debug("%s: ph_command %x\n", isac->name, command);
> - if (isac->type & IPAC_TYPE_ISACX)
> - WriteISAC(isac, ISACX_CIX0, (command << 4) | 0xE);
> - else
> - WriteISAC(isac, ISAC_CIX0, (command << 2) | 3);
> -}
> -
> -static void
> -isac_ph_state_change(struct isac_hw *isac)
> -{
> - switch (isac->state) {
> - case (ISAC_IND_RS):
> - case (ISAC_IND_EI):
> - ph_command(isac, ISAC_CMD_DUI);
> - }
> - schedule_event(&isac->dch, FLG_PHCHANGE);
> -}
> -
> -static void
> -isac_ph_state_bh(struct dchannel *dch)
> -{
> - struct isac_hw *isac = container_of(dch, struct isac_hw, dch);
> -
> - switch (isac->state) {
> - case ISAC_IND_RS:
> - case ISAC_IND_EI:
> - dch->state = 0;
> - l1_event(dch->l1, HW_RESET_IND);
> - break;
> - case ISAC_IND_DID:
> - dch->state = 3;
> - l1_event(dch->l1, HW_DEACT_CNF);
> - break;
> - case ISAC_IND_DR:
> - case ISAC_IND_DR6:
> - dch->state = 3;
> - l1_event(dch->l1, HW_DEACT_IND);
> - break;
> - case ISAC_IND_PU:
> - dch->state = 4;
> - l1_event(dch->l1, HW_POWERUP_IND);
> - break;
> - case ISAC_IND_RSY:
> - if (dch->state <= 5) {
> - dch->state = 5;
> - l1_event(dch->l1, ANYSIGNAL);
> - } else {
> - dch->state = 8;
> - l1_event(dch->l1, LOSTFRAMING);
> - }
> - break;
> - case ISAC_IND_ARD:
> - dch->state = 6;
> - l1_event(dch->l1, INFO2);
> - break;
> - case ISAC_IND_AI8:
> - dch->state = 7;
> - l1_event(dch->l1, INFO4_P8);
> - break;
> - case ISAC_IND_AI10:
> - dch->state = 7;
> - l1_event(dch->l1, INFO4_P10);
> - break;
> - }
> - pr_debug("%s: TE newstate %x\n", isac->name, dch->state);
> -}
> -
> -static void
> -isac_empty_fifo(struct isac_hw *isac, int count)
> -{
> - u8 *ptr;
> -
> - pr_debug("%s: %s %d\n", isac->name, __func__, count);
> -
> - if (!isac->dch.rx_skb) {
> - isac->dch.rx_skb = mI_alloc_skb(isac->dch.maxlen, GFP_ATOMIC);
> - if (!isac->dch.rx_skb) {
> - pr_info("%s: D receive out of memory\n", isac->name);
> - WriteISAC(isac, ISAC_CMDR, 0x80);
> - return;
> - }
> - }
> - if ((isac->dch.rx_skb->len + count) >= isac->dch.maxlen) {
> - pr_debug("%s: %s overrun %d\n", isac->name, __func__,
> - isac->dch.rx_skb->len + count);
> - WriteISAC(isac, ISAC_CMDR, 0x80);
> - return;
> - }
> - ptr = skb_put(isac->dch.rx_skb, count);
> - isac->read_fifo(isac->dch.hw, isac->off, ptr, count);
> - WriteISAC(isac, ISAC_CMDR, 0x80);
> - if (isac->dch.debug & DEBUG_HW_DFIFO) {
> - char pfx[MISDN_MAX_IDLEN + 16];
> -
> - snprintf(pfx, MISDN_MAX_IDLEN + 15, "D-recv %s %d ",
> - isac->name, count);
> - print_hex_dump_bytes(pfx, DUMP_PREFIX_OFFSET, ptr, count);
> - }
> -}
> -
> -static void
> -isac_fill_fifo(struct isac_hw *isac)
> -{
> - int count, more;
> - u8 *ptr;
> -
> - if (!isac->dch.tx_skb)
> - return;
> - count = isac->dch.tx_skb->len - isac->dch.tx_idx;
> - if (count <= 0)
> - return;
> -
> - more = 0;
> - if (count > 32) {
> - more = !0;
> - count = 32;
> - }
> - pr_debug("%s: %s %d\n", isac->name, __func__, count);
> - ptr = isac->dch.tx_skb->data + isac->dch.tx_idx;
> - isac->dch.tx_idx += count;
> - isac->write_fifo(isac->dch.hw, isac->off, ptr, count);
> - WriteISAC(isac, ISAC_CMDR, more ? 0x8 : 0xa);
> - if (test_and_set_bit(FLG_BUSY_TIMER, &isac->dch.Flags)) {
> - pr_debug("%s: %s dbusytimer running\n", isac->name, __func__);
> - timer_delete(&isac->dch.timer);
> - }
> - isac->dch.timer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000);
> - add_timer(&isac->dch.timer);
> - if (isac->dch.debug & DEBUG_HW_DFIFO) {
> - char pfx[MISDN_MAX_IDLEN + 16];
> -
> - snprintf(pfx, MISDN_MAX_IDLEN + 15, "D-send %s %d ",
> - isac->name, count);
> - print_hex_dump_bytes(pfx, DUMP_PREFIX_OFFSET, ptr, count);
> - }
> -}
> -
> -static void
> -isac_rme_irq(struct isac_hw *isac)
> -{
> - u8 val, count;
> -
> - val = ReadISAC(isac, ISAC_RSTA);
> - if ((val & 0x70) != 0x20) {
> - if (val & 0x40) {
> - pr_debug("%s: ISAC RDO\n", isac->name);
> -#ifdef ERROR_STATISTIC
> - isac->dch.err_rx++;
> -#endif
> - }
> - if (!(val & 0x20)) {
> - pr_debug("%s: ISAC CRC error\n", isac->name);
> -#ifdef ERROR_STATISTIC
> - isac->dch.err_crc++;
> -#endif
> - }
> - WriteISAC(isac, ISAC_CMDR, 0x80);
> - dev_kfree_skb(isac->dch.rx_skb);
> - isac->dch.rx_skb = NULL;
> - } else {
> - count = ReadISAC(isac, ISAC_RBCL) & 0x1f;
> - if (count == 0)
> - count = 32;
> - isac_empty_fifo(isac, count);
> - recv_Dchannel(&isac->dch);
> - }
> -}
> -
> -static void
> -isac_xpr_irq(struct isac_hw *isac)
> -{
> - if (test_and_clear_bit(FLG_BUSY_TIMER, &isac->dch.Flags))
> - timer_delete(&isac->dch.timer);
> - if (isac->dch.tx_skb && isac->dch.tx_idx < isac->dch.tx_skb->len) {
> - isac_fill_fifo(isac);
> - } else {
> - dev_kfree_skb(isac->dch.tx_skb);
> - if (get_next_dframe(&isac->dch))
> - isac_fill_fifo(isac);
> - }
> -}
> -
> -static void
> -isac_retransmit(struct isac_hw *isac)
> -{
> - if (test_and_clear_bit(FLG_BUSY_TIMER, &isac->dch.Flags))
> - timer_delete(&isac->dch.timer);
> - if (test_bit(FLG_TX_BUSY, &isac->dch.Flags)) {
> - /* Restart frame */
> - isac->dch.tx_idx = 0;
> - isac_fill_fifo(isac);
> - } else if (isac->dch.tx_skb) { /* should not happen */
> - pr_info("%s: tx_skb exist but not busy\n", isac->name);
> - test_and_set_bit(FLG_TX_BUSY, &isac->dch.Flags);
> - isac->dch.tx_idx = 0;
> - isac_fill_fifo(isac);
> - } else {
> - pr_info("%s: ISAC XDU no TX_BUSY\n", isac->name);
> - if (get_next_dframe(&isac->dch))
> - isac_fill_fifo(isac);
> - }
> -}
> -
> -static void
> -isac_mos_irq(struct isac_hw *isac)
> -{
> - u8 val;
> - int ret;
> -
> - val = ReadISAC(isac, ISAC_MOSR);
> - pr_debug("%s: ISAC MOSR %02x\n", isac->name, val);
> -#if ARCOFI_USE
> - if (val & 0x08) {
> - if (!isac->mon_rx) {
> - isac->mon_rx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC);
> - if (!isac->mon_rx) {
> - pr_info("%s: ISAC MON RX out of memory!\n",
> - isac->name);
> - isac->mocr &= 0xf0;
> - isac->mocr |= 0x0a;
> - WriteISAC(isac, ISAC_MOCR, isac->mocr);
> - goto afterMONR0;
> - } else
> - isac->mon_rxp = 0;
> - }
> - if (isac->mon_rxp >= MAX_MON_FRAME) {
> - isac->mocr &= 0xf0;
> - isac->mocr |= 0x0a;
> - WriteISAC(isac, ISAC_MOCR, isac->mocr);
> - isac->mon_rxp = 0;
> - pr_debug("%s: ISAC MON RX overflow!\n", isac->name);
> - goto afterMONR0;
> - }
> - isac->mon_rx[isac->mon_rxp++] = ReadISAC(isac, ISAC_MOR0);
> - pr_debug("%s: ISAC MOR0 %02x\n", isac->name,
> - isac->mon_rx[isac->mon_rxp - 1]);
> - if (isac->mon_rxp == 1) {
> - isac->mocr |= 0x04;
> - WriteISAC(isac, ISAC_MOCR, isac->mocr);
> - }
> - }
> -afterMONR0:
> - if (val & 0x80) {
> - if (!isac->mon_rx) {
> - isac->mon_rx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC);
> - if (!isac->mon_rx) {
> - pr_info("%s: ISAC MON RX out of memory!\n",
> - isac->name);
> - isac->mocr &= 0x0f;
> - isac->mocr |= 0xa0;
> - WriteISAC(isac, ISAC_MOCR, isac->mocr);
> - goto afterMONR1;
> - } else
> - isac->mon_rxp = 0;
> - }
> - if (isac->mon_rxp >= MAX_MON_FRAME) {
> - isac->mocr &= 0x0f;
> - isac->mocr |= 0xa0;
> - WriteISAC(isac, ISAC_MOCR, isac->mocr);
> - isac->mon_rxp = 0;
> - pr_debug("%s: ISAC MON RX overflow!\n", isac->name);
> - goto afterMONR1;
> - }
> - isac->mon_rx[isac->mon_rxp++] = ReadISAC(isac, ISAC_MOR1);
> - pr_debug("%s: ISAC MOR1 %02x\n", isac->name,
> - isac->mon_rx[isac->mon_rxp - 1]);
> - isac->mocr |= 0x40;
> - WriteISAC(isac, ISAC_MOCR, isac->mocr);
> - }
> -afterMONR1:
> - if (val & 0x04) {
> - isac->mocr &= 0xf0;
> - WriteISAC(isac, ISAC_MOCR, isac->mocr);
> - isac->mocr |= 0x0a;
> - WriteISAC(isac, ISAC_MOCR, isac->mocr);
> - if (isac->monitor) {
> - ret = isac->monitor(isac->dch.hw, MONITOR_RX_0,
> - isac->mon_rx, isac->mon_rxp);
> - if (ret)
> - kfree(isac->mon_rx);
> - } else {
> - pr_info("%s: MONITOR 0 received %d but no user\n",
> - isac->name, isac->mon_rxp);
> - kfree(isac->mon_rx);
> - }
> - isac->mon_rx = NULL;
> - isac->mon_rxp = 0;
> - }
> - if (val & 0x40) {
> - isac->mocr &= 0x0f;
> - WriteISAC(isac, ISAC_MOCR, isac->mocr);
> - isac->mocr |= 0xa0;
> - WriteISAC(isac, ISAC_MOCR, isac->mocr);
> - if (isac->monitor) {
> - ret = isac->monitor(isac->dch.hw, MONITOR_RX_1,
> - isac->mon_rx, isac->mon_rxp);
> - if (ret)
> - kfree(isac->mon_rx);
> - } else {
> - pr_info("%s: MONITOR 1 received %d but no user\n",
> - isac->name, isac->mon_rxp);
> - kfree(isac->mon_rx);
> - }
> - isac->mon_rx = NULL;
> - isac->mon_rxp = 0;
> - }
> - if (val & 0x02) {
> - if ((!isac->mon_tx) || (isac->mon_txc &&
> - (isac->mon_txp >= isac->mon_txc) && !(val & 0x08))) {
> - isac->mocr &= 0xf0;
> - WriteISAC(isac, ISAC_MOCR, isac->mocr);
> - isac->mocr |= 0x0a;
> - WriteISAC(isac, ISAC_MOCR, isac->mocr);
> - if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) {
> - if (isac->monitor)
> - isac->monitor(isac->dch.hw,
> - MONITOR_TX_0, NULL, 0);
> - }
> - kfree(isac->mon_tx);
> - isac->mon_tx = NULL;
> - isac->mon_txc = 0;
> - isac->mon_txp = 0;
> - goto AfterMOX0;
> - }
> - if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) {
> - if (isac->monitor)
> - isac->monitor(isac->dch.hw,
> - MONITOR_TX_0, NULL, 0);
> - kfree(isac->mon_tx);
> - isac->mon_tx = NULL;
> - isac->mon_txc = 0;
> - isac->mon_txp = 0;
> - goto AfterMOX0;
> - }
> - WriteISAC(isac, ISAC_MOX0, isac->mon_tx[isac->mon_txp++]);
> - pr_debug("%s: ISAC %02x -> MOX0\n", isac->name,
> - isac->mon_tx[isac->mon_txp - 1]);
> - }
> -AfterMOX0:
> - if (val & 0x20) {
> - if ((!isac->mon_tx) || (isac->mon_txc &&
> - (isac->mon_txp >= isac->mon_txc) && !(val & 0x80))) {
> - isac->mocr &= 0x0f;
> - WriteISAC(isac, ISAC_MOCR, isac->mocr);
> - isac->mocr |= 0xa0;
> - WriteISAC(isac, ISAC_MOCR, isac->mocr);
> - if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) {
> - if (isac->monitor)
> - isac->monitor(isac->dch.hw,
> - MONITOR_TX_1, NULL, 0);
> - }
> - kfree(isac->mon_tx);
> - isac->mon_tx = NULL;
> - isac->mon_txc = 0;
> - isac->mon_txp = 0;
> - goto AfterMOX1;
> - }
> - if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) {
> - if (isac->monitor)
> - isac->monitor(isac->dch.hw,
> - MONITOR_TX_1, NULL, 0);
> - kfree(isac->mon_tx);
> - isac->mon_tx = NULL;
> - isac->mon_txc = 0;
> - isac->mon_txp = 0;
> - goto AfterMOX1;
> - }
> - WriteISAC(isac, ISAC_MOX1, isac->mon_tx[isac->mon_txp++]);
> - pr_debug("%s: ISAC %02x -> MOX1\n", isac->name,
> - isac->mon_tx[isac->mon_txp - 1]);
> - }
> -AfterMOX1:
> - val = 0; /* dummy to avoid warning */
> -#endif
> -}
> -
> -static void
> -isac_cisq_irq(struct isac_hw *isac) {
> - u8 val;
> -
> - val = ReadISAC(isac, ISAC_CIR0);
> - pr_debug("%s: ISAC CIR0 %02X\n", isac->name, val);
> - if (val & 2) {
> - pr_debug("%s: ph_state change %x->%x\n", isac->name,
> - isac->state, (val >> 2) & 0xf);
> - isac->state = (val >> 2) & 0xf;
> - isac_ph_state_change(isac);
> - }
> - if (val & 1) {
> - val = ReadISAC(isac, ISAC_CIR1);
> - pr_debug("%s: ISAC CIR1 %02X\n", isac->name, val);
> - }
> -}
> -
> -static void
> -isacsx_cic_irq(struct isac_hw *isac)
> -{
> - u8 val;
> -
> - val = ReadISAC(isac, ISACX_CIR0);
> - pr_debug("%s: ISACX CIR0 %02X\n", isac->name, val);
> - if (val & ISACX_CIR0_CIC0) {
> - pr_debug("%s: ph_state change %x->%x\n", isac->name,
> - isac->state, val >> 4);
> - isac->state = val >> 4;
> - isac_ph_state_change(isac);
> - }
> -}
> -
> -static void
> -isacsx_rme_irq(struct isac_hw *isac)
> -{
> - int count;
> - u8 val;
> -
> - val = ReadISAC(isac, ISACX_RSTAD);
> - if ((val & (ISACX_RSTAD_VFR |
> - ISACX_RSTAD_RDO |
> - ISACX_RSTAD_CRC |
> - ISACX_RSTAD_RAB))
> - != (ISACX_RSTAD_VFR | ISACX_RSTAD_CRC)) {
> - pr_debug("%s: RSTAD %#x, dropped\n", isac->name, val);
> -#ifdef ERROR_STATISTIC
> - if (val & ISACX_RSTAD_CRC)
> - isac->dch.err_rx++;
> - else
> - isac->dch.err_crc++;
> -#endif
> - WriteISAC(isac, ISACX_CMDRD, ISACX_CMDRD_RMC);
> - dev_kfree_skb(isac->dch.rx_skb);
> - isac->dch.rx_skb = NULL;
> - } else {
> - count = ReadISAC(isac, ISACX_RBCLD) & 0x1f;
> - if (count == 0)
> - count = 32;
> - isac_empty_fifo(isac, count);
> - if (isac->dch.rx_skb) {
> - skb_trim(isac->dch.rx_skb, isac->dch.rx_skb->len - 1);
> - pr_debug("%s: dchannel received %d\n", isac->name,
> - isac->dch.rx_skb->len);
> - recv_Dchannel(&isac->dch);
> - }
> - }
> -}
> -
> -irqreturn_t
> -mISDNisac_irq(struct isac_hw *isac, u8 val)
> -{
> - if (unlikely(!val))
> - return IRQ_NONE;
> - pr_debug("%s: ISAC interrupt %02x\n", isac->name, val);
> - if (isac->type & IPAC_TYPE_ISACX) {
> - if (val & ISACX__CIC)
> - isacsx_cic_irq(isac);
> - if (val & ISACX__ICD) {
> - val = ReadISAC(isac, ISACX_ISTAD);
> - pr_debug("%s: ISTAD %02x\n", isac->name, val);
> - if (val & ISACX_D_XDU) {
> - pr_debug("%s: ISAC XDU\n", isac->name);
> -#ifdef ERROR_STATISTIC
> - isac->dch.err_tx++;
> -#endif
> - isac_retransmit(isac);
> - }
> - if (val & ISACX_D_XMR) {
> - pr_debug("%s: ISAC XMR\n", isac->name);
> -#ifdef ERROR_STATISTIC
> - isac->dch.err_tx++;
> -#endif
> - isac_retransmit(isac);
> - }
> - if (val & ISACX_D_XPR)
> - isac_xpr_irq(isac);
> - if (val & ISACX_D_RFO) {
> - pr_debug("%s: ISAC RFO\n", isac->name);
> - WriteISAC(isac, ISACX_CMDRD, ISACX_CMDRD_RMC);
> - }
> - if (val & ISACX_D_RME)
> - isacsx_rme_irq(isac);
> - if (val & ISACX_D_RPF)
> - isac_empty_fifo(isac, 0x20);
> - }
> - } else {
> - if (val & 0x80) /* RME */
> - isac_rme_irq(isac);
> - if (val & 0x40) /* RPF */
> - isac_empty_fifo(isac, 32);
> - if (val & 0x10) /* XPR */
> - isac_xpr_irq(isac);
> - if (val & 0x04) /* CISQ */
> - isac_cisq_irq(isac);
> - if (val & 0x20) /* RSC - never */
> - pr_debug("%s: ISAC RSC interrupt\n", isac->name);
> - if (val & 0x02) /* SIN - never */
> - pr_debug("%s: ISAC SIN interrupt\n", isac->name);
> - if (val & 0x01) { /* EXI */
> - val = ReadISAC(isac, ISAC_EXIR);
> - pr_debug("%s: ISAC EXIR %02x\n", isac->name, val);
> - if (val & 0x80) /* XMR */
> - pr_debug("%s: ISAC XMR\n", isac->name);
> - if (val & 0x40) { /* XDU */
> - pr_debug("%s: ISAC XDU\n", isac->name);
> -#ifdef ERROR_STATISTIC
> - isac->dch.err_tx++;
> -#endif
> - isac_retransmit(isac);
> - }
> - if (val & 0x04) /* MOS */
> - isac_mos_irq(isac);
> - }
> - }
> - return IRQ_HANDLED;
> -}
> -EXPORT_SYMBOL(mISDNisac_irq);
> -
> -static int
> -isac_l1hw(struct mISDNchannel *ch, struct sk_buff *skb)
> -{
> - struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
> - struct dchannel *dch = container_of(dev, struct dchannel, dev);
> - struct isac_hw *isac = container_of(dch, struct isac_hw, dch);
> - int ret = -EINVAL;
> - struct mISDNhead *hh = mISDN_HEAD_P(skb);
> - u32 id;
> - u_long flags;
> -
> - switch (hh->prim) {
> - case PH_DATA_REQ:
> - spin_lock_irqsave(isac->hwlock, flags);
> - ret = dchannel_senddata(dch, skb);
> - if (ret > 0) { /* direct TX */
> - id = hh->id; /* skb can be freed */
> - isac_fill_fifo(isac);
> - ret = 0;
> - spin_unlock_irqrestore(isac->hwlock, flags);
> - queue_ch_frame(ch, PH_DATA_CNF, id, NULL);
> - } else
> - spin_unlock_irqrestore(isac->hwlock, flags);
> - return ret;
> - case PH_ACTIVATE_REQ:
> - ret = l1_event(dch->l1, hh->prim);
> - break;
> - case PH_DEACTIVATE_REQ:
> - test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
> - ret = l1_event(dch->l1, hh->prim);
> - break;
> - }
> -
> - if (!ret)
> - dev_kfree_skb(skb);
> - return ret;
> -}
> -
> -static int
> -isac_ctrl(struct isac_hw *isac, u32 cmd, unsigned long para)
> -{
> - u8 tl = 0;
> - unsigned long flags;
> - int ret = 0;
> -
> - switch (cmd) {
> - case HW_TESTLOOP:
> - spin_lock_irqsave(isac->hwlock, flags);
> - if (!(isac->type & IPAC_TYPE_ISACX)) {
> - /* TODO: implement for IPAC_TYPE_ISACX */
> - if (para & 1) /* B1 */
> - tl |= 0x0c;
> - else if (para & 2) /* B2 */
> - tl |= 0x3;
> - /* we only support IOM2 mode */
> - WriteISAC(isac, ISAC_SPCR, tl);
> - if (tl)
> - WriteISAC(isac, ISAC_ADF1, 0x8);
> - else
> - WriteISAC(isac, ISAC_ADF1, 0x0);
> - }
> - spin_unlock_irqrestore(isac->hwlock, flags);
> - break;
> - case HW_TIMER3_VALUE:
> - ret = l1_event(isac->dch.l1, HW_TIMER3_VALUE | (para & 0xff));
> - break;
> - default:
> - pr_debug("%s: %s unknown command %x %lx\n", isac->name,
> - __func__, cmd, para);
> - ret = -1;
> - }
> - return ret;
> -}
> -
> -static int
> -isac_l1cmd(struct dchannel *dch, u32 cmd)
> -{
> - struct isac_hw *isac = container_of(dch, struct isac_hw, dch);
> - u_long flags;
> -
> - pr_debug("%s: cmd(%x) state(%02x)\n", isac->name, cmd, isac->state);
> - switch (cmd) {
> - case INFO3_P8:
> - spin_lock_irqsave(isac->hwlock, flags);
> - ph_command(isac, ISAC_CMD_AR8);
> - spin_unlock_irqrestore(isac->hwlock, flags);
> - break;
> - case INFO3_P10:
> - spin_lock_irqsave(isac->hwlock, flags);
> - ph_command(isac, ISAC_CMD_AR10);
> - spin_unlock_irqrestore(isac->hwlock, flags);
> - break;
> - case HW_RESET_REQ:
> - spin_lock_irqsave(isac->hwlock, flags);
> - if ((isac->state == ISAC_IND_EI) ||
> - (isac->state == ISAC_IND_DR) ||
> - (isac->state == ISAC_IND_DR6) ||
> - (isac->state == ISAC_IND_RS))
> - ph_command(isac, ISAC_CMD_TIM);
> - else
> - ph_command(isac, ISAC_CMD_RS);
> - spin_unlock_irqrestore(isac->hwlock, flags);
> - break;
> - case HW_DEACT_REQ:
> - skb_queue_purge(&dch->squeue);
> - if (dch->tx_skb) {
> - dev_kfree_skb(dch->tx_skb);
> - dch->tx_skb = NULL;
> - }
> - dch->tx_idx = 0;
> - if (dch->rx_skb) {
> - dev_kfree_skb(dch->rx_skb);
> - dch->rx_skb = NULL;
> - }
> - test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
> - if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
> - timer_delete(&dch->timer);
> - break;
> - case HW_POWERUP_REQ:
> - spin_lock_irqsave(isac->hwlock, flags);
> - ph_command(isac, ISAC_CMD_TIM);
> - spin_unlock_irqrestore(isac->hwlock, flags);
> - break;
> - case PH_ACTIVATE_IND:
> - test_and_set_bit(FLG_ACTIVE, &dch->Flags);
> - _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
> - GFP_ATOMIC);
> - break;
> - case PH_DEACTIVATE_IND:
> - test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
> - _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
> - GFP_ATOMIC);
> - break;
> - default:
> - pr_debug("%s: %s unknown command %x\n", isac->name,
> - __func__, cmd);
> - return -1;
> - }
> - return 0;
> -}
> -
> -static void
> -isac_release(struct isac_hw *isac)
> -{
> - if (isac->type & IPAC_TYPE_ISACX)
> - WriteISAC(isac, ISACX_MASK, 0xff);
> - else if (isac->type != 0)
> - WriteISAC(isac, ISAC_MASK, 0xff);
> - if (isac->dch.timer.function != NULL) {
> - timer_delete(&isac->dch.timer);
> - isac->dch.timer.function = NULL;
> - }
> - kfree(isac->mon_rx);
> - isac->mon_rx = NULL;
> - kfree(isac->mon_tx);
> - isac->mon_tx = NULL;
> - if (isac->dch.l1)
> - l1_event(isac->dch.l1, CLOSE_CHANNEL);
> - mISDN_freedchannel(&isac->dch);
> -}
> -
> -static void
> -dbusy_timer_handler(struct timer_list *t)
> -{
> - struct isac_hw *isac = timer_container_of(isac, t, dch.timer);
> - int rbch, star;
> - u_long flags;
> -
> - if (test_bit(FLG_BUSY_TIMER, &isac->dch.Flags)) {
> - spin_lock_irqsave(isac->hwlock, flags);
> - rbch = ReadISAC(isac, ISAC_RBCH);
> - star = ReadISAC(isac, ISAC_STAR);
> - pr_debug("%s: D-Channel Busy RBCH %02x STAR %02x\n",
> - isac->name, rbch, star);
> - if (rbch & ISAC_RBCH_XAC) /* D-Channel Busy */
> - test_and_set_bit(FLG_L1_BUSY, &isac->dch.Flags);
> - else {
> - /* discard frame; reset transceiver */
> - test_and_clear_bit(FLG_BUSY_TIMER, &isac->dch.Flags);
> - if (isac->dch.tx_idx)
> - isac->dch.tx_idx = 0;
> - else
> - pr_info("%s: ISAC D-Channel Busy no tx_idx\n",
> - isac->name);
> - /* Transmitter reset */
> - WriteISAC(isac, ISAC_CMDR, 0x01);
> - }
> - spin_unlock_irqrestore(isac->hwlock, flags);
> - }
> -}
> -
> -static int
> -open_dchannel_caller(struct isac_hw *isac, struct channel_req *rq, void *caller)
> -{
> - pr_debug("%s: %s dev(%d) open from %p\n", isac->name, __func__,
> - isac->dch.dev.id, caller);
> - if (rq->protocol != ISDN_P_TE_S0)
> - return -EINVAL;
> - if (rq->adr.channel == 1)
> - /* E-Channel not supported */
> - return -EINVAL;
> - rq->ch = &isac->dch.dev.D;
> - rq->ch->protocol = rq->protocol;
> - if (isac->dch.state == 7)
> - _queue_data(rq->ch, PH_ACTIVATE_IND, MISDN_ID_ANY,
> - 0, NULL, GFP_KERNEL);
> - return 0;
> -}
> -
> -static int
> -open_dchannel(struct isac_hw *isac, struct channel_req *rq)
> -{
> - return open_dchannel_caller(isac, rq, __builtin_return_address(0));
> -}
> -
> -static const char *ISACVer[] =
> -{"2086/2186 V1.1", "2085 B1", "2085 B2",
> - "2085 V2.3"};
> -
> -static int
> -isac_init(struct isac_hw *isac)
> -{
> - u8 val;
> - int err = 0;
> -
> - if (!isac->dch.l1) {
> - err = create_l1(&isac->dch, isac_l1cmd);
> - if (err)
> - return err;
> - }
> - isac->mon_tx = NULL;
> - isac->mon_rx = NULL;
> - timer_setup(&isac->dch.timer, dbusy_timer_handler, 0);
> - isac->mocr = 0xaa;
> - if (isac->type & IPAC_TYPE_ISACX) {
> - /* Disable all IRQ */
> - WriteISAC(isac, ISACX_MASK, 0xff);
> - val = ReadISAC(isac, ISACX_STARD);
> - pr_debug("%s: ISACX STARD %x\n", isac->name, val);
> - val = ReadISAC(isac, ISACX_ISTAD);
> - pr_debug("%s: ISACX ISTAD %x\n", isac->name, val);
> - val = ReadISAC(isac, ISACX_ISTA);
> - pr_debug("%s: ISACX ISTA %x\n", isac->name, val);
> - /* clear LDD */
> - WriteISAC(isac, ISACX_TR_CONF0, 0x00);
> - /* enable transmitter */
> - WriteISAC(isac, ISACX_TR_CONF2, 0x00);
> - /* transparent mode 0, RAC, stop/go */
> - WriteISAC(isac, ISACX_MODED, 0xc9);
> - /* all HDLC IRQ unmasked */
> - val = ReadISAC(isac, ISACX_ID);
> - if (isac->dch.debug & DEBUG_HW)
> - pr_notice("%s: ISACX Design ID %x\n",
> - isac->name, val & 0x3f);
> - val = ReadISAC(isac, ISACX_CIR0);
> - pr_debug("%s: ISACX CIR0 %02X\n", isac->name, val);
> - isac->state = val >> 4;
> - isac_ph_state_change(isac);
> - ph_command(isac, ISAC_CMD_RS);
> - WriteISAC(isac, ISACX_MASK, IPACX__ON);
> - WriteISAC(isac, ISACX_MASKD, 0x00);
> - } else { /* old isac */
> - WriteISAC(isac, ISAC_MASK, 0xff);
> - val = ReadISAC(isac, ISAC_STAR);
> - pr_debug("%s: ISAC STAR %x\n", isac->name, val);
> - val = ReadISAC(isac, ISAC_MODE);
> - pr_debug("%s: ISAC MODE %x\n", isac->name, val);
> - val = ReadISAC(isac, ISAC_ADF2);
> - pr_debug("%s: ISAC ADF2 %x\n", isac->name, val);
> - val = ReadISAC(isac, ISAC_ISTA);
> - pr_debug("%s: ISAC ISTA %x\n", isac->name, val);
> - if (val & 0x01) {
> - val = ReadISAC(isac, ISAC_EXIR);
> - pr_debug("%s: ISAC EXIR %x\n", isac->name, val);
> - }
> - val = ReadISAC(isac, ISAC_RBCH);
> - if (isac->dch.debug & DEBUG_HW)
> - pr_notice("%s: ISAC version (%x): %s\n", isac->name,
> - val, ISACVer[(val >> 5) & 3]);
> - isac->type |= ((val >> 5) & 3);
> - if (!isac->adf2)
> - isac->adf2 = 0x80;
> - if (!(isac->adf2 & 0x80)) { /* only IOM 2 Mode */
> - pr_info("%s: only support IOM2 mode but adf2=%02x\n",
> - isac->name, isac->adf2);
> - isac_release(isac);
> - return -EINVAL;
> - }
> - WriteISAC(isac, ISAC_ADF2, isac->adf2);
> - WriteISAC(isac, ISAC_SQXR, 0x2f);
> - WriteISAC(isac, ISAC_SPCR, 0x00);
> - WriteISAC(isac, ISAC_STCR, 0x70);
> - WriteISAC(isac, ISAC_MODE, 0xc9);
> - WriteISAC(isac, ISAC_TIMR, 0x00);
> - WriteISAC(isac, ISAC_ADF1, 0x00);
> - val = ReadISAC(isac, ISAC_CIR0);
> - pr_debug("%s: ISAC CIR0 %x\n", isac->name, val);
> - isac->state = (val >> 2) & 0xf;
> - isac_ph_state_change(isac);
> - ph_command(isac, ISAC_CMD_RS);
> - WriteISAC(isac, ISAC_MASK, 0);
> - }
> - return err;
> -}
> -
> -int
> -mISDNisac_init(struct isac_hw *isac, void *hw)
> -{
> - mISDN_initdchannel(&isac->dch, MAX_DFRAME_LEN_L1, isac_ph_state_bh);
> - isac->dch.hw = hw;
> - isac->dch.dev.D.send = isac_l1hw;
> - isac->init = isac_init;
> - isac->release = isac_release;
> - isac->ctrl = isac_ctrl;
> - isac->open = open_dchannel;
> - isac->dch.dev.Dprotocols = (1 << ISDN_P_TE_S0);
> - isac->dch.dev.nrbchan = 2;
> - return 0;
> -}
> -EXPORT_SYMBOL(mISDNisac_init);
> -
> -static void
> -waitforCEC(struct hscx_hw *hx)
> -{
> - u8 starb, to = 50;
> -
> - while (to) {
> - starb = ReadHSCX(hx, IPAC_STARB);
> - if (!(starb & 0x04))
> - break;
> - udelay(1);
> - to--;
> - }
> - if (to < 50)
> - pr_debug("%s: B%1d CEC %d us\n", hx->ip->name, hx->bch.nr,
> - 50 - to);
> - if (!to)
> - pr_info("%s: B%1d CEC timeout\n", hx->ip->name, hx->bch.nr);
> -}
> -
> -
> -static void
> -waitforXFW(struct hscx_hw *hx)
> -{
> - u8 starb, to = 50;
> -
> - while (to) {
> - starb = ReadHSCX(hx, IPAC_STARB);
> - if ((starb & 0x44) == 0x40)
> - break;
> - udelay(1);
> - to--;
> - }
> - if (to < 50)
> - pr_debug("%s: B%1d XFW %d us\n", hx->ip->name, hx->bch.nr,
> - 50 - to);
> - if (!to)
> - pr_info("%s: B%1d XFW timeout\n", hx->ip->name, hx->bch.nr);
> -}
> -
> -static void
> -hscx_cmdr(struct hscx_hw *hx, u8 cmd)
> -{
> - if (hx->ip->type & IPAC_TYPE_IPACX)
> - WriteHSCX(hx, IPACX_CMDRB, cmd);
> - else {
> - waitforCEC(hx);
> - WriteHSCX(hx, IPAC_CMDRB, cmd);
> - }
> -}
> -
> -static void
> -hscx_empty_fifo(struct hscx_hw *hscx, u8 count)
> -{
> - u8 *p;
> - int maxlen;
> -
> - pr_debug("%s: B%1d %d\n", hscx->ip->name, hscx->bch.nr, count);
> - if (test_bit(FLG_RX_OFF, &hscx->bch.Flags)) {
> - hscx->bch.dropcnt += count;
> - hscx_cmdr(hscx, 0x80); /* RMC */
> - return;
> - }
> - maxlen = bchannel_get_rxbuf(&hscx->bch, count);
> - if (maxlen < 0) {
> - hscx_cmdr(hscx, 0x80); /* RMC */
> - if (hscx->bch.rx_skb)
> - skb_trim(hscx->bch.rx_skb, 0);
> - pr_warn("%s.B%d: No bufferspace for %d bytes\n",
> - hscx->ip->name, hscx->bch.nr, count);
> - return;
> - }
> - p = skb_put(hscx->bch.rx_skb, count);
> -
> - if (hscx->ip->type & IPAC_TYPE_IPACX)
> - hscx->ip->read_fifo(hscx->ip->hw,
> - hscx->off + IPACX_RFIFOB, p, count);
> - else
> - hscx->ip->read_fifo(hscx->ip->hw,
> - hscx->off, p, count);
> -
> - hscx_cmdr(hscx, 0x80); /* RMC */
> -
> - if (hscx->bch.debug & DEBUG_HW_BFIFO) {
> - snprintf(hscx->log, 64, "B%1d-recv %s %d ",
> - hscx->bch.nr, hscx->ip->name, count);
> - print_hex_dump_bytes(hscx->log, DUMP_PREFIX_OFFSET, p, count);
> - }
> -}
> -
> -static void
> -hscx_fill_fifo(struct hscx_hw *hscx)
> -{
> - int count, more;
> - u8 *p;
> -
> - if (!hscx->bch.tx_skb) {
> - if (!test_bit(FLG_TX_EMPTY, &hscx->bch.Flags))
> - return;
> - count = hscx->fifo_size;
> - more = 1;
> - p = hscx->log;
> - memset(p, hscx->bch.fill[0], count);
> - } else {
> - count = hscx->bch.tx_skb->len - hscx->bch.tx_idx;
> - if (count <= 0)
> - return;
> - p = hscx->bch.tx_skb->data + hscx->bch.tx_idx;
> -
> - more = test_bit(FLG_TRANSPARENT, &hscx->bch.Flags) ? 1 : 0;
> - if (count > hscx->fifo_size) {
> - count = hscx->fifo_size;
> - more = 1;
> - }
> - pr_debug("%s: B%1d %d/%d/%d\n", hscx->ip->name, hscx->bch.nr,
> - count, hscx->bch.tx_idx, hscx->bch.tx_skb->len);
> - hscx->bch.tx_idx += count;
> - }
> - if (hscx->ip->type & IPAC_TYPE_IPACX)
> - hscx->ip->write_fifo(hscx->ip->hw,
> - hscx->off + IPACX_XFIFOB, p, count);
> - else {
> - waitforXFW(hscx);
> - hscx->ip->write_fifo(hscx->ip->hw,
> - hscx->off, p, count);
> - }
> - hscx_cmdr(hscx, more ? 0x08 : 0x0a);
> -
> - if (hscx->bch.tx_skb && (hscx->bch.debug & DEBUG_HW_BFIFO)) {
> - snprintf(hscx->log, 64, "B%1d-send %s %d ",
> - hscx->bch.nr, hscx->ip->name, count);
> - print_hex_dump_bytes(hscx->log, DUMP_PREFIX_OFFSET, p, count);
> - }
> -}
> -
> -static void
> -hscx_xpr(struct hscx_hw *hx)
> -{
> - if (hx->bch.tx_skb && hx->bch.tx_idx < hx->bch.tx_skb->len) {
> - hscx_fill_fifo(hx);
> - } else {
> - dev_kfree_skb(hx->bch.tx_skb);
> - if (get_next_bframe(&hx->bch)) {
> - hscx_fill_fifo(hx);
> - test_and_clear_bit(FLG_TX_EMPTY, &hx->bch.Flags);
> - } else if (test_bit(FLG_TX_EMPTY, &hx->bch.Flags)) {
> - hscx_fill_fifo(hx);
> - }
> - }
> -}
> -
> -static void
> -ipac_rme(struct hscx_hw *hx)
> -{
> - int count;
> - u8 rstab;
> -
> - if (hx->ip->type & IPAC_TYPE_IPACX)
> - rstab = ReadHSCX(hx, IPACX_RSTAB);
> - else
> - rstab = ReadHSCX(hx, IPAC_RSTAB);
> - pr_debug("%s: B%1d RSTAB %02x\n", hx->ip->name, hx->bch.nr, rstab);
> - if ((rstab & 0xf0) != 0xa0) {
> - /* !(VFR && !RDO && CRC && !RAB) */
> - if (!(rstab & 0x80)) {
> - if (hx->bch.debug & DEBUG_HW_BCHANNEL)
> - pr_notice("%s: B%1d invalid frame\n",
> - hx->ip->name, hx->bch.nr);
> - }
> - if (rstab & 0x40) {
> - if (hx->bch.debug & DEBUG_HW_BCHANNEL)
> - pr_notice("%s: B%1d RDO proto=%x\n",
> - hx->ip->name, hx->bch.nr,
> - hx->bch.state);
> - }
> - if (!(rstab & 0x20)) {
> - if (hx->bch.debug & DEBUG_HW_BCHANNEL)
> - pr_notice("%s: B%1d CRC error\n",
> - hx->ip->name, hx->bch.nr);
> - }
> - hscx_cmdr(hx, 0x80); /* Do RMC */
> - return;
> - }
> - if (hx->ip->type & IPAC_TYPE_IPACX)
> - count = ReadHSCX(hx, IPACX_RBCLB);
> - else
> - count = ReadHSCX(hx, IPAC_RBCLB);
> - count &= (hx->fifo_size - 1);
> - if (count == 0)
> - count = hx->fifo_size;
> - hscx_empty_fifo(hx, count);
> - if (!hx->bch.rx_skb)
> - return;
> - if (hx->bch.rx_skb->len < 2) {
> - pr_debug("%s: B%1d frame too short %d\n",
> - hx->ip->name, hx->bch.nr, hx->bch.rx_skb->len);
> - skb_trim(hx->bch.rx_skb, 0);
> - } else {
> - skb_trim(hx->bch.rx_skb, hx->bch.rx_skb->len - 1);
> - recv_Bchannel(&hx->bch, 0, false);
> - }
> -}
> -
> -static void
> -ipac_irq(struct hscx_hw *hx, u8 ista)
> -{
> - u8 istab, m, exirb = 0;
> -
> - if (hx->ip->type & IPAC_TYPE_IPACX)
> - istab = ReadHSCX(hx, IPACX_ISTAB);
> - else if (hx->ip->type & IPAC_TYPE_IPAC) {
> - istab = ReadHSCX(hx, IPAC_ISTAB);
> - m = (hx->bch.nr & 1) ? IPAC__EXA : IPAC__EXB;
> - if (m & ista) {
> - exirb = ReadHSCX(hx, IPAC_EXIRB);
> - pr_debug("%s: B%1d EXIRB %02x\n", hx->ip->name,
> - hx->bch.nr, exirb);
> - }
> - } else if (hx->bch.nr & 2) { /* HSCX B */
> - if (ista & (HSCX__EXA | HSCX__ICA))
> - ipac_irq(&hx->ip->hscx[0], ista);
> - if (ista & HSCX__EXB) {
> - exirb = ReadHSCX(hx, IPAC_EXIRB);
> - pr_debug("%s: B%1d EXIRB %02x\n", hx->ip->name,
> - hx->bch.nr, exirb);
> - }
> - istab = ista & 0xF8;
> - } else { /* HSCX A */
> - istab = ReadHSCX(hx, IPAC_ISTAB);
> - if (ista & HSCX__EXA) {
> - exirb = ReadHSCX(hx, IPAC_EXIRB);
> - pr_debug("%s: B%1d EXIRB %02x\n", hx->ip->name,
> - hx->bch.nr, exirb);
> - }
> - istab = istab & 0xF8;
> - }
> - if (exirb & IPAC_B_XDU)
> - istab |= IPACX_B_XDU;
> - if (exirb & IPAC_B_RFO)
> - istab |= IPACX_B_RFO;
> - pr_debug("%s: B%1d ISTAB %02x\n", hx->ip->name, hx->bch.nr, istab);
> -
> - if (!test_bit(FLG_ACTIVE, &hx->bch.Flags))
> - return;
> -
> - if (istab & IPACX_B_RME)
> - ipac_rme(hx);
> -
> - if (istab & IPACX_B_RPF) {
> - hscx_empty_fifo(hx, hx->fifo_size);
> - if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags))
> - recv_Bchannel(&hx->bch, 0, false);
> - }
> -
> - if (istab & IPACX_B_RFO) {
> - pr_debug("%s: B%1d RFO error\n", hx->ip->name, hx->bch.nr);
> - hscx_cmdr(hx, 0x40); /* RRES */
> - }
> -
> - if (istab & IPACX_B_XPR)
> - hscx_xpr(hx);
> -
> - if (istab & IPACX_B_XDU) {
> - if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags)) {
> - if (test_bit(FLG_FILLEMPTY, &hx->bch.Flags))
> - test_and_set_bit(FLG_TX_EMPTY, &hx->bch.Flags);
> - hscx_xpr(hx);
> - return;
> - }
> - pr_debug("%s: B%1d XDU error at len %d\n", hx->ip->name,
> - hx->bch.nr, hx->bch.tx_idx);
> - hx->bch.tx_idx = 0;
> - hscx_cmdr(hx, 0x01); /* XRES */
> - }
> -}
> -
> -irqreturn_t
> -mISDNipac_irq(struct ipac_hw *ipac, int maxloop)
> -{
> - int cnt = maxloop + 1;
> - u8 ista, istad;
> - struct isac_hw *isac = &ipac->isac;
> -
> - if (ipac->type & IPAC_TYPE_IPACX) {
> - ista = ReadIPAC(ipac, ISACX_ISTA);
> - while (ista && --cnt) {
> - pr_debug("%s: ISTA %02x\n", ipac->name, ista);
> - if (ista & IPACX__ICA)
> - ipac_irq(&ipac->hscx[0], ista);
> - if (ista & IPACX__ICB)
> - ipac_irq(&ipac->hscx[1], ista);
> - if (ista & (ISACX__ICD | ISACX__CIC))
> - mISDNisac_irq(&ipac->isac, ista);
> - ista = ReadIPAC(ipac, ISACX_ISTA);
> - }
> - } else if (ipac->type & IPAC_TYPE_IPAC) {
> - ista = ReadIPAC(ipac, IPAC_ISTA);
> - while (ista && --cnt) {
> - pr_debug("%s: ISTA %02x\n", ipac->name, ista);
> - if (ista & (IPAC__ICD | IPAC__EXD)) {
> - istad = ReadISAC(isac, ISAC_ISTA);
> - pr_debug("%s: ISTAD %02x\n", ipac->name, istad);
> - if (istad & IPAC_D_TIN2)
> - pr_debug("%s TIN2 irq\n", ipac->name);
> - if (ista & IPAC__EXD)
> - istad |= 1; /* ISAC EXI */
> - mISDNisac_irq(isac, istad);
> - }
> - if (ista & (IPAC__ICA | IPAC__EXA))
> - ipac_irq(&ipac->hscx[0], ista);
> - if (ista & (IPAC__ICB | IPAC__EXB))
> - ipac_irq(&ipac->hscx[1], ista);
> - ista = ReadIPAC(ipac, IPAC_ISTA);
> - }
> - } else if (ipac->type & IPAC_TYPE_HSCX) {
> - while (--cnt) {
> - ista = ReadIPAC(ipac, IPAC_ISTAB + ipac->hscx[1].off);
> - pr_debug("%s: B2 ISTA %02x\n", ipac->name, ista);
> - if (ista)
> - ipac_irq(&ipac->hscx[1], ista);
> - istad = ReadISAC(isac, ISAC_ISTA);
> - pr_debug("%s: ISTAD %02x\n", ipac->name, istad);
> - if (istad)
> - mISDNisac_irq(isac, istad);
> - if (0 == (ista | istad))
> - break;
> - }
> - }
> - if (cnt > maxloop) /* only for ISAC/HSCX without PCI IRQ test */
> - return IRQ_NONE;
> - if (cnt < maxloop)
> - pr_debug("%s: %d irqloops cpu%d\n", ipac->name,
> - maxloop - cnt, smp_processor_id());
> - if (maxloop && !cnt)
> - pr_notice("%s: %d IRQ LOOP cpu%d\n", ipac->name,
> - maxloop, smp_processor_id());
> - return IRQ_HANDLED;
> -}
> -EXPORT_SYMBOL(mISDNipac_irq);
> -
> -static int
> -hscx_mode(struct hscx_hw *hscx, u32 bprotocol)
> -{
> - pr_debug("%s: HSCX %c protocol %x-->%x ch %d\n", hscx->ip->name,
> - '@' + hscx->bch.nr, hscx->bch.state, bprotocol, hscx->bch.nr);
> - if (hscx->ip->type & IPAC_TYPE_IPACX) {
> - if (hscx->bch.nr & 1) { /* B1 and ICA */
> - WriteIPAC(hscx->ip, ISACX_BCHA_TSDP_BC1, 0x80);
> - WriteIPAC(hscx->ip, ISACX_BCHA_CR, 0x88);
> - } else { /* B2 and ICB */
> - WriteIPAC(hscx->ip, ISACX_BCHB_TSDP_BC1, 0x81);
> - WriteIPAC(hscx->ip, ISACX_BCHB_CR, 0x88);
> - }
> - switch (bprotocol) {
> - case ISDN_P_NONE: /* init */
> - WriteHSCX(hscx, IPACX_MODEB, 0xC0); /* rec off */
> - WriteHSCX(hscx, IPACX_EXMB, 0x30); /* std adj. */
> - WriteHSCX(hscx, IPACX_MASKB, 0xFF); /* ints off */
> - hscx_cmdr(hscx, 0x41);
> - test_and_clear_bit(FLG_HDLC, &hscx->bch.Flags);
> - test_and_clear_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
> - break;
> - case ISDN_P_B_RAW:
> - WriteHSCX(hscx, IPACX_MODEB, 0x88); /* ex trans */
> - WriteHSCX(hscx, IPACX_EXMB, 0x00); /* trans */
> - hscx_cmdr(hscx, 0x41);
> - WriteHSCX(hscx, IPACX_MASKB, IPACX_B_ON);
> - test_and_set_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
> - break;
> - case ISDN_P_B_HDLC:
> - WriteHSCX(hscx, IPACX_MODEB, 0xC0); /* trans */
> - WriteHSCX(hscx, IPACX_EXMB, 0x00); /* hdlc,crc */
> - hscx_cmdr(hscx, 0x41);
> - WriteHSCX(hscx, IPACX_MASKB, IPACX_B_ON);
> - test_and_set_bit(FLG_HDLC, &hscx->bch.Flags);
> - break;
> - default:
> - pr_info("%s: protocol not known %x\n", hscx->ip->name,
> - bprotocol);
> - return -ENOPROTOOPT;
> - }
> - } else if (hscx->ip->type & IPAC_TYPE_IPAC) { /* IPAC */
> - WriteHSCX(hscx, IPAC_CCR1, 0x82);
> - WriteHSCX(hscx, IPAC_CCR2, 0x30);
> - WriteHSCX(hscx, IPAC_XCCR, 0x07);
> - WriteHSCX(hscx, IPAC_RCCR, 0x07);
> - WriteHSCX(hscx, IPAC_TSAX, hscx->slot);
> - WriteHSCX(hscx, IPAC_TSAR, hscx->slot);
> - switch (bprotocol) {
> - case ISDN_P_NONE:
> - WriteHSCX(hscx, IPAC_TSAX, 0x1F);
> - WriteHSCX(hscx, IPAC_TSAR, 0x1F);
> - WriteHSCX(hscx, IPAC_MODEB, 0x84);
> - WriteHSCX(hscx, IPAC_CCR1, 0x82);
> - WriteHSCX(hscx, IPAC_MASKB, 0xFF); /* ints off */
> - test_and_clear_bit(FLG_HDLC, &hscx->bch.Flags);
> - test_and_clear_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
> - break;
> - case ISDN_P_B_RAW:
> - WriteHSCX(hscx, IPAC_MODEB, 0xe4); /* ex trans */
> - WriteHSCX(hscx, IPAC_CCR1, 0x82);
> - hscx_cmdr(hscx, 0x41);
> - WriteHSCX(hscx, IPAC_MASKB, 0);
> - test_and_set_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
> - break;
> - case ISDN_P_B_HDLC:
> - WriteHSCX(hscx, IPAC_MODEB, 0x8c);
> - WriteHSCX(hscx, IPAC_CCR1, 0x8a);
> - hscx_cmdr(hscx, 0x41);
> - WriteHSCX(hscx, IPAC_MASKB, 0);
> - test_and_set_bit(FLG_HDLC, &hscx->bch.Flags);
> - break;
> - default:
> - pr_info("%s: protocol not known %x\n", hscx->ip->name,
> - bprotocol);
> - return -ENOPROTOOPT;
> - }
> - } else if (hscx->ip->type & IPAC_TYPE_HSCX) { /* HSCX */
> - WriteHSCX(hscx, IPAC_CCR1, 0x85);
> - WriteHSCX(hscx, IPAC_CCR2, 0x30);
> - WriteHSCX(hscx, IPAC_XCCR, 0x07);
> - WriteHSCX(hscx, IPAC_RCCR, 0x07);
> - WriteHSCX(hscx, IPAC_TSAX, hscx->slot);
> - WriteHSCX(hscx, IPAC_TSAR, hscx->slot);
> - switch (bprotocol) {
> - case ISDN_P_NONE:
> - WriteHSCX(hscx, IPAC_TSAX, 0x1F);
> - WriteHSCX(hscx, IPAC_TSAR, 0x1F);
> - WriteHSCX(hscx, IPAC_MODEB, 0x84);
> - WriteHSCX(hscx, IPAC_CCR1, 0x85);
> - WriteHSCX(hscx, IPAC_MASKB, 0xFF); /* ints off */
> - test_and_clear_bit(FLG_HDLC, &hscx->bch.Flags);
> - test_and_clear_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
> - break;
> - case ISDN_P_B_RAW:
> - WriteHSCX(hscx, IPAC_MODEB, 0xe4); /* ex trans */
> - WriteHSCX(hscx, IPAC_CCR1, 0x85);
> - hscx_cmdr(hscx, 0x41);
> - WriteHSCX(hscx, IPAC_MASKB, 0);
> - test_and_set_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
> - break;
> - case ISDN_P_B_HDLC:
> - WriteHSCX(hscx, IPAC_MODEB, 0x8c);
> - WriteHSCX(hscx, IPAC_CCR1, 0x8d);
> - hscx_cmdr(hscx, 0x41);
> - WriteHSCX(hscx, IPAC_MASKB, 0);
> - test_and_set_bit(FLG_HDLC, &hscx->bch.Flags);
> - break;
> - default:
> - pr_info("%s: protocol not known %x\n", hscx->ip->name,
> - bprotocol);
> - return -ENOPROTOOPT;
> - }
> - } else
> - return -EINVAL;
> - hscx->bch.state = bprotocol;
> - return 0;
> -}
> -
> -static int
> -hscx_l2l1(struct mISDNchannel *ch, struct sk_buff *skb)
> -{
> - struct bchannel *bch = container_of(ch, struct bchannel, ch);
> - struct hscx_hw *hx = container_of(bch, struct hscx_hw, bch);
> - int ret = -EINVAL;
> - struct mISDNhead *hh = mISDN_HEAD_P(skb);
> - unsigned long flags;
> -
> - switch (hh->prim) {
> - case PH_DATA_REQ:
> - spin_lock_irqsave(hx->ip->hwlock, flags);
> - ret = bchannel_senddata(bch, skb);
> - if (ret > 0) { /* direct TX */
> - ret = 0;
> - hscx_fill_fifo(hx);
> - }
> - spin_unlock_irqrestore(hx->ip->hwlock, flags);
> - return ret;
> - case PH_ACTIVATE_REQ:
> - spin_lock_irqsave(hx->ip->hwlock, flags);
> - if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags))
> - ret = hscx_mode(hx, ch->protocol);
> - else
> - ret = 0;
> - spin_unlock_irqrestore(hx->ip->hwlock, flags);
> - if (!ret)
> - _queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
> - NULL, GFP_KERNEL);
> - break;
> - case PH_DEACTIVATE_REQ:
> - spin_lock_irqsave(hx->ip->hwlock, flags);
> - mISDN_clear_bchannel(bch);
> - hscx_mode(hx, ISDN_P_NONE);
> - spin_unlock_irqrestore(hx->ip->hwlock, flags);
> - _queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
> - NULL, GFP_KERNEL);
> - ret = 0;
> - break;
> - default:
> - pr_info("%s: %s unknown prim(%x,%x)\n",
> - hx->ip->name, __func__, hh->prim, hh->id);
> - ret = -EINVAL;
> - }
> - if (!ret)
> - dev_kfree_skb(skb);
> - return ret;
> -}
> -
> -static int
> -channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
> -{
> - return mISDN_ctrl_bchannel(bch, cq);
> -}
> -
> -static int
> -hscx_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
> -{
> - struct bchannel *bch = container_of(ch, struct bchannel, ch);
> - struct hscx_hw *hx = container_of(bch, struct hscx_hw, bch);
> - int ret = -EINVAL;
> - u_long flags;
> -
> - pr_debug("%s: %s cmd:%x %p\n", hx->ip->name, __func__, cmd, arg);
> - switch (cmd) {
> - case CLOSE_CHANNEL:
> - test_and_clear_bit(FLG_OPEN, &bch->Flags);
> - cancel_work_sync(&bch->workq);
> - spin_lock_irqsave(hx->ip->hwlock, flags);
> - mISDN_clear_bchannel(bch);
> - hscx_mode(hx, ISDN_P_NONE);
> - spin_unlock_irqrestore(hx->ip->hwlock, flags);
> - ch->protocol = ISDN_P_NONE;
> - ch->peer = NULL;
> - module_put(hx->ip->owner);
> - ret = 0;
> - break;
> - case CONTROL_CHANNEL:
> - ret = channel_bctrl(bch, arg);
> - break;
> - default:
> - pr_info("%s: %s unknown prim(%x)\n",
> - hx->ip->name, __func__, cmd);
> - }
> - return ret;
> -}
> -
> -static void
> -free_ipac(struct ipac_hw *ipac)
> -{
> - isac_release(&ipac->isac);
> -}
> -
> -static const char *HSCXVer[] =
> -{"A1", "?1", "A2", "?3", "A3", "V2.1", "?6", "?7",
> - "?8", "?9", "?10", "?11", "?12", "?13", "?14", "???"};
> -
> -
> -
> -static void
> -hscx_init(struct hscx_hw *hx)
> -{
> - u8 val;
> -
> - WriteHSCX(hx, IPAC_RAH2, 0xFF);
> - WriteHSCX(hx, IPAC_XBCH, 0x00);
> - WriteHSCX(hx, IPAC_RLCR, 0x00);
> -
> - if (hx->ip->type & IPAC_TYPE_HSCX) {
> - WriteHSCX(hx, IPAC_CCR1, 0x85);
> - val = ReadHSCX(hx, HSCX_VSTR);
> - pr_debug("%s: HSCX VSTR %02x\n", hx->ip->name, val);
> - if (hx->bch.debug & DEBUG_HW)
> - pr_notice("%s: HSCX version %s\n", hx->ip->name,
> - HSCXVer[val & 0x0f]);
> - } else
> - WriteHSCX(hx, IPAC_CCR1, 0x82);
> - WriteHSCX(hx, IPAC_CCR2, 0x30);
> - WriteHSCX(hx, IPAC_XCCR, 0x07);
> - WriteHSCX(hx, IPAC_RCCR, 0x07);
> -}
> -
> -static int
> -ipac_init(struct ipac_hw *ipac)
> -{
> - u8 val;
> -
> - if (ipac->type & IPAC_TYPE_HSCX) {
> - hscx_init(&ipac->hscx[0]);
> - hscx_init(&ipac->hscx[1]);
> - val = ReadIPAC(ipac, IPAC_ID);
> - } else if (ipac->type & IPAC_TYPE_IPAC) {
> - hscx_init(&ipac->hscx[0]);
> - hscx_init(&ipac->hscx[1]);
> - WriteIPAC(ipac, IPAC_MASK, IPAC__ON);
> - val = ReadIPAC(ipac, IPAC_CONF);
> - /* conf is default 0, but can be overwritten by card setup */
> - pr_debug("%s: IPAC CONF %02x/%02x\n", ipac->name,
> - val, ipac->conf);
> - WriteIPAC(ipac, IPAC_CONF, ipac->conf);
> - val = ReadIPAC(ipac, IPAC_ID);
> - if (ipac->hscx[0].bch.debug & DEBUG_HW)
> - pr_notice("%s: IPAC Design ID %02x\n", ipac->name, val);
> - }
> - /* nothing special for IPACX to do here */
> - return isac_init(&ipac->isac);
> -}
> -
> -static int
> -open_bchannel(struct ipac_hw *ipac, struct channel_req *rq)
> -{
> - struct bchannel *bch;
> -
> - if (rq->adr.channel == 0 || rq->adr.channel > 2)
> - return -EINVAL;
> - if (rq->protocol == ISDN_P_NONE)
> - return -EINVAL;
> - bch = &ipac->hscx[rq->adr.channel - 1].bch;
> - if (test_and_set_bit(FLG_OPEN, &bch->Flags))
> - return -EBUSY; /* b-channel can be only open once */
> - test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);
> - bch->ch.protocol = rq->protocol;
> - rq->ch = &bch->ch;
> - return 0;
> -}
> -
> -static int
> -channel_ctrl(struct ipac_hw *ipac, struct mISDN_ctrl_req *cq)
> -{
> - int ret = 0;
> -
> - switch (cq->op) {
> - case MISDN_CTRL_GETOP:
> - cq->op = MISDN_CTRL_LOOP | MISDN_CTRL_L1_TIMER3;
> - break;
> - case MISDN_CTRL_LOOP:
> - /* cq->channel: 0 disable, 1 B1 loop 2 B2 loop, 3 both */
> - if (cq->channel < 0 || cq->channel > 3) {
> - ret = -EINVAL;
> - break;
> - }
> - ret = ipac->ctrl(ipac, HW_TESTLOOP, cq->channel);
> - break;
> - case MISDN_CTRL_L1_TIMER3:
> - ret = ipac->isac.ctrl(&ipac->isac, HW_TIMER3_VALUE, cq->p1);
> - break;
> - default:
> - pr_info("%s: unknown CTRL OP %x\n", ipac->name, cq->op);
> - ret = -EINVAL;
> - break;
> - }
> - return ret;
> -}
> -
> -static int
> -ipac_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
> -{
> - struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
> - struct dchannel *dch = container_of(dev, struct dchannel, dev);
> - struct isac_hw *isac = container_of(dch, struct isac_hw, dch);
> - struct ipac_hw *ipac = container_of(isac, struct ipac_hw, isac);
> - struct channel_req *rq;
> - int err = 0;
> -
> - pr_debug("%s: DCTRL: %x %p\n", ipac->name, cmd, arg);
> - switch (cmd) {
> - case OPEN_CHANNEL:
> - rq = arg;
> - if (rq->protocol == ISDN_P_TE_S0)
> - err = open_dchannel_caller(isac, rq, __builtin_return_address(0));
> - else
> - err = open_bchannel(ipac, rq);
> - if (err)
> - break;
> - if (!try_module_get(ipac->owner))
> - pr_info("%s: cannot get module\n", ipac->name);
> - break;
> - case CLOSE_CHANNEL:
> - pr_debug("%s: dev(%d) close from %p\n", ipac->name,
> - dch->dev.id, __builtin_return_address(0));
> - module_put(ipac->owner);
> - break;
> - case CONTROL_CHANNEL:
> - err = channel_ctrl(ipac, arg);
> - break;
> - default:
> - pr_debug("%s: unknown DCTRL command %x\n", ipac->name, cmd);
> - return -EINVAL;
> - }
> - return err;
> -}
> -
> -u32
> -mISDNipac_init(struct ipac_hw *ipac, void *hw)
> -{
> - u32 ret;
> - u8 i;
> -
> - ipac->hw = hw;
> - if (ipac->isac.dch.debug & DEBUG_HW)
> - pr_notice("%s: ipac type %x\n", ipac->name, ipac->type);
> - if (ipac->type & IPAC_TYPE_HSCX) {
> - ipac->isac.type = IPAC_TYPE_ISAC;
> - ipac->hscx[0].off = 0;
> - ipac->hscx[1].off = 0x40;
> - ipac->hscx[0].fifo_size = 32;
> - ipac->hscx[1].fifo_size = 32;
> - } else if (ipac->type & IPAC_TYPE_IPAC) {
> - ipac->isac.type = IPAC_TYPE_IPAC | IPAC_TYPE_ISAC;
> - ipac->hscx[0].off = 0;
> - ipac->hscx[1].off = 0x40;
> - ipac->hscx[0].fifo_size = 64;
> - ipac->hscx[1].fifo_size = 64;
> - } else if (ipac->type & IPAC_TYPE_IPACX) {
> - ipac->isac.type = IPAC_TYPE_IPACX | IPAC_TYPE_ISACX;
> - ipac->hscx[0].off = IPACX_OFF_ICA;
> - ipac->hscx[1].off = IPACX_OFF_ICB;
> - ipac->hscx[0].fifo_size = 64;
> - ipac->hscx[1].fifo_size = 64;
> - } else
> - return 0;
> -
> - mISDNisac_init(&ipac->isac, hw);
> -
> - ipac->isac.dch.dev.D.ctrl = ipac_dctrl;
> -
> - for (i = 0; i < 2; i++) {
> - ipac->hscx[i].bch.nr = i + 1;
> - set_channelmap(i + 1, ipac->isac.dch.dev.channelmap);
> - list_add(&ipac->hscx[i].bch.ch.list,
> - &ipac->isac.dch.dev.bchannels);
> - mISDN_initbchannel(&ipac->hscx[i].bch, MAX_DATA_MEM,
> - ipac->hscx[i].fifo_size);
> - ipac->hscx[i].bch.ch.nr = i + 1;
> - ipac->hscx[i].bch.ch.send = &hscx_l2l1;
> - ipac->hscx[i].bch.ch.ctrl = hscx_bctrl;
> - ipac->hscx[i].bch.hw = hw;
> - ipac->hscx[i].ip = ipac;
> - /* default values for IOM time slots
> - * can be overwritten by card */
> - ipac->hscx[i].slot = (i == 0) ? 0x2f : 0x03;
> - }
> -
> - ipac->init = ipac_init;
> - ipac->release = free_ipac;
> -
> - ret = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
> - (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
> - return ret;
> -}
> -EXPORT_SYMBOL(mISDNipac_init);
> -
> -static int __init
> -isac_mod_init(void)
> -{
> - pr_notice("mISDNipac module version %s\n", ISAC_REV);
> - return 0;
> -}
> -
> -static void __exit
> -isac_mod_cleanup(void)
> -{
> - pr_notice("mISDNipac module unloaded\n");
> -}
> -module_init(isac_mod_init);
> -module_exit(isac_mod_cleanup);
> diff --git a/drivers/isdn/hardware/mISDN/mISDNisar.c b/drivers/isdn/hardware/mISDN/mISDNisar.c
> deleted file mode 100644
> index dace91ba412b..000000000000
> --- a/drivers/isdn/hardware/mISDN/mISDNisar.c
> +++ /dev/null
> @@ -1,1694 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * mISDNisar.c ISAR (Siemens PSB 7110) specific functions
> - *
> - * Author Karsten Keil (keil@isdn4linux.de)
> - *
> - * Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
> - */
> -
> -/* define this to enable static debug messages, if you kernel supports
> - * dynamic debugging, you should use debugfs for this
> - */
> -/* #define DEBUG */
> -
> -#include <linux/gfp.h>
> -#include <linux/delay.h>
> -#include <linux/vmalloc.h>
> -#include <linux/mISDNhw.h>
> -#include <linux/module.h>
> -#include "isar.h"
> -
> -#define ISAR_REV "2.1"
> -
> -MODULE_AUTHOR("Karsten Keil");
> -MODULE_DESCRIPTION("mISDN driver for ISAR (Siemens PSB 7110) specific functions");
> -MODULE_LICENSE("GPL v2");
> -MODULE_VERSION(ISAR_REV);
> -
> -#define DEBUG_HW_FIRMWARE_FIFO 0x10000
> -
> -static const u8 faxmodulation[] = {3, 24, 48, 72, 73, 74, 96, 97, 98, 121,
> - 122, 145, 146};
> -#define FAXMODCNT 13
> -
> -static void isar_setup(struct isar_hw *);
> -
> -static inline int
> -waitforHIA(struct isar_hw *isar, int timeout)
> -{
> - int t = timeout;
> - u8 val = isar->read_reg(isar->hw, ISAR_HIA);
> -
> - while ((val & 1) && t) {
> - udelay(1);
> - t--;
> - val = isar->read_reg(isar->hw, ISAR_HIA);
> - }
> - pr_debug("%s: HIA after %dus\n", isar->name, timeout - t);
> - return timeout;
> -}
> -
> -/*
> - * send msg to ISAR mailbox
> - * if msg is NULL use isar->buf
> - */
> -static int
> -send_mbox(struct isar_hw *isar, u8 his, u8 creg, u8 len, u8 *msg)
> -{
> - if (!waitforHIA(isar, 1000))
> - return 0;
> - pr_debug("send_mbox(%02x,%02x,%d)\n", his, creg, len);
> - isar->write_reg(isar->hw, ISAR_CTRL_H, creg);
> - isar->write_reg(isar->hw, ISAR_CTRL_L, len);
> - isar->write_reg(isar->hw, ISAR_WADR, 0);
> - if (!msg)
> - msg = isar->buf;
> - if (msg && len) {
> - isar->write_fifo(isar->hw, ISAR_MBOX, msg, len);
> - if (isar->ch[0].bch.debug & DEBUG_HW_BFIFO) {
> - int l = 0;
> -
> - while (l < (int)len) {
> - hex_dump_to_buffer(msg + l, len - l, 32, 1,
> - isar->log, 256, 1);
> - pr_debug("%s: %s %02x: %s\n", isar->name,
> - __func__, l, isar->log);
> - l += 32;
> - }
> - }
> - }
> - isar->write_reg(isar->hw, ISAR_HIS, his);
> - waitforHIA(isar, 1000);
> - return 1;
> -}
> -
> -/*
> - * receive message from ISAR mailbox
> - * if msg is NULL use isar->buf
> - */
> -static void
> -rcv_mbox(struct isar_hw *isar, u8 *msg)
> -{
> - if (!msg)
> - msg = isar->buf;
> - isar->write_reg(isar->hw, ISAR_RADR, 0);
> - if (msg && isar->clsb) {
> - isar->read_fifo(isar->hw, ISAR_MBOX, msg, isar->clsb);
> - if (isar->ch[0].bch.debug & DEBUG_HW_BFIFO) {
> - int l = 0;
> -
> - while (l < (int)isar->clsb) {
> - hex_dump_to_buffer(msg + l, isar->clsb - l, 32,
> - 1, isar->log, 256, 1);
> - pr_debug("%s: %s %02x: %s\n", isar->name,
> - __func__, l, isar->log);
> - l += 32;
> - }
> - }
> - }
> - isar->write_reg(isar->hw, ISAR_IIA, 0);
> -}
> -
> -static inline void
> -get_irq_infos(struct isar_hw *isar)
> -{
> - isar->iis = isar->read_reg(isar->hw, ISAR_IIS);
> - isar->cmsb = isar->read_reg(isar->hw, ISAR_CTRL_H);
> - isar->clsb = isar->read_reg(isar->hw, ISAR_CTRL_L);
> - pr_debug("%s: rcv_mbox(%02x,%02x,%d)\n", isar->name,
> - isar->iis, isar->cmsb, isar->clsb);
> -}
> -
> -/*
> - * poll answer message from ISAR mailbox
> - * should be used only with ISAR IRQs disabled before DSP was started
> - *
> - */
> -static int
> -poll_mbox(struct isar_hw *isar, int maxdelay)
> -{
> - int t = maxdelay;
> - u8 irq;
> -
> - irq = isar->read_reg(isar->hw, ISAR_IRQBIT);
> - while (t && !(irq & ISAR_IRQSTA)) {
> - udelay(1);
> - t--;
> - }
> - if (t) {
> - get_irq_infos(isar);
> - rcv_mbox(isar, NULL);
> - }
> - pr_debug("%s: pulled %d bytes after %d us\n",
> - isar->name, isar->clsb, maxdelay - t);
> - return t;
> -}
> -
> -static int
> -ISARVersion(struct isar_hw *isar)
> -{
> - int ver;
> -
> - /* disable ISAR IRQ */
> - isar->write_reg(isar->hw, ISAR_IRQBIT, 0);
> - isar->buf[0] = ISAR_MSG_HWVER;
> - isar->buf[1] = 0;
> - isar->buf[2] = 1;
> - if (!send_mbox(isar, ISAR_HIS_VNR, 0, 3, NULL))
> - return -1;
> - if (!poll_mbox(isar, 1000))
> - return -2;
> - if (isar->iis == ISAR_IIS_VNR) {
> - if (isar->clsb == 1) {
> - ver = isar->buf[0] & 0xf;
> - return ver;
> - }
> - return -3;
> - }
> - return -4;
> -}
> -
> -static int
> -load_firmware(struct isar_hw *isar, const u8 *buf, int size)
> -{
> - u32 saved_debug = isar->ch[0].bch.debug;
> - int ret, cnt;
> - u8 nom, noc;
> - u16 left, val, *sp = (u16 *)buf;
> - u8 *mp;
> - u_long flags;
> -
> - struct {
> - u16 sadr;
> - u16 len;
> - u16 d_key;
> - } blk_head;
> -
> - if (1 != isar->version) {
> - pr_err("%s: ISAR wrong version %d firmware download aborted\n",
> - isar->name, isar->version);
> - return -EINVAL;
> - }
> - if (!(saved_debug & DEBUG_HW_FIRMWARE_FIFO))
> - isar->ch[0].bch.debug &= ~DEBUG_HW_BFIFO;
> - pr_debug("%s: load firmware %d words (%d bytes)\n",
> - isar->name, size / 2, size);
> - cnt = 0;
> - size /= 2;
> - /* disable ISAR IRQ */
> - spin_lock_irqsave(isar->hwlock, flags);
> - isar->write_reg(isar->hw, ISAR_IRQBIT, 0);
> - spin_unlock_irqrestore(isar->hwlock, flags);
> - while (cnt < size) {
> - blk_head.sadr = le16_to_cpu(*sp++);
> - blk_head.len = le16_to_cpu(*sp++);
> - blk_head.d_key = le16_to_cpu(*sp++);
> - cnt += 3;
> - pr_debug("ISAR firmware block (%#x,%d,%#x)\n",
> - blk_head.sadr, blk_head.len, blk_head.d_key & 0xff);
> - left = blk_head.len;
> - if (cnt + left > size) {
> - pr_info("%s: firmware error have %d need %d words\n",
> - isar->name, size, cnt + left);
> - ret = -EINVAL;
> - goto reterrflg;
> - }
> - spin_lock_irqsave(isar->hwlock, flags);
> - if (!send_mbox(isar, ISAR_HIS_DKEY, blk_head.d_key & 0xff,
> - 0, NULL)) {
> - pr_info("ISAR send_mbox dkey failed\n");
> - ret = -ETIME;
> - goto reterror;
> - }
> - if (!poll_mbox(isar, 1000)) {
> - pr_warn("ISAR poll_mbox dkey failed\n");
> - ret = -ETIME;
> - goto reterror;
> - }
> - spin_unlock_irqrestore(isar->hwlock, flags);
> - if ((isar->iis != ISAR_IIS_DKEY) || isar->cmsb || isar->clsb) {
> - pr_info("ISAR wrong dkey response (%x,%x,%x)\n",
> - isar->iis, isar->cmsb, isar->clsb);
> - ret = 1;
> - goto reterrflg;
> - }
> - while (left > 0) {
> - if (left > 126)
> - noc = 126;
> - else
> - noc = left;
> - nom = (2 * noc) + 3;
> - mp = isar->buf;
> - /* the ISAR is big endian */
> - *mp++ = blk_head.sadr >> 8;
> - *mp++ = blk_head.sadr & 0xFF;
> - left -= noc;
> - cnt += noc;
> - *mp++ = noc;
> - pr_debug("%s: load %3d words at %04x\n", isar->name,
> - noc, blk_head.sadr);
> - blk_head.sadr += noc;
> - while (noc) {
> - val = le16_to_cpu(*sp++);
> - *mp++ = val >> 8;
> - *mp++ = val & 0xFF;
> - noc--;
> - }
> - spin_lock_irqsave(isar->hwlock, flags);
> - if (!send_mbox(isar, ISAR_HIS_FIRM, 0, nom, NULL)) {
> - pr_info("ISAR send_mbox prog failed\n");
> - ret = -ETIME;
> - goto reterror;
> - }
> - if (!poll_mbox(isar, 1000)) {
> - pr_info("ISAR poll_mbox prog failed\n");
> - ret = -ETIME;
> - goto reterror;
> - }
> - spin_unlock_irqrestore(isar->hwlock, flags);
> - if ((isar->iis != ISAR_IIS_FIRM) ||
> - isar->cmsb || isar->clsb) {
> - pr_info("ISAR wrong prog response (%x,%x,%x)\n",
> - isar->iis, isar->cmsb, isar->clsb);
> - ret = -EIO;
> - goto reterrflg;
> - }
> - }
> - pr_debug("%s: ISAR firmware block %d words loaded\n",
> - isar->name, blk_head.len);
> - }
> - isar->ch[0].bch.debug = saved_debug;
> - /* 10ms delay */
> - cnt = 10;
> - while (cnt--)
> - mdelay(1);
> - isar->buf[0] = 0xff;
> - isar->buf[1] = 0xfe;
> - isar->bstat = 0;
> - spin_lock_irqsave(isar->hwlock, flags);
> - if (!send_mbox(isar, ISAR_HIS_STDSP, 0, 2, NULL)) {
> - pr_info("ISAR send_mbox start dsp failed\n");
> - ret = -ETIME;
> - goto reterror;
> - }
> - if (!poll_mbox(isar, 1000)) {
> - pr_info("ISAR poll_mbox start dsp failed\n");
> - ret = -ETIME;
> - goto reterror;
> - }
> - if ((isar->iis != ISAR_IIS_STDSP) || isar->cmsb || isar->clsb) {
> - pr_info("ISAR wrong start dsp response (%x,%x,%x)\n",
> - isar->iis, isar->cmsb, isar->clsb);
> - ret = -EIO;
> - goto reterror;
> - } else
> - pr_debug("%s: ISAR start dsp success\n", isar->name);
> -
> - /* NORMAL mode entered */
> - /* Enable IRQs of ISAR */
> - isar->write_reg(isar->hw, ISAR_IRQBIT, ISAR_IRQSTA);
> - spin_unlock_irqrestore(isar->hwlock, flags);
> - cnt = 1000; /* max 1s */
> - while ((!isar->bstat) && cnt) {
> - mdelay(1);
> - cnt--;
> - }
> - if (!cnt) {
> - pr_info("ISAR no general status event received\n");
> - ret = -ETIME;
> - goto reterrflg;
> - } else
> - pr_debug("%s: ISAR general status event %x\n",
> - isar->name, isar->bstat);
> - /* 10ms delay */
> - cnt = 10;
> - while (cnt--)
> - mdelay(1);
> - isar->iis = 0;
> - spin_lock_irqsave(isar->hwlock, flags);
> - if (!send_mbox(isar, ISAR_HIS_DIAG, ISAR_CTRL_STST, 0, NULL)) {
> - pr_info("ISAR send_mbox self tst failed\n");
> - ret = -ETIME;
> - goto reterror;
> - }
> - spin_unlock_irqrestore(isar->hwlock, flags);
> - cnt = 10000; /* max 100 ms */
> - while ((isar->iis != ISAR_IIS_DIAG) && cnt) {
> - udelay(10);
> - cnt--;
> - }
> - mdelay(1);
> - if (!cnt) {
> - pr_info("ISAR no self tst response\n");
> - ret = -ETIME;
> - goto reterrflg;
> - }
> - if ((isar->cmsb == ISAR_CTRL_STST) && (isar->clsb == 1)
> - && (isar->buf[0] == 0))
> - pr_debug("%s: ISAR selftest OK\n", isar->name);
> - else {
> - pr_info("ISAR selftest not OK %x/%x/%x\n",
> - isar->cmsb, isar->clsb, isar->buf[0]);
> - ret = -EIO;
> - goto reterrflg;
> - }
> - spin_lock_irqsave(isar->hwlock, flags);
> - isar->iis = 0;
> - if (!send_mbox(isar, ISAR_HIS_DIAG, ISAR_CTRL_SWVER, 0, NULL)) {
> - pr_info("ISAR RQST SVN failed\n");
> - ret = -ETIME;
> - goto reterror;
> - }
> - spin_unlock_irqrestore(isar->hwlock, flags);
> - cnt = 30000; /* max 300 ms */
> - while ((isar->iis != ISAR_IIS_DIAG) && cnt) {
> - udelay(10);
> - cnt--;
> - }
> - mdelay(1);
> - if (!cnt) {
> - pr_info("ISAR no SVN response\n");
> - ret = -ETIME;
> - goto reterrflg;
> - } else {
> - if ((isar->cmsb == ISAR_CTRL_SWVER) && (isar->clsb == 1)) {
> - pr_notice("%s: ISAR software version %#x\n",
> - isar->name, isar->buf[0]);
> - } else {
> - pr_info("%s: ISAR wrong swver response (%x,%x)"
> - " cnt(%d)\n", isar->name, isar->cmsb,
> - isar->clsb, cnt);
> - ret = -EIO;
> - goto reterrflg;
> - }
> - }
> - spin_lock_irqsave(isar->hwlock, flags);
> - isar_setup(isar);
> - spin_unlock_irqrestore(isar->hwlock, flags);
> - ret = 0;
> -reterrflg:
> - spin_lock_irqsave(isar->hwlock, flags);
> -reterror:
> - isar->ch[0].bch.debug = saved_debug;
> - if (ret)
> - /* disable ISAR IRQ */
> - isar->write_reg(isar->hw, ISAR_IRQBIT, 0);
> - spin_unlock_irqrestore(isar->hwlock, flags);
> - return ret;
> -}
> -
> -static inline void
> -deliver_status(struct isar_ch *ch, int status)
> -{
> - pr_debug("%s: HL->LL FAXIND %x\n", ch->is->name, status);
> - _queue_data(&ch->bch.ch, PH_CONTROL_IND, status, 0, NULL, GFP_ATOMIC);
> -}
> -
> -static inline void
> -isar_rcv_frame(struct isar_ch *ch)
> -{
> - u8 *ptr;
> - int maxlen;
> -
> - if (!ch->is->clsb) {
> - pr_debug("%s; ISAR zero len frame\n", ch->is->name);
> - ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
> - return;
> - }
> - if (test_bit(FLG_RX_OFF, &ch->bch.Flags)) {
> - ch->bch.dropcnt += ch->is->clsb;
> - ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
> - return;
> - }
> - switch (ch->bch.state) {
> - case ISDN_P_NONE:
> - pr_debug("%s: ISAR protocol 0 spurious IIS_RDATA %x/%x/%x\n",
> - ch->is->name, ch->is->iis, ch->is->cmsb, ch->is->clsb);
> - ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
> - break;
> - case ISDN_P_B_RAW:
> - case ISDN_P_B_L2DTMF:
> - case ISDN_P_B_MODEM_ASYNC:
> - maxlen = bchannel_get_rxbuf(&ch->bch, ch->is->clsb);
> - if (maxlen < 0) {
> - pr_warn("%s.B%d: No bufferspace for %d bytes\n",
> - ch->is->name, ch->bch.nr, ch->is->clsb);
> - ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
> - break;
> - }
> - rcv_mbox(ch->is, skb_put(ch->bch.rx_skb, ch->is->clsb));
> - recv_Bchannel(&ch->bch, 0, false);
> - break;
> - case ISDN_P_B_HDLC:
> - maxlen = bchannel_get_rxbuf(&ch->bch, ch->is->clsb);
> - if (maxlen < 0) {
> - pr_warn("%s.B%d: No bufferspace for %d bytes\n",
> - ch->is->name, ch->bch.nr, ch->is->clsb);
> - ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
> - break;
> - }
> - if (ch->is->cmsb & HDLC_ERROR) {
> - pr_debug("%s: ISAR frame error %x len %d\n",
> - ch->is->name, ch->is->cmsb, ch->is->clsb);
> -#ifdef ERROR_STATISTIC
> - if (ch->is->cmsb & HDLC_ERR_RER)
> - ch->bch.err_inv++;
> - if (ch->is->cmsb & HDLC_ERR_CER)
> - ch->bch.err_crc++;
> -#endif
> - skb_trim(ch->bch.rx_skb, 0);
> - ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
> - break;
> - }
> - if (ch->is->cmsb & HDLC_FSD)
> - skb_trim(ch->bch.rx_skb, 0);
> - ptr = skb_put(ch->bch.rx_skb, ch->is->clsb);
> - rcv_mbox(ch->is, ptr);
> - if (ch->is->cmsb & HDLC_FED) {
> - if (ch->bch.rx_skb->len < 3) { /* last 2 are the FCS */
> - pr_debug("%s: ISAR frame too short %d\n",
> - ch->is->name, ch->bch.rx_skb->len);
> - skb_trim(ch->bch.rx_skb, 0);
> - break;
> - }
> - skb_trim(ch->bch.rx_skb, ch->bch.rx_skb->len - 2);
> - recv_Bchannel(&ch->bch, 0, false);
> - }
> - break;
> - case ISDN_P_B_T30_FAX:
> - if (ch->state != STFAX_ACTIV) {
> - pr_debug("%s: isar_rcv_frame: not ACTIV\n",
> - ch->is->name);
> - ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
> - if (ch->bch.rx_skb)
> - skb_trim(ch->bch.rx_skb, 0);
> - break;
> - }
> - if (!ch->bch.rx_skb) {
> - ch->bch.rx_skb = mI_alloc_skb(ch->bch.maxlen,
> - GFP_ATOMIC);
> - if (unlikely(!ch->bch.rx_skb)) {
> - pr_info("%s: B receive out of memory\n",
> - __func__);
> - ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
> - break;
> - }
> - }
> - if (ch->cmd == PCTRL_CMD_FRM) {
> - rcv_mbox(ch->is, skb_put(ch->bch.rx_skb, ch->is->clsb));
> - pr_debug("%s: isar_rcv_frame: %d\n",
> - ch->is->name, ch->bch.rx_skb->len);
> - if (ch->is->cmsb & SART_NMD) { /* ABORT */
> - pr_debug("%s: isar_rcv_frame: no more data\n",
> - ch->is->name);
> - ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
> - send_mbox(ch->is, SET_DPS(ch->dpath) |
> - ISAR_HIS_PUMPCTRL, PCTRL_CMD_ESC,
> - 0, NULL);
> - ch->state = STFAX_ESCAPE;
> - /* set_skb_flag(skb, DF_NOMOREDATA); */
> - }
> - recv_Bchannel(&ch->bch, 0, false);
> - if (ch->is->cmsb & SART_NMD)
> - deliver_status(ch, HW_MOD_NOCARR);
> - break;
> - }
> - if (ch->cmd != PCTRL_CMD_FRH) {
> - pr_debug("%s: isar_rcv_frame: unknown fax mode %x\n",
> - ch->is->name, ch->cmd);
> - ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
> - if (ch->bch.rx_skb)
> - skb_trim(ch->bch.rx_skb, 0);
> - break;
> - }
> - /* PCTRL_CMD_FRH */
> - if ((ch->bch.rx_skb->len + ch->is->clsb) >
> - (ch->bch.maxlen + 2)) {
> - pr_info("%s: %s incoming packet too large\n",
> - ch->is->name, __func__);
> - ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
> - skb_trim(ch->bch.rx_skb, 0);
> - break;
> - } else if (ch->is->cmsb & HDLC_ERROR) {
> - pr_info("%s: ISAR frame error %x len %d\n",
> - ch->is->name, ch->is->cmsb, ch->is->clsb);
> - skb_trim(ch->bch.rx_skb, 0);
> - ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
> - break;
> - }
> - if (ch->is->cmsb & HDLC_FSD)
> - skb_trim(ch->bch.rx_skb, 0);
> - ptr = skb_put(ch->bch.rx_skb, ch->is->clsb);
> - rcv_mbox(ch->is, ptr);
> - if (ch->is->cmsb & HDLC_FED) {
> - if (ch->bch.rx_skb->len < 3) { /* last 2 are the FCS */
> - pr_info("%s: ISAR frame too short %d\n",
> - ch->is->name, ch->bch.rx_skb->len);
> - skb_trim(ch->bch.rx_skb, 0);
> - break;
> - }
> - skb_trim(ch->bch.rx_skb, ch->bch.rx_skb->len - 2);
> - recv_Bchannel(&ch->bch, 0, false);
> - }
> - if (ch->is->cmsb & SART_NMD) { /* ABORT */
> - pr_debug("%s: isar_rcv_frame: no more data\n",
> - ch->is->name);
> - ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
> - if (ch->bch.rx_skb)
> - skb_trim(ch->bch.rx_skb, 0);
> - send_mbox(ch->is, SET_DPS(ch->dpath) |
> - ISAR_HIS_PUMPCTRL, PCTRL_CMD_ESC, 0, NULL);
> - ch->state = STFAX_ESCAPE;
> - deliver_status(ch, HW_MOD_NOCARR);
> - }
> - break;
> - default:
> - pr_info("isar_rcv_frame protocol (%x)error\n", ch->bch.state);
> - ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
> - break;
> - }
> -}
> -
> -static void
> -isar_fill_fifo(struct isar_ch *ch)
> -{
> - int count;
> - u8 msb;
> - u8 *ptr;
> -
> - pr_debug("%s: ch%d tx_skb %d tx_idx %d\n", ch->is->name, ch->bch.nr,
> - ch->bch.tx_skb ? ch->bch.tx_skb->len : -1, ch->bch.tx_idx);
> - if (!(ch->is->bstat &
> - (ch->dpath == 1 ? BSTAT_RDM1 : BSTAT_RDM2)))
> - return;
> - if (!ch->bch.tx_skb) {
> - if (!test_bit(FLG_TX_EMPTY, &ch->bch.Flags) ||
> - (ch->bch.state != ISDN_P_B_RAW))
> - return;
> - count = ch->mml;
> - /* use the card buffer */
> - memset(ch->is->buf, ch->bch.fill[0], count);
> - send_mbox(ch->is, SET_DPS(ch->dpath) | ISAR_HIS_SDATA,
> - 0, count, ch->is->buf);
> - return;
> - }
> - count = ch->bch.tx_skb->len - ch->bch.tx_idx;
> - if (count <= 0)
> - return;
> - if (count > ch->mml) {
> - msb = 0;
> - count = ch->mml;
> - } else {
> - msb = HDLC_FED;
> - }
> - ptr = ch->bch.tx_skb->data + ch->bch.tx_idx;
> - if (!ch->bch.tx_idx) {
> - pr_debug("%s: frame start\n", ch->is->name);
> - if ((ch->bch.state == ISDN_P_B_T30_FAX) &&
> - (ch->cmd == PCTRL_CMD_FTH)) {
> - if (count > 1) {
> - if ((ptr[0] == 0xff) && (ptr[1] == 0x13)) {
> - /* last frame */
> - test_and_set_bit(FLG_LASTDATA,
> - &ch->bch.Flags);
> - pr_debug("%s: set LASTDATA\n",
> - ch->is->name);
> - if (msb == HDLC_FED)
> - test_and_set_bit(FLG_DLEETX,
> - &ch->bch.Flags);
> - }
> - }
> - }
> - msb |= HDLC_FST;
> - }
> - ch->bch.tx_idx += count;
> - switch (ch->bch.state) {
> - case ISDN_P_NONE:
> - pr_info("%s: wrong protocol 0\n", __func__);
> - break;
> - case ISDN_P_B_RAW:
> - case ISDN_P_B_L2DTMF:
> - case ISDN_P_B_MODEM_ASYNC:
> - send_mbox(ch->is, SET_DPS(ch->dpath) | ISAR_HIS_SDATA,
> - 0, count, ptr);
> - break;
> - case ISDN_P_B_HDLC:
> - send_mbox(ch->is, SET_DPS(ch->dpath) | ISAR_HIS_SDATA,
> - msb, count, ptr);
> - break;
> - case ISDN_P_B_T30_FAX:
> - if (ch->state != STFAX_ACTIV)
> - pr_debug("%s: not ACTIV\n", ch->is->name);
> - else if (ch->cmd == PCTRL_CMD_FTH)
> - send_mbox(ch->is, SET_DPS(ch->dpath) | ISAR_HIS_SDATA,
> - msb, count, ptr);
> - else if (ch->cmd == PCTRL_CMD_FTM)
> - send_mbox(ch->is, SET_DPS(ch->dpath) | ISAR_HIS_SDATA,
> - 0, count, ptr);
> - else
> - pr_debug("%s: not FTH/FTM\n", ch->is->name);
> - break;
> - default:
> - pr_info("%s: protocol(%x) error\n",
> - __func__, ch->bch.state);
> - break;
> - }
> -}
> -
> -static inline struct isar_ch *
> -sel_bch_isar(struct isar_hw *isar, u8 dpath)
> -{
> - struct isar_ch *base = &isar->ch[0];
> -
> - if ((!dpath) || (dpath > 2))
> - return NULL;
> - if (base->dpath == dpath)
> - return base;
> - base++;
> - if (base->dpath == dpath)
> - return base;
> - return NULL;
> -}
> -
> -static void
> -send_next(struct isar_ch *ch)
> -{
> - pr_debug("%s: %s ch%d tx_skb %d tx_idx %d\n", ch->is->name, __func__,
> - ch->bch.nr, ch->bch.tx_skb ? ch->bch.tx_skb->len : -1,
> - ch->bch.tx_idx);
> - if (ch->bch.state == ISDN_P_B_T30_FAX) {
> - if (ch->cmd == PCTRL_CMD_FTH) {
> - if (test_bit(FLG_LASTDATA, &ch->bch.Flags)) {
> - pr_debug("set NMD_DATA\n");
> - test_and_set_bit(FLG_NMD_DATA, &ch->bch.Flags);
> - }
> - } else if (ch->cmd == PCTRL_CMD_FTM) {
> - if (test_bit(FLG_DLEETX, &ch->bch.Flags)) {
> - test_and_set_bit(FLG_LASTDATA, &ch->bch.Flags);
> - test_and_set_bit(FLG_NMD_DATA, &ch->bch.Flags);
> - }
> - }
> - }
> - dev_kfree_skb(ch->bch.tx_skb);
> - if (get_next_bframe(&ch->bch)) {
> - isar_fill_fifo(ch);
> - test_and_clear_bit(FLG_TX_EMPTY, &ch->bch.Flags);
> - } else if (test_bit(FLG_TX_EMPTY, &ch->bch.Flags)) {
> - isar_fill_fifo(ch);
> - } else {
> - if (test_and_clear_bit(FLG_DLEETX, &ch->bch.Flags)) {
> - if (test_and_clear_bit(FLG_LASTDATA,
> - &ch->bch.Flags)) {
> - if (test_and_clear_bit(FLG_NMD_DATA,
> - &ch->bch.Flags)) {
> - u8 zd = 0;
> - send_mbox(ch->is, SET_DPS(ch->dpath) |
> - ISAR_HIS_SDATA, 0x01, 1, &zd);
> - }
> - test_and_set_bit(FLG_LL_OK, &ch->bch.Flags);
> - } else {
> - deliver_status(ch, HW_MOD_CONNECT);
> - }
> - } else if (test_bit(FLG_FILLEMPTY, &ch->bch.Flags)) {
> - test_and_set_bit(FLG_TX_EMPTY, &ch->bch.Flags);
> - }
> - }
> -}
> -
> -static void
> -check_send(struct isar_hw *isar, u8 rdm)
> -{
> - struct isar_ch *ch;
> -
> - pr_debug("%s: rdm %x\n", isar->name, rdm);
> - if (rdm & BSTAT_RDM1) {
> - ch = sel_bch_isar(isar, 1);
> - if (ch && test_bit(FLG_ACTIVE, &ch->bch.Flags)) {
> - if (ch->bch.tx_skb && (ch->bch.tx_skb->len >
> - ch->bch.tx_idx))
> - isar_fill_fifo(ch);
> - else
> - send_next(ch);
> - }
> - }
> - if (rdm & BSTAT_RDM2) {
> - ch = sel_bch_isar(isar, 2);
> - if (ch && test_bit(FLG_ACTIVE, &ch->bch.Flags)) {
> - if (ch->bch.tx_skb && (ch->bch.tx_skb->len >
> - ch->bch.tx_idx))
> - isar_fill_fifo(ch);
> - else
> - send_next(ch);
> - }
> - }
> -}
> -
> -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 isar_ch *ch) {
> - u8 ril = ch->is->buf[0];
> - u8 rim;
> -
> - if (!test_and_clear_bit(ISAR_RATE_REQ, &ch->is->Flags))
> - return;
> - if (ril > 14) {
> - pr_info("%s: wrong pstrsp ril=%d\n", ch->is->name, ril);
> - ril = 15;
> - }
> - switch (ch->is->buf[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(ch->conmsg, "%s %s", dmril[ril], dmrim[rim]);
> - pr_debug("%s: pump strsp %s\n", ch->is->name, ch->conmsg);
> -}
> -
> -static void
> -isar_pump_statev_modem(struct isar_ch *ch, u8 devt) {
> - u8 dps = SET_DPS(ch->dpath);
> -
> - switch (devt) {
> - case PSEV_10MS_TIMER:
> - pr_debug("%s: pump stev TIMER\n", ch->is->name);
> - break;
> - case PSEV_CON_ON:
> - pr_debug("%s: pump stev CONNECT\n", ch->is->name);
> - deliver_status(ch, HW_MOD_CONNECT);
> - break;
> - case PSEV_CON_OFF:
> - pr_debug("%s: pump stev NO CONNECT\n", ch->is->name);
> - send_mbox(ch->is, dps | ISAR_HIS_PSTREQ, 0, 0, NULL);
> - deliver_status(ch, HW_MOD_NOCARR);
> - break;
> - case PSEV_V24_OFF:
> - pr_debug("%s: pump stev V24 OFF\n", ch->is->name);
> - break;
> - case PSEV_CTS_ON:
> - pr_debug("%s: pump stev CTS ON\n", ch->is->name);
> - break;
> - case PSEV_CTS_OFF:
> - pr_debug("%s pump stev CTS OFF\n", ch->is->name);
> - break;
> - case PSEV_DCD_ON:
> - pr_debug("%s: pump stev CARRIER ON\n", ch->is->name);
> - test_and_set_bit(ISAR_RATE_REQ, &ch->is->Flags);
> - send_mbox(ch->is, dps | ISAR_HIS_PSTREQ, 0, 0, NULL);
> - break;
> - case PSEV_DCD_OFF:
> - pr_debug("%s: pump stev CARRIER OFF\n", ch->is->name);
> - break;
> - case PSEV_DSR_ON:
> - pr_debug("%s: pump stev DSR ON\n", ch->is->name);
> - break;
> - case PSEV_DSR_OFF:
> - pr_debug("%s: pump stev DSR_OFF\n", ch->is->name);
> - break;
> - case PSEV_REM_RET:
> - pr_debug("%s: pump stev REMOTE RETRAIN\n", ch->is->name);
> - break;
> - case PSEV_REM_REN:
> - pr_debug("%s: pump stev REMOTE RENEGOTIATE\n", ch->is->name);
> - break;
> - case PSEV_GSTN_CLR:
> - pr_debug("%s: pump stev GSTN CLEAR\n", ch->is->name);
> - break;
> - default:
> - pr_info("u%s: unknown pump stev %x\n", ch->is->name, devt);
> - break;
> - }
> -}
> -
> -static void
> -isar_pump_statev_fax(struct isar_ch *ch, u8 devt) {
> - u8 dps = SET_DPS(ch->dpath);
> - u8 p1;
> -
> - switch (devt) {
> - case PSEV_10MS_TIMER:
> - pr_debug("%s: pump stev TIMER\n", ch->is->name);
> - break;
> - case PSEV_RSP_READY:
> - pr_debug("%s: pump stev RSP_READY\n", ch->is->name);
> - ch->state = STFAX_READY;
> - deliver_status(ch, HW_MOD_READY);
> -#ifdef AUTOCON
> - if (test_bit(BC_FLG_ORIG, &ch->bch.Flags))
> - isar_pump_cmd(bch, HW_MOD_FRH, 3);
> - else
> - isar_pump_cmd(bch, HW_MOD_FTH, 3);
> -#endif
> - break;
> - case PSEV_LINE_TX_H:
> - if (ch->state == STFAX_LINE) {
> - pr_debug("%s: pump stev LINE_TX_H\n", ch->is->name);
> - ch->state = STFAX_CONT;
> - send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
> - PCTRL_CMD_CONT, 0, NULL);
> - } else {
> - pr_debug("%s: pump stev LINE_TX_H wrong st %x\n",
> - ch->is->name, ch->state);
> - }
> - break;
> - case PSEV_LINE_RX_H:
> - if (ch->state == STFAX_LINE) {
> - pr_debug("%s: pump stev LINE_RX_H\n", ch->is->name);
> - ch->state = STFAX_CONT;
> - send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
> - PCTRL_CMD_CONT, 0, NULL);
> - } else {
> - pr_debug("%s: pump stev LINE_RX_H wrong st %x\n",
> - ch->is->name, ch->state);
> - }
> - break;
> - case PSEV_LINE_TX_B:
> - if (ch->state == STFAX_LINE) {
> - pr_debug("%s: pump stev LINE_TX_B\n", ch->is->name);
> - ch->state = STFAX_CONT;
> - send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
> - PCTRL_CMD_CONT, 0, NULL);
> - } else {
> - pr_debug("%s: pump stev LINE_TX_B wrong st %x\n",
> - ch->is->name, ch->state);
> - }
> - break;
> - case PSEV_LINE_RX_B:
> - if (ch->state == STFAX_LINE) {
> - pr_debug("%s: pump stev LINE_RX_B\n", ch->is->name);
> - ch->state = STFAX_CONT;
> - send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
> - PCTRL_CMD_CONT, 0, NULL);
> - } else {
> - pr_debug("%s: pump stev LINE_RX_B wrong st %x\n",
> - ch->is->name, ch->state);
> - }
> - break;
> - case PSEV_RSP_CONN:
> - if (ch->state == STFAX_CONT) {
> - pr_debug("%s: pump stev RSP_CONN\n", ch->is->name);
> - ch->state = STFAX_ACTIV;
> - test_and_set_bit(ISAR_RATE_REQ, &ch->is->Flags);
> - send_mbox(ch->is, dps | ISAR_HIS_PSTREQ, 0, 0, NULL);
> - if (ch->cmd == PCTRL_CMD_FTH) {
> - int delay = (ch->mod == 3) ? 1000 : 200;
> - /* 1s (200 ms) Flags before data */
> - if (test_and_set_bit(FLG_FTI_RUN,
> - &ch->bch.Flags))
> - timer_delete(&ch->ftimer);
> - ch->ftimer.expires =
> - jiffies + ((delay * HZ) / 1000);
> - test_and_set_bit(FLG_LL_CONN,
> - &ch->bch.Flags);
> - add_timer(&ch->ftimer);
> - } else {
> - deliver_status(ch, HW_MOD_CONNECT);
> - }
> - } else {
> - pr_debug("%s: pump stev RSP_CONN wrong st %x\n",
> - ch->is->name, ch->state);
> - }
> - break;
> - case PSEV_FLAGS_DET:
> - pr_debug("%s: pump stev FLAGS_DET\n", ch->is->name);
> - break;
> - case PSEV_RSP_DISC:
> - pr_debug("%s: pump stev RSP_DISC state(%d)\n",
> - ch->is->name, ch->state);
> - if (ch->state == STFAX_ESCAPE) {
> - p1 = 5;
> - switch (ch->newcmd) {
> - case 0:
> - ch->state = STFAX_READY;
> - break;
> - case PCTRL_CMD_FTM:
> - p1 = 2;
> - fallthrough;
> - case PCTRL_CMD_FTH:
> - send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
> - PCTRL_CMD_SILON, 1, &p1);
> - ch->state = STFAX_SILDET;
> - break;
> - case PCTRL_CMD_FRH:
> - case PCTRL_CMD_FRM:
> - ch->mod = ch->newmod;
> - p1 = ch->newmod;
> - ch->newmod = 0;
> - ch->cmd = ch->newcmd;
> - ch->newcmd = 0;
> - send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
> - ch->cmd, 1, &p1);
> - ch->state = STFAX_LINE;
> - ch->try_mod = 3;
> - break;
> - default:
> - pr_debug("%s: RSP_DISC unknown newcmd %x\n",
> - ch->is->name, ch->newcmd);
> - break;
> - }
> - } else if (ch->state == STFAX_ACTIV) {
> - if (test_and_clear_bit(FLG_LL_OK, &ch->bch.Flags))
> - deliver_status(ch, HW_MOD_OK);
> - else if (ch->cmd == PCTRL_CMD_FRM)
> - deliver_status(ch, HW_MOD_NOCARR);
> - else
> - deliver_status(ch, HW_MOD_FCERROR);
> - ch->state = STFAX_READY;
> - } else if (ch->state != STFAX_SILDET) {
> - /* ignore in STFAX_SILDET */
> - ch->state = STFAX_READY;
> - deliver_status(ch, HW_MOD_FCERROR);
> - }
> - break;
> - case PSEV_RSP_SILDET:
> - pr_debug("%s: pump stev RSP_SILDET\n", ch->is->name);
> - if (ch->state == STFAX_SILDET) {
> - ch->mod = ch->newmod;
> - p1 = ch->newmod;
> - ch->newmod = 0;
> - ch->cmd = ch->newcmd;
> - ch->newcmd = 0;
> - send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
> - ch->cmd, 1, &p1);
> - ch->state = STFAX_LINE;
> - ch->try_mod = 3;
> - }
> - break;
> - case PSEV_RSP_SILOFF:
> - pr_debug("%s: pump stev RSP_SILOFF\n", ch->is->name);
> - break;
> - case PSEV_RSP_FCERR:
> - if (ch->state == STFAX_LINE) {
> - pr_debug("%s: pump stev RSP_FCERR try %d\n",
> - ch->is->name, ch->try_mod);
> - if (ch->try_mod--) {
> - send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
> - ch->cmd, 1, &ch->mod);
> - break;
> - }
> - }
> - pr_debug("%s: pump stev RSP_FCERR\n", ch->is->name);
> - ch->state = STFAX_ESCAPE;
> - send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL, PCTRL_CMD_ESC,
> - 0, NULL);
> - deliver_status(ch, HW_MOD_FCERROR);
> - break;
> - default:
> - break;
> - }
> -}
> -
> -void
> -mISDNisar_irq(struct isar_hw *isar)
> -{
> - struct isar_ch *ch;
> -
> - get_irq_infos(isar);
> - switch (isar->iis & ISAR_IIS_MSCMSD) {
> - case ISAR_IIS_RDATA:
> - ch = sel_bch_isar(isar, isar->iis >> 6);
> - if (ch)
> - isar_rcv_frame(ch);
> - else {
> - pr_debug("%s: ISAR spurious IIS_RDATA %x/%x/%x\n",
> - isar->name, isar->iis, isar->cmsb,
> - isar->clsb);
> - isar->write_reg(isar->hw, ISAR_IIA, 0);
> - }
> - break;
> - case ISAR_IIS_GSTEV:
> - isar->write_reg(isar->hw, ISAR_IIA, 0);
> - isar->bstat |= isar->cmsb;
> - check_send(isar, isar->cmsb);
> - break;
> - case ISAR_IIS_BSTEV:
> -#ifdef ERROR_STATISTIC
> - ch = sel_bch_isar(isar, isar->iis >> 6);
> - if (ch) {
> - if (isar->cmsb == BSTEV_TBO)
> - ch->bch.err_tx++;
> - if (isar->cmsb == BSTEV_RBO)
> - ch->bch.err_rdo++;
> - }
> -#endif
> - pr_debug("%s: Buffer STEV dpath%d msb(%x)\n",
> - isar->name, isar->iis >> 6, isar->cmsb);
> - isar->write_reg(isar->hw, ISAR_IIA, 0);
> - break;
> - case ISAR_IIS_PSTEV:
> - ch = sel_bch_isar(isar, isar->iis >> 6);
> - if (ch) {
> - rcv_mbox(isar, NULL);
> - if (ch->bch.state == ISDN_P_B_MODEM_ASYNC)
> - isar_pump_statev_modem(ch, isar->cmsb);
> - else if (ch->bch.state == ISDN_P_B_T30_FAX)
> - isar_pump_statev_fax(ch, isar->cmsb);
> - else if (ch->bch.state == ISDN_P_B_RAW) {
> - int tt;
> - tt = isar->cmsb | 0x30;
> - if (tt == 0x3e)
> - tt = '*';
> - else if (tt == 0x3f)
> - tt = '#';
> - else if (tt > '9')
> - tt += 7;
> - tt |= DTMF_TONE_VAL;
> - _queue_data(&ch->bch.ch, PH_CONTROL_IND,
> - MISDN_ID_ANY, sizeof(tt), &tt,
> - GFP_ATOMIC);
> - } else
> - pr_debug("%s: ISAR IIS_PSTEV pm %d sta %x\n",
> - isar->name, ch->bch.state,
> - isar->cmsb);
> - } else {
> - pr_debug("%s: ISAR spurious IIS_PSTEV %x/%x/%x\n",
> - isar->name, isar->iis, isar->cmsb,
> - isar->clsb);
> - isar->write_reg(isar->hw, ISAR_IIA, 0);
> - }
> - break;
> - case ISAR_IIS_PSTRSP:
> - ch = sel_bch_isar(isar, isar->iis >> 6);
> - if (ch) {
> - rcv_mbox(isar, NULL);
> - isar_pump_status_rsp(ch);
> - } else {
> - pr_debug("%s: ISAR spurious IIS_PSTRSP %x/%x/%x\n",
> - isar->name, isar->iis, isar->cmsb,
> - isar->clsb);
> - isar->write_reg(isar->hw, ISAR_IIA, 0);
> - }
> - break;
> - case ISAR_IIS_DIAG:
> - case ISAR_IIS_BSTRSP:
> - case ISAR_IIS_IOM2RSP:
> - rcv_mbox(isar, NULL);
> - break;
> - case ISAR_IIS_INVMSG:
> - rcv_mbox(isar, NULL);
> - pr_debug("%s: invalid msg his:%x\n", isar->name, isar->cmsb);
> - break;
> - default:
> - rcv_mbox(isar, NULL);
> - pr_debug("%s: unhandled msg iis(%x) ctrl(%x/%x)\n",
> - isar->name, isar->iis, isar->cmsb, isar->clsb);
> - break;
> - }
> -}
> -EXPORT_SYMBOL(mISDNisar_irq);
> -
> -static void
> -ftimer_handler(struct timer_list *t)
> -{
> - struct isar_ch *ch = timer_container_of(ch, t, ftimer);
> -
> - pr_debug("%s: ftimer flags %lx\n", ch->is->name, ch->bch.Flags);
> - test_and_clear_bit(FLG_FTI_RUN, &ch->bch.Flags);
> - if (test_and_clear_bit(FLG_LL_CONN, &ch->bch.Flags))
> - deliver_status(ch, HW_MOD_CONNECT);
> -}
> -
> -static void
> -setup_pump(struct isar_ch *ch) {
> - u8 dps = SET_DPS(ch->dpath);
> - u8 ctrl, param[6];
> -
> - switch (ch->bch.state) {
> - case ISDN_P_NONE:
> - case ISDN_P_B_RAW:
> - case ISDN_P_B_HDLC:
> - send_mbox(ch->is, dps | ISAR_HIS_PUMPCFG, PMOD_BYPASS, 0, NULL);
> - break;
> - case ISDN_P_B_L2DTMF:
> - if (test_bit(FLG_DTMFSEND, &ch->bch.Flags)) {
> - param[0] = 5; /* TOA 5 db */
> - send_mbox(ch->is, dps | ISAR_HIS_PUMPCFG,
> - PMOD_DTMF_TRANS, 1, param);
> - } else {
> - param[0] = 40; /* REL -46 dbm */
> - send_mbox(ch->is, dps | ISAR_HIS_PUMPCFG,
> - PMOD_DTMF, 1, param);
> - }
> - fallthrough;
> - case ISDN_P_B_MODEM_ASYNC:
> - ctrl = PMOD_DATAMODEM;
> - if (test_bit(FLG_ORIGIN, &ch->bch.Flags)) {
> - ctrl |= PCTRL_ORIG;
> - param[5] = PV32P6_CTN;
> - } else {
> - param[5] = PV32P6_ATN;
> - }
> - param[0] = 6; /* 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;
> - send_mbox(ch->is, dps | ISAR_HIS_PUMPCFG, ctrl, 6, param);
> - break;
> - case ISDN_P_B_T30_FAX:
> - ctrl = PMOD_FAX;
> - if (test_bit(FLG_ORIGIN, &ch->bch.Flags)) {
> - ctrl |= PCTRL_ORIG;
> - param[1] = PFAXP2_CTN;
> - } else {
> - param[1] = PFAXP2_ATN;
> - }
> - param[0] = 6; /* 6 db */
> - send_mbox(ch->is, dps | ISAR_HIS_PUMPCFG, ctrl, 2, param);
> - ch->state = STFAX_NULL;
> - ch->newcmd = 0;
> - ch->newmod = 0;
> - test_and_set_bit(FLG_FTI_RUN, &ch->bch.Flags);
> - break;
> - }
> - udelay(1000);
> - send_mbox(ch->is, dps | ISAR_HIS_PSTREQ, 0, 0, NULL);
> - udelay(1000);
> -}
> -
> -static void
> -setup_sart(struct isar_ch *ch) {
> - u8 dps = SET_DPS(ch->dpath);
> - u8 ctrl, param[2] = {0, 0};
> -
> - switch (ch->bch.state) {
> - case ISDN_P_NONE:
> - send_mbox(ch->is, dps | ISAR_HIS_SARTCFG, SMODE_DISABLE,
> - 0, NULL);
> - break;
> - case ISDN_P_B_RAW:
> - case ISDN_P_B_L2DTMF:
> - send_mbox(ch->is, dps | ISAR_HIS_SARTCFG, SMODE_BINARY,
> - 2, param);
> - break;
> - case ISDN_P_B_HDLC:
> - case ISDN_P_B_T30_FAX:
> - send_mbox(ch->is, dps | ISAR_HIS_SARTCFG, SMODE_HDLC,
> - 1, param);
> - break;
> - case ISDN_P_B_MODEM_ASYNC:
> - ctrl = SMODE_V14 | SCTRL_HDMC_BOTH;
> - param[0] = S_P1_CHS_8;
> - param[1] = S_P2_BFT_DEF;
> - send_mbox(ch->is, dps | ISAR_HIS_SARTCFG, ctrl, 2, param);
> - break;
> - }
> - udelay(1000);
> - send_mbox(ch->is, dps | ISAR_HIS_BSTREQ, 0, 0, NULL);
> - udelay(1000);
> -}
> -
> -static void
> -setup_iom2(struct isar_ch *ch) {
> - u8 dps = SET_DPS(ch->dpath);
> - u8 cmsb = IOM_CTRL_ENA, msg[5] = {IOM_P1_TXD, 0, 0, 0, 0};
> -
> - if (ch->bch.nr == 2) {
> - msg[1] = 1;
> - msg[3] = 1;
> - }
> - switch (ch->bch.state) {
> - case ISDN_P_NONE:
> - cmsb = 0;
> - /* dummy slot */
> - msg[1] = ch->dpath + 2;
> - msg[3] = ch->dpath + 2;
> - break;
> - case ISDN_P_B_RAW:
> - case ISDN_P_B_HDLC:
> - break;
> - case ISDN_P_B_MODEM_ASYNC:
> - case ISDN_P_B_T30_FAX:
> - cmsb |= IOM_CTRL_RCV;
> - fallthrough;
> - case ISDN_P_B_L2DTMF:
> - if (test_bit(FLG_DTMFSEND, &ch->bch.Flags))
> - cmsb |= IOM_CTRL_RCV;
> - cmsb |= IOM_CTRL_ALAW;
> - break;
> - }
> - send_mbox(ch->is, dps | ISAR_HIS_IOM2CFG, cmsb, 5, msg);
> - udelay(1000);
> - send_mbox(ch->is, dps | ISAR_HIS_IOM2REQ, 0, 0, NULL);
> - udelay(1000);
> -}
> -
> -static int
> -modeisar(struct isar_ch *ch, u32 bprotocol)
> -{
> - /* Here we are selecting the best datapath for requested protocol */
> - if (ch->bch.state == ISDN_P_NONE) { /* New Setup */
> - switch (bprotocol) {
> - case ISDN_P_NONE: /* init */
> - if (!ch->dpath)
> - /* no init for dpath 0 */
> - return 0;
> - test_and_clear_bit(FLG_HDLC, &ch->bch.Flags);
> - test_and_clear_bit(FLG_TRANSPARENT, &ch->bch.Flags);
> - break;
> - case ISDN_P_B_RAW:
> - case ISDN_P_B_HDLC:
> - /* best is datapath 2 */
> - if (!test_and_set_bit(ISAR_DP2_USE, &ch->is->Flags))
> - ch->dpath = 2;
> - else if (!test_and_set_bit(ISAR_DP1_USE,
> - &ch->is->Flags))
> - ch->dpath = 1;
> - else {
> - pr_info("modeisar both paths in use\n");
> - return -EBUSY;
> - }
> - if (bprotocol == ISDN_P_B_HDLC)
> - test_and_set_bit(FLG_HDLC, &ch->bch.Flags);
> - else
> - test_and_set_bit(FLG_TRANSPARENT,
> - &ch->bch.Flags);
> - break;
> - case ISDN_P_B_MODEM_ASYNC:
> - case ISDN_P_B_T30_FAX:
> - case ISDN_P_B_L2DTMF:
> - /* only datapath 1 */
> - if (!test_and_set_bit(ISAR_DP1_USE, &ch->is->Flags))
> - ch->dpath = 1;
> - else {
> - pr_info("%s: ISAR modeisar analog functions"
> - "only with DP1\n", ch->is->name);
> - return -EBUSY;
> - }
> - break;
> - default:
> - pr_info("%s: protocol not known %x\n", ch->is->name,
> - bprotocol);
> - return -ENOPROTOOPT;
> - }
> - }
> - pr_debug("%s: ISAR ch%d dp%d protocol %x->%x\n", ch->is->name,
> - ch->bch.nr, ch->dpath, ch->bch.state, bprotocol);
> - ch->bch.state = bprotocol;
> - setup_pump(ch);
> - setup_iom2(ch);
> - setup_sart(ch);
> - if (ch->bch.state == ISDN_P_NONE) {
> - /* Clear resources */
> - if (ch->dpath == 1)
> - test_and_clear_bit(ISAR_DP1_USE, &ch->is->Flags);
> - else if (ch->dpath == 2)
> - test_and_clear_bit(ISAR_DP2_USE, &ch->is->Flags);
> - ch->dpath = 0;
> - ch->is->ctrl(ch->is->hw, HW_DEACT_IND, ch->bch.nr);
> - } else
> - ch->is->ctrl(ch->is->hw, HW_ACTIVATE_IND, ch->bch.nr);
> - return 0;
> -}
> -
> -static void
> -isar_pump_cmd(struct isar_ch *ch, u32 cmd, u8 para)
> -{
> - u8 dps = SET_DPS(ch->dpath);
> - u8 ctrl = 0, nom = 0, p1 = 0;
> -
> - pr_debug("%s: isar_pump_cmd %x/%x state(%x)\n",
> - ch->is->name, cmd, para, ch->bch.state);
> - switch (cmd) {
> - case HW_MOD_FTM:
> - if (ch->state == STFAX_READY) {
> - p1 = para;
> - ctrl = PCTRL_CMD_FTM;
> - nom = 1;
> - ch->state = STFAX_LINE;
> - ch->cmd = ctrl;
> - ch->mod = para;
> - ch->newmod = 0;
> - ch->newcmd = 0;
> - ch->try_mod = 3;
> - } else if ((ch->state == STFAX_ACTIV) &&
> - (ch->cmd == PCTRL_CMD_FTM) && (ch->mod == para))
> - deliver_status(ch, HW_MOD_CONNECT);
> - else {
> - ch->newmod = para;
> - ch->newcmd = PCTRL_CMD_FTM;
> - nom = 0;
> - ctrl = PCTRL_CMD_ESC;
> - ch->state = STFAX_ESCAPE;
> - }
> - break;
> - case HW_MOD_FTH:
> - if (ch->state == STFAX_READY) {
> - p1 = para;
> - ctrl = PCTRL_CMD_FTH;
> - nom = 1;
> - ch->state = STFAX_LINE;
> - ch->cmd = ctrl;
> - ch->mod = para;
> - ch->newmod = 0;
> - ch->newcmd = 0;
> - ch->try_mod = 3;
> - } else if ((ch->state == STFAX_ACTIV) &&
> - (ch->cmd == PCTRL_CMD_FTH) && (ch->mod == para))
> - deliver_status(ch, HW_MOD_CONNECT);
> - else {
> - ch->newmod = para;
> - ch->newcmd = PCTRL_CMD_FTH;
> - nom = 0;
> - ctrl = PCTRL_CMD_ESC;
> - ch->state = STFAX_ESCAPE;
> - }
> - break;
> - case HW_MOD_FRM:
> - if (ch->state == STFAX_READY) {
> - p1 = para;
> - ctrl = PCTRL_CMD_FRM;
> - nom = 1;
> - ch->state = STFAX_LINE;
> - ch->cmd = ctrl;
> - ch->mod = para;
> - ch->newmod = 0;
> - ch->newcmd = 0;
> - ch->try_mod = 3;
> - } else if ((ch->state == STFAX_ACTIV) &&
> - (ch->cmd == PCTRL_CMD_FRM) && (ch->mod == para))
> - deliver_status(ch, HW_MOD_CONNECT);
> - else {
> - ch->newmod = para;
> - ch->newcmd = PCTRL_CMD_FRM;
> - nom = 0;
> - ctrl = PCTRL_CMD_ESC;
> - ch->state = STFAX_ESCAPE;
> - }
> - break;
> - case HW_MOD_FRH:
> - if (ch->state == STFAX_READY) {
> - p1 = para;
> - ctrl = PCTRL_CMD_FRH;
> - nom = 1;
> - ch->state = STFAX_LINE;
> - ch->cmd = ctrl;
> - ch->mod = para;
> - ch->newmod = 0;
> - ch->newcmd = 0;
> - ch->try_mod = 3;
> - } else if ((ch->state == STFAX_ACTIV) &&
> - (ch->cmd == PCTRL_CMD_FRH) && (ch->mod == para))
> - deliver_status(ch, HW_MOD_CONNECT);
> - else {
> - ch->newmod = para;
> - ch->newcmd = PCTRL_CMD_FRH;
> - nom = 0;
> - ctrl = PCTRL_CMD_ESC;
> - ch->state = STFAX_ESCAPE;
> - }
> - break;
> - case PCTRL_CMD_TDTMF:
> - p1 = para;
> - nom = 1;
> - ctrl = PCTRL_CMD_TDTMF;
> - break;
> - }
> - if (ctrl)
> - send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL, ctrl, nom, &p1);
> -}
> -
> -static void
> -isar_setup(struct isar_hw *isar)
> -{
> - u8 msg;
> - int i;
> -
> - /* Dpath 1, 2 */
> - msg = 61;
> - for (i = 0; i < 2; i++) {
> - /* Buffer Config */
> - send_mbox(isar, (i ? ISAR_HIS_DPS2 : ISAR_HIS_DPS1) |
> - ISAR_HIS_P12CFG, 4, 1, &msg);
> - isar->ch[i].mml = msg;
> - isar->ch[i].bch.state = 0;
> - isar->ch[i].dpath = i + 1;
> - modeisar(&isar->ch[i], ISDN_P_NONE);
> - }
> -}
> -
> -static int
> -isar_l2l1(struct mISDNchannel *ch, struct sk_buff *skb)
> -{
> - struct bchannel *bch = container_of(ch, struct bchannel, ch);
> - struct isar_ch *ich = container_of(bch, struct isar_ch, bch);
> - int ret = -EINVAL;
> - struct mISDNhead *hh = mISDN_HEAD_P(skb);
> - u32 id, *val;
> - u_long flags;
> -
> - switch (hh->prim) {
> - case PH_DATA_REQ:
> - spin_lock_irqsave(ich->is->hwlock, flags);
> - ret = bchannel_senddata(bch, skb);
> - if (ret > 0) { /* direct TX */
> - ret = 0;
> - isar_fill_fifo(ich);
> - }
> - spin_unlock_irqrestore(ich->is->hwlock, flags);
> - return ret;
> - case PH_ACTIVATE_REQ:
> - spin_lock_irqsave(ich->is->hwlock, flags);
> - if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags))
> - ret = modeisar(ich, ch->protocol);
> - else
> - ret = 0;
> - spin_unlock_irqrestore(ich->is->hwlock, flags);
> - if (!ret)
> - _queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
> - NULL, GFP_KERNEL);
> - break;
> - case PH_DEACTIVATE_REQ:
> - spin_lock_irqsave(ich->is->hwlock, flags);
> - mISDN_clear_bchannel(bch);
> - modeisar(ich, ISDN_P_NONE);
> - spin_unlock_irqrestore(ich->is->hwlock, flags);
> - _queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
> - NULL, GFP_KERNEL);
> - ret = 0;
> - break;
> - case PH_CONTROL_REQ:
> - val = (u32 *)skb->data;
> - pr_debug("%s: PH_CONTROL | REQUEST %x/%x\n", ich->is->name,
> - hh->id, *val);
> - if ((hh->id == 0) && ((*val & ~DTMF_TONE_MASK) ==
> - DTMF_TONE_VAL)) {
> - if (bch->state == ISDN_P_B_L2DTMF) {
> - char tt = *val & DTMF_TONE_MASK;
> -
> - if (tt == '*')
> - tt = 0x1e;
> - else if (tt == '#')
> - tt = 0x1f;
> - else if (tt > '9')
> - tt -= 7;
> - tt &= 0x1f;
> - spin_lock_irqsave(ich->is->hwlock, flags);
> - isar_pump_cmd(ich, PCTRL_CMD_TDTMF, tt);
> - spin_unlock_irqrestore(ich->is->hwlock, flags);
> - } else {
> - pr_info("%s: DTMF send wrong protocol %x\n",
> - __func__, bch->state);
> - return -EINVAL;
> - }
> - } else if ((hh->id == HW_MOD_FRM) || (hh->id == HW_MOD_FRH) ||
> - (hh->id == HW_MOD_FTM) || (hh->id == HW_MOD_FTH)) {
> - for (id = 0; id < FAXMODCNT; id++)
> - if (faxmodulation[id] == *val)
> - break;
> - if ((FAXMODCNT > id) &&
> - test_bit(FLG_INITIALIZED, &bch->Flags)) {
> - pr_debug("%s: isar: new mod\n", ich->is->name);
> - isar_pump_cmd(ich, hh->id, *val);
> - ret = 0;
> - } else {
> - pr_info("%s: wrong modulation\n",
> - ich->is->name);
> - ret = -EINVAL;
> - }
> - } else if (hh->id == HW_MOD_LASTDATA)
> - test_and_set_bit(FLG_DLEETX, &bch->Flags);
> - else {
> - pr_info("%s: unknown PH_CONTROL_REQ %x\n",
> - ich->is->name, hh->id);
> - ret = -EINVAL;
> - }
> - fallthrough;
> - default:
> - pr_info("%s: %s unknown prim(%x,%x)\n",
> - ich->is->name, __func__, hh->prim, hh->id);
> - ret = -EINVAL;
> - }
> - if (!ret)
> - dev_kfree_skb(skb);
> - return ret;
> -}
> -
> -static int
> -channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
> -{
> - return mISDN_ctrl_bchannel(bch, cq);
> -}
> -
> -static int
> -isar_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
> -{
> - struct bchannel *bch = container_of(ch, struct bchannel, ch);
> - struct isar_ch *ich = container_of(bch, struct isar_ch, bch);
> - int ret = -EINVAL;
> - u_long flags;
> -
> - pr_debug("%s: %s cmd:%x %p\n", ich->is->name, __func__, cmd, arg);
> - switch (cmd) {
> - case CLOSE_CHANNEL:
> - test_and_clear_bit(FLG_OPEN, &bch->Flags);
> - cancel_work_sync(&bch->workq);
> - spin_lock_irqsave(ich->is->hwlock, flags);
> - mISDN_clear_bchannel(bch);
> - modeisar(ich, ISDN_P_NONE);
> - spin_unlock_irqrestore(ich->is->hwlock, flags);
> - ch->protocol = ISDN_P_NONE;
> - ch->peer = NULL;
> - module_put(ich->is->owner);
> - ret = 0;
> - break;
> - case CONTROL_CHANNEL:
> - ret = channel_bctrl(bch, arg);
> - break;
> - default:
> - pr_info("%s: %s unknown prim(%x)\n",
> - ich->is->name, __func__, cmd);
> - }
> - return ret;
> -}
> -
> -static void
> -free_isar(struct isar_hw *isar)
> -{
> - modeisar(&isar->ch[0], ISDN_P_NONE);
> - modeisar(&isar->ch[1], ISDN_P_NONE);
> - timer_delete(&isar->ch[0].ftimer);
> - timer_delete(&isar->ch[1].ftimer);
> - test_and_clear_bit(FLG_INITIALIZED, &isar->ch[0].bch.Flags);
> - test_and_clear_bit(FLG_INITIALIZED, &isar->ch[1].bch.Flags);
> -}
> -
> -static int
> -init_isar(struct isar_hw *isar)
> -{
> - int cnt = 3;
> -
> - while (cnt--) {
> - isar->version = ISARVersion(isar);
> - if (isar->ch[0].bch.debug & DEBUG_HW)
> - pr_notice("%s: Testing version %d (%d time)\n",
> - isar->name, isar->version, 3 - cnt);
> - if (isar->version == 1)
> - break;
> - isar->ctrl(isar->hw, HW_RESET_REQ, 0);
> - }
> - if (isar->version != 1)
> - return -EINVAL;
> - timer_setup(&isar->ch[0].ftimer, ftimer_handler, 0);
> - test_and_set_bit(FLG_INITIALIZED, &isar->ch[0].bch.Flags);
> - timer_setup(&isar->ch[1].ftimer, ftimer_handler, 0);
> - test_and_set_bit(FLG_INITIALIZED, &isar->ch[1].bch.Flags);
> - return 0;
> -}
> -
> -static int
> -isar_open(struct isar_hw *isar, struct channel_req *rq)
> -{
> - struct bchannel *bch;
> -
> - if (rq->adr.channel == 0 || rq->adr.channel > 2)
> - return -EINVAL;
> - if (rq->protocol == ISDN_P_NONE)
> - return -EINVAL;
> - bch = &isar->ch[rq->adr.channel - 1].bch;
> - if (test_and_set_bit(FLG_OPEN, &bch->Flags))
> - return -EBUSY; /* b-channel can be only open once */
> - bch->ch.protocol = rq->protocol;
> - rq->ch = &bch->ch;
> - return 0;
> -}
> -
> -u32
> -mISDNisar_init(struct isar_hw *isar, void *hw)
> -{
> - u32 ret, i;
> -
> - isar->hw = hw;
> - for (i = 0; i < 2; i++) {
> - isar->ch[i].bch.nr = i + 1;
> - mISDN_initbchannel(&isar->ch[i].bch, MAX_DATA_MEM, 32);
> - isar->ch[i].bch.ch.nr = i + 1;
> - isar->ch[i].bch.ch.send = &isar_l2l1;
> - isar->ch[i].bch.ch.ctrl = isar_bctrl;
> - isar->ch[i].bch.hw = hw;
> - isar->ch[i].is = isar;
> - }
> -
> - isar->init = &init_isar;
> - isar->release = &free_isar;
> - isar->firmware = &load_firmware;
> - isar->open = &isar_open;
> -
> - ret = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
> - (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK)) |
> - (1 << (ISDN_P_B_L2DTMF & ISDN_P_B_MASK)) |
> - (1 << (ISDN_P_B_MODEM_ASYNC & ISDN_P_B_MASK)) |
> - (1 << (ISDN_P_B_T30_FAX & ISDN_P_B_MASK));
> -
> - return ret;
> -}
> -EXPORT_SYMBOL(mISDNisar_init);
> -
> -static int __init isar_mod_init(void)
> -{
> - pr_notice("mISDN: ISAR driver Rev. %s\n", ISAR_REV);
> - return 0;
> -}
> -
> -static void __exit isar_mod_cleanup(void)
> -{
> - pr_notice("mISDN: ISAR module unloaded\n");
> -}
> -module_init(isar_mod_init);
> -module_exit(isar_mod_cleanup);
> diff --git a/drivers/isdn/hardware/mISDN/netjet.c b/drivers/isdn/hardware/mISDN/netjet.c
> deleted file mode 100644
> index 8d740d8eacec..000000000000
> --- a/drivers/isdn/hardware/mISDN/netjet.c
> +++ /dev/null
> @@ -1,1154 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * NETJet mISDN driver
> - *
> - * Author Karsten Keil <keil@isdn4linux.de>
> - *
> - * Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
> - */
> -
> -#include <linux/interrupt.h>
> -#include <linux/module.h>
> -#include <linux/pci.h>
> -#include <linux/delay.h>
> -#include <linux/mISDNhw.h>
> -#include <linux/slab.h>
> -#include "ipac.h"
> -#include "iohelper.h"
> -#include "netjet.h"
> -#include "isdnhdlc.h"
> -
> -#define NETJET_REV "2.0"
> -
> -enum nj_types {
> - NETJET_S_TJ300,
> - NETJET_S_TJ320,
> - ENTERNOW__TJ320,
> -};
> -
> -struct tiger_dma {
> - size_t size;
> - u32 *start;
> - int idx;
> - u32 dmastart;
> - u32 dmairq;
> - u32 dmaend;
> - u32 dmacur;
> -};
> -
> -struct tiger_hw;
> -
> -struct tiger_ch {
> - struct bchannel bch;
> - struct tiger_hw *nj;
> - int idx;
> - int free;
> - int lastrx;
> - u16 rxstate;
> - u16 txstate;
> - struct isdnhdlc_vars hsend;
> - struct isdnhdlc_vars hrecv;
> - u8 *hsbuf;
> - u8 *hrbuf;
> -};
> -
> -#define TX_INIT 0x0001
> -#define TX_IDLE 0x0002
> -#define TX_RUN 0x0004
> -#define TX_UNDERRUN 0x0100
> -#define RX_OVERRUN 0x0100
> -
> -#define LOG_SIZE 64
> -
> -struct tiger_hw {
> - struct list_head list;
> - struct pci_dev *pdev;
> - char name[MISDN_MAX_IDLEN];
> - enum nj_types typ;
> - int irq;
> - u32 irqcnt;
> - u32 base;
> - size_t base_s;
> - dma_addr_t dma;
> - void *dma_p;
> - spinlock_t lock; /* lock HW */
> - struct isac_hw isac;
> - struct tiger_dma send;
> - struct tiger_dma recv;
> - struct tiger_ch bc[2];
> - u8 ctrlreg;
> - u8 dmactrl;
> - u8 auxd;
> - u8 last_is0;
> - u8 irqmask0;
> - char log[LOG_SIZE];
> -};
> -
> -static LIST_HEAD(Cards);
> -static DEFINE_RWLOCK(card_lock); /* protect Cards */
> -static u32 debug;
> -static int nj_cnt;
> -
> -static void
> -_set_debug(struct tiger_hw *card)
> -{
> - card->isac.dch.debug = debug;
> - card->bc[0].bch.debug = debug;
> - card->bc[1].bch.debug = debug;
> -}
> -
> -static int
> -set_debug(const char *val, const struct kernel_param *kp)
> -{
> - int ret;
> - struct tiger_hw *card;
> -
> - ret = param_set_uint(val, kp);
> - if (!ret) {
> - read_lock(&card_lock);
> - list_for_each_entry(card, &Cards, list)
> - _set_debug(card);
> - read_unlock(&card_lock);
> - }
> - return ret;
> -}
> -
> -MODULE_AUTHOR("Karsten Keil");
> -MODULE_DESCRIPTION("mISDN driver for NETJet cards");
> -MODULE_LICENSE("GPL v2");
> -MODULE_VERSION(NETJET_REV);
> -module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR);
> -MODULE_PARM_DESC(debug, "Netjet debug mask");
> -
> -static void
> -nj_disable_hwirq(struct tiger_hw *card)
> -{
> - outb(0, card->base + NJ_IRQMASK0);
> - outb(0, card->base + NJ_IRQMASK1);
> -}
> -
> -
> -static u8
> -ReadISAC_nj(void *p, u8 offset)
> -{
> - struct tiger_hw *card = p;
> - u8 ret;
> -
> - card->auxd &= 0xfc;
> - card->auxd |= (offset >> 4) & 3;
> - outb(card->auxd, card->base + NJ_AUXDATA);
> - ret = inb(card->base + NJ_ISAC_OFF + ((offset & 0x0f) << 2));
> - return ret;
> -}
> -
> -static void
> -WriteISAC_nj(void *p, u8 offset, u8 value)
> -{
> - struct tiger_hw *card = p;
> -
> - card->auxd &= 0xfc;
> - card->auxd |= (offset >> 4) & 3;
> - outb(card->auxd, card->base + NJ_AUXDATA);
> - outb(value, card->base + NJ_ISAC_OFF + ((offset & 0x0f) << 2));
> -}
> -
> -static void
> -ReadFiFoISAC_nj(void *p, u8 offset, u8 *data, int size)
> -{
> - struct tiger_hw *card = p;
> -
> - card->auxd &= 0xfc;
> - outb(card->auxd, card->base + NJ_AUXDATA);
> - insb(card->base + NJ_ISAC_OFF, data, size);
> -}
> -
> -static void
> -WriteFiFoISAC_nj(void *p, u8 offset, u8 *data, int size)
> -{
> - struct tiger_hw *card = p;
> -
> - card->auxd &= 0xfc;
> - outb(card->auxd, card->base + NJ_AUXDATA);
> - outsb(card->base + NJ_ISAC_OFF, data, size);
> -}
> -
> -static void
> -fill_mem(struct tiger_ch *bc, u32 idx, u32 cnt, u32 fill)
> -{
> - struct tiger_hw *card = bc->bch.hw;
> - u32 mask = 0xff, val;
> -
> - pr_debug("%s: B%1d fill %02x len %d idx %d/%d\n", card->name,
> - bc->bch.nr, fill, cnt, idx, card->send.idx);
> - if (bc->bch.nr & 2) {
> - fill <<= 8;
> - mask <<= 8;
> - }
> - mask ^= 0xffffffff;
> - while (cnt--) {
> - val = card->send.start[idx];
> - val &= mask;
> - val |= fill;
> - card->send.start[idx++] = val;
> - if (idx >= card->send.size)
> - idx = 0;
> - }
> -}
> -
> -static int
> -mode_tiger(struct tiger_ch *bc, u32 protocol)
> -{
> - struct tiger_hw *card = bc->bch.hw;
> -
> - pr_debug("%s: B%1d protocol %x-->%x\n", card->name,
> - bc->bch.nr, bc->bch.state, protocol);
> - switch (protocol) {
> - case ISDN_P_NONE:
> - if (bc->bch.state == ISDN_P_NONE)
> - break;
> - fill_mem(bc, 0, card->send.size, 0xff);
> - bc->bch.state = protocol;
> - /* only stop dma and interrupts if both channels NULL */
> - if ((card->bc[0].bch.state == ISDN_P_NONE) &&
> - (card->bc[1].bch.state == ISDN_P_NONE)) {
> - card->dmactrl = 0;
> - outb(card->dmactrl, card->base + NJ_DMACTRL);
> - outb(0, card->base + NJ_IRQMASK0);
> - }
> - test_and_clear_bit(FLG_HDLC, &bc->bch.Flags);
> - test_and_clear_bit(FLG_TRANSPARENT, &bc->bch.Flags);
> - bc->txstate = 0;
> - bc->rxstate = 0;
> - bc->lastrx = -1;
> - break;
> - case ISDN_P_B_RAW:
> - test_and_set_bit(FLG_TRANSPARENT, &bc->bch.Flags);
> - bc->bch.state = protocol;
> - bc->idx = 0;
> - bc->free = card->send.size / 2;
> - bc->rxstate = 0;
> - bc->txstate = TX_INIT | TX_IDLE;
> - bc->lastrx = -1;
> - if (!card->dmactrl) {
> - card->dmactrl = 1;
> - outb(card->dmactrl, card->base + NJ_DMACTRL);
> - outb(0x0f, card->base + NJ_IRQMASK0);
> - }
> - break;
> - case ISDN_P_B_HDLC:
> - test_and_set_bit(FLG_HDLC, &bc->bch.Flags);
> - bc->bch.state = protocol;
> - bc->idx = 0;
> - bc->free = card->send.size / 2;
> - bc->rxstate = 0;
> - bc->txstate = TX_INIT | TX_IDLE;
> - isdnhdlc_rcv_init(&bc->hrecv, 0);
> - isdnhdlc_out_init(&bc->hsend, 0);
> - bc->lastrx = -1;
> - if (!card->dmactrl) {
> - card->dmactrl = 1;
> - outb(card->dmactrl, card->base + NJ_DMACTRL);
> - outb(0x0f, card->base + NJ_IRQMASK0);
> - }
> - break;
> - default:
> - pr_info("%s: %s protocol %x not handled\n", card->name,
> - __func__, protocol);
> - return -ENOPROTOOPT;
> - }
> - card->send.dmacur = inl(card->base + NJ_DMA_READ_ADR);
> - card->recv.dmacur = inl(card->base + NJ_DMA_WRITE_ADR);
> - card->send.idx = (card->send.dmacur - card->send.dmastart) >> 2;
> - card->recv.idx = (card->recv.dmacur - card->recv.dmastart) >> 2;
> - pr_debug("%s: %s ctrl %x irq %02x/%02x idx %d/%d\n",
> - card->name, __func__,
> - inb(card->base + NJ_DMACTRL),
> - inb(card->base + NJ_IRQMASK0),
> - inb(card->base + NJ_IRQSTAT0),
> - card->send.idx,
> - card->recv.idx);
> - return 0;
> -}
> -
> -static void
> -nj_reset(struct tiger_hw *card)
> -{
> - outb(0xff, card->base + NJ_CTRL); /* Reset On */
> - mdelay(1);
> -
> - /* now edge triggered for TJ320 GE 13/07/00 */
> - /* see comment in IRQ function */
> - if (card->typ == NETJET_S_TJ320) /* TJ320 */
> - card->ctrlreg = 0x40; /* Reset Off and status read clear */
> - else
> - card->ctrlreg = 0x00; /* Reset Off and status read clear */
> - outb(card->ctrlreg, card->base + NJ_CTRL);
> - mdelay(10);
> -
> - /* configure AUX pins (all output except ISAC IRQ pin) */
> - card->auxd = 0;
> - card->dmactrl = 0;
> - outb(~NJ_ISACIRQ, card->base + NJ_AUXCTRL);
> - outb(NJ_ISACIRQ, card->base + NJ_IRQMASK1);
> - outb(card->auxd, card->base + NJ_AUXDATA);
> -}
> -
> -static int
> -inittiger(struct tiger_hw *card)
> -{
> - int i;
> -
> - card->dma_p = dma_alloc_coherent(&card->pdev->dev, NJ_DMA_SIZE,
> - &card->dma, GFP_ATOMIC);
> - if (!card->dma_p) {
> - pr_info("%s: No DMA memory\n", card->name);
> - return -ENOMEM;
> - }
> - if ((u64)card->dma > 0xffffffff) {
> - pr_info("%s: DMA outside 32 bit\n", card->name);
> - return -ENOMEM;
> - }
> - for (i = 0; i < 2; i++) {
> - card->bc[i].hsbuf = kmalloc(NJ_DMA_TXSIZE, GFP_ATOMIC);
> - if (!card->bc[i].hsbuf) {
> - pr_info("%s: no B%d send buffer\n", card->name, i + 1);
> - return -ENOMEM;
> - }
> - card->bc[i].hrbuf = kmalloc(NJ_DMA_RXSIZE, GFP_ATOMIC);
> - if (!card->bc[i].hrbuf) {
> - pr_info("%s: no B%d recv buffer\n", card->name, i + 1);
> - return -ENOMEM;
> - }
> - }
> - memset(card->dma_p, 0xff, NJ_DMA_SIZE);
> -
> - card->send.start = card->dma_p;
> - card->send.dmastart = (u32)card->dma;
> - card->send.dmaend = card->send.dmastart +
> - (4 * (NJ_DMA_TXSIZE - 1));
> - card->send.dmairq = card->send.dmastart +
> - (4 * ((NJ_DMA_TXSIZE / 2) - 1));
> - card->send.size = NJ_DMA_TXSIZE;
> -
> - if (debug & DEBUG_HW)
> - pr_notice("%s: send buffer phy %#x - %#x - %#x virt %p"
> - " size %zu u32\n", card->name,
> - card->send.dmastart, card->send.dmairq,
> - card->send.dmaend, card->send.start, card->send.size);
> -
> - outl(card->send.dmastart, card->base + NJ_DMA_READ_START);
> - outl(card->send.dmairq, card->base + NJ_DMA_READ_IRQ);
> - outl(card->send.dmaend, card->base + NJ_DMA_READ_END);
> -
> - card->recv.start = card->dma_p + (NJ_DMA_SIZE / 2);
> - card->recv.dmastart = (u32)card->dma + (NJ_DMA_SIZE / 2);
> - card->recv.dmaend = card->recv.dmastart +
> - (4 * (NJ_DMA_RXSIZE - 1));
> - card->recv.dmairq = card->recv.dmastart +
> - (4 * ((NJ_DMA_RXSIZE / 2) - 1));
> - card->recv.size = NJ_DMA_RXSIZE;
> -
> - if (debug & DEBUG_HW)
> - pr_notice("%s: recv buffer phy %#x - %#x - %#x virt %p"
> - " size %zu u32\n", card->name,
> - card->recv.dmastart, card->recv.dmairq,
> - card->recv.dmaend, card->recv.start, card->recv.size);
> -
> - outl(card->recv.dmastart, card->base + NJ_DMA_WRITE_START);
> - outl(card->recv.dmairq, card->base + NJ_DMA_WRITE_IRQ);
> - outl(card->recv.dmaend, card->base + NJ_DMA_WRITE_END);
> - return 0;
> -}
> -
> -static void
> -read_dma(struct tiger_ch *bc, u32 idx, int cnt)
> -{
> - struct tiger_hw *card = bc->bch.hw;
> - int i, stat;
> - u32 val;
> - u8 *p, *pn;
> -
> - if (bc->lastrx == idx) {
> - bc->rxstate |= RX_OVERRUN;
> - pr_info("%s: B%1d overrun at idx %d\n", card->name,
> - bc->bch.nr, idx);
> - }
> - bc->lastrx = idx;
> - if (test_bit(FLG_RX_OFF, &bc->bch.Flags)) {
> - bc->bch.dropcnt += cnt;
> - return;
> - }
> - stat = bchannel_get_rxbuf(&bc->bch, cnt);
> - /* only transparent use the count here, HDLC overun is detected later */
> - if (stat == -ENOMEM) {
> - pr_warn("%s.B%d: No memory for %d bytes\n",
> - card->name, bc->bch.nr, cnt);
> - return;
> - }
> - if (test_bit(FLG_TRANSPARENT, &bc->bch.Flags))
> - p = skb_put(bc->bch.rx_skb, cnt);
> - else
> - p = bc->hrbuf;
> -
> - for (i = 0; i < cnt; i++) {
> - val = card->recv.start[idx++];
> - if (bc->bch.nr & 2)
> - val >>= 8;
> - if (idx >= card->recv.size)
> - idx = 0;
> - p[i] = val & 0xff;
> - }
> -
> - if (test_bit(FLG_TRANSPARENT, &bc->bch.Flags)) {
> - recv_Bchannel(&bc->bch, 0, false);
> - return;
> - }
> -
> - pn = bc->hrbuf;
> - while (cnt > 0) {
> - stat = isdnhdlc_decode(&bc->hrecv, pn, cnt, &i,
> - bc->bch.rx_skb->data, bc->bch.maxlen);
> - if (stat > 0) { /* valid frame received */
> - p = skb_put(bc->bch.rx_skb, stat);
> - if (debug & DEBUG_HW_BFIFO) {
> - snprintf(card->log, LOG_SIZE,
> - "B%1d-recv %s %d ", bc->bch.nr,
> - card->name, stat);
> - print_hex_dump_bytes(card->log,
> - DUMP_PREFIX_OFFSET, p,
> - stat);
> - }
> - recv_Bchannel(&bc->bch, 0, false);
> - stat = bchannel_get_rxbuf(&bc->bch, bc->bch.maxlen);
> - if (stat < 0) {
> - pr_warn("%s.B%d: No memory for %d bytes\n",
> - card->name, bc->bch.nr, cnt);
> - return;
> - }
> - } else if (stat == -HDLC_CRC_ERROR) {
> - pr_info("%s: B%1d receive frame CRC error\n",
> - card->name, bc->bch.nr);
> - } else if (stat == -HDLC_FRAMING_ERROR) {
> - pr_info("%s: B%1d receive framing error\n",
> - card->name, bc->bch.nr);
> - } else if (stat == -HDLC_LENGTH_ERROR) {
> - pr_info("%s: B%1d receive frame too long (> %d)\n",
> - card->name, bc->bch.nr, bc->bch.maxlen);
> - }
> - pn += i;
> - cnt -= i;
> - }
> -}
> -
> -static void
> -recv_tiger(struct tiger_hw *card, u8 irq_stat)
> -{
> - u32 idx;
> - int cnt = card->recv.size / 2;
> -
> - /* Note receive is via the WRITE DMA channel */
> - card->last_is0 &= ~NJ_IRQM0_WR_MASK;
> - card->last_is0 |= (irq_stat & NJ_IRQM0_WR_MASK);
> -
> - if (irq_stat & NJ_IRQM0_WR_END)
> - idx = cnt - 1;
> - else
> - idx = card->recv.size - 1;
> -
> - if (test_bit(FLG_ACTIVE, &card->bc[0].bch.Flags))
> - read_dma(&card->bc[0], idx, cnt);
> - if (test_bit(FLG_ACTIVE, &card->bc[1].bch.Flags))
> - read_dma(&card->bc[1], idx, cnt);
> -}
> -
> -/* sync with current DMA address at start or after exception */
> -static void
> -resync(struct tiger_ch *bc, struct tiger_hw *card)
> -{
> - card->send.dmacur = inl(card->base | NJ_DMA_READ_ADR);
> - card->send.idx = (card->send.dmacur - card->send.dmastart) >> 2;
> - if (bc->free > card->send.size / 2)
> - bc->free = card->send.size / 2;
> - /* currently we simple sync to the next complete free area
> - * this hast the advantage that we have always maximum time to
> - * handle TX irq
> - */
> - if (card->send.idx < ((card->send.size / 2) - 1))
> - bc->idx = (card->recv.size / 2) - 1;
> - else
> - bc->idx = card->recv.size - 1;
> - bc->txstate = TX_RUN;
> - pr_debug("%s: %s B%1d free %d idx %d/%d\n", card->name,
> - __func__, bc->bch.nr, bc->free, bc->idx, card->send.idx);
> -}
> -
> -static int bc_next_frame(struct tiger_ch *);
> -
> -static void
> -fill_hdlc_flag(struct tiger_ch *bc)
> -{
> - struct tiger_hw *card = bc->bch.hw;
> - int count, i;
> - u32 m, v;
> - u8 *p;
> -
> - if (bc->free == 0)
> - return;
> - pr_debug("%s: %s B%1d %d state %x idx %d/%d\n", card->name,
> - __func__, bc->bch.nr, bc->free, bc->txstate,
> - bc->idx, card->send.idx);
> - if (bc->txstate & (TX_IDLE | TX_INIT | TX_UNDERRUN))
> - resync(bc, card);
> - count = isdnhdlc_encode(&bc->hsend, NULL, 0, &i,
> - bc->hsbuf, bc->free);
> - pr_debug("%s: B%1d hdlc encoded %d flags\n", card->name,
> - bc->bch.nr, count);
> - bc->free -= count;
> - p = bc->hsbuf;
> - m = (bc->bch.nr & 1) ? 0xffffff00 : 0xffff00ff;
> - for (i = 0; i < count; i++) {
> - if (bc->idx >= card->send.size)
> - bc->idx = 0;
> - v = card->send.start[bc->idx];
> - v &= m;
> - v |= (bc->bch.nr & 1) ? (u32)(p[i]) : ((u32)(p[i])) << 8;
> - card->send.start[bc->idx++] = v;
> - }
> - if (debug & DEBUG_HW_BFIFO) {
> - snprintf(card->log, LOG_SIZE, "B%1d-send %s %d ",
> - bc->bch.nr, card->name, count);
> - print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, p, count);
> - }
> -}
> -
> -static void
> -fill_dma(struct tiger_ch *bc)
> -{
> - struct tiger_hw *card = bc->bch.hw;
> - int count, i, fillempty = 0;
> - u32 m, v, n = 0;
> - u8 *p;
> -
> - if (bc->free == 0)
> - return;
> - if (!bc->bch.tx_skb) {
> - if (!test_bit(FLG_TX_EMPTY, &bc->bch.Flags))
> - return;
> - fillempty = 1;
> - count = card->send.size >> 1;
> - p = bc->bch.fill;
> - } else {
> - count = bc->bch.tx_skb->len - bc->bch.tx_idx;
> - if (count <= 0)
> - return;
> - pr_debug("%s: %s B%1d %d/%d/%d/%d state %x idx %d/%d\n",
> - card->name, __func__, bc->bch.nr, count, bc->free,
> - bc->bch.tx_idx, bc->bch.tx_skb->len, bc->txstate,
> - bc->idx, card->send.idx);
> - p = bc->bch.tx_skb->data + bc->bch.tx_idx;
> - }
> - if (bc->txstate & (TX_IDLE | TX_INIT | TX_UNDERRUN))
> - resync(bc, card);
> - if (test_bit(FLG_HDLC, &bc->bch.Flags) && !fillempty) {
> - count = isdnhdlc_encode(&bc->hsend, p, count, &i,
> - bc->hsbuf, bc->free);
> - pr_debug("%s: B%1d hdlc encoded %d in %d\n", card->name,
> - bc->bch.nr, i, count);
> - bc->bch.tx_idx += i;
> - bc->free -= count;
> - p = bc->hsbuf;
> - } else {
> - if (count > bc->free)
> - count = bc->free;
> - if (!fillempty)
> - bc->bch.tx_idx += count;
> - bc->free -= count;
> - }
> - m = (bc->bch.nr & 1) ? 0xffffff00 : 0xffff00ff;
> - if (fillempty) {
> - n = p[0];
> - if (!(bc->bch.nr & 1))
> - n <<= 8;
> - for (i = 0; i < count; i++) {
> - if (bc->idx >= card->send.size)
> - bc->idx = 0;
> - v = card->send.start[bc->idx];
> - v &= m;
> - v |= n;
> - card->send.start[bc->idx++] = v;
> - }
> - } else {
> - for (i = 0; i < count; i++) {
> - if (bc->idx >= card->send.size)
> - bc->idx = 0;
> - v = card->send.start[bc->idx];
> - v &= m;
> - n = p[i];
> - v |= (bc->bch.nr & 1) ? n : n << 8;
> - card->send.start[bc->idx++] = v;
> - }
> - }
> - if (debug & DEBUG_HW_BFIFO) {
> - snprintf(card->log, LOG_SIZE, "B%1d-send %s %d ",
> - bc->bch.nr, card->name, count);
> - print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, p, count);
> - }
> - if (bc->free)
> - bc_next_frame(bc);
> -}
> -
> -
> -static int
> -bc_next_frame(struct tiger_ch *bc)
> -{
> - int ret = 1;
> -
> - if (bc->bch.tx_skb && bc->bch.tx_idx < bc->bch.tx_skb->len) {
> - fill_dma(bc);
> - } else {
> - dev_kfree_skb(bc->bch.tx_skb);
> - if (get_next_bframe(&bc->bch)) {
> - fill_dma(bc);
> - test_and_clear_bit(FLG_TX_EMPTY, &bc->bch.Flags);
> - } else if (test_bit(FLG_TX_EMPTY, &bc->bch.Flags)) {
> - fill_dma(bc);
> - } else if (test_bit(FLG_FILLEMPTY, &bc->bch.Flags)) {
> - test_and_set_bit(FLG_TX_EMPTY, &bc->bch.Flags);
> - ret = 0;
> - } else {
> - ret = 0;
> - }
> - }
> - return ret;
> -}
> -
> -static void
> -send_tiger_bc(struct tiger_hw *card, struct tiger_ch *bc)
> -{
> - int ret;
> -
> - bc->free += card->send.size / 2;
> - if (bc->free >= card->send.size) {
> - if (!(bc->txstate & (TX_UNDERRUN | TX_INIT))) {
> - pr_info("%s: B%1d TX underrun state %x\n", card->name,
> - bc->bch.nr, bc->txstate);
> - bc->txstate |= TX_UNDERRUN;
> - }
> - bc->free = card->send.size;
> - }
> - ret = bc_next_frame(bc);
> - if (!ret) {
> - if (test_bit(FLG_HDLC, &bc->bch.Flags)) {
> - fill_hdlc_flag(bc);
> - return;
> - }
> - pr_debug("%s: B%1d TX no data free %d idx %d/%d\n", card->name,
> - bc->bch.nr, bc->free, bc->idx, card->send.idx);
> - if (!(bc->txstate & (TX_IDLE | TX_INIT))) {
> - fill_mem(bc, bc->idx, bc->free, 0xff);
> - if (bc->free == card->send.size)
> - bc->txstate |= TX_IDLE;
> - }
> - }
> -}
> -
> -static void
> -send_tiger(struct tiger_hw *card, u8 irq_stat)
> -{
> - int i;
> -
> - /* Note send is via the READ DMA channel */
> - if ((irq_stat & card->last_is0) & NJ_IRQM0_RD_MASK) {
> - pr_info("%s: tiger warn write double dma %x/%x\n",
> - card->name, irq_stat, card->last_is0);
> - return;
> - } else {
> - card->last_is0 &= ~NJ_IRQM0_RD_MASK;
> - card->last_is0 |= (irq_stat & NJ_IRQM0_RD_MASK);
> - }
> - for (i = 0; i < 2; i++) {
> - if (test_bit(FLG_ACTIVE, &card->bc[i].bch.Flags))
> - send_tiger_bc(card, &card->bc[i]);
> - }
> -}
> -
> -static irqreturn_t
> -nj_irq(int intno, void *dev_id)
> -{
> - struct tiger_hw *card = dev_id;
> - u8 val, s1val, s0val;
> -
> - spin_lock(&card->lock);
> - s0val = inb(card->base | NJ_IRQSTAT0);
> - s1val = inb(card->base | NJ_IRQSTAT1);
> - if ((s1val & NJ_ISACIRQ) && (s0val == 0)) {
> - /* shared IRQ */
> - spin_unlock(&card->lock);
> - return IRQ_NONE;
> - }
> - pr_debug("%s: IRQSTAT0 %02x IRQSTAT1 %02x\n", card->name, s0val, s1val);
> - card->irqcnt++;
> - if (!(s1val & NJ_ISACIRQ)) {
> - val = ReadISAC_nj(card, ISAC_ISTA);
> - if (val)
> - mISDNisac_irq(&card->isac, val);
> - }
> -
> - if (s0val)
> - /* write to clear */
> - outb(s0val, card->base | NJ_IRQSTAT0);
> - else
> - goto end;
> - s1val = s0val;
> - /* set bits in sval to indicate which page is free */
> - card->recv.dmacur = inl(card->base | NJ_DMA_WRITE_ADR);
> - card->recv.idx = (card->recv.dmacur - card->recv.dmastart) >> 2;
> - if (card->recv.dmacur < card->recv.dmairq)
> - s0val = 0x08; /* the 2nd write area is free */
> - else
> - s0val = 0x04; /* the 1st write area is free */
> -
> - card->send.dmacur = inl(card->base | NJ_DMA_READ_ADR);
> - card->send.idx = (card->send.dmacur - card->send.dmastart) >> 2;
> - if (card->send.dmacur < card->send.dmairq)
> - s0val |= 0x02; /* the 2nd read area is free */
> - else
> - s0val |= 0x01; /* the 1st read area is free */
> -
> - pr_debug("%s: DMA Status %02x/%02x/%02x %d/%d\n", card->name,
> - s1val, s0val, card->last_is0,
> - card->recv.idx, card->send.idx);
> - /* test if we have a DMA interrupt */
> - if (s0val != card->last_is0) {
> - if ((s0val & NJ_IRQM0_RD_MASK) !=
> - (card->last_is0 & NJ_IRQM0_RD_MASK))
> - /* got a write dma int */
> - send_tiger(card, s0val);
> - if ((s0val & NJ_IRQM0_WR_MASK) !=
> - (card->last_is0 & NJ_IRQM0_WR_MASK))
> - /* got a read dma int */
> - recv_tiger(card, s0val);
> - }
> -end:
> - spin_unlock(&card->lock);
> - return IRQ_HANDLED;
> -}
> -
> -static int
> -nj_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)
> -{
> - int ret = -EINVAL;
> - struct bchannel *bch = container_of(ch, struct bchannel, ch);
> - struct tiger_ch *bc = container_of(bch, struct tiger_ch, bch);
> - struct tiger_hw *card = bch->hw;
> - struct mISDNhead *hh = mISDN_HEAD_P(skb);
> - unsigned long flags;
> -
> - switch (hh->prim) {
> - case PH_DATA_REQ:
> - spin_lock_irqsave(&card->lock, flags);
> - ret = bchannel_senddata(bch, skb);
> - if (ret > 0) { /* direct TX */
> - fill_dma(bc);
> - ret = 0;
> - }
> - spin_unlock_irqrestore(&card->lock, flags);
> - return ret;
> - case PH_ACTIVATE_REQ:
> - spin_lock_irqsave(&card->lock, flags);
> - if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags))
> - ret = mode_tiger(bc, ch->protocol);
> - else
> - ret = 0;
> - spin_unlock_irqrestore(&card->lock, flags);
> - if (!ret)
> - _queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
> - NULL, GFP_KERNEL);
> - break;
> - case PH_DEACTIVATE_REQ:
> - spin_lock_irqsave(&card->lock, flags);
> - mISDN_clear_bchannel(bch);
> - mode_tiger(bc, ISDN_P_NONE);
> - spin_unlock_irqrestore(&card->lock, flags);
> - _queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
> - NULL, GFP_KERNEL);
> - ret = 0;
> - break;
> - }
> - if (!ret)
> - dev_kfree_skb(skb);
> - return ret;
> -}
> -
> -static int
> -channel_bctrl(struct tiger_ch *bc, struct mISDN_ctrl_req *cq)
> -{
> - return mISDN_ctrl_bchannel(&bc->bch, cq);
> -}
> -
> -static int
> -nj_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
> -{
> - struct bchannel *bch = container_of(ch, struct bchannel, ch);
> - struct tiger_ch *bc = container_of(bch, struct tiger_ch, bch);
> - struct tiger_hw *card = bch->hw;
> - int ret = -EINVAL;
> - u_long flags;
> -
> - pr_debug("%s: %s cmd:%x %p\n", card->name, __func__, cmd, arg);
> - switch (cmd) {
> - case CLOSE_CHANNEL:
> - test_and_clear_bit(FLG_OPEN, &bch->Flags);
> - cancel_work_sync(&bch->workq);
> - spin_lock_irqsave(&card->lock, flags);
> - mISDN_clear_bchannel(bch);
> - mode_tiger(bc, ISDN_P_NONE);
> - spin_unlock_irqrestore(&card->lock, flags);
> - ch->protocol = ISDN_P_NONE;
> - ch->peer = NULL;
> - module_put(THIS_MODULE);
> - ret = 0;
> - break;
> - case CONTROL_CHANNEL:
> - ret = channel_bctrl(bc, arg);
> - break;
> - default:
> - pr_info("%s: %s unknown prim(%x)\n", card->name, __func__, cmd);
> - }
> - return ret;
> -}
> -
> -static int
> -channel_ctrl(struct tiger_hw *card, struct mISDN_ctrl_req *cq)
> -{
> - int ret = 0;
> -
> - switch (cq->op) {
> - case MISDN_CTRL_GETOP:
> - cq->op = MISDN_CTRL_LOOP | MISDN_CTRL_L1_TIMER3;
> - break;
> - case MISDN_CTRL_LOOP:
> - /* cq->channel: 0 disable, 1 B1 loop 2 B2 loop, 3 both */
> - if (cq->channel < 0 || cq->channel > 3) {
> - ret = -EINVAL;
> - break;
> - }
> - ret = card->isac.ctrl(&card->isac, HW_TESTLOOP, cq->channel);
> - break;
> - case MISDN_CTRL_L1_TIMER3:
> - ret = card->isac.ctrl(&card->isac, HW_TIMER3_VALUE, cq->p1);
> - break;
> - default:
> - pr_info("%s: %s unknown Op %x\n", card->name, __func__, cq->op);
> - ret = -EINVAL;
> - break;
> - }
> - return ret;
> -}
> -
> -static int
> -open_bchannel(struct tiger_hw *card, struct channel_req *rq)
> -{
> - struct bchannel *bch;
> -
> - if (rq->adr.channel == 0 || rq->adr.channel > 2)
> - return -EINVAL;
> - if (rq->protocol == ISDN_P_NONE)
> - return -EINVAL;
> - bch = &card->bc[rq->adr.channel - 1].bch;
> - if (test_and_set_bit(FLG_OPEN, &bch->Flags))
> - return -EBUSY; /* b-channel can be only open once */
> - test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);
> - bch->ch.protocol = rq->protocol;
> - rq->ch = &bch->ch;
> - return 0;
> -}
> -
> -/*
> - * device control function
> - */
> -static int
> -nj_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
> -{
> - struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
> - struct dchannel *dch = container_of(dev, struct dchannel, dev);
> - struct tiger_hw *card = dch->hw;
> - struct channel_req *rq;
> - int err = 0;
> -
> - pr_debug("%s: %s cmd:%x %p\n", card->name, __func__, cmd, arg);
> - switch (cmd) {
> - case OPEN_CHANNEL:
> - rq = arg;
> - if (rq->protocol == ISDN_P_TE_S0)
> - err = card->isac.open(&card->isac, rq);
> - else
> - err = open_bchannel(card, rq);
> - if (err)
> - break;
> - if (!try_module_get(THIS_MODULE))
> - pr_info("%s: cannot get module\n", card->name);
> - break;
> - case CLOSE_CHANNEL:
> - pr_debug("%s: dev(%d) close from %p\n", card->name, dch->dev.id,
> - __builtin_return_address(0));
> - module_put(THIS_MODULE);
> - break;
> - case CONTROL_CHANNEL:
> - err = channel_ctrl(card, arg);
> - break;
> - default:
> - pr_debug("%s: %s unknown command %x\n",
> - card->name, __func__, cmd);
> - return -EINVAL;
> - }
> - return err;
> -}
> -
> -static int
> -nj_init_card(struct tiger_hw *card)
> -{
> - u_long flags;
> - int ret;
> -
> - spin_lock_irqsave(&card->lock, flags);
> - nj_disable_hwirq(card);
> - spin_unlock_irqrestore(&card->lock, flags);
> -
> - card->irq = card->pdev->irq;
> - if (request_irq(card->irq, nj_irq, IRQF_SHARED, card->name, card)) {
> - pr_info("%s: couldn't get interrupt %d\n",
> - card->name, card->irq);
> - card->irq = -1;
> - return -EIO;
> - }
> -
> - spin_lock_irqsave(&card->lock, flags);
> - nj_reset(card);
> - ret = card->isac.init(&card->isac);
> - if (ret)
> - goto error;
> - ret = inittiger(card);
> - if (ret)
> - goto error;
> - mode_tiger(&card->bc[0], ISDN_P_NONE);
> - mode_tiger(&card->bc[1], ISDN_P_NONE);
> -error:
> - spin_unlock_irqrestore(&card->lock, flags);
> - return ret;
> -}
> -
> -
> -static void
> -nj_release(struct tiger_hw *card)
> -{
> - u_long flags;
> - int i;
> -
> - if (card->base_s) {
> - spin_lock_irqsave(&card->lock, flags);
> - nj_disable_hwirq(card);
> - mode_tiger(&card->bc[0], ISDN_P_NONE);
> - mode_tiger(&card->bc[1], ISDN_P_NONE);
> - spin_unlock_irqrestore(&card->lock, flags);
> - card->isac.release(&card->isac);
> - release_region(card->base, card->base_s);
> - card->base_s = 0;
> - }
> - if (card->irq > 0)
> - free_irq(card->irq, card);
> - if (device_is_registered(&card->isac.dch.dev.dev))
> - mISDN_unregister_device(&card->isac.dch.dev);
> -
> - for (i = 0; i < 2; i++) {
> - mISDN_freebchannel(&card->bc[i].bch);
> - kfree(card->bc[i].hsbuf);
> - kfree(card->bc[i].hrbuf);
> - }
> - if (card->dma_p)
> - dma_free_coherent(&card->pdev->dev, NJ_DMA_SIZE, card->dma_p,
> - card->dma);
> - write_lock_irqsave(&card_lock, flags);
> - list_del(&card->list);
> - write_unlock_irqrestore(&card_lock, flags);
> - pci_disable_device(card->pdev);
> - pci_set_drvdata(card->pdev, NULL);
> - kfree(card);
> -}
> -
> -
> -static int
> -nj_setup(struct tiger_hw *card)
> -{
> - card->base = pci_resource_start(card->pdev, 0);
> - card->base_s = pci_resource_len(card->pdev, 0);
> - if (!request_region(card->base, card->base_s, card->name)) {
> - pr_info("%s: NETjet config port %#x-%#x already in use\n",
> - card->name, card->base,
> - (u32)(card->base + card->base_s - 1));
> - card->base_s = 0;
> - return -EIO;
> - }
> - ASSIGN_FUNC(nj, ISAC, card->isac);
> - return 0;
> -}
> -
> -
> -static int
> -setup_instance(struct tiger_hw *card)
> -{
> - int i, err;
> - u_long flags;
> -
> - snprintf(card->name, MISDN_MAX_IDLEN - 1, "netjet.%d", nj_cnt + 1);
> - write_lock_irqsave(&card_lock, flags);
> - list_add_tail(&card->list, &Cards);
> - write_unlock_irqrestore(&card_lock, flags);
> -
> - _set_debug(card);
> - card->isac.name = card->name;
> - spin_lock_init(&card->lock);
> - card->isac.hwlock = &card->lock;
> - mISDNisac_init(&card->isac, card);
> -
> - card->isac.dch.dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
> - (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
> - card->isac.dch.dev.D.ctrl = nj_dctrl;
> - for (i = 0; i < 2; i++) {
> - card->bc[i].bch.nr = i + 1;
> - set_channelmap(i + 1, card->isac.dch.dev.channelmap);
> - mISDN_initbchannel(&card->bc[i].bch, MAX_DATA_MEM,
> - NJ_DMA_RXSIZE >> 1);
> - card->bc[i].bch.hw = card;
> - card->bc[i].bch.ch.send = nj_l2l1B;
> - card->bc[i].bch.ch.ctrl = nj_bctrl;
> - card->bc[i].bch.ch.nr = i + 1;
> - list_add(&card->bc[i].bch.ch.list,
> - &card->isac.dch.dev.bchannels);
> - card->bc[i].bch.hw = card;
> - }
> - err = nj_setup(card);
> - if (err)
> - goto error;
> - err = mISDN_register_device(&card->isac.dch.dev, &card->pdev->dev,
> - card->name);
> - if (err)
> - goto error;
> - err = nj_init_card(card);
> - if (!err) {
> - nj_cnt++;
> - pr_notice("Netjet %d cards installed\n", nj_cnt);
> - return 0;
> - }
> -error:
> - nj_release(card);
> - return err;
> -}
> -
> -static int
> -nj_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
> -{
> - int err = -ENOMEM;
> - int cfg;
> - struct tiger_hw *card;
> -
> - if (pdev->subsystem_vendor == 0x8086 &&
> - pdev->subsystem_device == 0x0003) {
> - pr_notice("Netjet: Digium X100P/X101P not handled\n");
> - return -ENODEV;
> - }
> -
> - if (pdev->subsystem_vendor == 0x55 &&
> - pdev->subsystem_device == 0x02) {
> - pr_notice("Netjet: Enter!Now not handled yet\n");
> - return -ENODEV;
> - }
> -
> - if (pdev->subsystem_vendor == 0xb100 &&
> - pdev->subsystem_device == 0x0003) {
> - pr_notice("Netjet: Digium TDM400P not handled yet\n");
> - return -ENODEV;
> - }
> -
> - card = kzalloc_obj(struct tiger_hw);
> - if (!card) {
> - pr_info("No kmem for Netjet\n");
> - return err;
> - }
> -
> - card->pdev = pdev;
> -
> - err = pci_enable_device(pdev);
> - if (err) {
> - kfree(card);
> - return err;
> - }
> -
> - printk(KERN_INFO "nj_probe(mISDN): found adapter at %s\n",
> - pci_name(pdev));
> -
> - pci_set_master(pdev);
> -
> - /* 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(pdev, 0x04, &cfg);
> - if (cfg & 0x00100000)
> - card->typ = NETJET_S_TJ320;
> - else
> - card->typ = NETJET_S_TJ300;
> -
> - card->base = pci_resource_start(pdev, 0);
> - pci_set_drvdata(pdev, card);
> - err = setup_instance(card);
> - if (err)
> - pci_set_drvdata(pdev, NULL);
> -
> - return err;
> -}
> -
> -
> -static void nj_remove(struct pci_dev *pdev)
> -{
> - struct tiger_hw *card = pci_get_drvdata(pdev);
> -
> - if (card)
> - nj_release(card);
> - else
> - pr_info("%s drvdata already removed\n", __func__);
> -}
> -
> -/* We cannot select cards with PCI_SUB... IDs, since here are cards with
> - * SUB IDs set to PCI_ANY_ID, so we need to match all and reject
> - * known other cards which not work with this driver - see probe function */
> -static const struct pci_device_id nj_pci_ids[] = {
> - { PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_300,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
> - { }
> -};
> -MODULE_DEVICE_TABLE(pci, nj_pci_ids);
> -
> -static struct pci_driver nj_driver = {
> - .name = "netjet",
> - .probe = nj_probe,
> - .remove = nj_remove,
> - .id_table = nj_pci_ids,
> -};
> -
> -static int __init nj_init(void)
> -{
> - int err;
> -
> - pr_notice("Netjet PCI driver Rev. %s\n", NETJET_REV);
> - err = pci_register_driver(&nj_driver);
> - return err;
> -}
> -
> -static void __exit nj_cleanup(void)
> -{
> - pci_unregister_driver(&nj_driver);
> -}
> -
> -module_init(nj_init);
> -module_exit(nj_cleanup);
> diff --git a/drivers/isdn/hardware/mISDN/speedfax.c b/drivers/isdn/hardware/mISDN/speedfax.c
> deleted file mode 100644
> index ab24c3c460e6..000000000000
> --- a/drivers/isdn/hardware/mISDN/speedfax.c
> +++ /dev/null
> @@ -1,520 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * speedfax.c low level stuff for Sedlbauer Speedfax+ cards
> - * based on the ISAR DSP
> - * Thanks to Sedlbauer AG for informations and HW
> - *
> - * Author Karsten Keil <keil@isdn4linux.de>
> - *
> - * Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
> - */
> -
> -#include <linux/interrupt.h>
> -#include <linux/module.h>
> -#include <linux/slab.h>
> -#include <linux/pci.h>
> -#include <linux/delay.h>
> -#include <linux/mISDNhw.h>
> -#include <linux/firmware.h>
> -#include "ipac.h"
> -#include "isar.h"
> -
> -#define SPEEDFAX_REV "2.0"
> -
> -#define PCI_SUBVENDOR_SPEEDFAX_PYRAMID 0x51
> -#define PCI_SUBVENDOR_SPEEDFAX_PCI 0x54
> -#define PCI_SUB_ID_SEDLBAUER 0x01
> -
> -#define SFAX_PCI_ADDR 0xc8
> -#define SFAX_PCI_ISAC 0xd0
> -#define SFAX_PCI_ISAR 0xe0
> -
> -/* TIGER 100 Registers */
> -
> -#define TIGER_RESET_ADDR 0x00
> -#define TIGER_EXTERN_RESET_ON 0x01
> -#define TIGER_EXTERN_RESET_OFF 0x00
> -#define TIGER_AUX_CTRL 0x02
> -#define TIGER_AUX_DATA 0x03
> -#define TIGER_AUX_IRQMASK 0x05
> -#define TIGER_AUX_STATUS 0x07
> -
> -/* Tiger AUX BITs */
> -#define SFAX_AUX_IOMASK 0xdd /* 1 and 5 are inputs */
> -#define SFAX_ISAR_RESET_BIT_OFF 0x00
> -#define SFAX_ISAR_RESET_BIT_ON 0x01
> -#define SFAX_TIGER_IRQ_BIT 0x02
> -#define SFAX_LED1_BIT 0x08
> -#define SFAX_LED2_BIT 0x10
> -
> -#define SFAX_PCI_RESET_ON (SFAX_ISAR_RESET_BIT_ON)
> -#define SFAX_PCI_RESET_OFF (SFAX_LED1_BIT | SFAX_LED2_BIT)
> -
> -static int sfax_cnt;
> -static u32 debug;
> -static u32 irqloops = 4;
> -
> -struct sfax_hw {
> - struct list_head list;
> - struct pci_dev *pdev;
> - char name[MISDN_MAX_IDLEN];
> - u32 irq;
> - u32 irqcnt;
> - u32 cfg;
> - struct _ioport p_isac;
> - struct _ioport p_isar;
> - u8 aux_data;
> - spinlock_t lock; /* HW access lock */
> - struct isac_hw isac;
> - struct isar_hw isar;
> -};
> -
> -static LIST_HEAD(Cards);
> -static DEFINE_RWLOCK(card_lock); /* protect Cards */
> -
> -static void
> -_set_debug(struct sfax_hw *card)
> -{
> - card->isac.dch.debug = debug;
> - card->isar.ch[0].bch.debug = debug;
> - card->isar.ch[1].bch.debug = debug;
> -}
> -
> -static int
> -set_debug(const char *val, const struct kernel_param *kp)
> -{
> - int ret;
> - struct sfax_hw *card;
> -
> - ret = param_set_uint(val, kp);
> - if (!ret) {
> - read_lock(&card_lock);
> - list_for_each_entry(card, &Cards, list)
> - _set_debug(card);
> - read_unlock(&card_lock);
> - }
> - return ret;
> -}
> -
> -MODULE_AUTHOR("Karsten Keil");
> -MODULE_DESCRIPTION("mISDN driver for Sedlbauer Speedfax+ cards");
> -MODULE_LICENSE("GPL v2");
> -MODULE_VERSION(SPEEDFAX_REV);
> -MODULE_FIRMWARE("isdn/ISAR.BIN");
> -module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR);
> -MODULE_PARM_DESC(debug, "Speedfax debug mask");
> -module_param(irqloops, uint, S_IRUGO | S_IWUSR);
> -MODULE_PARM_DESC(irqloops, "Speedfax maximal irqloops (default 4)");
> -
> -IOFUNC_IND(ISAC, sfax_hw, p_isac)
> -IOFUNC_IND(ISAR, sfax_hw, p_isar)
> -
> -static irqreturn_t
> -speedfax_irq(int intno, void *dev_id)
> -{
> - struct sfax_hw *sf = dev_id;
> - u8 val;
> - int cnt = irqloops;
> -
> - spin_lock(&sf->lock);
> - val = inb(sf->cfg + TIGER_AUX_STATUS);
> - if (val & SFAX_TIGER_IRQ_BIT) { /* for us or shared ? */
> - spin_unlock(&sf->lock);
> - return IRQ_NONE; /* shared */
> - }
> - sf->irqcnt++;
> - val = ReadISAR_IND(sf, ISAR_IRQBIT);
> -Start_ISAR:
> - if (val & ISAR_IRQSTA)
> - mISDNisar_irq(&sf->isar);
> - val = ReadISAC_IND(sf, ISAC_ISTA);
> - if (val)
> - mISDNisac_irq(&sf->isac, val);
> - val = ReadISAR_IND(sf, ISAR_IRQBIT);
> - if ((val & ISAR_IRQSTA) && cnt--)
> - goto Start_ISAR;
> - if (cnt < irqloops)
> - pr_debug("%s: %d irqloops cpu%d\n", sf->name,
> - irqloops - cnt, smp_processor_id());
> - if (irqloops && !cnt)
> - pr_notice("%s: %d IRQ LOOP cpu%d\n", sf->name,
> - irqloops, smp_processor_id());
> - spin_unlock(&sf->lock);
> - return IRQ_HANDLED;
> -}
> -
> -static void
> -enable_hwirq(struct sfax_hw *sf)
> -{
> - WriteISAC_IND(sf, ISAC_MASK, 0);
> - WriteISAR_IND(sf, ISAR_IRQBIT, ISAR_IRQMSK);
> - outb(SFAX_TIGER_IRQ_BIT, sf->cfg + TIGER_AUX_IRQMASK);
> -}
> -
> -static void
> -disable_hwirq(struct sfax_hw *sf)
> -{
> - WriteISAC_IND(sf, ISAC_MASK, 0xFF);
> - WriteISAR_IND(sf, ISAR_IRQBIT, 0);
> - outb(0, sf->cfg + TIGER_AUX_IRQMASK);
> -}
> -
> -static void
> -reset_speedfax(struct sfax_hw *sf)
> -{
> -
> - pr_debug("%s: resetting card\n", sf->name);
> - outb(TIGER_EXTERN_RESET_ON, sf->cfg + TIGER_RESET_ADDR);
> - outb(SFAX_PCI_RESET_ON, sf->cfg + TIGER_AUX_DATA);
> - mdelay(1);
> - outb(TIGER_EXTERN_RESET_OFF, sf->cfg + TIGER_RESET_ADDR);
> - sf->aux_data = SFAX_PCI_RESET_OFF;
> - outb(sf->aux_data, sf->cfg + TIGER_AUX_DATA);
> - mdelay(1);
> -}
> -
> -static int
> -sfax_ctrl(struct sfax_hw *sf, u32 cmd, u_long arg)
> -{
> - int ret = 0;
> -
> - switch (cmd) {
> - case HW_RESET_REQ:
> - reset_speedfax(sf);
> - break;
> - case HW_ACTIVATE_IND:
> - if (arg & 1)
> - sf->aux_data &= ~SFAX_LED1_BIT;
> - if (arg & 2)
> - sf->aux_data &= ~SFAX_LED2_BIT;
> - outb(sf->aux_data, sf->cfg + TIGER_AUX_DATA);
> - break;
> - case HW_DEACT_IND:
> - if (arg & 1)
> - sf->aux_data |= SFAX_LED1_BIT;
> - if (arg & 2)
> - sf->aux_data |= SFAX_LED2_BIT;
> - outb(sf->aux_data, sf->cfg + TIGER_AUX_DATA);
> - break;
> - default:
> - pr_info("%s: %s unknown command %x %lx\n",
> - sf->name, __func__, cmd, arg);
> - ret = -EINVAL;
> - break;
> - }
> - return ret;
> -}
> -
> -static int
> -channel_ctrl(struct sfax_hw *sf, struct mISDN_ctrl_req *cq)
> -{
> - int ret = 0;
> -
> - switch (cq->op) {
> - case MISDN_CTRL_GETOP:
> - cq->op = MISDN_CTRL_LOOP | MISDN_CTRL_L1_TIMER3;
> - break;
> - case MISDN_CTRL_LOOP:
> - /* cq->channel: 0 disable, 1 B1 loop 2 B2 loop, 3 both */
> - if (cq->channel < 0 || cq->channel > 3) {
> - ret = -EINVAL;
> - break;
> - }
> - ret = sf->isac.ctrl(&sf->isac, HW_TESTLOOP, cq->channel);
> - break;
> - case MISDN_CTRL_L1_TIMER3:
> - ret = sf->isac.ctrl(&sf->isac, HW_TIMER3_VALUE, cq->p1);
> - break;
> - default:
> - pr_info("%s: unknown Op %x\n", sf->name, cq->op);
> - ret = -EINVAL;
> - break;
> - }
> - return ret;
> -}
> -
> -static int
> -sfax_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
> -{
> - struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
> - struct dchannel *dch = container_of(dev, struct dchannel, dev);
> - struct sfax_hw *sf = dch->hw;
> - struct channel_req *rq;
> - int err = 0;
> -
> - pr_debug("%s: cmd:%x %p\n", sf->name, cmd, arg);
> - switch (cmd) {
> - case OPEN_CHANNEL:
> - rq = arg;
> - if (rq->protocol == ISDN_P_TE_S0)
> - err = sf->isac.open(&sf->isac, rq);
> - else
> - err = sf->isar.open(&sf->isar, rq);
> - if (err)
> - break;
> - if (!try_module_get(THIS_MODULE))
> - pr_info("%s: cannot get module\n", sf->name);
> - break;
> - case CLOSE_CHANNEL:
> - pr_debug("%s: dev(%d) close from %p\n", sf->name,
> - dch->dev.id, __builtin_return_address(0));
> - module_put(THIS_MODULE);
> - break;
> - case CONTROL_CHANNEL:
> - err = channel_ctrl(sf, arg);
> - break;
> - default:
> - pr_debug("%s: unknown command %x\n", sf->name, cmd);
> - return -EINVAL;
> - }
> - return err;
> -}
> -
> -static int
> -init_card(struct sfax_hw *sf)
> -{
> - int ret, cnt = 3;
> - u_long flags;
> -
> - ret = request_irq(sf->irq, speedfax_irq, IRQF_SHARED, sf->name, sf);
> - if (ret) {
> - pr_info("%s: couldn't get interrupt %d\n", sf->name, sf->irq);
> - return ret;
> - }
> - while (cnt--) {
> - spin_lock_irqsave(&sf->lock, flags);
> - ret = sf->isac.init(&sf->isac);
> - if (ret) {
> - spin_unlock_irqrestore(&sf->lock, flags);
> - pr_info("%s: ISAC init failed with %d\n",
> - sf->name, ret);
> - break;
> - }
> - enable_hwirq(sf);
> - /* RESET Receiver and Transmitter */
> - WriteISAC_IND(sf, ISAC_CMDR, 0x41);
> - spin_unlock_irqrestore(&sf->lock, flags);
> - msleep_interruptible(10);
> - if (debug & DEBUG_HW)
> - pr_notice("%s: IRQ %d count %d\n", sf->name,
> - sf->irq, sf->irqcnt);
> - if (!sf->irqcnt) {
> - pr_info("%s: IRQ(%d) got no requests during init %d\n",
> - sf->name, sf->irq, 3 - cnt);
> - } else
> - return 0;
> - }
> - free_irq(sf->irq, sf);
> - return -EIO;
> -}
> -
> -
> -static int
> -setup_speedfax(struct sfax_hw *sf)
> -{
> - u_long flags;
> -
> - if (!request_region(sf->cfg, 256, sf->name)) {
> - pr_info("mISDN: %s config port %x-%x already in use\n",
> - sf->name, sf->cfg, sf->cfg + 255);
> - return -EIO;
> - }
> - outb(0xff, sf->cfg);
> - outb(0, sf->cfg);
> - outb(0xdd, sf->cfg + TIGER_AUX_CTRL);
> - outb(0, sf->cfg + TIGER_AUX_IRQMASK);
> -
> - sf->isac.type = IPAC_TYPE_ISAC;
> - sf->p_isac.ale = sf->cfg + SFAX_PCI_ADDR;
> - sf->p_isac.port = sf->cfg + SFAX_PCI_ISAC;
> - sf->p_isar.ale = sf->cfg + SFAX_PCI_ADDR;
> - sf->p_isar.port = sf->cfg + SFAX_PCI_ISAR;
> - ASSIGN_FUNC(IND, ISAC, sf->isac);
> - ASSIGN_FUNC(IND, ISAR, sf->isar);
> - spin_lock_irqsave(&sf->lock, flags);
> - reset_speedfax(sf);
> - disable_hwirq(sf);
> - spin_unlock_irqrestore(&sf->lock, flags);
> - return 0;
> -}
> -
> -static void
> -release_card(struct sfax_hw *card) {
> - u_long flags;
> -
> - spin_lock_irqsave(&card->lock, flags);
> - disable_hwirq(card);
> - spin_unlock_irqrestore(&card->lock, flags);
> - card->isac.release(&card->isac);
> - free_irq(card->irq, card);
> - card->isar.release(&card->isar);
> - mISDN_unregister_device(&card->isac.dch.dev);
> - release_region(card->cfg, 256);
> - pci_disable_device(card->pdev);
> - pci_set_drvdata(card->pdev, NULL);
> - write_lock_irqsave(&card_lock, flags);
> - list_del(&card->list);
> - write_unlock_irqrestore(&card_lock, flags);
> - kfree(card);
> - sfax_cnt--;
> -}
> -
> -static int
> -setup_instance(struct sfax_hw *card)
> -{
> - const struct firmware *firmware;
> - int i, err;
> - u_long flags;
> -
> - snprintf(card->name, MISDN_MAX_IDLEN - 1, "Speedfax.%d", sfax_cnt + 1);
> - write_lock_irqsave(&card_lock, flags);
> - list_add_tail(&card->list, &Cards);
> - write_unlock_irqrestore(&card_lock, flags);
> - _set_debug(card);
> - spin_lock_init(&card->lock);
> - card->isac.hwlock = &card->lock;
> - card->isar.hwlock = &card->lock;
> - card->isar.ctrl = (void *)&sfax_ctrl;
> - card->isac.name = card->name;
> - card->isar.name = card->name;
> - card->isar.owner = THIS_MODULE;
> -
> - err = request_firmware(&firmware, "isdn/ISAR.BIN", &card->pdev->dev);
> - if (err < 0) {
> - pr_info("%s: firmware request failed %d\n",
> - card->name, err);
> - goto error_fw;
> - }
> - if (debug & DEBUG_HW)
> - pr_notice("%s: got firmware %zu bytes\n",
> - card->name, firmware->size);
> -
> - mISDNisac_init(&card->isac, card);
> -
> - card->isac.dch.dev.D.ctrl = sfax_dctrl;
> - card->isac.dch.dev.Bprotocols =
> - mISDNisar_init(&card->isar, card);
> - for (i = 0; i < 2; i++) {
> - set_channelmap(i + 1, card->isac.dch.dev.channelmap);
> - list_add(&card->isar.ch[i].bch.ch.list,
> - &card->isac.dch.dev.bchannels);
> - }
> -
> - err = setup_speedfax(card);
> - if (err)
> - goto error_setup;
> - err = card->isar.init(&card->isar);
> - if (err)
> - goto error;
> - err = mISDN_register_device(&card->isac.dch.dev,
> - &card->pdev->dev, card->name);
> - if (err)
> - goto error;
> - err = init_card(card);
> - if (err)
> - goto error_init;
> - err = card->isar.firmware(&card->isar, firmware->data, firmware->size);
> - if (!err) {
> - release_firmware(firmware);
> - sfax_cnt++;
> - pr_notice("SpeedFax %d cards installed\n", sfax_cnt);
> - return 0;
> - }
> - disable_hwirq(card);
> - free_irq(card->irq, card);
> -error_init:
> - mISDN_unregister_device(&card->isac.dch.dev);
> -error:
> - release_region(card->cfg, 256);
> -error_setup:
> - card->isac.release(&card->isac);
> - card->isar.release(&card->isar);
> - release_firmware(firmware);
> -error_fw:
> - pci_disable_device(card->pdev);
> - write_lock_irqsave(&card_lock, flags);
> - list_del(&card->list);
> - write_unlock_irqrestore(&card_lock, flags);
> - kfree(card);
> - return err;
> -}
> -
> -static int
> -sfaxpci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
> -{
> - int err = -ENOMEM;
> - struct sfax_hw *card = kzalloc_obj(struct sfax_hw);
> -
> - if (!card) {
> - pr_info("No memory for Speedfax+ PCI\n");
> - return err;
> - }
> - card->pdev = pdev;
> - err = pci_enable_device(pdev);
> - if (err) {
> - kfree(card);
> - return err;
> - }
> -
> - pr_notice("mISDN: Speedfax found adapter %s at %s\n",
> - (char *)ent->driver_data, pci_name(pdev));
> -
> - card->cfg = pci_resource_start(pdev, 0);
> - card->irq = pdev->irq;
> - pci_set_drvdata(pdev, card);
> - err = setup_instance(card);
> - if (err)
> - pci_set_drvdata(pdev, NULL);
> - return err;
> -}
> -
> -static void
> -sfax_remove_pci(struct pci_dev *pdev)
> -{
> - struct sfax_hw *card = pci_get_drvdata(pdev);
> -
> - if (card)
> - release_card(card);
> - else
> - pr_debug("%s: drvdata already removed\n", __func__);
> -}
> -
> -static struct pci_device_id sfaxpci_ids[] = {
> - { PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
> - PCI_SUBVENDOR_SPEEDFAX_PYRAMID, PCI_SUB_ID_SEDLBAUER,
> - 0, 0, (unsigned long) "Pyramid Speedfax + PCI"
> - },
> - { PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
> - PCI_SUBVENDOR_SPEEDFAX_PCI, PCI_SUB_ID_SEDLBAUER,
> - 0, 0, (unsigned long) "Sedlbauer Speedfax + PCI"
> - },
> - { }
> -};
> -MODULE_DEVICE_TABLE(pci, sfaxpci_ids);
> -
> -static struct pci_driver sfaxpci_driver = {
> - .name = "speedfax+ pci",
> - .probe = sfaxpci_probe,
> - .remove = sfax_remove_pci,
> - .id_table = sfaxpci_ids,
> -};
> -
> -static int __init
> -Speedfax_init(void)
> -{
> - int err;
> -
> - pr_notice("Sedlbauer Speedfax+ Driver Rev. %s\n",
> - SPEEDFAX_REV);
> - err = pci_register_driver(&sfaxpci_driver);
> - return err;
> -}
> -
> -static void __exit
> -Speedfax_cleanup(void)
> -{
> - pci_unregister_driver(&sfaxpci_driver);
> -}
> -
> -module_init(Speedfax_init);
> -module_exit(Speedfax_cleanup);
> diff --git a/drivers/isdn/hardware/mISDN/w6692.c b/drivers/isdn/hardware/mISDN/w6692.c
> deleted file mode 100644
> index a341470c042f..000000000000
> --- a/drivers/isdn/hardware/mISDN/w6692.c
> +++ /dev/null
> @@ -1,1417 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * w6692.c mISDN driver for Winbond w6692 based cards
> - *
> - * Author Karsten Keil <kkeil@suse.de>
> - * based on the w6692 I4L driver from Petr Novak <petr.novak@i.cz>
> - *
> - * Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
> - */
> -
> -#include <linux/interrupt.h>
> -#include <linux/module.h>
> -#include <linux/pci.h>
> -#include <linux/delay.h>
> -#include <linux/mISDNhw.h>
> -#include <linux/slab.h>
> -#include "w6692.h"
> -
> -#define W6692_REV "2.0"
> -
> -#define DBUSY_TIMER_VALUE 80
> -
> -enum {
> - W6692_ASUS,
> - W6692_WINBOND,
> - W6692_USR
> -};
> -
> -/* private data in the PCI devices list */
> -struct w6692map {
> - u_int subtype;
> - char *name;
> -};
> -
> -static const struct w6692map w6692_map[] =
> -{
> - {W6692_ASUS, "Dynalink/AsusCom IS64PH"},
> - {W6692_WINBOND, "Winbond W6692"},
> - {W6692_USR, "USR W6692"}
> -};
> -
> -#define PCI_DEVICE_ID_USR_6692 0x3409
> -
> -struct w6692_ch {
> - struct bchannel bch;
> - u32 addr;
> - struct timer_list timer;
> - u8 b_mode;
> -};
> -
> -struct w6692_hw {
> - struct list_head list;
> - struct pci_dev *pdev;
> - char name[MISDN_MAX_IDLEN];
> - u32 irq;
> - u32 irqcnt;
> - u32 addr;
> - u32 fmask; /* feature mask - bit set per card nr */
> - int subtype;
> - spinlock_t lock; /* hw lock */
> - u8 imask;
> - u8 pctl;
> - u8 xaddr;
> - u8 xdata;
> - u8 state;
> - struct w6692_ch bc[2];
> - struct dchannel dch;
> - char log[64];
> -};
> -
> -static LIST_HEAD(Cards);
> -static DEFINE_RWLOCK(card_lock); /* protect Cards */
> -
> -static int w6692_cnt;
> -static int debug;
> -static u32 led;
> -static u32 pots;
> -
> -static void
> -_set_debug(struct w6692_hw *card)
> -{
> - card->dch.debug = debug;
> - card->bc[0].bch.debug = debug;
> - card->bc[1].bch.debug = debug;
> -}
> -
> -static int
> -set_debug(const char *val, const struct kernel_param *kp)
> -{
> - int ret;
> - struct w6692_hw *card;
> -
> - ret = param_set_uint(val, kp);
> - if (!ret) {
> - read_lock(&card_lock);
> - list_for_each_entry(card, &Cards, list)
> - _set_debug(card);
> - read_unlock(&card_lock);
> - }
> - return ret;
> -}
> -
> -MODULE_AUTHOR("Karsten Keil");
> -MODULE_DESCRIPTION("mISDN driver for Winbond w6692 based cards");
> -MODULE_LICENSE("GPL v2");
> -MODULE_VERSION(W6692_REV);
> -module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR);
> -MODULE_PARM_DESC(debug, "W6692 debug mask");
> -module_param(led, uint, S_IRUGO | S_IWUSR);
> -MODULE_PARM_DESC(led, "W6692 LED support bitmask (one bit per card)");
> -module_param(pots, uint, S_IRUGO | S_IWUSR);
> -MODULE_PARM_DESC(pots, "W6692 POTS support bitmask (one bit per card)");
> -
> -static inline u8
> -ReadW6692(struct w6692_hw *card, u8 offset)
> -{
> - return inb(card->addr + offset);
> -}
> -
> -static inline void
> -WriteW6692(struct w6692_hw *card, u8 offset, u8 value)
> -{
> - outb(value, card->addr + offset);
> -}
> -
> -static inline u8
> -ReadW6692B(struct w6692_ch *bc, u8 offset)
> -{
> - return inb(bc->addr + offset);
> -}
> -
> -static inline void
> -WriteW6692B(struct w6692_ch *bc, u8 offset, u8 value)
> -{
> - outb(value, bc->addr + offset);
> -}
> -
> -static void
> -enable_hwirq(struct w6692_hw *card)
> -{
> - WriteW6692(card, W_IMASK, card->imask);
> -}
> -
> -static void
> -disable_hwirq(struct w6692_hw *card)
> -{
> - WriteW6692(card, W_IMASK, 0xff);
> -}
> -
> -static const char *W6692Ver[] = {"V00", "V01", "V10", "V11"};
> -
> -static void
> -W6692Version(struct w6692_hw *card)
> -{
> - int val;
> -
> - val = ReadW6692(card, W_D_RBCH);
> - pr_notice("%s: Winbond W6692 version: %s\n", card->name,
> - W6692Ver[(val >> 6) & 3]);
> -}
> -
> -static void
> -w6692_led_handler(struct w6692_hw *card, int on)
> -{
> - if ((!(card->fmask & led)) || card->subtype == W6692_USR)
> - return;
> - if (on) {
> - card->xdata &= 0xfb; /* LED ON */
> - WriteW6692(card, W_XDATA, card->xdata);
> - } else {
> - card->xdata |= 0x04; /* LED OFF */
> - WriteW6692(card, W_XDATA, card->xdata);
> - }
> -}
> -
> -static void
> -ph_command(struct w6692_hw *card, u8 cmd)
> -{
> - pr_debug("%s: ph_command %x\n", card->name, cmd);
> - WriteW6692(card, W_CIX, cmd);
> -}
> -
> -static void
> -W6692_new_ph(struct w6692_hw *card)
> -{
> - if (card->state == W_L1CMD_RST)
> - ph_command(card, W_L1CMD_DRC);
> - schedule_event(&card->dch, FLG_PHCHANGE);
> -}
> -
> -static void
> -W6692_ph_bh(struct dchannel *dch)
> -{
> - struct w6692_hw *card = dch->hw;
> -
> - switch (card->state) {
> - case W_L1CMD_RST:
> - dch->state = 0;
> - l1_event(dch->l1, HW_RESET_IND);
> - break;
> - case W_L1IND_CD:
> - dch->state = 3;
> - l1_event(dch->l1, HW_DEACT_CNF);
> - break;
> - case W_L1IND_DRD:
> - dch->state = 3;
> - l1_event(dch->l1, HW_DEACT_IND);
> - break;
> - case W_L1IND_CE:
> - dch->state = 4;
> - l1_event(dch->l1, HW_POWERUP_IND);
> - break;
> - case W_L1IND_LD:
> - if (dch->state <= 5) {
> - dch->state = 5;
> - l1_event(dch->l1, ANYSIGNAL);
> - } else {
> - dch->state = 8;
> - l1_event(dch->l1, LOSTFRAMING);
> - }
> - break;
> - case W_L1IND_ARD:
> - dch->state = 6;
> - l1_event(dch->l1, INFO2);
> - break;
> - case W_L1IND_AI8:
> - dch->state = 7;
> - l1_event(dch->l1, INFO4_P8);
> - break;
> - case W_L1IND_AI10:
> - dch->state = 7;
> - l1_event(dch->l1, INFO4_P10);
> - break;
> - default:
> - pr_debug("%s: TE unknown state %02x dch state %02x\n",
> - card->name, card->state, dch->state);
> - break;
> - }
> - pr_debug("%s: TE newstate %02x\n", card->name, dch->state);
> -}
> -
> -static void
> -W6692_empty_Dfifo(struct w6692_hw *card, int count)
> -{
> - struct dchannel *dch = &card->dch;
> - u8 *ptr;
> -
> - pr_debug("%s: empty_Dfifo %d\n", card->name, count);
> - if (!dch->rx_skb) {
> - dch->rx_skb = mI_alloc_skb(card->dch.maxlen, GFP_ATOMIC);
> - if (!dch->rx_skb) {
> - pr_info("%s: D receive out of memory\n", card->name);
> - WriteW6692(card, W_D_CMDR, W_D_CMDR_RACK);
> - return;
> - }
> - }
> - if ((dch->rx_skb->len + count) >= dch->maxlen) {
> - pr_debug("%s: empty_Dfifo overrun %d\n", card->name,
> - dch->rx_skb->len + count);
> - WriteW6692(card, W_D_CMDR, W_D_CMDR_RACK);
> - return;
> - }
> - ptr = skb_put(dch->rx_skb, count);
> - insb(card->addr + W_D_RFIFO, ptr, count);
> - WriteW6692(card, W_D_CMDR, W_D_CMDR_RACK);
> - if (debug & DEBUG_HW_DFIFO) {
> - snprintf(card->log, 63, "D-recv %s %d ",
> - card->name, count);
> - print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, ptr, count);
> - }
> -}
> -
> -static void
> -W6692_fill_Dfifo(struct w6692_hw *card)
> -{
> - struct dchannel *dch = &card->dch;
> - int count;
> - u8 *ptr;
> - u8 cmd = W_D_CMDR_XMS;
> -
> - pr_debug("%s: fill_Dfifo\n", card->name);
> - if (!dch->tx_skb)
> - return;
> - count = dch->tx_skb->len - dch->tx_idx;
> - if (count <= 0)
> - return;
> - if (count > W_D_FIFO_THRESH)
> - count = W_D_FIFO_THRESH;
> - else
> - cmd |= W_D_CMDR_XME;
> - ptr = dch->tx_skb->data + dch->tx_idx;
> - dch->tx_idx += count;
> - outsb(card->addr + W_D_XFIFO, ptr, count);
> - WriteW6692(card, W_D_CMDR, cmd);
> - if (test_and_set_bit(FLG_BUSY_TIMER, &dch->Flags)) {
> - pr_debug("%s: fill_Dfifo dbusytimer running\n", card->name);
> - timer_delete(&dch->timer);
> - }
> - dch->timer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ) / 1000);
> - add_timer(&dch->timer);
> - if (debug & DEBUG_HW_DFIFO) {
> - snprintf(card->log, 63, "D-send %s %d ",
> - card->name, count);
> - print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, ptr, count);
> - }
> -}
> -
> -static void
> -d_retransmit(struct w6692_hw *card)
> -{
> - struct dchannel *dch = &card->dch;
> -
> - if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
> - timer_delete(&dch->timer);
> -#ifdef FIXME
> - if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags))
> - dchannel_sched_event(dch, D_CLEARBUSY);
> -#endif
> - if (test_bit(FLG_TX_BUSY, &dch->Flags)) {
> - /* Restart frame */
> - dch->tx_idx = 0;
> - W6692_fill_Dfifo(card);
> - } else if (dch->tx_skb) { /* should not happen */
> - pr_info("%s: %s without TX_BUSY\n", card->name, __func__);
> - test_and_set_bit(FLG_TX_BUSY, &dch->Flags);
> - dch->tx_idx = 0;
> - W6692_fill_Dfifo(card);
> - } else {
> - pr_info("%s: XDU no TX_BUSY\n", card->name);
> - if (get_next_dframe(dch))
> - W6692_fill_Dfifo(card);
> - }
> -}
> -
> -static void
> -handle_rxD(struct w6692_hw *card) {
> - u8 stat;
> - int count;
> -
> - stat = ReadW6692(card, W_D_RSTA);
> - if (stat & (W_D_RSTA_RDOV | W_D_RSTA_CRCE | W_D_RSTA_RMB)) {
> - if (stat & W_D_RSTA_RDOV) {
> - pr_debug("%s: D-channel RDOV\n", card->name);
> -#ifdef ERROR_STATISTIC
> - card->dch.err_rx++;
> -#endif
> - }
> - if (stat & W_D_RSTA_CRCE) {
> - pr_debug("%s: D-channel CRC error\n", card->name);
> -#ifdef ERROR_STATISTIC
> - card->dch.err_crc++;
> -#endif
> - }
> - if (stat & W_D_RSTA_RMB) {
> - pr_debug("%s: D-channel ABORT\n", card->name);
> -#ifdef ERROR_STATISTIC
> - card->dch.err_rx++;
> -#endif
> - }
> - dev_kfree_skb(card->dch.rx_skb);
> - card->dch.rx_skb = NULL;
> - WriteW6692(card, W_D_CMDR, W_D_CMDR_RACK | W_D_CMDR_RRST);
> - } else {
> - count = ReadW6692(card, W_D_RBCL) & (W_D_FIFO_THRESH - 1);
> - if (count == 0)
> - count = W_D_FIFO_THRESH;
> - W6692_empty_Dfifo(card, count);
> - recv_Dchannel(&card->dch);
> - }
> -}
> -
> -static void
> -handle_txD(struct w6692_hw *card) {
> - if (test_and_clear_bit(FLG_BUSY_TIMER, &card->dch.Flags))
> - timer_delete(&card->dch.timer);
> - if (card->dch.tx_skb && card->dch.tx_idx < card->dch.tx_skb->len) {
> - W6692_fill_Dfifo(card);
> - } else {
> - dev_kfree_skb(card->dch.tx_skb);
> - if (get_next_dframe(&card->dch))
> - W6692_fill_Dfifo(card);
> - }
> -}
> -
> -static void
> -handle_statusD(struct w6692_hw *card)
> -{
> - struct dchannel *dch = &card->dch;
> - u8 exval, v1, cir;
> -
> - exval = ReadW6692(card, W_D_EXIR);
> -
> - pr_debug("%s: D_EXIR %02x\n", card->name, exval);
> - if (exval & (W_D_EXI_XDUN | W_D_EXI_XCOL)) {
> - /* Transmit underrun/collision */
> - pr_debug("%s: D-channel underrun/collision\n", card->name);
> -#ifdef ERROR_STATISTIC
> - dch->err_tx++;
> -#endif
> - d_retransmit(card);
> - }
> - if (exval & W_D_EXI_RDOV) { /* RDOV */
> - pr_debug("%s: D-channel RDOV\n", card->name);
> - WriteW6692(card, W_D_CMDR, W_D_CMDR_RRST);
> - }
> - if (exval & W_D_EXI_TIN2) /* TIN2 - never */
> - pr_debug("%s: spurious TIN2 interrupt\n", card->name);
> - if (exval & W_D_EXI_MOC) { /* MOC - not supported */
> - v1 = ReadW6692(card, W_MOSR);
> - pr_debug("%s: spurious MOC interrupt MOSR %02x\n",
> - card->name, v1);
> - }
> - if (exval & W_D_EXI_ISC) { /* ISC - Level1 change */
> - cir = ReadW6692(card, W_CIR);
> - pr_debug("%s: ISC CIR %02X\n", card->name, cir);
> - if (cir & W_CIR_ICC) {
> - v1 = cir & W_CIR_COD_MASK;
> - pr_debug("%s: ph_state_change %x -> %x\n", card->name,
> - dch->state, v1);
> - card->state = v1;
> - if (card->fmask & led) {
> - switch (v1) {
> - case W_L1IND_AI8:
> - case W_L1IND_AI10:
> - w6692_led_handler(card, 1);
> - break;
> - default:
> - w6692_led_handler(card, 0);
> - break;
> - }
> - }
> - W6692_new_ph(card);
> - }
> - if (cir & W_CIR_SCC) {
> - v1 = ReadW6692(card, W_SQR);
> - pr_debug("%s: SCC SQR %02X\n", card->name, v1);
> - }
> - }
> - if (exval & W_D_EXI_WEXP)
> - pr_debug("%s: spurious WEXP interrupt!\n", card->name);
> - if (exval & W_D_EXI_TEXP)
> - pr_debug("%s: spurious TEXP interrupt!\n", card->name);
> -}
> -
> -static void
> -W6692_empty_Bfifo(struct w6692_ch *wch, int count)
> -{
> - struct w6692_hw *card = wch->bch.hw;
> - u8 *ptr;
> - int maxlen;
> -
> - pr_debug("%s: empty_Bfifo %d\n", card->name, count);
> - if (unlikely(wch->bch.state == ISDN_P_NONE)) {
> - pr_debug("%s: empty_Bfifo ISDN_P_NONE\n", card->name);
> - WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT);
> - if (wch->bch.rx_skb)
> - skb_trim(wch->bch.rx_skb, 0);
> - return;
> - }
> - if (test_bit(FLG_RX_OFF, &wch->bch.Flags)) {
> - wch->bch.dropcnt += count;
> - WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT);
> - return;
> - }
> - maxlen = bchannel_get_rxbuf(&wch->bch, count);
> - if (maxlen < 0) {
> - WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT);
> - if (wch->bch.rx_skb)
> - skb_trim(wch->bch.rx_skb, 0);
> - pr_warn("%s.B%d: No bufferspace for %d bytes\n",
> - card->name, wch->bch.nr, count);
> - return;
> - }
> - ptr = skb_put(wch->bch.rx_skb, count);
> - insb(wch->addr + W_B_RFIFO, ptr, count);
> - WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT);
> - if (debug & DEBUG_HW_DFIFO) {
> - snprintf(card->log, 63, "B%1d-recv %s %d ",
> - wch->bch.nr, card->name, count);
> - print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, ptr, count);
> - }
> -}
> -
> -static void
> -W6692_fill_Bfifo(struct w6692_ch *wch)
> -{
> - struct w6692_hw *card = wch->bch.hw;
> - int count, fillempty = 0;
> - u8 *ptr, cmd = W_B_CMDR_RACT | W_B_CMDR_XMS;
> -
> - pr_debug("%s: fill Bfifo\n", card->name);
> - if (!wch->bch.tx_skb) {
> - if (!test_bit(FLG_TX_EMPTY, &wch->bch.Flags))
> - return;
> - ptr = wch->bch.fill;
> - count = W_B_FIFO_THRESH;
> - fillempty = 1;
> - } else {
> - count = wch->bch.tx_skb->len - wch->bch.tx_idx;
> - if (count <= 0)
> - return;
> - ptr = wch->bch.tx_skb->data + wch->bch.tx_idx;
> - }
> - if (count > W_B_FIFO_THRESH)
> - count = W_B_FIFO_THRESH;
> - else if (test_bit(FLG_HDLC, &wch->bch.Flags))
> - cmd |= W_B_CMDR_XME;
> -
> - pr_debug("%s: fill Bfifo%d/%d\n", card->name,
> - count, wch->bch.tx_idx);
> - wch->bch.tx_idx += count;
> - if (fillempty) {
> - while (count > 0) {
> - outsb(wch->addr + W_B_XFIFO, ptr, MISDN_BCH_FILL_SIZE);
> - count -= MISDN_BCH_FILL_SIZE;
> - }
> - } else {
> - outsb(wch->addr + W_B_XFIFO, ptr, count);
> - }
> - WriteW6692B(wch, W_B_CMDR, cmd);
> - if ((debug & DEBUG_HW_BFIFO) && !fillempty) {
> - snprintf(card->log, 63, "B%1d-send %s %d ",
> - wch->bch.nr, card->name, count);
> - print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, ptr, count);
> - }
> -}
> -
> -#if 0
> -static int
> -setvolume(struct w6692_ch *wch, int mic, struct sk_buff *skb)
> -{
> - struct w6692_hw *card = wch->bch.hw;
> - u16 *vol = (u16 *)skb->data;
> - u8 val;
> -
> - if ((!(card->fmask & pots)) ||
> - !test_bit(FLG_TRANSPARENT, &wch->bch.Flags))
> - return -ENODEV;
> - if (skb->len < 2)
> - return -EINVAL;
> - if (*vol > 7)
> - return -EINVAL;
> - val = *vol & 7;
> - val = 7 - val;
> - if (mic) {
> - val <<= 3;
> - card->xaddr &= 0xc7;
> - } else {
> - card->xaddr &= 0xf8;
> - }
> - card->xaddr |= val;
> - WriteW6692(card, W_XADDR, card->xaddr);
> - return 0;
> -}
> -
> -static int
> -enable_pots(struct w6692_ch *wch)
> -{
> - struct w6692_hw *card = wch->bch.hw;
> -
> - if ((!(card->fmask & pots)) ||
> - !test_bit(FLG_TRANSPARENT, &wch->bch.Flags))
> - return -ENODEV;
> - wch->b_mode |= W_B_MODE_EPCM | W_B_MODE_BSW0;
> - WriteW6692B(wch, W_B_MODE, wch->b_mode);
> - WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_XRST);
> - card->pctl |= ((wch->bch.nr & 2) ? W_PCTL_PCX : 0);
> - WriteW6692(card, W_PCTL, card->pctl);
> - return 0;
> -}
> -#endif
> -
> -static int
> -disable_pots(struct w6692_ch *wch)
> -{
> - struct w6692_hw *card = wch->bch.hw;
> -
> - if (!(card->fmask & pots))
> - return -ENODEV;
> - wch->b_mode &= ~(W_B_MODE_EPCM | W_B_MODE_BSW0);
> - WriteW6692B(wch, W_B_MODE, wch->b_mode);
> - WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_RACT |
> - W_B_CMDR_XRST);
> - return 0;
> -}
> -
> -static int
> -w6692_mode(struct w6692_ch *wch, u32 pr)
> -{
> - struct w6692_hw *card;
> -
> - card = wch->bch.hw;
> - pr_debug("%s: B%d protocol %x-->%x\n", card->name,
> - wch->bch.nr, wch->bch.state, pr);
> - switch (pr) {
> - case ISDN_P_NONE:
> - if ((card->fmask & pots) && (wch->b_mode & W_B_MODE_EPCM))
> - disable_pots(wch);
> - wch->b_mode = 0;
> - mISDN_clear_bchannel(&wch->bch);
> - WriteW6692B(wch, W_B_MODE, wch->b_mode);
> - WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_XRST);
> - test_and_clear_bit(FLG_HDLC, &wch->bch.Flags);
> - test_and_clear_bit(FLG_TRANSPARENT, &wch->bch.Flags);
> - break;
> - case ISDN_P_B_RAW:
> - wch->b_mode = W_B_MODE_MMS;
> - WriteW6692B(wch, W_B_MODE, wch->b_mode);
> - WriteW6692B(wch, W_B_EXIM, 0);
> - WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_RACT |
> - W_B_CMDR_XRST);
> - test_and_set_bit(FLG_TRANSPARENT, &wch->bch.Flags);
> - break;
> - case ISDN_P_B_HDLC:
> - wch->b_mode = W_B_MODE_ITF;
> - WriteW6692B(wch, W_B_MODE, wch->b_mode);
> - WriteW6692B(wch, W_B_ADM1, 0xff);
> - WriteW6692B(wch, W_B_ADM2, 0xff);
> - WriteW6692B(wch, W_B_EXIM, 0);
> - WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_RACT |
> - W_B_CMDR_XRST);
> - test_and_set_bit(FLG_HDLC, &wch->bch.Flags);
> - break;
> - default:
> - pr_info("%s: protocol %x not known\n", card->name, pr);
> - return -ENOPROTOOPT;
> - }
> - wch->bch.state = pr;
> - return 0;
> -}
> -
> -static void
> -send_next(struct w6692_ch *wch)
> -{
> - if (wch->bch.tx_skb && wch->bch.tx_idx < wch->bch.tx_skb->len) {
> - W6692_fill_Bfifo(wch);
> - } else {
> - dev_kfree_skb(wch->bch.tx_skb);
> - if (get_next_bframe(&wch->bch)) {
> - W6692_fill_Bfifo(wch);
> - test_and_clear_bit(FLG_TX_EMPTY, &wch->bch.Flags);
> - } else if (test_bit(FLG_TX_EMPTY, &wch->bch.Flags)) {
> - W6692_fill_Bfifo(wch);
> - }
> - }
> -}
> -
> -static void
> -W6692B_interrupt(struct w6692_hw *card, int ch)
> -{
> - struct w6692_ch *wch = &card->bc[ch];
> - int count;
> - u8 stat, star = 0;
> -
> - stat = ReadW6692B(wch, W_B_EXIR);
> - pr_debug("%s: B%d EXIR %02x\n", card->name, wch->bch.nr, stat);
> - if (stat & W_B_EXI_RME) {
> - star = ReadW6692B(wch, W_B_STAR);
> - if (star & (W_B_STAR_RDOV | W_B_STAR_CRCE | W_B_STAR_RMB)) {
> - if ((star & W_B_STAR_RDOV) &&
> - test_bit(FLG_ACTIVE, &wch->bch.Flags)) {
> - pr_debug("%s: B%d RDOV proto=%x\n", card->name,
> - wch->bch.nr, wch->bch.state);
> -#ifdef ERROR_STATISTIC
> - wch->bch.err_rdo++;
> -#endif
> - }
> - if (test_bit(FLG_HDLC, &wch->bch.Flags)) {
> - if (star & W_B_STAR_CRCE) {
> - pr_debug("%s: B%d CRC error\n",
> - card->name, wch->bch.nr);
> -#ifdef ERROR_STATISTIC
> - wch->bch.err_crc++;
> -#endif
> - }
> - if (star & W_B_STAR_RMB) {
> - pr_debug("%s: B%d message abort\n",
> - card->name, wch->bch.nr);
> -#ifdef ERROR_STATISTIC
> - wch->bch.err_inv++;
> -#endif
> - }
> - }
> - WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK |
> - W_B_CMDR_RRST | W_B_CMDR_RACT);
> - if (wch->bch.rx_skb)
> - skb_trim(wch->bch.rx_skb, 0);
> - } else {
> - count = ReadW6692B(wch, W_B_RBCL) &
> - (W_B_FIFO_THRESH - 1);
> - if (count == 0)
> - count = W_B_FIFO_THRESH;
> - W6692_empty_Bfifo(wch, count);
> - recv_Bchannel(&wch->bch, 0, false);
> - }
> - }
> - if (stat & W_B_EXI_RMR) {
> - if (!(stat & W_B_EXI_RME))
> - star = ReadW6692B(wch, W_B_STAR);
> - if (star & W_B_STAR_RDOV) {
> - pr_debug("%s: B%d RDOV proto=%x\n", card->name,
> - wch->bch.nr, wch->bch.state);
> -#ifdef ERROR_STATISTIC
> - wch->bch.err_rdo++;
> -#endif
> - WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK |
> - W_B_CMDR_RRST | W_B_CMDR_RACT);
> - } else {
> - W6692_empty_Bfifo(wch, W_B_FIFO_THRESH);
> - if (test_bit(FLG_TRANSPARENT, &wch->bch.Flags))
> - recv_Bchannel(&wch->bch, 0, false);
> - }
> - }
> - if (stat & W_B_EXI_RDOV) {
> - /* only if it is not handled yet */
> - if (!(star & W_B_STAR_RDOV)) {
> - pr_debug("%s: B%d RDOV IRQ proto=%x\n", card->name,
> - wch->bch.nr, wch->bch.state);
> -#ifdef ERROR_STATISTIC
> - wch->bch.err_rdo++;
> -#endif
> - WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK |
> - W_B_CMDR_RRST | W_B_CMDR_RACT);
> - }
> - }
> - if (stat & W_B_EXI_XFR) {
> - if (!(stat & (W_B_EXI_RME | W_B_EXI_RMR))) {
> - star = ReadW6692B(wch, W_B_STAR);
> - pr_debug("%s: B%d star %02x\n", card->name,
> - wch->bch.nr, star);
> - }
> - if (star & W_B_STAR_XDOW) {
> - pr_warn("%s: B%d XDOW proto=%x\n", card->name,
> - wch->bch.nr, wch->bch.state);
> -#ifdef ERROR_STATISTIC
> - wch->bch.err_xdu++;
> -#endif
> - WriteW6692B(wch, W_B_CMDR, W_B_CMDR_XRST |
> - W_B_CMDR_RACT);
> - /* resend */
> - if (wch->bch.tx_skb) {
> - if (!test_bit(FLG_TRANSPARENT, &wch->bch.Flags))
> - wch->bch.tx_idx = 0;
> - }
> - }
> - send_next(wch);
> - if (star & W_B_STAR_XDOW)
> - return; /* handle XDOW only once */
> - }
> - if (stat & W_B_EXI_XDUN) {
> - pr_warn("%s: B%d XDUN proto=%x\n", card->name,
> - wch->bch.nr, wch->bch.state);
> -#ifdef ERROR_STATISTIC
> - wch->bch.err_xdu++;
> -#endif
> - /* resend - no XRST needed */
> - if (wch->bch.tx_skb) {
> - if (!test_bit(FLG_TRANSPARENT, &wch->bch.Flags))
> - wch->bch.tx_idx = 0;
> - } else if (test_bit(FLG_FILLEMPTY, &wch->bch.Flags)) {
> - test_and_set_bit(FLG_TX_EMPTY, &wch->bch.Flags);
> - }
> - send_next(wch);
> - }
> -}
> -
> -static irqreturn_t
> -w6692_irq(int intno, void *dev_id)
> -{
> - struct w6692_hw *card = dev_id;
> - u8 ista;
> -
> - spin_lock(&card->lock);
> - ista = ReadW6692(card, W_ISTA);
> - if ((ista | card->imask) == card->imask) {
> - /* possible a shared IRQ reqest */
> - spin_unlock(&card->lock);
> - return IRQ_NONE;
> - }
> - card->irqcnt++;
> - pr_debug("%s: ista %02x\n", card->name, ista);
> - ista &= ~card->imask;
> - if (ista & W_INT_B1_EXI)
> - W6692B_interrupt(card, 0);
> - if (ista & W_INT_B2_EXI)
> - W6692B_interrupt(card, 1);
> - if (ista & W_INT_D_RME)
> - handle_rxD(card);
> - if (ista & W_INT_D_RMR)
> - W6692_empty_Dfifo(card, W_D_FIFO_THRESH);
> - if (ista & W_INT_D_XFR)
> - handle_txD(card);
> - if (ista & W_INT_D_EXI)
> - handle_statusD(card);
> - if (ista & (W_INT_XINT0 | W_INT_XINT1)) /* XINT0/1 - never */
> - pr_debug("%s: W6692 spurious XINT!\n", card->name);
> -/* End IRQ Handler */
> - spin_unlock(&card->lock);
> - return IRQ_HANDLED;
> -}
> -
> -static void
> -dbusy_timer_handler(struct timer_list *t)
> -{
> - struct dchannel *dch = timer_container_of(dch, t, timer);
> - struct w6692_hw *card = dch->hw;
> - int rbch, star;
> - u_long flags;
> -
> - if (test_bit(FLG_BUSY_TIMER, &dch->Flags)) {
> - spin_lock_irqsave(&card->lock, flags);
> - rbch = ReadW6692(card, W_D_RBCH);
> - star = ReadW6692(card, W_D_STAR);
> - pr_debug("%s: D-Channel Busy RBCH %02x STAR %02x\n",
> - card->name, rbch, star);
> - if (star & W_D_STAR_XBZ) /* D-Channel Busy */
> - test_and_set_bit(FLG_L1_BUSY, &dch->Flags);
> - else {
> - /* discard frame; reset transceiver */
> - test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags);
> - if (dch->tx_idx)
> - dch->tx_idx = 0;
> - else
> - pr_info("%s: W6692 D-Channel Busy no tx_idx\n",
> - card->name);
> - /* Transmitter reset */
> - WriteW6692(card, W_D_CMDR, W_D_CMDR_XRST);
> - }
> - spin_unlock_irqrestore(&card->lock, flags);
> - }
> -}
> -
> -static void initW6692(struct w6692_hw *card)
> -{
> - u8 val;
> -
> - timer_setup(&card->dch.timer, dbusy_timer_handler, 0);
> - w6692_mode(&card->bc[0], ISDN_P_NONE);
> - w6692_mode(&card->bc[1], ISDN_P_NONE);
> - WriteW6692(card, W_D_CTL, 0x00);
> - disable_hwirq(card);
> - WriteW6692(card, W_D_SAM, 0xff);
> - WriteW6692(card, W_D_TAM, 0xff);
> - WriteW6692(card, W_D_MODE, W_D_MODE_RACT);
> - card->state = W_L1CMD_RST;
> - ph_command(card, W_L1CMD_RST);
> - ph_command(card, W_L1CMD_ECK);
> - /* enable all IRQ but extern */
> - card->imask = 0x18;
> - WriteW6692(card, W_D_EXIM, 0x00);
> - WriteW6692B(&card->bc[0], W_B_EXIM, 0);
> - WriteW6692B(&card->bc[1], W_B_EXIM, 0);
> - /* Reset D-chan receiver and transmitter */
> - WriteW6692(card, W_D_CMDR, W_D_CMDR_RRST | W_D_CMDR_XRST);
> - /* Reset B-chan receiver and transmitter */
> - WriteW6692B(&card->bc[0], W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_XRST);
> - WriteW6692B(&card->bc[1], W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_XRST);
> - /* enable peripheral */
> - if (card->subtype == 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
> - */
> - card->pctl = 0x80;
> - card->xdata = 0;
> - WriteW6692(card, W_PCTL, card->pctl);
> - WriteW6692(card, W_XDATA, card->xdata);
> - } else {
> - card->pctl = W_PCTL_OE5 | W_PCTL_OE4 | W_PCTL_OE2 |
> - W_PCTL_OE1 | W_PCTL_OE0;
> - card->xaddr = 0x00;/* all sw off */
> - if (card->fmask & pots)
> - card->xdata |= 0x06; /* POWER UP/ LED OFF / ALAW */
> - if (card->fmask & led)
> - card->xdata |= 0x04; /* LED OFF */
> - if ((card->fmask & pots) || (card->fmask & led)) {
> - WriteW6692(card, W_PCTL, card->pctl);
> - WriteW6692(card, W_XADDR, card->xaddr);
> - WriteW6692(card, W_XDATA, card->xdata);
> - val = ReadW6692(card, W_XADDR);
> - if (debug & DEBUG_HW)
> - pr_notice("%s: W_XADDR=%02x\n",
> - card->name, val);
> - }
> - }
> -}
> -
> -static void
> -reset_w6692(struct w6692_hw *card)
> -{
> - WriteW6692(card, W_D_CTL, W_D_CTL_SRST);
> - mdelay(10);
> - WriteW6692(card, W_D_CTL, 0);
> -}
> -
> -static int
> -init_card(struct w6692_hw *card)
> -{
> - int cnt = 3;
> - u_long flags;
> -
> - spin_lock_irqsave(&card->lock, flags);
> - disable_hwirq(card);
> - spin_unlock_irqrestore(&card->lock, flags);
> - if (request_irq(card->irq, w6692_irq, IRQF_SHARED, card->name, card)) {
> - pr_info("%s: couldn't get interrupt %d\n", card->name,
> - card->irq);
> - return -EIO;
> - }
> - while (cnt--) {
> - spin_lock_irqsave(&card->lock, flags);
> - initW6692(card);
> - enable_hwirq(card);
> - spin_unlock_irqrestore(&card->lock, flags);
> - /* Timeout 10ms */
> - msleep_interruptible(10);
> - if (debug & DEBUG_HW)
> - pr_notice("%s: IRQ %d count %d\n", card->name,
> - card->irq, card->irqcnt);
> - if (!card->irqcnt) {
> - pr_info("%s: IRQ(%d) getting no IRQs during init %d\n",
> - card->name, card->irq, 3 - cnt);
> - reset_w6692(card);
> - } else
> - return 0;
> - }
> - free_irq(card->irq, card);
> - return -EIO;
> -}
> -
> -static int
> -w6692_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)
> -{
> - struct bchannel *bch = container_of(ch, struct bchannel, ch);
> - struct w6692_ch *bc = container_of(bch, struct w6692_ch, bch);
> - struct w6692_hw *card = bch->hw;
> - int ret = -EINVAL;
> - struct mISDNhead *hh = mISDN_HEAD_P(skb);
> - unsigned long flags;
> -
> - switch (hh->prim) {
> - case PH_DATA_REQ:
> - spin_lock_irqsave(&card->lock, flags);
> - ret = bchannel_senddata(bch, skb);
> - if (ret > 0) { /* direct TX */
> - ret = 0;
> - W6692_fill_Bfifo(bc);
> - }
> - spin_unlock_irqrestore(&card->lock, flags);
> - return ret;
> - case PH_ACTIVATE_REQ:
> - spin_lock_irqsave(&card->lock, flags);
> - if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags))
> - ret = w6692_mode(bc, ch->protocol);
> - else
> - ret = 0;
> - spin_unlock_irqrestore(&card->lock, flags);
> - if (!ret)
> - _queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
> - NULL, GFP_KERNEL);
> - break;
> - case PH_DEACTIVATE_REQ:
> - spin_lock_irqsave(&card->lock, flags);
> - mISDN_clear_bchannel(bch);
> - w6692_mode(bc, ISDN_P_NONE);
> - spin_unlock_irqrestore(&card->lock, flags);
> - _queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
> - NULL, GFP_KERNEL);
> - ret = 0;
> - break;
> - default:
> - pr_info("%s: %s unknown prim(%x,%x)\n",
> - card->name, __func__, hh->prim, hh->id);
> - ret = -EINVAL;
> - }
> - if (!ret)
> - dev_kfree_skb(skb);
> - return ret;
> -}
> -
> -static int
> -channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
> -{
> - return mISDN_ctrl_bchannel(bch, cq);
> -}
> -
> -static int
> -open_bchannel(struct w6692_hw *card, struct channel_req *rq)
> -{
> - struct bchannel *bch;
> -
> - if (rq->adr.channel == 0 || rq->adr.channel > 2)
> - return -EINVAL;
> - if (rq->protocol == ISDN_P_NONE)
> - return -EINVAL;
> - bch = &card->bc[rq->adr.channel - 1].bch;
> - if (test_and_set_bit(FLG_OPEN, &bch->Flags))
> - return -EBUSY; /* b-channel can be only open once */
> - bch->ch.protocol = rq->protocol;
> - rq->ch = &bch->ch;
> - return 0;
> -}
> -
> -static int
> -channel_ctrl(struct w6692_hw *card, struct mISDN_ctrl_req *cq)
> -{
> - int ret = 0;
> -
> - switch (cq->op) {
> - case MISDN_CTRL_GETOP:
> - cq->op = MISDN_CTRL_L1_TIMER3;
> - break;
> - case MISDN_CTRL_L1_TIMER3:
> - ret = l1_event(card->dch.l1, HW_TIMER3_VALUE | (cq->p1 & 0xff));
> - break;
> - default:
> - pr_info("%s: unknown CTRL OP %x\n", card->name, cq->op);
> - ret = -EINVAL;
> - break;
> - }
> - return ret;
> -}
> -
> -static int
> -w6692_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
> -{
> - struct bchannel *bch = container_of(ch, struct bchannel, ch);
> - struct w6692_ch *bc = container_of(bch, struct w6692_ch, bch);
> - struct w6692_hw *card = bch->hw;
> - int ret = -EINVAL;
> - u_long flags;
> -
> - pr_debug("%s: %s cmd:%x %p\n", card->name, __func__, cmd, arg);
> - switch (cmd) {
> - case CLOSE_CHANNEL:
> - test_and_clear_bit(FLG_OPEN, &bch->Flags);
> - cancel_work_sync(&bch->workq);
> - spin_lock_irqsave(&card->lock, flags);
> - mISDN_clear_bchannel(bch);
> - w6692_mode(bc, ISDN_P_NONE);
> - spin_unlock_irqrestore(&card->lock, flags);
> - ch->protocol = ISDN_P_NONE;
> - ch->peer = NULL;
> - module_put(THIS_MODULE);
> - ret = 0;
> - break;
> - case CONTROL_CHANNEL:
> - ret = channel_bctrl(bch, arg);
> - break;
> - default:
> - pr_info("%s: %s unknown prim(%x)\n",
> - card->name, __func__, cmd);
> - }
> - return ret;
> -}
> -
> -static int
> -w6692_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb)
> -{
> - struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
> - struct dchannel *dch = container_of(dev, struct dchannel, dev);
> - struct w6692_hw *card = container_of(dch, struct w6692_hw, dch);
> - int ret = -EINVAL;
> - struct mISDNhead *hh = mISDN_HEAD_P(skb);
> - u32 id;
> - u_long flags;
> -
> - switch (hh->prim) {
> - case PH_DATA_REQ:
> - spin_lock_irqsave(&card->lock, flags);
> - ret = dchannel_senddata(dch, skb);
> - if (ret > 0) { /* direct TX */
> - id = hh->id; /* skb can be freed */
> - W6692_fill_Dfifo(card);
> - ret = 0;
> - spin_unlock_irqrestore(&card->lock, flags);
> - queue_ch_frame(ch, PH_DATA_CNF, id, NULL);
> - } else
> - spin_unlock_irqrestore(&card->lock, flags);
> - return ret;
> - case PH_ACTIVATE_REQ:
> - ret = l1_event(dch->l1, hh->prim);
> - break;
> - case PH_DEACTIVATE_REQ:
> - test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
> - ret = l1_event(dch->l1, hh->prim);
> - break;
> - }
> -
> - if (!ret)
> - dev_kfree_skb(skb);
> - return ret;
> -}
> -
> -static int
> -w6692_l1callback(struct dchannel *dch, u32 cmd)
> -{
> - struct w6692_hw *card = container_of(dch, struct w6692_hw, dch);
> - u_long flags;
> -
> - pr_debug("%s: cmd(%x) state(%02x)\n", card->name, cmd, card->state);
> - switch (cmd) {
> - case INFO3_P8:
> - spin_lock_irqsave(&card->lock, flags);
> - ph_command(card, W_L1CMD_AR8);
> - spin_unlock_irqrestore(&card->lock, flags);
> - break;
> - case INFO3_P10:
> - spin_lock_irqsave(&card->lock, flags);
> - ph_command(card, W_L1CMD_AR10);
> - spin_unlock_irqrestore(&card->lock, flags);
> - break;
> - case HW_RESET_REQ:
> - spin_lock_irqsave(&card->lock, flags);
> - if (card->state != W_L1IND_DRD)
> - ph_command(card, W_L1CMD_RST);
> - ph_command(card, W_L1CMD_ECK);
> - spin_unlock_irqrestore(&card->lock, flags);
> - break;
> - case HW_DEACT_REQ:
> - skb_queue_purge(&dch->squeue);
> - if (dch->tx_skb) {
> - dev_kfree_skb(dch->tx_skb);
> - dch->tx_skb = NULL;
> - }
> - dch->tx_idx = 0;
> - if (dch->rx_skb) {
> - dev_kfree_skb(dch->rx_skb);
> - dch->rx_skb = NULL;
> - }
> - test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
> - if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
> - timer_delete(&dch->timer);
> - break;
> - case HW_POWERUP_REQ:
> - spin_lock_irqsave(&card->lock, flags);
> - ph_command(card, W_L1CMD_ECK);
> - spin_unlock_irqrestore(&card->lock, flags);
> - break;
> - case PH_ACTIVATE_IND:
> - test_and_set_bit(FLG_ACTIVE, &dch->Flags);
> - _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
> - GFP_ATOMIC);
> - break;
> - case PH_DEACTIVATE_IND:
> - test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
> - _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
> - GFP_ATOMIC);
> - break;
> - default:
> - pr_debug("%s: %s unknown command %x\n", card->name,
> - __func__, cmd);
> - return -1;
> - }
> - return 0;
> -}
> -
> -static int
> -open_dchannel(struct w6692_hw *card, struct channel_req *rq, void *caller)
> -{
> - pr_debug("%s: %s dev(%d) open from %p\n", card->name, __func__,
> - card->dch.dev.id, caller);
> - if (rq->protocol != ISDN_P_TE_S0)
> - return -EINVAL;
> - if (rq->adr.channel == 1)
> - /* E-Channel not supported */
> - return -EINVAL;
> - rq->ch = &card->dch.dev.D;
> - rq->ch->protocol = rq->protocol;
> - if (card->dch.state == 7)
> - _queue_data(rq->ch, PH_ACTIVATE_IND, MISDN_ID_ANY,
> - 0, NULL, GFP_KERNEL);
> - return 0;
> -}
> -
> -static int
> -w6692_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
> -{
> - struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
> - struct dchannel *dch = container_of(dev, struct dchannel, dev);
> - struct w6692_hw *card = container_of(dch, struct w6692_hw, dch);
> - struct channel_req *rq;
> - int err = 0;
> -
> - pr_debug("%s: DCTRL: %x %p\n", card->name, cmd, arg);
> - switch (cmd) {
> - case OPEN_CHANNEL:
> - rq = arg;
> - if (rq->protocol == ISDN_P_TE_S0)
> - err = open_dchannel(card, rq, __builtin_return_address(0));
> - else
> - err = open_bchannel(card, rq);
> - if (err)
> - break;
> - if (!try_module_get(THIS_MODULE))
> - pr_info("%s: cannot get module\n", card->name);
> - break;
> - case CLOSE_CHANNEL:
> - pr_debug("%s: dev(%d) close from %p\n", card->name,
> - dch->dev.id, __builtin_return_address(0));
> - module_put(THIS_MODULE);
> - break;
> - case CONTROL_CHANNEL:
> - err = channel_ctrl(card, arg);
> - break;
> - default:
> - pr_debug("%s: unknown DCTRL command %x\n", card->name, cmd);
> - return -EINVAL;
> - }
> - return err;
> -}
> -
> -static int
> -setup_w6692(struct w6692_hw *card)
> -{
> - u32 val;
> -
> - if (!request_region(card->addr, 256, card->name)) {
> - pr_info("%s: config port %x-%x already in use\n", card->name,
> - card->addr, card->addr + 255);
> - return -EIO;
> - }
> - W6692Version(card);
> - card->bc[0].addr = card->addr;
> - card->bc[1].addr = card->addr + 0x40;
> - val = ReadW6692(card, W_ISTA);
> - if (debug & DEBUG_HW)
> - pr_notice("%s ISTA=%02x\n", card->name, val);
> - val = ReadW6692(card, W_IMASK);
> - if (debug & DEBUG_HW)
> - pr_notice("%s IMASK=%02x\n", card->name, val);
> - val = ReadW6692(card, W_D_EXIR);
> - if (debug & DEBUG_HW)
> - pr_notice("%s D_EXIR=%02x\n", card->name, val);
> - val = ReadW6692(card, W_D_EXIM);
> - if (debug & DEBUG_HW)
> - pr_notice("%s D_EXIM=%02x\n", card->name, val);
> - val = ReadW6692(card, W_D_RSTA);
> - if (debug & DEBUG_HW)
> - pr_notice("%s D_RSTA=%02x\n", card->name, val);
> - return 0;
> -}
> -
> -static void
> -release_card(struct w6692_hw *card)
> -{
> - u_long flags;
> -
> - spin_lock_irqsave(&card->lock, flags);
> - disable_hwirq(card);
> - w6692_mode(&card->bc[0], ISDN_P_NONE);
> - w6692_mode(&card->bc[1], ISDN_P_NONE);
> - if ((card->fmask & led) || card->subtype == W6692_USR) {
> - card->xdata |= 0x04; /* LED OFF */
> - WriteW6692(card, W_XDATA, card->xdata);
> - }
> - spin_unlock_irqrestore(&card->lock, flags);
> - free_irq(card->irq, card);
> - l1_event(card->dch.l1, CLOSE_CHANNEL);
> - mISDN_unregister_device(&card->dch.dev);
> - release_region(card->addr, 256);
> - mISDN_freebchannel(&card->bc[1].bch);
> - mISDN_freebchannel(&card->bc[0].bch);
> - mISDN_freedchannel(&card->dch);
> - write_lock_irqsave(&card_lock, flags);
> - list_del(&card->list);
> - write_unlock_irqrestore(&card_lock, flags);
> - pci_disable_device(card->pdev);
> - pci_set_drvdata(card->pdev, NULL);
> - kfree(card);
> -}
> -
> -static int
> -setup_instance(struct w6692_hw *card)
> -{
> - int i, err;
> - u_long flags;
> -
> - snprintf(card->name, MISDN_MAX_IDLEN - 1, "w6692.%d", w6692_cnt + 1);
> - write_lock_irqsave(&card_lock, flags);
> - list_add_tail(&card->list, &Cards);
> - write_unlock_irqrestore(&card_lock, flags);
> - card->fmask = (1 << w6692_cnt);
> - _set_debug(card);
> - spin_lock_init(&card->lock);
> - mISDN_initdchannel(&card->dch, MAX_DFRAME_LEN_L1, W6692_ph_bh);
> - card->dch.dev.Dprotocols = (1 << ISDN_P_TE_S0);
> - card->dch.dev.D.send = w6692_l2l1D;
> - card->dch.dev.D.ctrl = w6692_dctrl;
> - card->dch.dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
> - (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
> - card->dch.hw = card;
> - card->dch.dev.nrbchan = 2;
> - for (i = 0; i < 2; i++) {
> - mISDN_initbchannel(&card->bc[i].bch, MAX_DATA_MEM,
> - W_B_FIFO_THRESH);
> - card->bc[i].bch.hw = card;
> - card->bc[i].bch.nr = i + 1;
> - card->bc[i].bch.ch.nr = i + 1;
> - card->bc[i].bch.ch.send = w6692_l2l1B;
> - card->bc[i].bch.ch.ctrl = w6692_bctrl;
> - set_channelmap(i + 1, card->dch.dev.channelmap);
> - list_add(&card->bc[i].bch.ch.list, &card->dch.dev.bchannels);
> - }
> - err = setup_w6692(card);
> - if (err)
> - goto error_setup;
> - err = mISDN_register_device(&card->dch.dev, &card->pdev->dev,
> - card->name);
> - if (err)
> - goto error_reg;
> - err = init_card(card);
> - if (err)
> - goto error_init;
> - err = create_l1(&card->dch, w6692_l1callback);
> - if (!err) {
> - w6692_cnt++;
> - pr_notice("W6692 %d cards installed\n", w6692_cnt);
> - return 0;
> - }
> -
> - free_irq(card->irq, card);
> -error_init:
> - mISDN_unregister_device(&card->dch.dev);
> -error_reg:
> - release_region(card->addr, 256);
> -error_setup:
> - mISDN_freebchannel(&card->bc[1].bch);
> - mISDN_freebchannel(&card->bc[0].bch);
> - mISDN_freedchannel(&card->dch);
> - write_lock_irqsave(&card_lock, flags);
> - list_del(&card->list);
> - write_unlock_irqrestore(&card_lock, flags);
> - kfree(card);
> - return err;
> -}
> -
> -static int
> -w6692_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
> -{
> - int err = -ENOMEM;
> - struct w6692_hw *card;
> - struct w6692map *m = (struct w6692map *)ent->driver_data;
> -
> - card = kzalloc_obj(struct w6692_hw);
> - if (!card) {
> - pr_info("No kmem for w6692 card\n");
> - return err;
> - }
> - card->pdev = pdev;
> - card->subtype = m->subtype;
> - err = pci_enable_device(pdev);
> - if (err) {
> - kfree(card);
> - return err;
> - }
> -
> - printk(KERN_INFO "mISDN_w6692: found adapter %s at %s\n",
> - m->name, pci_name(pdev));
> -
> - card->addr = pci_resource_start(pdev, 1);
> - card->irq = pdev->irq;
> - pci_set_drvdata(pdev, card);
> - err = setup_instance(card);
> - if (err)
> - pci_set_drvdata(pdev, NULL);
> - return err;
> -}
> -
> -static void
> -w6692_remove_pci(struct pci_dev *pdev)
> -{
> - struct w6692_hw *card = pci_get_drvdata(pdev);
> -
> - if (card)
> - release_card(card);
> - else
> - if (debug)
> - pr_notice("%s: drvdata already removed\n", __func__);
> -}
> -
> -static const struct pci_device_id w6692_ids[] = {
> - { PCI_VENDOR_ID_DYNALINK, PCI_DEVICE_ID_DYNALINK_IS64PH,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0, (ulong)&w6692_map[0]},
> - { PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_6692,
> - PCI_VENDOR_ID_USR, PCI_DEVICE_ID_USR_6692, 0, 0,
> - (ulong)&w6692_map[2]},
> - { PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_6692,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0, (ulong)&w6692_map[1]},
> - { }
> -};
> -MODULE_DEVICE_TABLE(pci, w6692_ids);
> -
> -static struct pci_driver w6692_driver = {
> - .name = "w6692",
> - .probe = w6692_probe,
> - .remove = w6692_remove_pci,
> - .id_table = w6692_ids,
> -};
> -
> -static int __init w6692_init(void)
> -{
> - int err;
> -
> - pr_notice("Winbond W6692 PCI driver Rev. %s\n", W6692_REV);
> -
> - err = pci_register_driver(&w6692_driver);
> - return err;
> -}
> -
> -static void __exit w6692_cleanup(void)
> -{
> - pci_unregister_driver(&w6692_driver);
> -}
> -
> -module_init(w6692_init);
> -module_exit(w6692_cleanup);
> diff --git a/drivers/isdn/mISDN/clock.c b/drivers/isdn/mISDN/clock.c
> deleted file mode 100644
> index 2668be9de20a..000000000000
> --- a/drivers/isdn/mISDN/clock.c
> +++ /dev/null
> @@ -1,197 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * Copyright 2008 by Andreas Eversberg <andreas@eversberg.eu>
> - *
> - * Quick API description:
> - *
> - * A clock source registers using mISDN_register_clock:
> - * name = text string to name clock source
> - * priority = value to priorize clock sources (0 = default)
> - * ctl = callback function to enable/disable clock source
> - * priv = private pointer of clock source
> - * return = pointer to clock source structure;
> - *
> - * Note: Callback 'ctl' can be called before mISDN_register_clock returns!
> - * Also it can be called during mISDN_unregister_clock.
> - *
> - * A clock source calls mISDN_clock_update with given samples elapsed, if
> - * enabled. If function call is delayed, tv must be set with the timestamp
> - * of the actual event.
> - *
> - * A clock source unregisters using mISDN_unregister_clock.
> - *
> - * To get current clock, call mISDN_clock_get. The signed short value
> - * counts the number of samples since. Time since last clock event is added.
> - */
> -
> -#include <linux/slab.h>
> -#include <linux/types.h>
> -#include <linux/stddef.h>
> -#include <linux/spinlock.h>
> -#include <linux/ktime.h>
> -#include <linux/mISDNif.h>
> -#include <linux/export.h>
> -#include "core.h"
> -
> -static u_int *debug;
> -static LIST_HEAD(iclock_list);
> -static DEFINE_RWLOCK(iclock_lock);
> -static u16 iclock_count; /* counter of last clock */
> -static ktime_t iclock_timestamp; /* time stamp of last clock */
> -static int iclock_timestamp_valid; /* already received one timestamp */
> -static struct mISDNclock *iclock_current;
> -
> -void
> -mISDN_init_clock(u_int *dp)
> -{
> - debug = dp;
> - iclock_timestamp = ktime_get();
> -}
> -
> -static void
> -select_iclock(void)
> -{
> - struct mISDNclock *iclock, *bestclock = NULL, *lastclock = NULL;
> - int pri = -128;
> -
> - list_for_each_entry(iclock, &iclock_list, list) {
> - if (iclock->pri > pri) {
> - pri = iclock->pri;
> - bestclock = iclock;
> - }
> - if (iclock_current == iclock)
> - lastclock = iclock;
> - }
> - if (lastclock && bestclock != lastclock) {
> - /* last used clock source still exists but changes, disable */
> - if (*debug & DEBUG_CLOCK)
> - printk(KERN_DEBUG "Old clock source '%s' disable.\n",
> - lastclock->name);
> - lastclock->ctl(lastclock->priv, 0);
> - }
> - if (bestclock && bestclock != iclock_current) {
> - /* new clock source selected, enable */
> - if (*debug & DEBUG_CLOCK)
> - printk(KERN_DEBUG "New clock source '%s' enable.\n",
> - bestclock->name);
> - bestclock->ctl(bestclock->priv, 1);
> - }
> - if (bestclock != iclock_current) {
> - /* no clock received yet */
> - iclock_timestamp_valid = 0;
> - }
> - iclock_current = bestclock;
> -}
> -
> -struct mISDNclock
> -*mISDN_register_clock(char *name, int pri, clockctl_func_t *ctl, void *priv)
> -{
> - u_long flags;
> - struct mISDNclock *iclock;
> -
> - if (*debug & (DEBUG_CORE | DEBUG_CLOCK))
> - printk(KERN_DEBUG "%s: %s %d\n", __func__, name, pri);
> - iclock = kzalloc_obj(struct mISDNclock, GFP_ATOMIC);
> - if (!iclock) {
> - printk(KERN_ERR "%s: No memory for clock entry.\n", __func__);
> - return NULL;
> - }
> - strscpy(iclock->name, name, sizeof(iclock->name));
> - iclock->pri = pri;
> - iclock->priv = priv;
> - iclock->ctl = ctl;
> - write_lock_irqsave(&iclock_lock, flags);
> - list_add_tail(&iclock->list, &iclock_list);
> - select_iclock();
> - write_unlock_irqrestore(&iclock_lock, flags);
> - return iclock;
> -}
> -EXPORT_SYMBOL(mISDN_register_clock);
> -
> -void
> -mISDN_unregister_clock(struct mISDNclock *iclock)
> -{
> - u_long flags;
> -
> - if (*debug & (DEBUG_CORE | DEBUG_CLOCK))
> - printk(KERN_DEBUG "%s: %s %d\n", __func__, iclock->name,
> - iclock->pri);
> - write_lock_irqsave(&iclock_lock, flags);
> - if (iclock_current == iclock) {
> - if (*debug & DEBUG_CLOCK)
> - printk(KERN_DEBUG
> - "Current clock source '%s' unregisters.\n",
> - iclock->name);
> - iclock->ctl(iclock->priv, 0);
> - }
> - list_del(&iclock->list);
> - select_iclock();
> - write_unlock_irqrestore(&iclock_lock, flags);
> -}
> -EXPORT_SYMBOL(mISDN_unregister_clock);
> -
> -void
> -mISDN_clock_update(struct mISDNclock *iclock, int samples, ktime_t *timestamp)
> -{
> - u_long flags;
> - ktime_t timestamp_now;
> - u16 delta;
> -
> - write_lock_irqsave(&iclock_lock, flags);
> - if (iclock_current != iclock) {
> - printk(KERN_ERR "%s: '%s' sends us clock updates, but we do "
> - "listen to '%s'. This is a bug!\n", __func__,
> - iclock->name,
> - iclock_current ? iclock_current->name : "nothing");
> - iclock->ctl(iclock->priv, 0);
> - write_unlock_irqrestore(&iclock_lock, flags);
> - return;
> - }
> - if (iclock_timestamp_valid) {
> - /* increment sample counter by given samples */
> - iclock_count += samples;
> - if (timestamp) { /* timestamp must be set, if function call is delayed */
> - iclock_timestamp = *timestamp;
> - } else {
> - iclock_timestamp = ktime_get();
> - }
> - } else {
> - /* calc elapsed time by system clock */
> - if (timestamp) { /* timestamp must be set, if function call is delayed */
> - timestamp_now = *timestamp;
> - } else {
> - timestamp_now = ktime_get();
> - }
> - delta = ktime_divns(ktime_sub(timestamp_now, iclock_timestamp),
> - (NSEC_PER_SEC / 8000));
> - /* add elapsed time to counter and set new timestamp */
> - iclock_count += delta;
> - iclock_timestamp = timestamp_now;
> - iclock_timestamp_valid = 1;
> - if (*debug & DEBUG_CLOCK)
> - printk("Received first clock from source '%s'.\n",
> - iclock_current ? iclock_current->name : "nothing");
> - }
> - write_unlock_irqrestore(&iclock_lock, flags);
> -}
> -EXPORT_SYMBOL(mISDN_clock_update);
> -
> -unsigned short
> -mISDN_clock_get(void)
> -{
> - u_long flags;
> - ktime_t timestamp_now;
> - u16 delta;
> - u16 count;
> -
> - read_lock_irqsave(&iclock_lock, flags);
> - /* calc elapsed time by system clock */
> - timestamp_now = ktime_get();
> - delta = ktime_divns(ktime_sub(timestamp_now, iclock_timestamp),
> - (NSEC_PER_SEC / 8000));
> - /* add elapsed time to counter */
> - count = iclock_count + delta;
> - read_unlock_irqrestore(&iclock_lock, flags);
> - return count;
> -}
> -EXPORT_SYMBOL(mISDN_clock_get);
> diff --git a/drivers/isdn/mISDN/core.c b/drivers/isdn/mISDN/core.c
> deleted file mode 100644
> index 8ec2d4d4f135..000000000000
> --- a/drivers/isdn/mISDN/core.c
> +++ /dev/null
> @@ -1,400 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * Copyright 2008 by Karsten Keil <kkeil@novell.com>
> - */
> -
> -#include <linux/slab.h>
> -#include <linux/types.h>
> -#include <linux/stddef.h>
> -#include <linux/module.h>
> -#include <linux/spinlock.h>
> -#include <linux/mISDNif.h>
> -#include "core.h"
> -
> -static u_int debug;
> -
> -MODULE_AUTHOR("Karsten Keil");
> -MODULE_DESCRIPTION("Modular ISDN core driver");
> -MODULE_LICENSE("GPL");
> -module_param(debug, uint, S_IRUGO | S_IWUSR);
> -
> -static u64 device_ids;
> -#define MAX_DEVICE_ID 63
> -
> -static LIST_HEAD(Bprotocols);
> -static DEFINE_RWLOCK(bp_lock);
> -
> -static void mISDN_dev_release(struct device *dev)
> -{
> - /* nothing to do: the device is part of its parent's data structure */
> -}
> -
> -static ssize_t id_show(struct device *dev,
> - struct device_attribute *attr, char *buf)
> -{
> - struct mISDNdevice *mdev = dev_to_mISDN(dev);
> -
> - if (!mdev)
> - return -ENODEV;
> - return sprintf(buf, "%d\n", mdev->id);
> -}
> -static DEVICE_ATTR_RO(id);
> -
> -static ssize_t nrbchan_show(struct device *dev,
> - struct device_attribute *attr, char *buf)
> -{
> - struct mISDNdevice *mdev = dev_to_mISDN(dev);
> -
> - if (!mdev)
> - return -ENODEV;
> - return sprintf(buf, "%d\n", mdev->nrbchan);
> -}
> -static DEVICE_ATTR_RO(nrbchan);
> -
> -static ssize_t d_protocols_show(struct device *dev,
> - struct device_attribute *attr, char *buf)
> -{
> - struct mISDNdevice *mdev = dev_to_mISDN(dev);
> -
> - if (!mdev)
> - return -ENODEV;
> - return sprintf(buf, "%d\n", mdev->Dprotocols);
> -}
> -static DEVICE_ATTR_RO(d_protocols);
> -
> -static ssize_t b_protocols_show(struct device *dev,
> - struct device_attribute *attr, char *buf)
> -{
> - struct mISDNdevice *mdev = dev_to_mISDN(dev);
> -
> - if (!mdev)
> - return -ENODEV;
> - return sprintf(buf, "%d\n", mdev->Bprotocols | get_all_Bprotocols());
> -}
> -static DEVICE_ATTR_RO(b_protocols);
> -
> -static ssize_t protocol_show(struct device *dev,
> - struct device_attribute *attr, char *buf)
> -{
> - struct mISDNdevice *mdev = dev_to_mISDN(dev);
> -
> - if (!mdev)
> - return -ENODEV;
> - return sprintf(buf, "%d\n", mdev->D.protocol);
> -}
> -static DEVICE_ATTR_RO(protocol);
> -
> -static ssize_t name_show(struct device *dev,
> - struct device_attribute *attr, char *buf)
> -{
> - strcpy(buf, dev_name(dev));
> - return strlen(buf);
> -}
> -static DEVICE_ATTR_RO(name);
> -
> -#if 0 /* hangs */
> -static ssize_t name_set(struct device *dev, struct device_attribute *attr,
> - const char *buf, size_t count)
> -{
> - int err = 0;
> - char *out = kmalloc(count + 1, GFP_KERNEL);
> -
> - if (!out)
> - return -ENOMEM;
> -
> - memcpy(out, buf, count);
> - if (count && out[count - 1] == '\n')
> - out[--count] = 0;
> - if (count)
> - err = device_rename(dev, out);
> - kfree(out);
> -
> - return (err < 0) ? err : count;
> -}
> -static DEVICE_ATTR_RW(name);
> -#endif
> -
> -static ssize_t channelmap_show(struct device *dev,
> - struct device_attribute *attr, char *buf)
> -{
> - struct mISDNdevice *mdev = dev_to_mISDN(dev);
> - char *bp = buf;
> - int i;
> -
> - for (i = 0; i <= mdev->nrbchan; i++)
> - *bp++ = test_channelmap(i, mdev->channelmap) ? '1' : '0';
> -
> - return bp - buf;
> -}
> -static DEVICE_ATTR_RO(channelmap);
> -
> -static struct attribute *mISDN_attrs[] = {
> - &dev_attr_id.attr,
> - &dev_attr_d_protocols.attr,
> - &dev_attr_b_protocols.attr,
> - &dev_attr_protocol.attr,
> - &dev_attr_channelmap.attr,
> - &dev_attr_nrbchan.attr,
> - &dev_attr_name.attr,
> - NULL,
> -};
> -ATTRIBUTE_GROUPS(mISDN);
> -
> -static int mISDN_uevent(const struct device *dev, struct kobj_uevent_env *env)
> -{
> - const struct mISDNdevice *mdev = dev_to_mISDN(dev);
> -
> - if (!mdev)
> - return 0;
> -
> - if (add_uevent_var(env, "nchans=%d", mdev->nrbchan))
> - return -ENOMEM;
> -
> - return 0;
> -}
> -
> -static struct class mISDN_class = {
> - .name = "mISDN",
> - .dev_uevent = mISDN_uevent,
> - .dev_groups = mISDN_groups,
> - .dev_release = mISDN_dev_release,
> -};
> -
> -static int
> -_get_mdevice(struct device *dev, const void *id)
> -{
> - struct mISDNdevice *mdev = dev_to_mISDN(dev);
> -
> - if (!mdev)
> - return 0;
> - if (mdev->id != *(const u_int *)id)
> - return 0;
> - return 1;
> -}
> -
> -struct mISDNdevice
> -*get_mdevice(u_int id)
> -{
> - return dev_to_mISDN(class_find_device(&mISDN_class, NULL, &id,
> - _get_mdevice));
> -}
> -
> -static int
> -_get_mdevice_count(struct device *dev, void *cnt)
> -{
> - *(int *)cnt += 1;
> - return 0;
> -}
> -
> -int
> -get_mdevice_count(void)
> -{
> - int cnt = 0;
> -
> - class_for_each_device(&mISDN_class, NULL, &cnt, _get_mdevice_count);
> - return cnt;
> -}
> -
> -static int
> -get_free_devid(void)
> -{
> - u_int i;
> -
> - for (i = 0; i <= MAX_DEVICE_ID; i++)
> - if (!test_and_set_bit(i, (u_long *)&device_ids))
> - break;
> - if (i > MAX_DEVICE_ID)
> - return -EBUSY;
> - return i;
> -}
> -
> -int
> -mISDN_register_device(struct mISDNdevice *dev,
> - struct device *parent, char *name)
> -{
> - int err;
> -
> - err = get_free_devid();
> - if (err < 0)
> - return err;
> - dev->id = err;
> -
> - device_initialize(&dev->dev);
> - if (name && name[0])
> - dev_set_name(&dev->dev, "%s", name);
> - else
> - dev_set_name(&dev->dev, "mISDN%d", dev->id);
> - if (debug & DEBUG_CORE)
> - printk(KERN_DEBUG "mISDN_register %s %d\n",
> - dev_name(&dev->dev), dev->id);
> - dev->dev.class = &mISDN_class;
> -
> - err = create_stack(dev);
> - if (err)
> - goto error1;
> -
> - dev->dev.platform_data = dev;
> - dev->dev.parent = parent;
> - dev_set_drvdata(&dev->dev, dev);
> -
> - err = device_add(&dev->dev);
> - if (err)
> - goto error3;
> - return 0;
> -
> -error3:
> - delete_stack(dev);
> -error1:
> - put_device(&dev->dev);
> - return err;
> -
> -}
> -EXPORT_SYMBOL(mISDN_register_device);
> -
> -void
> -mISDN_unregister_device(struct mISDNdevice *dev) {
> - if (debug & DEBUG_CORE)
> - printk(KERN_DEBUG "mISDN_unregister %s %d\n",
> - dev_name(&dev->dev), dev->id);
> - /* sysfs_remove_link(&dev->dev.kobj, "device"); */
> - device_del(&dev->dev);
> - dev_set_drvdata(&dev->dev, NULL);
> -
> - test_and_clear_bit(dev->id, (u_long *)&device_ids);
> - delete_stack(dev);
> - put_device(&dev->dev);
> -}
> -EXPORT_SYMBOL(mISDN_unregister_device);
> -
> -u_int
> -get_all_Bprotocols(void)
> -{
> - struct Bprotocol *bp;
> - u_int m = 0;
> -
> - read_lock(&bp_lock);
> - list_for_each_entry(bp, &Bprotocols, list)
> - m |= bp->Bprotocols;
> - read_unlock(&bp_lock);
> - return m;
> -}
> -
> -struct Bprotocol *
> -get_Bprotocol4mask(u_int m)
> -{
> - struct Bprotocol *bp;
> -
> - read_lock(&bp_lock);
> - list_for_each_entry(bp, &Bprotocols, list)
> - if (bp->Bprotocols & m) {
> - read_unlock(&bp_lock);
> - return bp;
> - }
> - read_unlock(&bp_lock);
> - return NULL;
> -}
> -
> -int
> -mISDN_register_Bprotocol(struct Bprotocol *bp)
> -{
> - u_long flags;
> - struct Bprotocol *old;
> -
> - if (debug & DEBUG_CORE)
> - printk(KERN_DEBUG "%s: %s/%x\n", __func__,
> - bp->name, bp->Bprotocols);
> - old = get_Bprotocol4mask(bp->Bprotocols);
> - if (old) {
> - printk(KERN_WARNING
> - "register duplicate protocol old %s/%x new %s/%x\n",
> - old->name, old->Bprotocols, bp->name, bp->Bprotocols);
> - return -EBUSY;
> - }
> - write_lock_irqsave(&bp_lock, flags);
> - list_add_tail(&bp->list, &Bprotocols);
> - write_unlock_irqrestore(&bp_lock, flags);
> - return 0;
> -}
> -EXPORT_SYMBOL(mISDN_register_Bprotocol);
> -
> -void
> -mISDN_unregister_Bprotocol(struct Bprotocol *bp)
> -{
> - u_long flags;
> -
> - if (debug & DEBUG_CORE)
> - printk(KERN_DEBUG "%s: %s/%x\n", __func__, bp->name,
> - bp->Bprotocols);
> - write_lock_irqsave(&bp_lock, flags);
> - list_del(&bp->list);
> - write_unlock_irqrestore(&bp_lock, flags);
> -}
> -EXPORT_SYMBOL(mISDN_unregister_Bprotocol);
> -
> -static const char *msg_no_channel = "<no channel>";
> -static const char *msg_no_stack = "<no stack>";
> -static const char *msg_no_stackdev = "<no stack device>";
> -
> -const char *mISDNDevName4ch(struct mISDNchannel *ch)
> -{
> - if (!ch)
> - return msg_no_channel;
> - if (!ch->st)
> - return msg_no_stack;
> - if (!ch->st->dev)
> - return msg_no_stackdev;
> - return dev_name(&ch->st->dev->dev);
> -};
> -EXPORT_SYMBOL(mISDNDevName4ch);
> -
> -static int
> -mISDNInit(void)
> -{
> - int err;
> -
> - printk(KERN_INFO "Modular ISDN core version %d.%d.%d\n",
> - MISDN_MAJOR_VERSION, MISDN_MINOR_VERSION, MISDN_RELEASE);
> - mISDN_init_clock(&debug);
> - mISDN_initstack(&debug);
> - err = class_register(&mISDN_class);
> - if (err)
> - goto error1;
> - err = mISDN_inittimer(&debug);
> - if (err)
> - goto error2;
> - err = Isdnl1_Init(&debug);
> - if (err)
> - goto error3;
> - err = Isdnl2_Init(&debug);
> - if (err)
> - goto error4;
> - err = misdn_sock_init(&debug);
> - if (err)
> - goto error5;
> - return 0;
> -
> -error5:
> - Isdnl2_cleanup();
> -error4:
> - Isdnl1_cleanup();
> -error3:
> - mISDN_timer_cleanup();
> -error2:
> - class_unregister(&mISDN_class);
> -error1:
> - return err;
> -}
> -
> -static void mISDN_cleanup(void)
> -{
> - misdn_sock_cleanup();
> - Isdnl2_cleanup();
> - Isdnl1_cleanup();
> - mISDN_timer_cleanup();
> - class_unregister(&mISDN_class);
> -
> - printk(KERN_DEBUG "mISDNcore unloaded\n");
> -}
> -
> -module_init(mISDNInit);
> -module_exit(mISDN_cleanup);
> diff --git a/drivers/isdn/mISDN/dsp_audio.c b/drivers/isdn/mISDN/dsp_audio.c
> deleted file mode 100644
> index bbef98e7a16e..000000000000
> --- a/drivers/isdn/mISDN/dsp_audio.c
> +++ /dev/null
> @@ -1,421 +0,0 @@
> -/*
> - * Audio support data for mISDN_dsp.
> - *
> - * Copyright 2002/2003 by Andreas Eversberg (jolly@eversberg.eu)
> - * Rewritten by Peter
> - *
> - * This software may be used and distributed according to the terms
> - * of the GNU General Public License, incorporated herein by reference.
> - *
> - */
> -
> -#include <linux/delay.h>
> -#include <linux/mISDNif.h>
> -#include <linux/mISDNdsp.h>
> -#include <linux/export.h>
> -#include <linux/bitrev.h>
> -#include "core.h"
> -#include "dsp.h"
> -
> -/* ulaw[unsigned char] -> signed 16-bit */
> -s32 dsp_audio_ulaw_to_s32[256];
> -/* alaw[unsigned char] -> signed 16-bit */
> -s32 dsp_audio_alaw_to_s32[256];
> -
> -s32 *dsp_audio_law_to_s32;
> -EXPORT_SYMBOL(dsp_audio_law_to_s32);
> -
> -/* signed 16-bit -> law */
> -u8 dsp_audio_s16_to_law[65536];
> -EXPORT_SYMBOL(dsp_audio_s16_to_law);
> -
> -/* alaw -> ulaw */
> -u8 dsp_audio_alaw_to_ulaw[256];
> -/* ulaw -> alaw */
> -static u8 dsp_audio_ulaw_to_alaw[256];
> -u8 dsp_silence;
> -
> -
> -/*****************************************************
> - * generate table for conversion of s16 to alaw/ulaw *
> - *****************************************************/
> -
> -#define AMI_MASK 0x55
> -
> -static inline unsigned char linear2alaw(short int linear)
> -{
> - int mask;
> - int seg;
> - int pcm_val;
> - static int seg_end[8] = {
> - 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF
> - };
> -
> - pcm_val = linear;
> - if (pcm_val >= 0) {
> - /* Sign (7th) bit = 1 */
> - mask = AMI_MASK | 0x80;
> - } else {
> - /* Sign bit = 0 */
> - mask = AMI_MASK;
> - pcm_val = -pcm_val;
> - }
> -
> - /* Convert the scaled magnitude to segment number. */
> - for (seg = 0; seg < 8; seg++) {
> - if (pcm_val <= seg_end[seg])
> - break;
> - }
> - /* Combine the sign, segment, and quantization bits. */
> - return ((seg << 4) |
> - ((pcm_val >> ((seg) ? (seg + 3) : 4)) & 0x0F)) ^ mask;
> -}
> -
> -
> -static inline short int alaw2linear(unsigned char alaw)
> -{
> - int i;
> - int seg;
> -
> - alaw ^= AMI_MASK;
> - i = ((alaw & 0x0F) << 4) + 8 /* rounding error */;
> - seg = (((int) alaw & 0x70) >> 4);
> - if (seg)
> - i = (i + 0x100) << (seg - 1);
> - return (short int) ((alaw & 0x80) ? i : -i);
> -}
> -
> -static inline short int ulaw2linear(unsigned char ulaw)
> -{
> - short mu, e, f, y;
> - static short etab[] = {0, 132, 396, 924, 1980, 4092, 8316, 16764};
> -
> - mu = 255 - ulaw;
> - e = (mu & 0x70) / 16;
> - f = mu & 0x0f;
> - y = f * (1 << (e + 3));
> - y += etab[e];
> - if (mu & 0x80)
> - y = -y;
> - return y;
> -}
> -
> -#define BIAS 0x84 /*!< define the add-in bias for 16 bit samples */
> -
> -static unsigned char linear2ulaw(short sample)
> -{
> - static int exp_lut[256] = {
> - 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
> - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
> - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
> - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
> - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
> - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
> - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
> - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
> - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
> - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
> - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
> - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
> - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
> - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
> - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
> - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7};
> - int sign, exponent, mantissa;
> - unsigned char ulawbyte;
> -
> - /* Get the sample into sign-magnitude. */
> - sign = (sample >> 8) & 0x80; /* set aside the sign */
> - if (sign != 0)
> - sample = -sample; /* get magnitude */
> -
> - /* Convert from 16 bit linear to ulaw. */
> - sample = sample + BIAS;
> - exponent = exp_lut[(sample >> 7) & 0xFF];
> - mantissa = (sample >> (exponent + 3)) & 0x0F;
> - ulawbyte = ~(sign | (exponent << 4) | mantissa);
> -
> - return ulawbyte;
> -}
> -
> -void dsp_audio_generate_law_tables(void)
> -{
> - int i;
> - for (i = 0; i < 256; i++)
> - dsp_audio_alaw_to_s32[i] = alaw2linear(bitrev8((u8)i));
> -
> - for (i = 0; i < 256; i++)
> - dsp_audio_ulaw_to_s32[i] = ulaw2linear(bitrev8((u8)i));
> -
> - for (i = 0; i < 256; i++) {
> - dsp_audio_alaw_to_ulaw[i] =
> - linear2ulaw(dsp_audio_alaw_to_s32[i]);
> - dsp_audio_ulaw_to_alaw[i] =
> - linear2alaw(dsp_audio_ulaw_to_s32[i]);
> - }
> -}
> -
> -void
> -dsp_audio_generate_s2law_table(void)
> -{
> - int i;
> -
> - if (dsp_options & DSP_OPT_ULAW) {
> - /* generating ulaw-table */
> - for (i = -32768; i < 32768; i++) {
> - dsp_audio_s16_to_law[i & 0xffff] =
> - bitrev8(linear2ulaw(i));
> - }
> - } else {
> - /* generating alaw-table */
> - for (i = -32768; i < 32768; i++) {
> - dsp_audio_s16_to_law[i & 0xffff] =
> - bitrev8(linear2alaw(i));
> - }
> - }
> -}
> -
> -
> -/*
> - * the seven bit sample is the number of every second alaw-sample ordered by
> - * aplitude. 0x00 is negative, 0x7f is positive amplitude.
> - */
> -u8 dsp_audio_seven2law[128];
> -u8 dsp_audio_law2seven[256];
> -
> -/********************************************************************
> - * generate table for conversion law from/to 7-bit alaw-like sample *
> - ********************************************************************/
> -
> -void
> -dsp_audio_generate_seven(void)
> -{
> - int i, j, k;
> - u8 spl;
> - u8 sorted_alaw[256];
> -
> - /* generate alaw table, sorted by the linear value */
> - for (i = 0; i < 256; i++) {
> - j = 0;
> - for (k = 0; k < 256; k++) {
> - if (dsp_audio_alaw_to_s32[k]
> - < dsp_audio_alaw_to_s32[i])
> - j++;
> - }
> - sorted_alaw[j] = i;
> - }
> -
> - /* generate tabels */
> - for (i = 0; i < 256; i++) {
> - /* spl is the source: the law-sample (converted to alaw) */
> - spl = i;
> - if (dsp_options & DSP_OPT_ULAW)
> - spl = dsp_audio_ulaw_to_alaw[i];
> - /* find the 7-bit-sample */
> - for (j = 0; j < 256; j++) {
> - if (sorted_alaw[j] == spl)
> - break;
> - }
> - /* write 7-bit audio value */
> - dsp_audio_law2seven[i] = j >> 1;
> - }
> - for (i = 0; i < 128; i++) {
> - spl = sorted_alaw[i << 1];
> - if (dsp_options & DSP_OPT_ULAW)
> - spl = dsp_audio_alaw_to_ulaw[spl];
> - dsp_audio_seven2law[i] = spl;
> - }
> -}
> -
> -
> -/* mix 2*law -> law */
> -u8 dsp_audio_mix_law[65536];
> -
> -/******************************************************
> - * generate mix table to mix two law samples into one *
> - ******************************************************/
> -
> -void
> -dsp_audio_generate_mix_table(void)
> -{
> - int i, j;
> - s32 sample;
> -
> - i = 0;
> - while (i < 256) {
> - j = 0;
> - while (j < 256) {
> - sample = dsp_audio_law_to_s32[i];
> - sample += dsp_audio_law_to_s32[j];
> - if (sample > 32767)
> - sample = 32767;
> - if (sample < -32768)
> - sample = -32768;
> - dsp_audio_mix_law[(i << 8) | j] =
> - dsp_audio_s16_to_law[sample & 0xffff];
> - j++;
> - }
> - i++;
> - }
> -}
> -
> -
> -/*************************************
> - * generate different volume changes *
> - *************************************/
> -
> -static u8 dsp_audio_reduce8[256];
> -static u8 dsp_audio_reduce7[256];
> -static u8 dsp_audio_reduce6[256];
> -static u8 dsp_audio_reduce5[256];
> -static u8 dsp_audio_reduce4[256];
> -static u8 dsp_audio_reduce3[256];
> -static u8 dsp_audio_reduce2[256];
> -static u8 dsp_audio_reduce1[256];
> -static u8 dsp_audio_increase1[256];
> -static u8 dsp_audio_increase2[256];
> -static u8 dsp_audio_increase3[256];
> -static u8 dsp_audio_increase4[256];
> -static u8 dsp_audio_increase5[256];
> -static u8 dsp_audio_increase6[256];
> -static u8 dsp_audio_increase7[256];
> -static u8 dsp_audio_increase8[256];
> -
> -static u8 *dsp_audio_volume_change[16] = {
> - dsp_audio_reduce8,
> - dsp_audio_reduce7,
> - dsp_audio_reduce6,
> - dsp_audio_reduce5,
> - dsp_audio_reduce4,
> - dsp_audio_reduce3,
> - dsp_audio_reduce2,
> - dsp_audio_reduce1,
> - dsp_audio_increase1,
> - dsp_audio_increase2,
> - dsp_audio_increase3,
> - dsp_audio_increase4,
> - dsp_audio_increase5,
> - dsp_audio_increase6,
> - dsp_audio_increase7,
> - dsp_audio_increase8,
> -};
> -
> -void
> -dsp_audio_generate_volume_changes(void)
> -{
> - register s32 sample;
> - int i;
> - int num[] = { 110, 125, 150, 175, 200, 300, 400, 500 };
> - int denum[] = { 100, 100, 100, 100, 100, 100, 100, 100 };
> -
> - i = 0;
> - while (i < 256) {
> - dsp_audio_reduce8[i] = dsp_audio_s16_to_law[
> - (dsp_audio_law_to_s32[i] * denum[7] / num[7]) & 0xffff];
> - dsp_audio_reduce7[i] = dsp_audio_s16_to_law[
> - (dsp_audio_law_to_s32[i] * denum[6] / num[6]) & 0xffff];
> - dsp_audio_reduce6[i] = dsp_audio_s16_to_law[
> - (dsp_audio_law_to_s32[i] * denum[5] / num[5]) & 0xffff];
> - dsp_audio_reduce5[i] = dsp_audio_s16_to_law[
> - (dsp_audio_law_to_s32[i] * denum[4] / num[4]) & 0xffff];
> - dsp_audio_reduce4[i] = dsp_audio_s16_to_law[
> - (dsp_audio_law_to_s32[i] * denum[3] / num[3]) & 0xffff];
> - dsp_audio_reduce3[i] = dsp_audio_s16_to_law[
> - (dsp_audio_law_to_s32[i] * denum[2] / num[2]) & 0xffff];
> - dsp_audio_reduce2[i] = dsp_audio_s16_to_law[
> - (dsp_audio_law_to_s32[i] * denum[1] / num[1]) & 0xffff];
> - dsp_audio_reduce1[i] = dsp_audio_s16_to_law[
> - (dsp_audio_law_to_s32[i] * denum[0] / num[0]) & 0xffff];
> - sample = dsp_audio_law_to_s32[i] * num[0] / denum[0];
> - if (sample < -32768)
> - sample = -32768;
> - else if (sample > 32767)
> - sample = 32767;
> - dsp_audio_increase1[i] = dsp_audio_s16_to_law[sample & 0xffff];
> - sample = dsp_audio_law_to_s32[i] * num[1] / denum[1];
> - if (sample < -32768)
> - sample = -32768;
> - else if (sample > 32767)
> - sample = 32767;
> - dsp_audio_increase2[i] = dsp_audio_s16_to_law[sample & 0xffff];
> - sample = dsp_audio_law_to_s32[i] * num[2] / denum[2];
> - if (sample < -32768)
> - sample = -32768;
> - else if (sample > 32767)
> - sample = 32767;
> - dsp_audio_increase3[i] = dsp_audio_s16_to_law[sample & 0xffff];
> - sample = dsp_audio_law_to_s32[i] * num[3] / denum[3];
> - if (sample < -32768)
> - sample = -32768;
> - else if (sample > 32767)
> - sample = 32767;
> - dsp_audio_increase4[i] = dsp_audio_s16_to_law[sample & 0xffff];
> - sample = dsp_audio_law_to_s32[i] * num[4] / denum[4];
> - if (sample < -32768)
> - sample = -32768;
> - else if (sample > 32767)
> - sample = 32767;
> - dsp_audio_increase5[i] = dsp_audio_s16_to_law[sample & 0xffff];
> - sample = dsp_audio_law_to_s32[i] * num[5] / denum[5];
> - if (sample < -32768)
> - sample = -32768;
> - else if (sample > 32767)
> - sample = 32767;
> - dsp_audio_increase6[i] = dsp_audio_s16_to_law[sample & 0xffff];
> - sample = dsp_audio_law_to_s32[i] * num[6] / denum[6];
> - if (sample < -32768)
> - sample = -32768;
> - else if (sample > 32767)
> - sample = 32767;
> - dsp_audio_increase7[i] = dsp_audio_s16_to_law[sample & 0xffff];
> - sample = dsp_audio_law_to_s32[i] * num[7] / denum[7];
> - if (sample < -32768)
> - sample = -32768;
> - else if (sample > 32767)
> - sample = 32767;
> - dsp_audio_increase8[i] = dsp_audio_s16_to_law[sample & 0xffff];
> -
> - i++;
> - }
> -}
> -
> -
> -/**************************************
> - * change the volume of the given skb *
> - **************************************/
> -
> -/* this is a helper function for changing volume of skb. the range may be
> - * -8 to 8, which is a shift to the power of 2. 0 == no volume, 3 == volume*8
> - */
> -void
> -dsp_change_volume(struct sk_buff *skb, int volume)
> -{
> - u8 *volume_change;
> - int i, ii;
> - u8 *p;
> - int shift;
> -
> - if (volume == 0)
> - return;
> -
> - /* get correct conversion table */
> - if (volume < 0) {
> - shift = volume + 8;
> - if (shift < 0)
> - shift = 0;
> - } else {
> - shift = volume + 7;
> - if (shift > 15)
> - shift = 15;
> - }
> - volume_change = dsp_audio_volume_change[shift];
> - i = 0;
> - ii = skb->len;
> - p = skb->data;
> - /* change volume */
> - while (i < ii) {
> - *p = volume_change[*p];
> - p++;
> - i++;
> - }
> -}
> diff --git a/drivers/isdn/mISDN/dsp_blowfish.c b/drivers/isdn/mISDN/dsp_blowfish.c
> deleted file mode 100644
> index 0e77c282c862..000000000000
> --- a/drivers/isdn/mISDN/dsp_blowfish.c
> +++ /dev/null
> @@ -1,667 +0,0 @@
> -/*
> - * Blowfish encryption/decryption for mISDN_dsp.
> - *
> - * Copyright Andreas Eversberg (jolly@eversberg.eu)
> - *
> - * This software may be used and distributed according to the terms
> - * of the GNU General Public License, incorporated herein by reference.
> - *
> - */
> -
> -#include <linux/mISDNif.h>
> -#include <linux/mISDNdsp.h>
> -#include "core.h"
> -#include "dsp.h"
> -
> -/*
> - * how to encode a sample stream to 64-bit blocks that will be encryped
> - *
> - * first of all, data is collected until a block of 9 samples are received.
> - * of course, a packet may have much more than 9 sample, but is may have
> - * not excacly the multiple of 9 samples. if there is a rest, the next
> - * received data will complete the block.
> - *
> - * the block is then converted to 9 uLAW samples without the least sigificant
> - * bit. the result is a 7-bit encoded sample.
> - *
> - * the samples will be reoganised to form 8 bytes of data:
> - * (5(6) means: encoded sample no. 5, bit 6)
> - *
> - * 0(6) 0(5) 0(4) 0(3) 0(2) 0(1) 0(0) 1(6)
> - * 1(5) 1(4) 1(3) 1(2) 1(1) 1(0) 2(6) 2(5)
> - * 2(4) 2(3) 2(2) 2(1) 2(0) 3(6) 3(5) 3(4)
> - * 3(3) 3(2) 3(1) 3(0) 4(6) 4(5) 4(4) 4(3)
> - * 4(2) 4(1) 4(0) 5(6) 5(5) 5(4) 5(3) 5(2)
> - * 5(1) 5(0) 6(6) 6(5) 6(4) 6(3) 6(2) 6(1)
> - * 6(0) 7(6) 7(5) 7(4) 7(3) 7(2) 7(1) 7(0)
> - * 8(6) 8(5) 8(4) 8(3) 8(2) 8(1) 8(0)
> - *
> - * the missing bit 0 of the last byte is filled with some
> - * random noise, to fill all 8 bytes.
> - *
> - * the 8 bytes will be encrypted using blowfish.
> - *
> - * the result will be converted into 9 bytes. the bit 7 is used for
> - * checksumme (CS) for sync (0, 1) and for the last bit:
> - * (5(6) means: crypted byte 5, bit 6)
> - *
> - * 1 0(7) 0(6) 0(5) 0(4) 0(3) 0(2) 0(1)
> - * 0 0(0) 1(7) 1(6) 1(5) 1(4) 1(3) 1(2)
> - * 0 1(1) 1(0) 2(7) 2(6) 2(5) 2(4) 2(3)
> - * 0 2(2) 2(1) 2(0) 3(7) 3(6) 3(5) 3(4)
> - * 0 3(3) 3(2) 3(1) 3(0) 4(7) 4(6) 4(5)
> - * CS 4(4) 4(3) 4(2) 4(1) 4(0) 5(7) 5(6)
> - * CS 5(5) 5(4) 5(3) 5(2) 5(1) 5(0) 6(7)
> - * CS 6(6) 6(5) 6(4) 6(3) 6(2) 6(1) 6(0)
> - * 7(0) 7(6) 7(5) 7(4) 7(3) 7(2) 7(1) 7(0)
> - *
> - * the checksum is used to detect transmission errors and frame drops.
> - *
> - * synchronisation of received block is done by shifting the upper bit of each
> - * byte (bit 7) to a shift register. if the rigister has the first five bits
> - * (10000), this is used to find the sync. only if sync has been found, the
> - * current block of 9 received bytes are decrypted. before that the check
> - * sum is calculated. if it is incorrect the block is dropped.
> - * this will avoid loud noise due to corrupt encrypted data.
> - *
> - * if the last block is corrupt, the current decoded block is repeated
> - * until a valid block has been received.
> - */
> -
> -/*
> - * some blowfish parts are taken from the
> - * crypto-api for faster implementation
> - */
> -
> -static const u32 bf_pbox[16 + 2] = {
> - 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
> - 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
> - 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
> - 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
> - 0x9216d5d9, 0x8979fb1b,
> -};
> -
> -static const u32 bf_sbox[256 * 4] = {
> - 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
> - 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
> - 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
> - 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
> - 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
> - 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
> - 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
> - 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
> - 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
> - 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
> - 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
> - 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
> - 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
> - 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
> - 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
> - 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
> - 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
> - 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
> - 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
> - 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
> - 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
> - 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
> - 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
> - 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
> - 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
> - 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
> - 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
> - 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
> - 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
> - 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
> - 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
> - 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
> - 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
> - 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
> - 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
> - 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
> - 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
> - 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
> - 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
> - 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
> - 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
> - 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
> - 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
> - 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
> - 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
> - 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
> - 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
> - 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
> - 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
> - 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
> - 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
> - 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
> - 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
> - 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
> - 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
> - 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
> - 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
> - 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
> - 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
> - 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
> - 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
> - 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
> - 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
> - 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a,
> - 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
> - 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
> - 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
> - 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
> - 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
> - 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
> - 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
> - 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
> - 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
> - 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
> - 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
> - 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
> - 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
> - 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
> - 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
> - 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
> - 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
> - 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
> - 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
> - 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
> - 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
> - 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
> - 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
> - 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
> - 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
> - 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
> - 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
> - 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
> - 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
> - 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
> - 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
> - 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
> - 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
> - 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
> - 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
> - 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
> - 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
> - 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
> - 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
> - 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
> - 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
> - 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
> - 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
> - 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
> - 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
> - 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
> - 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
> - 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
> - 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
> - 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
> - 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
> - 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
> - 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
> - 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
> - 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
> - 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
> - 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
> - 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
> - 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
> - 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
> - 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
> - 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
> - 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
> - 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7,
> - 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
> - 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
> - 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
> - 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
> - 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
> - 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
> - 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
> - 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
> - 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
> - 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
> - 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
> - 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
> - 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
> - 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
> - 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
> - 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
> - 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
> - 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
> - 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
> - 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
> - 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
> - 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
> - 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
> - 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
> - 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
> - 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
> - 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
> - 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
> - 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
> - 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
> - 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
> - 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
> - 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
> - 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
> - 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
> - 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
> - 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
> - 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
> - 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
> - 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
> - 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
> - 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
> - 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
> - 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
> - 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
> - 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
> - 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
> - 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
> - 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
> - 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
> - 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
> - 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
> - 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
> - 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
> - 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
> - 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
> - 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
> - 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
> - 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
> - 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
> - 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
> - 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
> - 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
> - 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0,
> - 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
> - 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
> - 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
> - 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
> - 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
> - 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
> - 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
> - 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
> - 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
> - 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
> - 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
> - 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
> - 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
> - 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
> - 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
> - 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
> - 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
> - 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
> - 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
> - 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
> - 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
> - 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
> - 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
> - 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
> - 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
> - 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
> - 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
> - 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
> - 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
> - 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
> - 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
> - 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
> - 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
> - 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
> - 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
> - 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
> - 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
> - 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
> - 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
> - 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
> - 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
> - 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
> - 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
> - 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
> - 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
> - 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
> - 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
> - 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
> - 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
> - 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
> - 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
> - 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
> - 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
> - 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
> - 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
> - 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
> - 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
> - 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
> - 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
> - 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
> - 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
> - 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
> - 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
> - 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6,
> -};
> -
> -/*
> - * Round loop unrolling macros, S is a pointer to a S-Box array
> - * organized in 4 unsigned longs at a row.
> - */
> -#define GET32_3(x) (((x) & 0xff))
> -#define GET32_2(x) (((x) >> (8)) & (0xff))
> -#define GET32_1(x) (((x) >> (16)) & (0xff))
> -#define GET32_0(x) (((x) >> (24)) & (0xff))
> -
> -#define bf_F(x) (((S[GET32_0(x)] + S[256 + GET32_1(x)]) ^ \
> - S[512 + GET32_2(x)]) + S[768 + GET32_3(x)])
> -
> -#define EROUND(a, b, n) do { b ^= P[n]; a ^= bf_F(b); } while (0)
> -#define DROUND(a, b, n) do { a ^= bf_F(b); b ^= P[n]; } while (0)
> -
> -
> -/*
> - * encrypt isdn data frame
> - * every block with 9 samples is encrypted
> - */
> -void
> -dsp_bf_encrypt(struct dsp *dsp, u8 *data, int len)
> -{
> - int i = 0, j = dsp->bf_crypt_pos;
> - u8 *bf_data_in = dsp->bf_data_in;
> - u8 *bf_crypt_out = dsp->bf_crypt_out;
> - u32 *P = dsp->bf_p;
> - u32 *S = dsp->bf_s;
> - u32 yl, yr;
> - u32 cs;
> - u8 nibble;
> -
> - while (i < len) {
> - /* collect a block of 9 samples */
> - if (j < 9) {
> - bf_data_in[j] = *data;
> - *data++ = bf_crypt_out[j++];
> - i++;
> - continue;
> - }
> - j = 0;
> - /* transcode 9 samples xlaw to 8 bytes */
> - yl = dsp_audio_law2seven[bf_data_in[0]];
> - yl = (yl << 7) | dsp_audio_law2seven[bf_data_in[1]];
> - yl = (yl << 7) | dsp_audio_law2seven[bf_data_in[2]];
> - yl = (yl << 7) | dsp_audio_law2seven[bf_data_in[3]];
> - nibble = dsp_audio_law2seven[bf_data_in[4]];
> - yr = nibble;
> - yl = (yl << 4) | (nibble >> 3);
> - yr = (yr << 7) | dsp_audio_law2seven[bf_data_in[5]];
> - yr = (yr << 7) | dsp_audio_law2seven[bf_data_in[6]];
> - yr = (yr << 7) | dsp_audio_law2seven[bf_data_in[7]];
> - yr = (yr << 7) | dsp_audio_law2seven[bf_data_in[8]];
> - yr = (yr << 1) | (bf_data_in[0] & 1);
> -
> - /* fill unused bit with random noise of audio input */
> - /* encrypt */
> -
> - EROUND(yr, yl, 0);
> - EROUND(yl, yr, 1);
> - EROUND(yr, yl, 2);
> - EROUND(yl, yr, 3);
> - EROUND(yr, yl, 4);
> - EROUND(yl, yr, 5);
> - EROUND(yr, yl, 6);
> - EROUND(yl, yr, 7);
> - EROUND(yr, yl, 8);
> - EROUND(yl, yr, 9);
> - EROUND(yr, yl, 10);
> - EROUND(yl, yr, 11);
> - EROUND(yr, yl, 12);
> - EROUND(yl, yr, 13);
> - EROUND(yr, yl, 14);
> - EROUND(yl, yr, 15);
> - yl ^= P[16];
> - yr ^= P[17];
> -
> - /* calculate 3-bit checksumme */
> - cs = yl ^ (yl >> 3) ^ (yl >> 6) ^ (yl >> 9) ^ (yl >> 12) ^ (yl >> 15)
> - ^ (yl >> 18) ^ (yl >> 21) ^ (yl >> 24) ^ (yl >> 27) ^ (yl >> 30)
> - ^ (yr << 2) ^ (yr >> 1) ^ (yr >> 4) ^ (yr >> 7) ^ (yr >> 10)
> - ^ (yr >> 13) ^ (yr >> 16) ^ (yr >> 19) ^ (yr >> 22) ^ (yr >> 25)
> - ^ (yr >> 28) ^ (yr >> 31);
> -
> - /*
> - * transcode 8 crypted bytes to 9 data bytes with sync
> - * and checksum information
> - */
> - bf_crypt_out[0] = (yl >> 25) | 0x80;
> - bf_crypt_out[1] = (yl >> 18) & 0x7f;
> - bf_crypt_out[2] = (yl >> 11) & 0x7f;
> - bf_crypt_out[3] = (yl >> 4) & 0x7f;
> - bf_crypt_out[4] = ((yl << 3) & 0x78) | ((yr >> 29) & 0x07);
> - bf_crypt_out[5] = ((yr >> 22) & 0x7f) | ((cs << 5) & 0x80);
> - bf_crypt_out[6] = ((yr >> 15) & 0x7f) | ((cs << 6) & 0x80);
> - bf_crypt_out[7] = ((yr >> 8) & 0x7f) | (cs << 7);
> - bf_crypt_out[8] = yr;
> - }
> -
> - /* write current count */
> - dsp->bf_crypt_pos = j;
> -
> -}
> -
> -
> -/*
> - * decrypt isdn data frame
> - * every block with 9 bytes is decrypted
> - */
> -void
> -dsp_bf_decrypt(struct dsp *dsp, u8 *data, int len)
> -{
> - int i = 0;
> - u8 j = dsp->bf_decrypt_in_pos;
> - u8 k = dsp->bf_decrypt_out_pos;
> - u8 *bf_crypt_inring = dsp->bf_crypt_inring;
> - u8 *bf_data_out = dsp->bf_data_out;
> - u16 sync = dsp->bf_sync;
> - u32 *P = dsp->bf_p;
> - u32 *S = dsp->bf_s;
> - u32 yl, yr;
> - u8 nibble;
> - u8 cs, cs0, cs1, cs2;
> -
> - while (i < len) {
> - /*
> - * shift upper bit and rotate data to buffer ring
> - * send current decrypted data
> - */
> - sync = (sync << 1) | ((*data) >> 7);
> - bf_crypt_inring[j++ & 15] = *data;
> - *data++ = bf_data_out[k++];
> - i++;
> - if (k == 9)
> - k = 0; /* repeat if no sync has been found */
> - /* check if not in sync */
> - if ((sync & 0x1f0) != 0x100)
> - continue;
> - j -= 9;
> - /* transcode receive data to 64 bit block of encrypted data */
> - yl = bf_crypt_inring[j++ & 15];
> - yl = (yl << 7) | bf_crypt_inring[j++ & 15]; /* bit7 = 0 */
> - yl = (yl << 7) | bf_crypt_inring[j++ & 15]; /* bit7 = 0 */
> - yl = (yl << 7) | bf_crypt_inring[j++ & 15]; /* bit7 = 0 */
> - nibble = bf_crypt_inring[j++ & 15]; /* bit7 = 0 */
> - yr = nibble;
> - yl = (yl << 4) | (nibble >> 3);
> - cs2 = bf_crypt_inring[j++ & 15];
> - yr = (yr << 7) | (cs2 & 0x7f);
> - cs1 = bf_crypt_inring[j++ & 15];
> - yr = (yr << 7) | (cs1 & 0x7f);
> - cs0 = bf_crypt_inring[j++ & 15];
> - yr = (yr << 7) | (cs0 & 0x7f);
> - yr = (yr << 8) | bf_crypt_inring[j++ & 15];
> -
> - /* calculate 3-bit checksumme */
> - cs = yl ^ (yl >> 3) ^ (yl >> 6) ^ (yl >> 9) ^ (yl >> 12) ^ (yl >> 15)
> - ^ (yl >> 18) ^ (yl >> 21) ^ (yl >> 24) ^ (yl >> 27) ^ (yl >> 30)
> - ^ (yr << 2) ^ (yr >> 1) ^ (yr >> 4) ^ (yr >> 7) ^ (yr >> 10)
> - ^ (yr >> 13) ^ (yr >> 16) ^ (yr >> 19) ^ (yr >> 22) ^ (yr >> 25)
> - ^ (yr >> 28) ^ (yr >> 31);
> -
> - /* check if frame is valid */
> - if ((cs & 0x7) != (((cs2 >> 5) & 4) | ((cs1 >> 6) & 2) | (cs0 >> 7))) {
> - if (dsp_debug & DEBUG_DSP_BLOWFISH)
> - printk(KERN_DEBUG
> - "DSP BLOWFISH: received corrupt frame, "
> - "checksumme is not correct\n");
> - continue;
> - }
> -
> - /* decrypt */
> - yr ^= P[17];
> - yl ^= P[16];
> - DROUND(yl, yr, 15);
> - DROUND(yr, yl, 14);
> - DROUND(yl, yr, 13);
> - DROUND(yr, yl, 12);
> - DROUND(yl, yr, 11);
> - DROUND(yr, yl, 10);
> - DROUND(yl, yr, 9);
> - DROUND(yr, yl, 8);
> - DROUND(yl, yr, 7);
> - DROUND(yr, yl, 6);
> - DROUND(yl, yr, 5);
> - DROUND(yr, yl, 4);
> - DROUND(yl, yr, 3);
> - DROUND(yr, yl, 2);
> - DROUND(yl, yr, 1);
> - DROUND(yr, yl, 0);
> -
> - /* transcode 8 crypted bytes to 9 sample bytes */
> - bf_data_out[0] = dsp_audio_seven2law[(yl >> 25) & 0x7f];
> - bf_data_out[1] = dsp_audio_seven2law[(yl >> 18) & 0x7f];
> - bf_data_out[2] = dsp_audio_seven2law[(yl >> 11) & 0x7f];
> - bf_data_out[3] = dsp_audio_seven2law[(yl >> 4) & 0x7f];
> - bf_data_out[4] = dsp_audio_seven2law[((yl << 3) & 0x78) |
> - ((yr >> 29) & 0x07)];
> -
> - bf_data_out[5] = dsp_audio_seven2law[(yr >> 22) & 0x7f];
> - bf_data_out[6] = dsp_audio_seven2law[(yr >> 15) & 0x7f];
> - bf_data_out[7] = dsp_audio_seven2law[(yr >> 8) & 0x7f];
> - bf_data_out[8] = dsp_audio_seven2law[(yr >> 1) & 0x7f];
> - k = 0; /* start with new decoded frame */
> - }
> -
> - /* write current count and sync */
> - dsp->bf_decrypt_in_pos = j;
> - dsp->bf_decrypt_out_pos = k;
> - dsp->bf_sync = sync;
> -}
> -
> -
> -/* used to encrypt S and P boxes */
> -static inline void
> -encrypt_block(const u32 *P, const u32 *S, u32 *dst, u32 *src)
> -{
> - u32 yl = src[0];
> - u32 yr = src[1];
> -
> - EROUND(yr, yl, 0);
> - EROUND(yl, yr, 1);
> - EROUND(yr, yl, 2);
> - EROUND(yl, yr, 3);
> - EROUND(yr, yl, 4);
> - EROUND(yl, yr, 5);
> - EROUND(yr, yl, 6);
> - EROUND(yl, yr, 7);
> - EROUND(yr, yl, 8);
> - EROUND(yl, yr, 9);
> - EROUND(yr, yl, 10);
> - EROUND(yl, yr, 11);
> - EROUND(yr, yl, 12);
> - EROUND(yl, yr, 13);
> - EROUND(yr, yl, 14);
> - EROUND(yl, yr, 15);
> -
> - yl ^= P[16];
> - yr ^= P[17];
> -
> - dst[0] = yr;
> - dst[1] = yl;
> -}
> -
> -/*
> - * initialize the dsp for encryption and decryption using the same key
> - * Calculates the blowfish S and P boxes for encryption and decryption.
> - * The margin of keylen must be 4-56 bytes.
> - * returns 0 if ok.
> - */
> -int
> -dsp_bf_init(struct dsp *dsp, const u8 *key, uint keylen)
> -{
> - short i, j, count;
> - u32 data[2], temp;
> - u32 *P = (u32 *)dsp->bf_p;
> - u32 *S = (u32 *)dsp->bf_s;
> -
> - if (keylen < 4 || keylen > 56)
> - return 1;
> -
> - /* Set dsp states */
> - i = 0;
> - while (i < 9) {
> - dsp->bf_crypt_out[i] = 0xff;
> - dsp->bf_data_out[i] = dsp_silence;
> - i++;
> - }
> - dsp->bf_crypt_pos = 0;
> - dsp->bf_decrypt_in_pos = 0;
> - dsp->bf_decrypt_out_pos = 0;
> - dsp->bf_sync = 0x1ff;
> - dsp->bf_enable = 1;
> -
> - /* Copy the initialization s-boxes */
> - for (i = 0, count = 0; i < 256; i++)
> - for (j = 0; j < 4; j++, count++)
> - S[count] = bf_sbox[count];
> -
> - /* Set the p-boxes */
> - for (i = 0; i < 16 + 2; i++)
> - P[i] = bf_pbox[i];
> -
> - /* Actual subkey generation */
> - for (j = 0, i = 0; i < 16 + 2; i++) {
> - temp = (((u32)key[j] << 24) |
> - ((u32)key[(j + 1) % keylen] << 16) |
> - ((u32)key[(j + 2) % keylen] << 8) |
> - ((u32)key[(j + 3) % keylen]));
> -
> - P[i] = P[i] ^ temp;
> - j = (j + 4) % keylen;
> - }
> -
> - data[0] = 0x00000000;
> - data[1] = 0x00000000;
> -
> - for (i = 0; i < 16 + 2; i += 2) {
> - encrypt_block(P, S, data, data);
> -
> - P[i] = data[0];
> - P[i + 1] = data[1];
> - }
> -
> - for (i = 0; i < 4; i++) {
> - for (j = 0, count = i * 256; j < 256; j += 2, count += 2) {
> - encrypt_block(P, S, data, data);
> -
> - S[count] = data[0];
> - S[count + 1] = data[1];
> - }
> - }
> -
> - return 0;
> -}
> -
> -
> -/*
> - * turn encryption off
> - */
> -void
> -dsp_bf_cleanup(struct dsp *dsp)
> -{
> - dsp->bf_enable = 0;
> -}
> diff --git a/drivers/isdn/mISDN/dsp_cmx.c b/drivers/isdn/mISDN/dsp_cmx.c
> deleted file mode 100644
> index d5eb2349c414..000000000000
> --- a/drivers/isdn/mISDN/dsp_cmx.c
> +++ /dev/null
> @@ -1,1949 +0,0 @@
> -/*
> - * Audio crossconnecting/conferrencing (hardware level).
> - *
> - * Copyright 2002 by Andreas Eversberg (jolly@eversberg.eu)
> - *
> - * This software may be used and distributed according to the terms
> - * of the GNU General Public License, incorporated herein by reference.
> - *
> - */
> -
> -/*
> - * The process of adding and removing parties to/from a conference:
> - *
> - * There is a chain of struct dsp_conf which has one or more members in a chain
> - * of struct dsp_conf_member.
> - *
> - * After a party is added, the conference is checked for hardware capability.
> - * Also if a party is removed, the conference is checked again.
> - *
> - * There are 3 different solutions: -1 = software, 0 = hardware-crossconnect
> - * 1-n = hardware-conference. The n will give the conference number.
> - *
> - * Depending on the change after removal or insertion of a party, hardware
> - * commands are given.
> - *
> - * The current solution is stored within the struct dsp_conf entry.
> - */
> -
> -/*
> - * HOW THE CMX WORKS:
> - *
> - * There are 3 types of interaction: One member is alone, in this case only
> - * data flow from upper to lower layer is done.
> - * Two members will also exchange their data so they are crossconnected.
> - * Three or more members will be added in a conference and will hear each
> - * other but will not receive their own speech (echo) if not enabled.
> - *
> - * Features of CMX are:
> - * - Crossconnecting or even conference, if more than two members are together.
> - * - Force mixing of transmit data with other crossconnect/conference members.
> - * - Echo generation to benchmark the delay of audio processing.
> - * - Use hardware to minimize cpu load, disable FIFO load and minimize delay.
> - * - Dejittering and clock generation.
> - *
> - * There are 2 buffers:
> - *
> - *
> - * RX-Buffer
> - * R W
> - * | |
> - * ----------------+-------------+-------------------
> - *
> - * The rx-buffer is a ring buffer used to store the received data for each
> - * individual member. This is only the case if data needs to be dejittered
> - * or in case of a conference where different clocks require reclocking.
> - * The transmit-clock (R) will read the buffer.
> - * If the clock overruns the write-pointer, we will have a buffer underrun.
> - * If the write pointer always has a certain distance from the transmit-
> - * clock, we will have a delay. The delay will dynamically be increased and
> - * reduced.
> - *
> - *
> - * TX-Buffer
> - * R W
> - * | |
> - * -----------------+--------+-----------------------
> - *
> - * The tx-buffer is a ring buffer to queue the transmit data from user space
> - * until it will be mixed or sent. There are two pointers, R and W. If the write
> - * pointer W would reach or overrun R, the buffer would overrun. In this case
> - * (some) data is dropped so that it will not overrun.
> - * Additionally a dynamic dejittering can be enabled. this allows data from
> - * user space that have jitter and different clock source.
> - *
> - *
> - * Clock:
> - *
> - * A Clock is not required, if the data source has exactly one clock. In this
> - * case the data source is forwarded to the destination.
> - *
> - * A Clock is required, because the data source
> - * - has multiple clocks.
> - * - has no usable clock due to jitter or packet loss (VoIP).
> - * In this case the system's clock is used. The clock resolution depends on
> - * the jiffy resolution.
> - *
> - * If a member joins a conference:
> - *
> - * - If a member joins, its rx_buff is set to silence and change read pointer
> - * to transmit clock.
> - *
> - * The procedure of received data from card is explained in cmx_receive.
> - * The procedure of received data from user space is explained in cmx_transmit.
> - * The procedure of transmit data to card is cmx_send.
> - *
> - *
> - * Interaction with other features:
> - *
> - * DTMF:
> - * DTMF decoding is done before the data is crossconnected.
> - *
> - * Volume change:
> - * Changing rx-volume is done before the data is crossconnected. The tx-volume
> - * must be changed whenever data is transmitted to the card by the cmx.
> - *
> - * Tones:
> - * If a tone is enabled, it will be processed whenever data is transmitted to
> - * the card. It will replace the tx-data from the user space.
> - * If tones are generated by hardware, this conference member is removed for
> - * this time.
> - *
> - * Disable rx-data:
> - * If cmx is realized in hardware, rx data will be disabled if requested by
> - * the upper layer. If dtmf decoding is done by software and enabled, rx data
> - * will not be disabled but blocked to the upper layer.
> - *
> - * HFC conference engine:
> - * If it is possible to realize all features using hardware, hardware will be
> - * used if not forbidden by control command. Disabling rx-data provides
> - * absolutely traffic free audio processing. (except for the quick 1-frame
> - * upload of a tone loop, only once for a new tone)
> - *
> - */
> -
> -/* delay.h is required for hw_lock.h */
> -
> -#include <linux/slab.h>
> -#include <linux/delay.h>
> -#include <linux/mISDNif.h>
> -#include <linux/mISDNdsp.h>
> -#include "core.h"
> -#include "dsp.h"
> -/*
> - * debugging of multi party conference,
> - * by using conference even with two members
> - */
> -
> -/* #define CMX_CONF_DEBUG */
> -
> -/*#define CMX_DEBUG * massive read/write pointer output */
> -/*#define CMX_DELAY_DEBUG * gives rx-buffer delay overview */
> -/*#define CMX_TX_DEBUG * massive read/write on tx-buffer with content */
> -
> -/*
> - * debug cmx memory structure
> - */
> -void
> -dsp_cmx_debug(struct dsp *dsp)
> -{
> - struct dsp_conf *conf;
> - struct dsp_conf_member *member;
> - struct dsp *odsp;
> -
> - printk(KERN_DEBUG "-----Current DSP\n");
> - list_for_each_entry(odsp, &dsp_ilist, list) {
> - printk(KERN_DEBUG "* %s hardecho=%d softecho=%d txmix=%d",
> - odsp->name, odsp->echo.hardware, odsp->echo.software,
> - odsp->tx_mix);
> - if (odsp->conf)
> - printk(" (Conf %d)", odsp->conf->id);
> - if (dsp == odsp)
> - printk(" *this*");
> - printk("\n");
> - }
> - printk(KERN_DEBUG "-----Current Conf:\n");
> - list_for_each_entry(conf, &conf_ilist, list) {
> - printk(KERN_DEBUG "* Conf %d (%p)\n", conf->id, conf);
> - list_for_each_entry(member, &conf->mlist, list) {
> - printk(KERN_DEBUG
> - " - member = %s (slot_tx %d, bank_tx %d, "
> - "slot_rx %d, bank_rx %d hfc_conf %d "
> - "tx_data %d rx_is_off %d)%s\n",
> - member->dsp->name, member->dsp->pcm_slot_tx,
> - member->dsp->pcm_bank_tx, member->dsp->pcm_slot_rx,
> - member->dsp->pcm_bank_rx, member->dsp->hfc_conf,
> - member->dsp->tx_data, member->dsp->rx_is_off,
> - (member->dsp == dsp) ? " *this*" : "");
> - }
> - }
> - printk(KERN_DEBUG "-----end\n");
> -}
> -
> -/*
> - * search conference
> - */
> -static struct dsp_conf *
> -dsp_cmx_search_conf(u32 id)
> -{
> - struct dsp_conf *conf;
> -
> - if (!id) {
> - printk(KERN_WARNING "%s: conference ID is 0.\n", __func__);
> - return NULL;
> - }
> -
> - /* search conference */
> - list_for_each_entry(conf, &conf_ilist, list)
> - if (conf->id == id)
> - return conf;
> -
> - return NULL;
> -}
> -
> -
> -/*
> - * add member to conference
> - */
> -static int
> -dsp_cmx_add_conf_member(struct dsp *dsp, struct dsp_conf *conf)
> -{
> - struct dsp_conf_member *member;
> -
> - if (!conf || !dsp) {
> - printk(KERN_WARNING "%s: conf or dsp is 0.\n", __func__);
> - return -EINVAL;
> - }
> - if (dsp->member) {
> - printk(KERN_WARNING "%s: dsp is already member in a conf.\n",
> - __func__);
> - return -EINVAL;
> - }
> -
> - if (dsp->conf) {
> - printk(KERN_WARNING "%s: dsp is already in a conf.\n",
> - __func__);
> - return -EINVAL;
> - }
> -
> - member = kzalloc_obj(struct dsp_conf_member, GFP_ATOMIC);
> - if (!member) {
> - printk(KERN_ERR "kzalloc struct dsp_conf_member failed\n");
> - return -ENOMEM;
> - }
> - member->dsp = dsp;
> - /* clear rx buffer */
> - memset(dsp->rx_buff, dsp_silence, sizeof(dsp->rx_buff));
> - dsp->rx_init = 1; /* rx_W and rx_R will be adjusted on first frame */
> - dsp->rx_W = 0;
> - dsp->rx_R = 0;
> -
> - list_add_tail(&member->list, &conf->mlist);
> -
> - dsp->conf = conf;
> - dsp->member = member;
> -
> - return 0;
> -}
> -
> -
> -/*
> - * del member from conference
> - */
> -int
> -dsp_cmx_del_conf_member(struct dsp *dsp)
> -{
> - struct dsp_conf_member *member;
> -
> - if (!dsp) {
> - printk(KERN_WARNING "%s: dsp is 0.\n",
> - __func__);
> - return -EINVAL;
> - }
> -
> - if (!dsp->conf) {
> - printk(KERN_WARNING "%s: dsp is not in a conf.\n",
> - __func__);
> - return -EINVAL;
> - }
> -
> - if (list_empty(&dsp->conf->mlist)) {
> - printk(KERN_WARNING "%s: dsp has linked an empty conf.\n",
> - __func__);
> - return -EINVAL;
> - }
> -
> - /* find us in conf */
> - list_for_each_entry(member, &dsp->conf->mlist, list) {
> - if (member->dsp == dsp) {
> - list_del(&member->list);
> - dsp->conf = NULL;
> - dsp->member = NULL;
> - kfree(member);
> - return 0;
> - }
> - }
> - printk(KERN_WARNING
> - "%s: dsp is not present in its own conf_member list.\n",
> - __func__);
> -
> - return -EINVAL;
> -}
> -
> -
> -/*
> - * new conference
> - */
> -static struct dsp_conf
> -*dsp_cmx_new_conf(u32 id)
> -{
> - struct dsp_conf *conf;
> -
> - if (!id) {
> - printk(KERN_WARNING "%s: id is 0.\n",
> - __func__);
> - return NULL;
> - }
> -
> - conf = kzalloc_obj(struct dsp_conf, GFP_ATOMIC);
> - if (!conf) {
> - printk(KERN_ERR "kzalloc struct dsp_conf failed\n");
> - return NULL;
> - }
> - INIT_LIST_HEAD(&conf->mlist);
> - conf->id = id;
> -
> - list_add_tail(&conf->list, &conf_ilist);
> -
> - return conf;
> -}
> -
> -
> -/*
> - * del conference
> - */
> -int
> -dsp_cmx_del_conf(struct dsp_conf *conf)
> -{
> - if (!conf) {
> - printk(KERN_WARNING "%s: conf is null.\n",
> - __func__);
> - return -EINVAL;
> - }
> -
> - if (!list_empty(&conf->mlist)) {
> - printk(KERN_WARNING "%s: conf not empty.\n",
> - __func__);
> - return -EINVAL;
> - }
> - list_del(&conf->list);
> - kfree(conf);
> -
> - return 0;
> -}
> -
> -
> -/*
> - * send HW message to hfc card
> - */
> -static void
> -dsp_cmx_hw_message(struct dsp *dsp, u32 message, u32 param1, u32 param2,
> - u32 param3, u32 param4)
> -{
> - struct mISDN_ctrl_req cq;
> -
> - memset(&cq, 0, sizeof(cq));
> - cq.op = message;
> - cq.p1 = param1 | (param2 << 8);
> - cq.p2 = param3 | (param4 << 8);
> - if (dsp->ch.peer)
> - dsp->ch.peer->ctrl(dsp->ch.peer, CONTROL_CHANNEL, &cq);
> -}
> -
> -
> -/*
> - * do hardware update and set the software/hardware flag
> - *
> - * either a conference or a dsp instance can be given
> - * if only dsp instance is given, the instance is not associated with a conf
> - * and therefore removed. if a conference is given, the dsp is expected to
> - * be member of that conference.
> - */
> -void
> -dsp_cmx_hardware(struct dsp_conf *conf, struct dsp *dsp)
> -{
> - struct dsp_conf_member *member, *nextm;
> - struct dsp *finddsp;
> - int memb = 0, i, ii, i1, i2;
> - int freeunits[8];
> - u_char freeslots[256];
> - int same_hfc = -1, same_pcm = -1, current_conf = -1,
> - all_conf = 1, tx_data = 0;
> -
> - /* dsp gets updated (no conf) */
> - if (!conf) {
> - if (!dsp)
> - return;
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG "%s checking dsp %s\n",
> - __func__, dsp->name);
> - one_member:
> - /* remove HFC conference if enabled */
> - if (dsp->hfc_conf >= 0) {
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG
> - "%s removing %s from HFC conf %d "
> - "because dsp is split\n", __func__,
> - dsp->name, dsp->hfc_conf);
> - dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_CONF_SPLIT,
> - 0, 0, 0, 0);
> - dsp->hfc_conf = -1;
> - }
> - /* process hw echo */
> - if (dsp->features.pcm_banks < 1)
> - return;
> - if (!dsp->echo.software && !dsp->echo.hardware) {
> - /* NO ECHO: remove PCM slot if assigned */
> - if (dsp->pcm_slot_tx >= 0 || dsp->pcm_slot_rx >= 0) {
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG "%s removing %s from"
> - " PCM slot %d (TX) %d (RX) because"
> - " dsp is split (no echo)\n",
> - __func__, dsp->name,
> - dsp->pcm_slot_tx, dsp->pcm_slot_rx);
> - dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_PCM_DISC,
> - 0, 0, 0, 0);
> - dsp->pcm_slot_tx = -1;
> - dsp->pcm_bank_tx = -1;
> - dsp->pcm_slot_rx = -1;
> - dsp->pcm_bank_rx = -1;
> - }
> - return;
> - }
> - /* echo is enabled, find out if we use soft or hardware */
> - dsp->echo.software = dsp->tx_data;
> - dsp->echo.hardware = 0;
> - /* ECHO: already echo */
> - if (dsp->pcm_slot_tx >= 0 && dsp->pcm_slot_rx < 0 &&
> - dsp->pcm_bank_tx == 2 && dsp->pcm_bank_rx == 2) {
> - dsp->echo.hardware = 1;
> - return;
> - }
> - /* ECHO: if slot already assigned */
> - if (dsp->pcm_slot_tx >= 0) {
> - dsp->pcm_slot_rx = dsp->pcm_slot_tx;
> - dsp->pcm_bank_tx = 2; /* 2 means loop */
> - dsp->pcm_bank_rx = 2;
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG
> - "%s refresh %s for echo using slot %d\n",
> - __func__, dsp->name,
> - dsp->pcm_slot_tx);
> - dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_PCM_CONN,
> - dsp->pcm_slot_tx, 2, dsp->pcm_slot_rx, 2);
> - dsp->echo.hardware = 1;
> - return;
> - }
> - /* ECHO: find slot */
> - dsp->pcm_slot_tx = -1;
> - dsp->pcm_slot_rx = -1;
> - memset(freeslots, 1, sizeof(freeslots));
> - list_for_each_entry(finddsp, &dsp_ilist, list) {
> - if (finddsp->features.pcm_id == dsp->features.pcm_id) {
> - if (finddsp->pcm_slot_rx >= 0 &&
> - finddsp->pcm_slot_rx < sizeof(freeslots))
> - freeslots[finddsp->pcm_slot_rx] = 0;
> - if (finddsp->pcm_slot_tx >= 0 &&
> - finddsp->pcm_slot_tx < sizeof(freeslots))
> - freeslots[finddsp->pcm_slot_tx] = 0;
> - }
> - }
> - i = 0;
> - ii = dsp->features.pcm_slots;
> - while (i < ii) {
> - if (freeslots[i])
> - break;
> - i++;
> - }
> - if (i == ii) {
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG
> - "%s no slot available for echo\n",
> - __func__);
> - /* no more slots available */
> - dsp->echo.software = 1;
> - return;
> - }
> - /* assign free slot */
> - dsp->pcm_slot_tx = i;
> - dsp->pcm_slot_rx = i;
> - dsp->pcm_bank_tx = 2; /* loop */
> - dsp->pcm_bank_rx = 2;
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG
> - "%s assign echo for %s using slot %d\n",
> - __func__, dsp->name, dsp->pcm_slot_tx);
> - dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_PCM_CONN,
> - dsp->pcm_slot_tx, 2, dsp->pcm_slot_rx, 2);
> - dsp->echo.hardware = 1;
> - return;
> - }
> -
> - /* conf gets updated (all members) */
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG "%s checking conference %d\n",
> - __func__, conf->id);
> -
> - if (list_empty(&conf->mlist)) {
> - printk(KERN_ERR "%s: conference without members\n",
> - __func__);
> - return;
> - }
> - member = list_entry(conf->mlist.next, struct dsp_conf_member, list);
> - same_hfc = member->dsp->features.hfc_id;
> - same_pcm = member->dsp->features.pcm_id;
> - /* check all members in our conference */
> - list_for_each_entry(member, &conf->mlist, list) {
> - /* check if member uses mixing */
> - if (member->dsp->tx_mix) {
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG
> - "%s dsp %s cannot form a conf, because "
> - "tx_mix is turned on\n", __func__,
> - member->dsp->name);
> - conf_software:
> - list_for_each_entry(member, &conf->mlist, list) {
> - dsp = member->dsp;
> - /* remove HFC conference if enabled */
> - if (dsp->hfc_conf >= 0) {
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG
> - "%s removing %s from HFC "
> - "conf %d because not "
> - "possible with hardware\n",
> - __func__,
> - dsp->name,
> - dsp->hfc_conf);
> - dsp_cmx_hw_message(dsp,
> - MISDN_CTRL_HFC_CONF_SPLIT,
> - 0, 0, 0, 0);
> - dsp->hfc_conf = -1;
> - }
> - /* remove PCM slot if assigned */
> - if (dsp->pcm_slot_tx >= 0 ||
> - dsp->pcm_slot_rx >= 0) {
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG "%s removing "
> - "%s from PCM slot %d (TX)"
> - " slot %d (RX) because not"
> - " possible with hardware\n",
> - __func__,
> - dsp->name,
> - dsp->pcm_slot_tx,
> - dsp->pcm_slot_rx);
> - dsp_cmx_hw_message(dsp,
> - MISDN_CTRL_HFC_PCM_DISC,
> - 0, 0, 0, 0);
> - dsp->pcm_slot_tx = -1;
> - dsp->pcm_bank_tx = -1;
> - dsp->pcm_slot_rx = -1;
> - dsp->pcm_bank_rx = -1;
> - }
> - }
> - conf->hardware = 0;
> - conf->software = 1;
> - return;
> - }
> - /* check if member has echo turned on */
> - if (member->dsp->echo.hardware || member->dsp->echo.software) {
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG
> - "%s dsp %s cannot form a conf, because "
> - "echo is turned on\n", __func__,
> - member->dsp->name);
> - goto conf_software;
> - }
> - /* check if member has tx_mix turned on */
> - if (member->dsp->tx_mix) {
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG
> - "%s dsp %s cannot form a conf, because "
> - "tx_mix is turned on\n",
> - __func__, member->dsp->name);
> - goto conf_software;
> - }
> - /* check if member changes volume at an not suppoted level */
> - if (member->dsp->tx_volume) {
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG
> - "%s dsp %s cannot form a conf, because "
> - "tx_volume is changed\n",
> - __func__, member->dsp->name);
> - goto conf_software;
> - }
> - if (member->dsp->rx_volume) {
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG
> - "%s dsp %s cannot form a conf, because "
> - "rx_volume is changed\n",
> - __func__, member->dsp->name);
> - goto conf_software;
> - }
> - /* check if tx-data turned on */
> - if (member->dsp->tx_data) {
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG
> - "%s dsp %s tx_data is turned on\n",
> - __func__, member->dsp->name);
> - tx_data = 1;
> - }
> - /* check if pipeline exists */
> - if (member->dsp->pipeline.inuse) {
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG
> - "%s dsp %s cannot form a conf, because "
> - "pipeline exists\n", __func__,
> - member->dsp->name);
> - goto conf_software;
> - }
> - /* check if encryption is enabled */
> - if (member->dsp->bf_enable) {
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG "%s dsp %s cannot form a "
> - "conf, because encryption is enabled\n",
> - __func__, member->dsp->name);
> - goto conf_software;
> - }
> - /* check if member is on a card with PCM support */
> - if (member->dsp->features.pcm_id < 0) {
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG
> - "%s dsp %s cannot form a conf, because "
> - "dsp has no PCM bus\n",
> - __func__, member->dsp->name);
> - goto conf_software;
> - }
> - /* check if relations are on the same PCM bus */
> - if (member->dsp->features.pcm_id != same_pcm) {
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG
> - "%s dsp %s cannot form a conf, because "
> - "dsp is on a different PCM bus than the "
> - "first dsp\n",
> - __func__, member->dsp->name);
> - goto conf_software;
> - }
> - /* determine if members are on the same hfc chip */
> - if (same_hfc != member->dsp->features.hfc_id)
> - same_hfc = -1;
> - /* if there are members already in a conference */
> - if (current_conf < 0 && member->dsp->hfc_conf >= 0)
> - current_conf = member->dsp->hfc_conf;
> - /* if any member is not in a conference */
> - if (member->dsp->hfc_conf < 0)
> - all_conf = 0;
> -
> - memb++;
> - }
> -
> - /* if no member, this is an error */
> - if (memb < 1)
> - return;
> -
> - /* one member */
> - if (memb == 1) {
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG
> - "%s conf %d cannot form a HW conference, "
> - "because dsp is alone\n", __func__, conf->id);
> - conf->hardware = 0;
> - conf->software = 0;
> - member = list_entry(conf->mlist.next, struct dsp_conf_member,
> - list);
> - dsp = member->dsp;
> - goto one_member;
> - }
> -
> - /*
> - * ok, now we are sure that all members are on the same pcm.
> - * now we will see if we have only two members, so we can do
> - * crossconnections, which don't have any limitations.
> - */
> -
> - /* if we have only two members */
> - if (memb == 2) {
> - member = list_entry(conf->mlist.next, struct dsp_conf_member,
> - list);
> - nextm = list_entry(member->list.next, struct dsp_conf_member,
> - list);
> - /* remove HFC conference if enabled */
> - if (member->dsp->hfc_conf >= 0) {
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG
> - "%s removing %s from HFC conf %d because "
> - "two parties require only a PCM slot\n",
> - __func__, member->dsp->name,
> - member->dsp->hfc_conf);
> - dsp_cmx_hw_message(member->dsp,
> - MISDN_CTRL_HFC_CONF_SPLIT, 0, 0, 0, 0);
> - member->dsp->hfc_conf = -1;
> - }
> - if (nextm->dsp->hfc_conf >= 0) {
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG
> - "%s removing %s from HFC conf %d because "
> - "two parties require only a PCM slot\n",
> - __func__, nextm->dsp->name,
> - nextm->dsp->hfc_conf);
> - dsp_cmx_hw_message(nextm->dsp,
> - MISDN_CTRL_HFC_CONF_SPLIT, 0, 0, 0, 0);
> - nextm->dsp->hfc_conf = -1;
> - }
> - /* if members have two banks (and not on the same chip) */
> - if (member->dsp->features.pcm_banks > 1 &&
> - nextm->dsp->features.pcm_banks > 1 &&
> - member->dsp->features.hfc_id !=
> - nextm->dsp->features.hfc_id) {
> - /* if both members have same slots with crossed banks */
> - if (member->dsp->pcm_slot_tx >= 0 &&
> - member->dsp->pcm_slot_rx >= 0 &&
> - nextm->dsp->pcm_slot_tx >= 0 &&
> - nextm->dsp->pcm_slot_rx >= 0 &&
> - nextm->dsp->pcm_slot_tx ==
> - member->dsp->pcm_slot_rx &&
> - nextm->dsp->pcm_slot_rx ==
> - member->dsp->pcm_slot_tx &&
> - nextm->dsp->pcm_slot_tx ==
> - member->dsp->pcm_slot_tx &&
> - member->dsp->pcm_bank_tx !=
> - member->dsp->pcm_bank_rx &&
> - nextm->dsp->pcm_bank_tx !=
> - nextm->dsp->pcm_bank_rx) {
> - /* all members have same slot */
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG
> - "%s dsp %s & %s stay joined on "
> - "PCM slot %d bank %d (TX) bank %d "
> - "(RX) (on different chips)\n",
> - __func__,
> - member->dsp->name,
> - nextm->dsp->name,
> - member->dsp->pcm_slot_tx,
> - member->dsp->pcm_bank_tx,
> - member->dsp->pcm_bank_rx);
> - conf->hardware = 1;
> - conf->software = tx_data;
> - return;
> - }
> - /* find a new slot */
> - memset(freeslots, 1, sizeof(freeslots));
> - list_for_each_entry(dsp, &dsp_ilist, list) {
> - if (dsp != member->dsp &&
> - dsp != nextm->dsp &&
> - member->dsp->features.pcm_id ==
> - dsp->features.pcm_id) {
> - if (dsp->pcm_slot_rx >= 0 &&
> - dsp->pcm_slot_rx <
> - sizeof(freeslots))
> - freeslots[dsp->pcm_slot_rx] = 0;
> - if (dsp->pcm_slot_tx >= 0 &&
> - dsp->pcm_slot_tx <
> - sizeof(freeslots))
> - freeslots[dsp->pcm_slot_tx] = 0;
> - }
> - }
> - i = 0;
> - ii = member->dsp->features.pcm_slots;
> - while (i < ii) {
> - if (freeslots[i])
> - break;
> - i++;
> - }
> - if (i == ii) {
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG
> - "%s no slot available for "
> - "%s & %s\n", __func__,
> - member->dsp->name,
> - nextm->dsp->name);
> - /* no more slots available */
> - goto conf_software;
> - }
> - /* assign free slot */
> - member->dsp->pcm_slot_tx = i;
> - member->dsp->pcm_slot_rx = i;
> - nextm->dsp->pcm_slot_tx = i;
> - nextm->dsp->pcm_slot_rx = i;
> - member->dsp->pcm_bank_rx = 0;
> - member->dsp->pcm_bank_tx = 1;
> - nextm->dsp->pcm_bank_rx = 1;
> - nextm->dsp->pcm_bank_tx = 0;
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG
> - "%s adding %s & %s to new PCM slot %d "
> - "(TX and RX on different chips) because "
> - "both members have not same slots\n",
> - __func__,
> - member->dsp->name,
> - nextm->dsp->name,
> - member->dsp->pcm_slot_tx);
> - dsp_cmx_hw_message(member->dsp, MISDN_CTRL_HFC_PCM_CONN,
> - member->dsp->pcm_slot_tx, member->dsp->pcm_bank_tx,
> - member->dsp->pcm_slot_rx, member->dsp->pcm_bank_rx);
> - dsp_cmx_hw_message(nextm->dsp, MISDN_CTRL_HFC_PCM_CONN,
> - nextm->dsp->pcm_slot_tx, nextm->dsp->pcm_bank_tx,
> - nextm->dsp->pcm_slot_rx, nextm->dsp->pcm_bank_rx);
> - conf->hardware = 1;
> - conf->software = tx_data;
> - return;
> - /* if members have one bank (or on the same chip) */
> - } else {
> - /* if both members have different crossed slots */
> - if (member->dsp->pcm_slot_tx >= 0 &&
> - member->dsp->pcm_slot_rx >= 0 &&
> - nextm->dsp->pcm_slot_tx >= 0 &&
> - nextm->dsp->pcm_slot_rx >= 0 &&
> - nextm->dsp->pcm_slot_tx ==
> - member->dsp->pcm_slot_rx &&
> - nextm->dsp->pcm_slot_rx ==
> - member->dsp->pcm_slot_tx &&
> - member->dsp->pcm_slot_tx !=
> - member->dsp->pcm_slot_rx &&
> - member->dsp->pcm_bank_tx == 0 &&
> - member->dsp->pcm_bank_rx == 0 &&
> - nextm->dsp->pcm_bank_tx == 0 &&
> - nextm->dsp->pcm_bank_rx == 0) {
> - /* all members have same slot */
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG
> - "%s dsp %s & %s stay joined on PCM "
> - "slot %d (TX) %d (RX) on same chip "
> - "or one bank PCM)\n", __func__,
> - member->dsp->name,
> - nextm->dsp->name,
> - member->dsp->pcm_slot_tx,
> - member->dsp->pcm_slot_rx);
> - conf->hardware = 1;
> - conf->software = tx_data;
> - return;
> - }
> - /* find two new slot */
> - memset(freeslots, 1, sizeof(freeslots));
> - list_for_each_entry(dsp, &dsp_ilist, list) {
> - if (dsp != member->dsp &&
> - dsp != nextm->dsp &&
> - member->dsp->features.pcm_id ==
> - dsp->features.pcm_id) {
> - if (dsp->pcm_slot_rx >= 0 &&
> - dsp->pcm_slot_rx <
> - sizeof(freeslots))
> - freeslots[dsp->pcm_slot_rx] = 0;
> - if (dsp->pcm_slot_tx >= 0 &&
> - dsp->pcm_slot_tx <
> - sizeof(freeslots))
> - freeslots[dsp->pcm_slot_tx] = 0;
> - }
> - }
> - i1 = 0;
> - ii = member->dsp->features.pcm_slots;
> - while (i1 < ii) {
> - if (freeslots[i1])
> - break;
> - i1++;
> - }
> - if (i1 == ii) {
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG
> - "%s no slot available "
> - "for %s & %s\n", __func__,
> - member->dsp->name,
> - nextm->dsp->name);
> - /* no more slots available */
> - goto conf_software;
> - }
> - i2 = i1 + 1;
> - while (i2 < ii) {
> - if (freeslots[i2])
> - break;
> - i2++;
> - }
> - if (i2 == ii) {
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG
> - "%s no slot available "
> - "for %s & %s\n",
> - __func__,
> - member->dsp->name,
> - nextm->dsp->name);
> - /* no more slots available */
> - goto conf_software;
> - }
> - /* assign free slots */
> - member->dsp->pcm_slot_tx = i1;
> - member->dsp->pcm_slot_rx = i2;
> - nextm->dsp->pcm_slot_tx = i2;
> - nextm->dsp->pcm_slot_rx = i1;
> - member->dsp->pcm_bank_rx = 0;
> - member->dsp->pcm_bank_tx = 0;
> - nextm->dsp->pcm_bank_rx = 0;
> - nextm->dsp->pcm_bank_tx = 0;
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG
> - "%s adding %s & %s to new PCM slot %d "
> - "(TX) %d (RX) on same chip or one bank "
> - "PCM, because both members have not "
> - "crossed slots\n", __func__,
> - member->dsp->name,
> - nextm->dsp->name,
> - member->dsp->pcm_slot_tx,
> - member->dsp->pcm_slot_rx);
> - dsp_cmx_hw_message(member->dsp, MISDN_CTRL_HFC_PCM_CONN,
> - member->dsp->pcm_slot_tx, member->dsp->pcm_bank_tx,
> - member->dsp->pcm_slot_rx, member->dsp->pcm_bank_rx);
> - dsp_cmx_hw_message(nextm->dsp, MISDN_CTRL_HFC_PCM_CONN,
> - nextm->dsp->pcm_slot_tx, nextm->dsp->pcm_bank_tx,
> - nextm->dsp->pcm_slot_rx, nextm->dsp->pcm_bank_rx);
> - conf->hardware = 1;
> - conf->software = tx_data;
> - return;
> - }
> - }
> -
> - /*
> - * if we have more than two, we may check if we have a conference
> - * unit available on the chip. also all members must be on the same
> - */
> -
> - /* if not the same HFC chip */
> - if (same_hfc < 0) {
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG
> - "%s conference %d cannot be formed, because "
> - "members are on different chips or not "
> - "on HFC chip\n",
> - __func__, conf->id);
> - goto conf_software;
> - }
> -
> - /* for more than two members.. */
> -
> - /* if all members already have the same conference */
> - if (all_conf) {
> - conf->hardware = 1;
> - conf->software = tx_data;
> - return;
> - }
> -
> - /*
> - * if there is an existing conference, but not all members have joined
> - */
> - if (current_conf >= 0) {
> - join_members:
> - list_for_each_entry(member, &conf->mlist, list) {
> - /* if no conference engine on our chip, change to
> - * software */
> - if (!member->dsp->features.hfc_conf)
> - goto conf_software;
> - /* in case of hdlc, change to software */
> - if (member->dsp->hdlc)
> - goto conf_software;
> - /* join to current conference */
> - if (member->dsp->hfc_conf == current_conf)
> - continue;
> - /* get a free timeslot first */
> - memset(freeslots, 1, sizeof(freeslots));
> - list_for_each_entry(dsp, &dsp_ilist, list) {
> - /*
> - * not checking current member, because
> - * slot will be overwritten.
> - */
> - if (
> - dsp != member->dsp &&
> - /* dsp must be on the same PCM */
> - member->dsp->features.pcm_id ==
> - dsp->features.pcm_id) {
> - /* dsp must be on a slot */
> - if (dsp->pcm_slot_tx >= 0 &&
> - dsp->pcm_slot_tx <
> - sizeof(freeslots))
> - freeslots[dsp->pcm_slot_tx] = 0;
> - if (dsp->pcm_slot_rx >= 0 &&
> - dsp->pcm_slot_rx <
> - sizeof(freeslots))
> - freeslots[dsp->pcm_slot_rx] = 0;
> - }
> - }
> - i = 0;
> - ii = member->dsp->features.pcm_slots;
> - while (i < ii) {
> - if (freeslots[i])
> - break;
> - i++;
> - }
> - if (i == ii) {
> - /* no more slots available */
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG
> - "%s conference %d cannot be formed,"
> - " because no slot free\n",
> - __func__, conf->id);
> - goto conf_software;
> - }
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG
> - "%s changing dsp %s to HW conference "
> - "%d slot %d\n", __func__,
> - member->dsp->name, current_conf, i);
> - /* assign free slot & set PCM & join conf */
> - member->dsp->pcm_slot_tx = i;
> - member->dsp->pcm_slot_rx = i;
> - member->dsp->pcm_bank_tx = 2; /* loop */
> - member->dsp->pcm_bank_rx = 2;
> - member->dsp->hfc_conf = current_conf;
> - dsp_cmx_hw_message(member->dsp, MISDN_CTRL_HFC_PCM_CONN,
> - i, 2, i, 2);
> - dsp_cmx_hw_message(member->dsp,
> - MISDN_CTRL_HFC_CONF_JOIN, current_conf, 0, 0, 0);
> - }
> - conf->hardware = 1;
> - conf->software = tx_data;
> - return;
> - }
> -
> - /*
> - * no member is in a conference yet, so we find a free one
> - */
> - memset(freeunits, 1, sizeof(freeunits));
> - list_for_each_entry(dsp, &dsp_ilist, list) {
> - /* dsp must be on the same chip */
> - if (dsp->features.hfc_id == same_hfc &&
> - /* dsp must have joined a HW conference */
> - dsp->hfc_conf >= 0 &&
> - /* slot must be within range */
> - dsp->hfc_conf < 8)
> - freeunits[dsp->hfc_conf] = 0;
> - }
> - i = 0;
> - ii = 8;
> - while (i < ii) {
> - if (freeunits[i])
> - break;
> - i++;
> - }
> - if (i == ii) {
> - /* no more conferences available */
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG
> - "%s conference %d cannot be formed, because "
> - "no conference number free\n",
> - __func__, conf->id);
> - goto conf_software;
> - }
> - /* join all members */
> - current_conf = i;
> - goto join_members;
> -}
> -
> -
> -/*
> - * conf_id != 0: join or change conference
> - * conf_id == 0: split from conference if not already
> - */
> -int
> -dsp_cmx_conf(struct dsp *dsp, u32 conf_id)
> -{
> - int err;
> - struct dsp_conf *conf;
> - struct dsp_conf_member *member;
> -
> - /* if conference doesn't change */
> - if (dsp->conf_id == conf_id)
> - return 0;
> -
> - /* first remove us from current conf */
> - if (dsp->conf_id) {
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG "removing us from conference %d\n",
> - dsp->conf->id);
> - /* remove us from conf */
> - conf = dsp->conf;
> - err = dsp_cmx_del_conf_member(dsp);
> - if (err)
> - return err;
> - dsp->conf_id = 0;
> -
> - /* update hardware */
> - dsp_cmx_hardware(NULL, dsp);
> -
> - /* conf now empty? */
> - if (list_empty(&conf->mlist)) {
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG
> - "conference is empty, so we remove it.\n");
> - err = dsp_cmx_del_conf(conf);
> - if (err)
> - return err;
> - } else {
> - /* update members left on conf */
> - dsp_cmx_hardware(conf, NULL);
> - }
> - }
> -
> - /* if split */
> - if (!conf_id)
> - return 0;
> -
> - /* now add us to conf */
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG "searching conference %d\n",
> - conf_id);
> - conf = dsp_cmx_search_conf(conf_id);
> - if (!conf) {
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG
> - "conference doesn't exist yet, creating.\n");
> - /* the conference doesn't exist, so we create */
> - conf = dsp_cmx_new_conf(conf_id);
> - if (!conf)
> - return -EINVAL;
> - } else if (!list_empty(&conf->mlist)) {
> - member = list_entry(conf->mlist.next, struct dsp_conf_member,
> - list);
> - if (dsp->hdlc && !member->dsp->hdlc) {
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG
> - "cannot join transparent conference.\n");
> - return -EINVAL;
> - }
> - if (!dsp->hdlc && member->dsp->hdlc) {
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG
> - "cannot join hdlc conference.\n");
> - return -EINVAL;
> - }
> - }
> - /* add conference member */
> - err = dsp_cmx_add_conf_member(dsp, conf);
> - if (err)
> - return err;
> - dsp->conf_id = conf_id;
> -
> - /* if we are alone, we do nothing! */
> - if (list_empty(&conf->mlist)) {
> - if (dsp_debug & DEBUG_DSP_CMX)
> - printk(KERN_DEBUG
> - "we are alone in this conference, so exit.\n");
> - /* update hardware */
> - dsp_cmx_hardware(NULL, dsp);
> - return 0;
> - }
> -
> - /* update members on conf */
> - dsp_cmx_hardware(conf, NULL);
> -
> - return 0;
> -}
> -
> -#ifdef CMX_DELAY_DEBUG
> -int delaycount;
> -static void
> -showdelay(struct dsp *dsp, int samples, int delay)
> -{
> - char bar[] = "--------------------------------------------------|";
> - int sdelay;
> -
> - delaycount += samples;
> - if (delaycount < 8000)
> - return;
> - delaycount = 0;
> -
> - sdelay = delay * 50 / (dsp_poll << 2);
> -
> - printk(KERN_DEBUG "DELAY (%s) %3d >%s\n", dsp->name, delay,
> - sdelay > 50 ? "..." : bar + 50 - sdelay);
> -}
> -#endif
> -
> -/*
> - * audio data is received from card
> - */
> -void
> -dsp_cmx_receive(struct dsp *dsp, struct sk_buff *skb)
> -{
> - u8 *d, *p;
> - int len = skb->len;
> - struct mISDNhead *hh = mISDN_HEAD_P(skb);
> - int w, i, ii;
> -
> - /* check if we have sompen */
> - if (len < 1)
> - return;
> -
> - /* half of the buffer should be larger than maximum packet size */
> - if (len >= CMX_BUFF_HALF) {
> - printk(KERN_ERR
> - "%s line %d: packet from card is too large (%d bytes). "
> - "please make card send smaller packets OR increase "
> - "CMX_BUFF_SIZE\n", __FILE__, __LINE__, len);
> - return;
> - }
> -
> - /*
> - * initialize pointers if not already -
> - * also add delay if requested by PH_SIGNAL
> - */
> - if (dsp->rx_init) {
> - dsp->rx_init = 0;
> - if (dsp->features.unordered) {
> - dsp->rx_R = (hh->id & CMX_BUFF_MASK);
> - if (dsp->cmx_delay)
> - dsp->rx_W = (dsp->rx_R + dsp->cmx_delay)
> - & CMX_BUFF_MASK;
> - else
> - dsp->rx_W = (dsp->rx_R + (dsp_poll >> 1))
> - & CMX_BUFF_MASK;
> - } else {
> - dsp->rx_R = 0;
> - if (dsp->cmx_delay)
> - dsp->rx_W = dsp->cmx_delay;
> - else
> - dsp->rx_W = dsp_poll >> 1;
> - }
> - }
> - /* if frame contains time code, write directly */
> - if (dsp->features.unordered) {
> - dsp->rx_W = (hh->id & CMX_BUFF_MASK);
> - /* printk(KERN_DEBUG "%s %08x\n", dsp->name, hh->id); */
> - }
> - /*
> - * if we underrun (or maybe overrun),
> - * we set our new read pointer, and write silence to buffer
> - */
> - if (((dsp->rx_W-dsp->rx_R) & CMX_BUFF_MASK) >= CMX_BUFF_HALF) {
> - if (dsp_debug & DEBUG_DSP_CLOCK)
> - printk(KERN_DEBUG
> - "cmx_receive(dsp=%lx): UNDERRUN (or overrun the "
> - "maximum delay), adjusting read pointer! "
> - "(inst %s)\n", (u_long)dsp, dsp->name);
> - /* flush rx buffer and set delay to dsp_poll / 2 */
> - if (dsp->features.unordered) {
> - dsp->rx_R = (hh->id & CMX_BUFF_MASK);
> - if (dsp->cmx_delay)
> - dsp->rx_W = (dsp->rx_R + dsp->cmx_delay)
> - & CMX_BUFF_MASK;
> - else
> - dsp->rx_W = (dsp->rx_R + (dsp_poll >> 1))
> - & CMX_BUFF_MASK;
> - } else {
> - dsp->rx_R = 0;
> - if (dsp->cmx_delay)
> - dsp->rx_W = dsp->cmx_delay;
> - else
> - dsp->rx_W = dsp_poll >> 1;
> - }
> - memset(dsp->rx_buff, dsp_silence, sizeof(dsp->rx_buff));
> - }
> - /* if we have reached double delay, jump back to middle */
> - if (dsp->cmx_delay)
> - if (((dsp->rx_W - dsp->rx_R) & CMX_BUFF_MASK) >=
> - (dsp->cmx_delay << 1)) {
> - if (dsp_debug & DEBUG_DSP_CLOCK)
> - printk(KERN_DEBUG
> - "cmx_receive(dsp=%lx): OVERRUN (because "
> - "twice the delay is reached), adjusting "
> - "read pointer! (inst %s)\n",
> - (u_long)dsp, dsp->name);
> - /* flush buffer */
> - if (dsp->features.unordered) {
> - dsp->rx_R = (hh->id & CMX_BUFF_MASK);
> - dsp->rx_W = (dsp->rx_R + dsp->cmx_delay)
> - & CMX_BUFF_MASK;
> - } else {
> - dsp->rx_R = 0;
> - dsp->rx_W = dsp->cmx_delay;
> - }
> - memset(dsp->rx_buff, dsp_silence, sizeof(dsp->rx_buff));
> - }
> -
> - /* show where to write */
> -#ifdef CMX_DEBUG
> - printk(KERN_DEBUG
> - "cmx_receive(dsp=%lx): rx_R(dsp)=%05x rx_W(dsp)=%05x len=%d %s\n",
> - (u_long)dsp, dsp->rx_R, dsp->rx_W, len, dsp->name);
> -#endif
> -
> - /* write data into rx_buffer */
> - p = skb->data;
> - d = dsp->rx_buff;
> - w = dsp->rx_W;
> - i = 0;
> - ii = len;
> - while (i < ii) {
> - d[w++ & CMX_BUFF_MASK] = *p++;
> - i++;
> - }
> -
> - /* increase write-pointer */
> - dsp->rx_W = ((dsp->rx_W + len) & CMX_BUFF_MASK);
> -#ifdef CMX_DELAY_DEBUG
> - showdelay(dsp, len, (dsp->rx_W-dsp->rx_R) & CMX_BUFF_MASK);
> -#endif
> -}
> -
> -
> -/*
> - * send (mixed) audio data to card and control jitter
> - */
> -static void
> -dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members)
> -{
> - struct dsp_conf *conf = dsp->conf;
> - struct dsp *member, *other;
> - register s32 sample;
> - u8 *d, *p, *q, *o_q;
> - struct sk_buff *nskb, *txskb;
> - int r, rr, t, tt, o_r, o_rr;
> - int preload = 0;
> - struct mISDNhead *hh, *thh;
> - int tx_data_only = 0;
> -
> - /* don't process if: */
> - if (!dsp->b_active) { /* if not active */
> - dsp->last_tx = 0;
> - return;
> - }
> - if (((dsp->conf && dsp->conf->hardware) || /* hardware conf */
> - dsp->echo.hardware) && /* OR hardware echo */
> - dsp->tx_R == dsp->tx_W && /* AND no tx-data */
> - !(dsp->tone.tone && dsp->tone.software)) { /* AND not soft tones */
> - if (!dsp->tx_data) { /* no tx_data for user space required */
> - dsp->last_tx = 0;
> - return;
> - }
> - if (dsp->conf && dsp->conf->software && dsp->conf->hardware)
> - tx_data_only = 1;
> - if (dsp->echo.software && dsp->echo.hardware)
> - tx_data_only = 1;
> - }
> -
> -#ifdef CMX_DEBUG
> - printk(KERN_DEBUG
> - "SEND members=%d dsp=%s, conf=%p, rx_R=%05x rx_W=%05x\n",
> - members, dsp->name, conf, dsp->rx_R, dsp->rx_W);
> -#endif
> -
> - /* preload if we have delay set */
> - if (dsp->cmx_delay && !dsp->last_tx) {
> - preload = len;
> - if (preload < 128)
> - preload = 128;
> - }
> -
> - /* PREPARE RESULT */
> - nskb = mI_alloc_skb(len + preload, GFP_ATOMIC);
> - if (!nskb) {
> - printk(KERN_ERR
> - "FATAL ERROR in mISDN_dsp.o: cannot alloc %d bytes\n",
> - len + preload);
> - return;
> - }
> - hh = mISDN_HEAD_P(nskb);
> - hh->prim = PH_DATA_REQ;
> - hh->id = 0;
> - dsp->last_tx = 1;
> -
> - /* set pointers, indexes and stuff */
> - member = dsp;
> - p = dsp->tx_buff; /* transmit data */
> - q = dsp->rx_buff; /* received data */
> - d = skb_put(nskb, preload + len); /* result */
> - t = dsp->tx_R; /* tx-pointers */
> - tt = dsp->tx_W;
> - r = dsp->rx_R; /* rx-pointers */
> - rr = (r + len) & CMX_BUFF_MASK;
> -
> - /* preload with silence, if required */
> - if (preload) {
> - memset(d, dsp_silence, preload);
> - d += preload;
> - }
> -
> - /* PROCESS TONES/TX-DATA ONLY */
> - if (dsp->tone.tone && dsp->tone.software) {
> - /* -> copy tone */
> - dsp_tone_copy(dsp, d, len);
> - dsp->tx_R = 0; /* clear tx buffer */
> - dsp->tx_W = 0;
> - goto send_packet;
> - }
> - /* if we have tx-data but do not use mixing */
> - if (!dsp->tx_mix && t != tt) {
> - /* -> send tx-data and continue when not enough */
> -#ifdef CMX_TX_DEBUG
> - sprintf(debugbuf, "TX sending (%04x-%04x)%p: ", t, tt, p);
> -#endif
> - while (r != rr && t != tt) {
> -#ifdef CMX_TX_DEBUG
> - if (strlen(debugbuf) < 48)
> - sprintf(debugbuf + strlen(debugbuf), " %02x",
> - p[t]);
> -#endif
> - *d++ = p[t]; /* write tx_buff */
> - t = (t + 1) & CMX_BUFF_MASK;
> - r = (r + 1) & CMX_BUFF_MASK;
> - }
> - if (r == rr) {
> - dsp->tx_R = t;
> -#ifdef CMX_TX_DEBUG
> - printk(KERN_DEBUG "%s\n", debugbuf);
> -#endif
> - goto send_packet;
> - }
> - }
> -#ifdef CMX_TX_DEBUG
> - printk(KERN_DEBUG "%s\n", debugbuf);
> -#endif
> -
> - /* PROCESS DATA (one member / no conf) */
> - if (!conf || members <= 1) {
> - /* -> if echo is NOT enabled */
> - if (!dsp->echo.software) {
> - /* -> send tx-data if available or use 0-volume */
> - while (r != rr && t != tt) {
> - *d++ = p[t]; /* write tx_buff */
> - t = (t + 1) & CMX_BUFF_MASK;
> - r = (r + 1) & CMX_BUFF_MASK;
> - }
> - if (r != rr) {
> - if (dsp_debug & DEBUG_DSP_CLOCK)
> - printk(KERN_DEBUG "%s: RX empty\n",
> - __func__);
> - memset(d, dsp_silence, (rr - r) & CMX_BUFF_MASK);
> - }
> - /* -> if echo is enabled */
> - } else {
> - /*
> - * -> mix tx-data with echo if available,
> - * or use echo only
> - */
> - while (r != rr && t != tt) {
> - *d++ = dsp_audio_mix_law[(p[t] << 8) | q[r]];
> - t = (t + 1) & CMX_BUFF_MASK;
> - r = (r + 1) & CMX_BUFF_MASK;
> - }
> - while (r != rr) {
> - *d++ = q[r]; /* echo */
> - r = (r + 1) & CMX_BUFF_MASK;
> - }
> - }
> - dsp->tx_R = t;
> - goto send_packet;
> - }
> - /* PROCESS DATA (two members) */
> -#ifdef CMX_CONF_DEBUG
> - if (0) {
> -#else
> - if (members == 2) {
> -#endif
> - /* "other" becomes other party */
> - other = (list_entry(conf->mlist.next,
> - struct dsp_conf_member, list))->dsp;
> - if (other == member)
> - other = (list_entry(conf->mlist.prev,
> - struct dsp_conf_member, list))->dsp;
> - o_q = other->rx_buff; /* received data */
> - o_rr = (other->rx_R + len) & CMX_BUFF_MASK;
> - /* end of rx-pointer */
> - o_r = (o_rr - rr + r) & CMX_BUFF_MASK;
> - /* start rx-pointer at current read position*/
> - /* -> if echo is NOT enabled */
> - if (!dsp->echo.software) {
> - /*
> - * -> copy other member's rx-data,
> - * if tx-data is available, mix
> - */
> - while (o_r != o_rr && t != tt) {
> - *d++ = dsp_audio_mix_law[(p[t] << 8) | o_q[o_r]];
> - t = (t + 1) & CMX_BUFF_MASK;
> - o_r = (o_r + 1) & CMX_BUFF_MASK;
> - }
> - while (o_r != o_rr) {
> - *d++ = o_q[o_r];
> - o_r = (o_r + 1) & CMX_BUFF_MASK;
> - }
> - /* -> if echo is enabled */
> - } else {
> - /*
> - * -> mix other member's rx-data with echo,
> - * if tx-data is available, mix
> - */
> - while (r != rr && t != tt) {
> - sample = dsp_audio_law_to_s32[p[t]] +
> - dsp_audio_law_to_s32[q[r]] +
> - dsp_audio_law_to_s32[o_q[o_r]];
> - if (sample < -32768)
> - sample = -32768;
> - else if (sample > 32767)
> - sample = 32767;
> - *d++ = dsp_audio_s16_to_law[sample & 0xffff];
> - /* tx-data + rx_data + echo */
> - t = (t + 1) & CMX_BUFF_MASK;
> - r = (r + 1) & CMX_BUFF_MASK;
> - o_r = (o_r + 1) & CMX_BUFF_MASK;
> - }
> - while (r != rr) {
> - *d++ = dsp_audio_mix_law[(q[r] << 8) | o_q[o_r]];
> - r = (r + 1) & CMX_BUFF_MASK;
> - o_r = (o_r + 1) & CMX_BUFF_MASK;
> - }
> - }
> - dsp->tx_R = t;
> - goto send_packet;
> - }
> - /* PROCESS DATA (three or more members) */
> - /* -> if echo is NOT enabled */
> - if (!dsp->echo.software) {
> - /*
> - * -> subtract rx-data from conf-data,
> - * if tx-data is available, mix
> - */
> - while (r != rr && t != tt) {
> - sample = dsp_audio_law_to_s32[p[t]] + *c++ -
> - dsp_audio_law_to_s32[q[r]];
> - if (sample < -32768)
> - sample = -32768;
> - else if (sample > 32767)
> - sample = 32767;
> - *d++ = dsp_audio_s16_to_law[sample & 0xffff];
> - /* conf-rx+tx */
> - r = (r + 1) & CMX_BUFF_MASK;
> - t = (t + 1) & CMX_BUFF_MASK;
> - }
> - while (r != rr) {
> - sample = *c++ - dsp_audio_law_to_s32[q[r]];
> - if (sample < -32768)
> - sample = -32768;
> - else if (sample > 32767)
> - sample = 32767;
> - *d++ = dsp_audio_s16_to_law[sample & 0xffff];
> - /* conf-rx */
> - r = (r + 1) & CMX_BUFF_MASK;
> - }
> - /* -> if echo is enabled */
> - } else {
> - /*
> - * -> encode conf-data, if tx-data
> - * is available, mix
> - */
> - while (r != rr && t != tt) {
> - sample = dsp_audio_law_to_s32[p[t]] + *c++;
> - if (sample < -32768)
> - sample = -32768;
> - else if (sample > 32767)
> - sample = 32767;
> - *d++ = dsp_audio_s16_to_law[sample & 0xffff];
> - /* conf(echo)+tx */
> - t = (t + 1) & CMX_BUFF_MASK;
> - r = (r + 1) & CMX_BUFF_MASK;
> - }
> - while (r != rr) {
> - sample = *c++;
> - if (sample < -32768)
> - sample = -32768;
> - else if (sample > 32767)
> - sample = 32767;
> - *d++ = dsp_audio_s16_to_law[sample & 0xffff];
> - /* conf(echo) */
> - r = (r + 1) & CMX_BUFF_MASK;
> - }
> - }
> - dsp->tx_R = t;
> - goto send_packet;
> -
> -send_packet:
> - /*
> - * send tx-data if enabled - don't filter,
> - * because we want what we send, not what we filtered
> - */
> - if (dsp->tx_data) {
> - if (tx_data_only) {
> - hh->prim = DL_DATA_REQ;
> - hh->id = 0;
> - /* queue and trigger */
> - skb_queue_tail(&dsp->sendq, nskb);
> - schedule_work(&dsp->workq);
> - /* exit because only tx_data is used */
> - return;
> - } else {
> - txskb = mI_alloc_skb(len, GFP_ATOMIC);
> - if (!txskb) {
> - printk(KERN_ERR
> - "FATAL ERROR in mISDN_dsp.o: "
> - "cannot alloc %d bytes\n", len);
> - } else {
> - thh = mISDN_HEAD_P(txskb);
> - thh->prim = DL_DATA_REQ;
> - thh->id = 0;
> - skb_put_data(txskb, nskb->data + preload, len);
> - /* queue (trigger later) */
> - skb_queue_tail(&dsp->sendq, txskb);
> - }
> - }
> - }
> -
> - /* send data only to card, if we don't just calculated tx_data */
> - /* adjust volume */
> - if (dsp->tx_volume)
> - dsp_change_volume(nskb, dsp->tx_volume);
> - /* pipeline */
> - if (dsp->pipeline.inuse)
> - dsp_pipeline_process_tx(&dsp->pipeline, nskb->data,
> - nskb->len);
> - /* crypt */
> - if (dsp->bf_enable)
> - dsp_bf_encrypt(dsp, nskb->data, nskb->len);
> - /* queue and trigger */
> - skb_queue_tail(&dsp->sendq, nskb);
> - schedule_work(&dsp->workq);
> -}
> -
> -static u32 jittercount; /* counter for jitter check */
> -struct timer_list dsp_spl_tl;
> -unsigned long dsp_spl_jiffies; /* calculate the next time to fire */
> -static u16 dsp_count; /* last sample count */
> -static int dsp_count_valid; /* if we have last sample count */
> -
> -void
> -dsp_cmx_send(struct timer_list *arg)
> -{
> - struct dsp_conf *conf;
> - struct dsp_conf_member *member;
> - struct dsp *dsp;
> - int mustmix, members;
> - static s32 mixbuffer[MAX_POLL + 100];
> - s32 *c;
> - u8 *p, *q;
> - int r, rr;
> - int jittercheck = 0, delay, i;
> - u_long flags;
> - u16 length, count;
> -
> - /* lock */
> - spin_lock_irqsave(&dsp_lock, flags);
> -
> - if (!dsp_count_valid) {
> - dsp_count = mISDN_clock_get();
> - length = dsp_poll;
> - dsp_count_valid = 1;
> - } else {
> - count = mISDN_clock_get();
> - length = count - dsp_count;
> - dsp_count = count;
> - }
> - if (length > MAX_POLL + 100)
> - length = MAX_POLL + 100;
> - /* printk(KERN_DEBUG "len=%d dsp_count=0x%x\n", length, dsp_count); */
> -
> - /*
> - * check if jitter needs to be checked (this is every second)
> - */
> - jittercount += length;
> - if (jittercount >= 8000) {
> - jittercount -= 8000;
> - jittercheck = 1;
> - }
> -
> - /* loop all members that do not require conference mixing */
> - list_for_each_entry(dsp, &dsp_ilist, list) {
> - if (dsp->hdlc)
> - continue;
> - conf = dsp->conf;
> - mustmix = 0;
> - members = 0;
> - if (conf) {
> - members = list_count_nodes(&conf->mlist);
> -#ifdef CMX_CONF_DEBUG
> - if (conf->software && members > 1)
> -#else
> - if (conf->software && members > 2)
> -#endif
> - mustmix = 1;
> - }
> -
> - /* transmission required */
> - if (!mustmix) {
> - dsp_cmx_send_member(dsp, length, mixbuffer, members);
> -
> - /*
> - * unused mixbuffer is given to prevent a
> - * potential null-pointer-bug
> - */
> - }
> - }
> -
> - /* loop all members that require conference mixing */
> - list_for_each_entry(conf, &conf_ilist, list) {
> - /* count members and check hardware */
> - members = list_count_nodes(&conf->mlist);
> -#ifdef CMX_CONF_DEBUG
> - if (conf->software && members > 1) {
> -#else
> - if (conf->software && members > 2) {
> -#endif
> - /* check for hdlc conf */
> - member = list_entry(conf->mlist.next,
> - struct dsp_conf_member, list);
> - if (member->dsp->hdlc)
> - continue;
> - /* mix all data */
> - memset(mixbuffer, 0, length * sizeof(s32));
> - list_for_each_entry(member, &conf->mlist, list) {
> - dsp = member->dsp;
> - /* get range of data to mix */
> - c = mixbuffer;
> - q = dsp->rx_buff;
> - r = dsp->rx_R;
> - rr = (r + length) & CMX_BUFF_MASK;
> - /* add member's data */
> - while (r != rr) {
> - *c++ += dsp_audio_law_to_s32[q[r]];
> - r = (r + 1) & CMX_BUFF_MASK;
> - }
> - }
> -
> - /* process each member */
> - list_for_each_entry(member, &conf->mlist, list) {
> - /* transmission */
> - dsp_cmx_send_member(member->dsp, length,
> - mixbuffer, members);
> - }
> - }
> - }
> -
> - /* delete rx-data, increment buffers, change pointers */
> - list_for_each_entry(dsp, &dsp_ilist, list) {
> - if (dsp->hdlc)
> - continue;
> - p = dsp->rx_buff;
> - q = dsp->tx_buff;
> - r = dsp->rx_R;
> - /* move receive pointer when receiving */
> - if (!dsp->rx_is_off) {
> - rr = (r + length) & CMX_BUFF_MASK;
> - /* delete rx-data */
> - while (r != rr) {
> - p[r] = dsp_silence;
> - r = (r + 1) & CMX_BUFF_MASK;
> - }
> - /* increment rx-buffer pointer */
> - dsp->rx_R = r; /* write incremented read pointer */
> - }
> -
> - /* check current rx_delay */
> - delay = (dsp->rx_W-dsp->rx_R) & CMX_BUFF_MASK;
> - if (delay >= CMX_BUFF_HALF)
> - delay = 0; /* will be the delay before next write */
> - /* check for lower delay */
> - if (delay < dsp->rx_delay[0])
> - dsp->rx_delay[0] = delay;
> - /* check current tx_delay */
> - delay = (dsp->tx_W-dsp->tx_R) & CMX_BUFF_MASK;
> - if (delay >= CMX_BUFF_HALF)
> - delay = 0; /* will be the delay before next write */
> - /* check for lower delay */
> - if (delay < dsp->tx_delay[0])
> - dsp->tx_delay[0] = delay;
> - if (jittercheck) {
> - /* find the lowest of all rx_delays */
> - delay = dsp->rx_delay[0];
> - i = 1;
> - while (i < MAX_SECONDS_JITTER_CHECK) {
> - if (delay > dsp->rx_delay[i])
> - delay = dsp->rx_delay[i];
> - i++;
> - }
> - /*
> - * remove rx_delay only if we have delay AND we
> - * have not preset cmx_delay AND
> - * the delay is greater dsp_poll
> - */
> - if (delay > dsp_poll && !dsp->cmx_delay) {
> - if (dsp_debug & DEBUG_DSP_CLOCK)
> - printk(KERN_DEBUG
> - "%s lowest rx_delay of %d bytes for"
> - " dsp %s are now removed.\n",
> - __func__, delay,
> - dsp->name);
> - r = dsp->rx_R;
> - rr = (r + delay - (dsp_poll >> 1))
> - & CMX_BUFF_MASK;
> - /* delete rx-data */
> - while (r != rr) {
> - p[r] = dsp_silence;
> - r = (r + 1) & CMX_BUFF_MASK;
> - }
> - /* increment rx-buffer pointer */
> - dsp->rx_R = r;
> - /* write incremented read pointer */
> - }
> - /* find the lowest of all tx_delays */
> - delay = dsp->tx_delay[0];
> - i = 1;
> - while (i < MAX_SECONDS_JITTER_CHECK) {
> - if (delay > dsp->tx_delay[i])
> - delay = dsp->tx_delay[i];
> - i++;
> - }
> - /*
> - * remove delay only if we have delay AND we
> - * have enabled tx_dejitter
> - */
> - if (delay > dsp_poll && dsp->tx_dejitter) {
> - if (dsp_debug & DEBUG_DSP_CLOCK)
> - printk(KERN_DEBUG
> - "%s lowest tx_delay of %d bytes for"
> - " dsp %s are now removed.\n",
> - __func__, delay,
> - dsp->name);
> - r = dsp->tx_R;
> - rr = (r + delay - (dsp_poll >> 1))
> - & CMX_BUFF_MASK;
> - /* delete tx-data */
> - while (r != rr) {
> - q[r] = dsp_silence;
> - r = (r + 1) & CMX_BUFF_MASK;
> - }
> - /* increment rx-buffer pointer */
> - dsp->tx_R = r;
> - /* write incremented read pointer */
> - }
> - /* scroll up delays */
> - i = MAX_SECONDS_JITTER_CHECK - 1;
> - while (i) {
> - dsp->rx_delay[i] = dsp->rx_delay[i - 1];
> - dsp->tx_delay[i] = dsp->tx_delay[i - 1];
> - i--;
> - }
> - dsp->tx_delay[0] = CMX_BUFF_HALF; /* (infinite) delay */
> - dsp->rx_delay[0] = CMX_BUFF_HALF; /* (infinite) delay */
> - }
> - }
> -
> - /* if next event would be in the past ... */
> - if ((s32)(dsp_spl_jiffies + dsp_tics-jiffies) <= 0)
> - dsp_spl_jiffies = jiffies + 1;
> - else
> - dsp_spl_jiffies += dsp_tics;
> -
> - dsp_spl_tl.expires = dsp_spl_jiffies;
> - add_timer(&dsp_spl_tl);
> -
> - /* unlock */
> - spin_unlock_irqrestore(&dsp_lock, flags);
> -}
> -
> -/*
> - * audio data is transmitted from upper layer to the dsp
> - */
> -void
> -dsp_cmx_transmit(struct dsp *dsp, struct sk_buff *skb)
> -{
> - u_int w, ww;
> - u8 *d, *p;
> - int space; /* todo: , l = skb->len; */
> -#ifdef CMX_TX_DEBUG
> - char debugbuf[256] = "";
> -#endif
> -
> - /* check if there is enough space, and then copy */
> - w = dsp->tx_W;
> - ww = dsp->tx_R;
> - p = dsp->tx_buff;
> - d = skb->data;
> - space = (ww - w - 1) & CMX_BUFF_MASK;
> - /* write-pointer should not overrun nor reach read pointer */
> - if (space < skb->len) {
> - /* write to the space we have left */
> - ww = (ww - 1) & CMX_BUFF_MASK; /* end one byte prior tx_R */
> - if (dsp_debug & DEBUG_DSP_CLOCK)
> - printk(KERN_DEBUG "%s: TX overflow space=%d skb->len="
> - "%d, w=0x%04x, ww=0x%04x\n", __func__, space,
> - skb->len, w, ww);
> - } else
> - /* write until all byte are copied */
> - ww = (w + skb->len) & CMX_BUFF_MASK;
> - dsp->tx_W = ww;
> - /* show current buffer */
> -#ifdef CMX_DEBUG
> - printk(KERN_DEBUG
> - "cmx_transmit(dsp=%lx) %d bytes to 0x%x-0x%x. %s\n",
> - (u_long)dsp, (ww - w) & CMX_BUFF_MASK, w, ww, dsp->name);
> -#endif
> -
> - /* copy transmit data to tx-buffer */
> -#ifdef CMX_TX_DEBUG
> - sprintf(debugbuf, "TX getting (%04x-%04x)%p: ", w, ww, p);
> -#endif
> - while (w != ww) {
> -#ifdef CMX_TX_DEBUG
> - if (strlen(debugbuf) < 48)
> - sprintf(debugbuf + strlen(debugbuf), " %02x", *d);
> -#endif
> - p[w] = *d++;
> - w = (w + 1) & CMX_BUFF_MASK;
> - }
> -#ifdef CMX_TX_DEBUG
> - printk(KERN_DEBUG "%s\n", debugbuf);
> -#endif
> -
> -}
> -
> -/*
> - * hdlc data is received from card and sent to all members.
> - */
> -void
> -dsp_cmx_hdlc(struct dsp *dsp, struct sk_buff *skb)
> -{
> - struct sk_buff *nskb = NULL;
> - struct dsp_conf_member *member;
> - struct mISDNhead *hh;
> -
> - /* not if not active */
> - if (!dsp->b_active)
> - return;
> -
> - /* check if we have sompen */
> - if (skb->len < 1)
> - return;
> -
> - /* no conf */
> - if (!dsp->conf) {
> - /* in case of software echo */
> - if (dsp->echo.software) {
> - nskb = skb_clone(skb, GFP_ATOMIC);
> - if (nskb) {
> - hh = mISDN_HEAD_P(nskb);
> - hh->prim = PH_DATA_REQ;
> - hh->id = 0;
> - skb_queue_tail(&dsp->sendq, nskb);
> - schedule_work(&dsp->workq);
> - }
> - }
> - return;
> - }
> - /* in case of hardware conference */
> - if (dsp->conf->hardware)
> - return;
> - list_for_each_entry(member, &dsp->conf->mlist, list) {
> - if (dsp->echo.software || member->dsp != dsp) {
> - nskb = skb_clone(skb, GFP_ATOMIC);
> - if (nskb) {
> - hh = mISDN_HEAD_P(nskb);
> - hh->prim = PH_DATA_REQ;
> - hh->id = 0;
> - skb_queue_tail(&member->dsp->sendq, nskb);
> - schedule_work(&member->dsp->workq);
> - }
> - }
> - }
> -}
> diff --git a/drivers/isdn/mISDN/dsp_core.c b/drivers/isdn/mISDN/dsp_core.c
> deleted file mode 100644
> index d0aa415a6b09..000000000000
> --- a/drivers/isdn/mISDN/dsp_core.c
> +++ /dev/null
> @@ -1,1227 +0,0 @@
> -/*
> - * Author Andreas Eversberg (jolly@eversberg.eu)
> - * Based on source code structure by
> - * Karsten Keil (keil@isdn4linux.de)
> - *
> - * This file is (c) under GNU PUBLIC LICENSE
> - *
> - * Thanks to Karsten Keil (great drivers)
> - * Cologne Chip (great chips)
> - *
> - * This module does:
> - * Real-time tone generation
> - * DTMF detection
> - * Real-time cross-connection and conferrence
> - * Compensate jitter due to system load and hardware fault.
> - * All features are done in kernel space and will be realized
> - * using hardware, if available and supported by chip set.
> - * Blowfish encryption/decryption
> - */
> -
> -/* STRUCTURE:
> - *
> - * The dsp module provides layer 2 for b-channels (64kbit). It provides
> - * transparent audio forwarding with special digital signal processing:
> - *
> - * - (1) generation of tones
> - * - (2) detection of dtmf tones
> - * - (3) crossconnecting and conferences (clocking)
> - * - (4) echo generation for delay test
> - * - (5) volume control
> - * - (6) disable receive data
> - * - (7) pipeline
> - * - (8) encryption/decryption
> - *
> - * Look:
> - * TX RX
> - * ------upper layer------
> - * | ^
> - * | |(6)
> - * v |
> - * +-----+-------------+-----+
> - * |(3)(4) |
> - * | CMX |
> - * | |
> - * | +-------------+
> - * | | ^
> - * | | |
> - * |+---------+| +----+----+
> - * ||(1) || |(2) |
> - * || || | |
> - * || Tones || | DTMF |
> - * || || | |
> - * || || | |
> - * |+----+----+| +----+----+
> - * +-----+-----+ ^
> - * | |
> - * v |
> - * +----+----+ +----+----+
> - * |(5) | |(5) |
> - * | | | |
> - * |TX Volume| |RX Volume|
> - * | | | |
> - * | | | |
> - * +----+----+ +----+----+
> - * | ^
> - * | |
> - * v |
> - * +----+-------------+----+
> - * |(7) |
> - * | |
> - * | Pipeline Processing |
> - * | |
> - * | |
> - * +----+-------------+----+
> - * | ^
> - * | |
> - * v |
> - * +----+----+ +----+----+
> - * |(8) | |(8) |
> - * | | | |
> - * | Encrypt | | Decrypt |
> - * | | | |
> - * | | | |
> - * +----+----+ +----+----+
> - * | ^
> - * | |
> - * v |
> - * ------card layer------
> - * TX RX
> - *
> - * Above you can see the logical data flow. If software is used to do the
> - * process, it is actually the real data flow. If hardware is used, data
> - * may not flow, but hardware commands to the card, to provide the data flow
> - * as shown.
> - *
> - * NOTE: The channel must be activated in order to make dsp work, even if
> - * no data flow to the upper layer is intended. Activation can be done
> - * after and before controlling the setting using PH_CONTROL requests.
> - *
> - * DTMF: Will be detected by hardware if possible. It is done before CMX
> - * processing.
> - *
> - * Tones: Will be generated via software if endless looped audio fifos are
> - * not supported by hardware. Tones will override all data from CMX.
> - * It is not required to join a conference to use tones at any time.
> - *
> - * CMX: Is transparent when not used. When it is used, it will do
> - * crossconnections and conferences via software if not possible through
> - * hardware. If hardware capability is available, hardware is used.
> - *
> - * Echo: Is generated by CMX and is used to check performance of hard and
> - * software CMX.
> - *
> - * The CMX has special functions for conferences with one, two and more
> - * members. It will allow different types of data flow. Receive and transmit
> - * data to/form upper layer may be switched on/off individually without losing
> - * features of CMX, Tones and DTMF.
> - *
> - * Echo Cancellation: Sometimes we like to cancel echo from the interface.
> - * Note that a VoIP call may not have echo caused by the IP phone. The echo
> - * is generated by the telephone line connected to it. Because the delay
> - * is high, it becomes an echo. RESULT: Echo Cachelation is required if
> - * both echo AND delay is applied to an interface.
> - * Remember that software CMX always generates a more or less delay.
> - *
> - * If all used features can be realized in hardware, and if transmit and/or
> - * receive data ist disabled, the card may not send/receive any data at all.
> - * Not receiving is useful if only announcements are played. Not sending is
> - * useful if an answering machine records audio. Not sending and receiving is
> - * useful during most states of the call. If supported by hardware, tones
> - * will be played without cpu load. Small PBXs and NT-Mode applications will
> - * not need expensive hardware when processing calls.
> - *
> - *
> - * LOCKING:
> - *
> - * When data is received from upper or lower layer (card), the complete dsp
> - * module is locked by a global lock. This lock MUST lock irq, because it
> - * must lock timer events by DSP poll timer.
> - * When data is ready to be transmitted down, the data is queued and sent
> - * outside lock and timer event.
> - * PH_CONTROL must not change any settings, join or split conference members
> - * during process of data.
> - *
> - * HDLC:
> - *
> - * It works quite the same as transparent, except that HDLC data is forwarded
> - * to all other conference members if no hardware bridging is possible.
> - * Send data will be writte to sendq. Sendq will be sent if confirm is received.
> - * Conference cannot join, if one member is not hdlc.
> - *
> - */
> -
> -#include <linux/delay.h>
> -#include <linux/gfp.h>
> -#include <linux/mISDNif.h>
> -#include <linux/mISDNdsp.h>
> -#include <linux/module.h>
> -#include <linux/vmalloc.h>
> -#include "core.h"
> -#include "dsp.h"
> -
> -static const char *mISDN_dsp_revision = "2.0";
> -
> -static int debug;
> -static int options;
> -static int poll;
> -static int dtmfthreshold = 100;
> -
> -MODULE_AUTHOR("Andreas Eversberg");
> -module_param(debug, uint, S_IRUGO | S_IWUSR);
> -module_param(options, uint, S_IRUGO | S_IWUSR);
> -module_param(poll, uint, S_IRUGO | S_IWUSR);
> -module_param(dtmfthreshold, uint, S_IRUGO | S_IWUSR);
> -MODULE_DESCRIPTION("mISDN driver for Digital Audio Processing of transparent data");
> -MODULE_LICENSE("GPL");
> -
> -/*int spinnest = 0;*/
> -
> -DEFINE_SPINLOCK(dsp_lock); /* global dsp lock */
> -LIST_HEAD(dsp_ilist);
> -LIST_HEAD(conf_ilist);
> -int dsp_debug;
> -int dsp_options;
> -int dsp_poll, dsp_tics;
> -
> -/* check if rx may be turned off or must be turned on */
> -static void
> -dsp_rx_off_member(struct dsp *dsp)
> -{
> - struct mISDN_ctrl_req cq;
> - int rx_off = 1;
> -
> - memset(&cq, 0, sizeof(cq));
> -
> - if (!dsp->features_rx_off)
> - return;
> -
> - /* not disabled */
> - if (!dsp->rx_disabled)
> - rx_off = 0;
> - /* software dtmf */
> - else if (dsp->dtmf.software)
> - rx_off = 0;
> - /* echo in software */
> - else if (dsp->echo.software)
> - rx_off = 0;
> - /* bridge in software */
> - else if (dsp->conf && dsp->conf->software)
> - rx_off = 0;
> - /* data is not required by user space and not required
> - * for echo dtmf detection, soft-echo, soft-bridging */
> -
> - if (rx_off == dsp->rx_is_off)
> - return;
> -
> - if (!dsp->ch.peer) {
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: no peer, no rx_off\n",
> - __func__);
> - return;
> - }
> - cq.op = MISDN_CTRL_RX_OFF;
> - cq.p1 = rx_off;
> - if (dsp->ch.peer->ctrl(dsp->ch.peer, CONTROL_CHANNEL, &cq)) {
> - printk(KERN_DEBUG "%s: 2nd CONTROL_CHANNEL failed\n",
> - __func__);
> - return;
> - }
> - dsp->rx_is_off = rx_off;
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: %s set rx_off = %d\n",
> - __func__, dsp->name, rx_off);
> -}
> -static void
> -dsp_rx_off(struct dsp *dsp)
> -{
> - struct dsp_conf_member *member;
> -
> - if (dsp_options & DSP_OPT_NOHARDWARE)
> - return;
> -
> - /* no conf */
> - if (!dsp->conf) {
> - dsp_rx_off_member(dsp);
> - return;
> - }
> - /* check all members in conf */
> - list_for_each_entry(member, &dsp->conf->mlist, list) {
> - dsp_rx_off_member(member->dsp);
> - }
> -}
> -
> -/* enable "fill empty" feature */
> -static void
> -dsp_fill_empty(struct dsp *dsp)
> -{
> - struct mISDN_ctrl_req cq;
> -
> - memset(&cq, 0, sizeof(cq));
> -
> - if (!dsp->ch.peer) {
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: no peer, no fill_empty\n",
> - __func__);
> - return;
> - }
> - cq.op = MISDN_CTRL_FILL_EMPTY;
> - cq.p1 = 1;
> - cq.p2 = dsp_silence;
> - if (dsp->ch.peer->ctrl(dsp->ch.peer, CONTROL_CHANNEL, &cq)) {
> - printk(KERN_DEBUG "%s: CONTROL_CHANNEL failed\n",
> - __func__);
> - return;
> - }
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: %s set fill_empty = 1\n",
> - __func__, dsp->name);
> -}
> -
> -static int
> -dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb)
> -{
> - struct sk_buff *nskb;
> - int ret = 0;
> - int cont;
> - u8 *data;
> - int len;
> -
> - if (skb->len < sizeof(int)) {
> - printk(KERN_ERR "%s: PH_CONTROL message too short\n", __func__);
> - return -EINVAL;
> - }
> - cont = *((int *)skb->data);
> - len = skb->len - sizeof(int);
> - data = skb->data + sizeof(int);
> -
> - switch (cont) {
> - case DTMF_TONE_START: /* turn on DTMF */
> - if (dsp->hdlc) {
> - ret = -EINVAL;
> - break;
> - }
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: start dtmf\n", __func__);
> - if (len == sizeof(int)) {
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_NOTICE "changing DTMF Threshold "
> - "to %d\n", *((int *)data));
> - dsp->dtmf.treshold = (*(int *)data) * 10000;
> - }
> - dsp->dtmf.enable = 1;
> - /* init goertzel */
> - dsp_dtmf_goertzel_init(dsp);
> -
> - /* check dtmf hardware */
> - dsp_dtmf_hardware(dsp);
> - dsp_rx_off(dsp);
> - break;
> - case DTMF_TONE_STOP: /* turn off DTMF */
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: stop dtmf\n", __func__);
> - dsp->dtmf.enable = 0;
> - dsp->dtmf.hardware = 0;
> - dsp->dtmf.software = 0;
> - break;
> - case DSP_CONF_JOIN: /* join / update conference */
> - if (len < sizeof(int)) {
> - ret = -EINVAL;
> - break;
> - }
> - if (*((u32 *)data) == 0)
> - goto conf_split;
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: join conference %d\n",
> - __func__, *((u32 *)data));
> - ret = dsp_cmx_conf(dsp, *((u32 *)data));
> - /* dsp_cmx_hardware will also be called here */
> - dsp_rx_off(dsp);
> - if (dsp_debug & DEBUG_DSP_CMX)
> - dsp_cmx_debug(dsp);
> - break;
> - case DSP_CONF_SPLIT: /* remove from conference */
> - conf_split:
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: release conference\n", __func__);
> - ret = dsp_cmx_conf(dsp, 0);
> - /* dsp_cmx_hardware will also be called here */
> - if (dsp_debug & DEBUG_DSP_CMX)
> - dsp_cmx_debug(dsp);
> - dsp_rx_off(dsp);
> - break;
> - case DSP_TONE_PATT_ON: /* play tone */
> - if (dsp->hdlc) {
> - ret = -EINVAL;
> - break;
> - }
> - if (len < sizeof(int)) {
> - ret = -EINVAL;
> - break;
> - }
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: turn tone 0x%x on\n",
> - __func__, *((int *)skb->data));
> - ret = dsp_tone(dsp, *((int *)data));
> - if (!ret) {
> - dsp_cmx_hardware(dsp->conf, dsp);
> - dsp_rx_off(dsp);
> - }
> - if (!dsp->tone.tone)
> - goto tone_off;
> - break;
> - case DSP_TONE_PATT_OFF: /* stop tone */
> - if (dsp->hdlc) {
> - ret = -EINVAL;
> - break;
> - }
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: turn tone off\n", __func__);
> - dsp_tone(dsp, 0);
> - dsp_cmx_hardware(dsp->conf, dsp);
> - dsp_rx_off(dsp);
> - /* reset tx buffers (user space data) */
> - tone_off:
> - dsp->rx_W = 0;
> - dsp->rx_R = 0;
> - break;
> - case DSP_VOL_CHANGE_TX: /* change volume */
> - if (dsp->hdlc) {
> - ret = -EINVAL;
> - break;
> - }
> - if (len < sizeof(int)) {
> - ret = -EINVAL;
> - break;
> - }
> - dsp->tx_volume = *((int *)data);
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: change tx vol to %d\n",
> - __func__, dsp->tx_volume);
> - dsp_cmx_hardware(dsp->conf, dsp);
> - dsp_dtmf_hardware(dsp);
> - dsp_rx_off(dsp);
> - break;
> - case DSP_VOL_CHANGE_RX: /* change volume */
> - if (dsp->hdlc) {
> - ret = -EINVAL;
> - break;
> - }
> - if (len < sizeof(int)) {
> - ret = -EINVAL;
> - break;
> - }
> - dsp->rx_volume = *((int *)data);
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: change rx vol to %d\n",
> - __func__, dsp->tx_volume);
> - dsp_cmx_hardware(dsp->conf, dsp);
> - dsp_dtmf_hardware(dsp);
> - dsp_rx_off(dsp);
> - break;
> - case DSP_ECHO_ON: /* enable echo */
> - dsp->echo.software = 1; /* soft echo */
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: enable cmx-echo\n", __func__);
> - dsp_cmx_hardware(dsp->conf, dsp);
> - dsp_rx_off(dsp);
> - if (dsp_debug & DEBUG_DSP_CMX)
> - dsp_cmx_debug(dsp);
> - break;
> - case DSP_ECHO_OFF: /* disable echo */
> - dsp->echo.software = 0;
> - dsp->echo.hardware = 0;
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: disable cmx-echo\n", __func__);
> - dsp_cmx_hardware(dsp->conf, dsp);
> - dsp_rx_off(dsp);
> - if (dsp_debug & DEBUG_DSP_CMX)
> - dsp_cmx_debug(dsp);
> - break;
> - case DSP_RECEIVE_ON: /* enable receive to user space */
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: enable receive to user "
> - "space\n", __func__);
> - dsp->rx_disabled = 0;
> - dsp_rx_off(dsp);
> - break;
> - case DSP_RECEIVE_OFF: /* disable receive to user space */
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: disable receive to "
> - "user space\n", __func__);
> - dsp->rx_disabled = 1;
> - dsp_rx_off(dsp);
> - break;
> - case DSP_MIX_ON: /* enable mixing of tx data */
> - if (dsp->hdlc) {
> - ret = -EINVAL;
> - break;
> - }
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: enable mixing of "
> - "tx-data with conf members\n", __func__);
> - dsp->tx_mix = 1;
> - dsp_cmx_hardware(dsp->conf, dsp);
> - dsp_rx_off(dsp);
> - if (dsp_debug & DEBUG_DSP_CMX)
> - dsp_cmx_debug(dsp);
> - break;
> - case DSP_MIX_OFF: /* disable mixing of tx data */
> - if (dsp->hdlc) {
> - ret = -EINVAL;
> - break;
> - }
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: disable mixing of "
> - "tx-data with conf members\n", __func__);
> - dsp->tx_mix = 0;
> - dsp_cmx_hardware(dsp->conf, dsp);
> - dsp_rx_off(dsp);
> - if (dsp_debug & DEBUG_DSP_CMX)
> - dsp_cmx_debug(dsp);
> - break;
> - case DSP_TXDATA_ON: /* enable txdata */
> - dsp->tx_data = 1;
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: enable tx-data\n", __func__);
> - dsp_cmx_hardware(dsp->conf, dsp);
> - dsp_rx_off(dsp);
> - if (dsp_debug & DEBUG_DSP_CMX)
> - dsp_cmx_debug(dsp);
> - break;
> - case DSP_TXDATA_OFF: /* disable txdata */
> - dsp->tx_data = 0;
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: disable tx-data\n", __func__);
> - dsp_cmx_hardware(dsp->conf, dsp);
> - dsp_rx_off(dsp);
> - if (dsp_debug & DEBUG_DSP_CMX)
> - dsp_cmx_debug(dsp);
> - break;
> - case DSP_DELAY: /* use delay algorithm instead of dynamic
> - jitter algorithm */
> - if (dsp->hdlc) {
> - ret = -EINVAL;
> - break;
> - }
> - if (len < sizeof(int)) {
> - ret = -EINVAL;
> - break;
> - }
> - dsp->cmx_delay = (*((int *)data)) << 3;
> - /* milliseconds to samples */
> - if (dsp->cmx_delay >= (CMX_BUFF_HALF >> 1))
> - /* clip to half of maximum usable buffer
> - (half of half buffer) */
> - dsp->cmx_delay = (CMX_BUFF_HALF >> 1) - 1;
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: use delay algorithm to "
> - "compensate jitter (%d samples)\n",
> - __func__, dsp->cmx_delay);
> - break;
> - case DSP_JITTER: /* use dynamic jitter algorithm instead of
> - delay algorithm */
> - if (dsp->hdlc) {
> - ret = -EINVAL;
> - break;
> - }
> - dsp->cmx_delay = 0;
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: use jitter algorithm to "
> - "compensate jitter\n", __func__);
> - break;
> - case DSP_TX_DEJITTER: /* use dynamic jitter algorithm for tx-buffer */
> - if (dsp->hdlc) {
> - ret = -EINVAL;
> - break;
> - }
> - dsp->tx_dejitter = 1;
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: use dejitter on TX "
> - "buffer\n", __func__);
> - break;
> - case DSP_TX_DEJ_OFF: /* use tx-buffer without dejittering*/
> - if (dsp->hdlc) {
> - ret = -EINVAL;
> - break;
> - }
> - dsp->tx_dejitter = 0;
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: use TX buffer without "
> - "dejittering\n", __func__);
> - break;
> - case DSP_PIPELINE_CFG:
> - if (dsp->hdlc) {
> - ret = -EINVAL;
> - break;
> - }
> - if (len > 0 && ((char *)data)[len - 1]) {
> - printk(KERN_DEBUG "%s: pipeline config string "
> - "is not NULL terminated!\n", __func__);
> - ret = -EINVAL;
> - } else {
> - dsp->pipeline.inuse = 1;
> - dsp_cmx_hardware(dsp->conf, dsp);
> - ret = dsp_pipeline_build(&dsp->pipeline,
> - len > 0 ? data : NULL);
> - dsp_cmx_hardware(dsp->conf, dsp);
> - dsp_rx_off(dsp);
> - }
> - break;
> - case DSP_BF_ENABLE_KEY: /* turn blowfish on */
> - if (dsp->hdlc) {
> - ret = -EINVAL;
> - break;
> - }
> - if (len < 4 || len > 56) {
> - ret = -EINVAL;
> - break;
> - }
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: turn blowfish on (key "
> - "not shown)\n", __func__);
> - ret = dsp_bf_init(dsp, (u8 *)data, len);
> - /* set new cont */
> - if (!ret)
> - cont = DSP_BF_ACCEPT;
> - else
> - cont = DSP_BF_REJECT;
> - /* send indication if it worked to set it */
> - nskb = _alloc_mISDN_skb(PH_CONTROL_IND, MISDN_ID_ANY,
> - sizeof(int), &cont, GFP_ATOMIC);
> - if (nskb) {
> - if (dsp->up) {
> - if (dsp->up->send(dsp->up, nskb))
> - dev_kfree_skb(nskb);
> - } else
> - dev_kfree_skb(nskb);
> - }
> - if (!ret) {
> - dsp_cmx_hardware(dsp->conf, dsp);
> - dsp_dtmf_hardware(dsp);
> - dsp_rx_off(dsp);
> - }
> - break;
> - case DSP_BF_DISABLE: /* turn blowfish off */
> - if (dsp->hdlc) {
> - ret = -EINVAL;
> - break;
> - }
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: turn blowfish off\n", __func__);
> - dsp_bf_cleanup(dsp);
> - dsp_cmx_hardware(dsp->conf, dsp);
> - dsp_dtmf_hardware(dsp);
> - dsp_rx_off(dsp);
> - break;
> - default:
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: ctrl req %x unhandled\n",
> - __func__, cont);
> - ret = -EINVAL;
> - }
> - return ret;
> -}
> -
> -static void
> -get_features(struct mISDNchannel *ch)
> -{
> - struct dsp *dsp = container_of(ch, struct dsp, ch);
> - struct mISDN_ctrl_req cq;
> -
> - if (!ch->peer) {
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: no peer, no features\n",
> - __func__);
> - return;
> - }
> - memset(&cq, 0, sizeof(cq));
> - cq.op = MISDN_CTRL_GETOP;
> - if (ch->peer->ctrl(ch->peer, CONTROL_CHANNEL, &cq) < 0) {
> - printk(KERN_DEBUG "%s: CONTROL_CHANNEL failed\n",
> - __func__);
> - return;
> - }
> - if (cq.op & MISDN_CTRL_RX_OFF)
> - dsp->features_rx_off = 1;
> - if (cq.op & MISDN_CTRL_FILL_EMPTY)
> - dsp->features_fill_empty = 1;
> - if (dsp_options & DSP_OPT_NOHARDWARE)
> - return;
> - if ((cq.op & MISDN_CTRL_HW_FEATURES_OP)) {
> - cq.op = MISDN_CTRL_HW_FEATURES;
> - *((u_long *)&cq.p1) = (u_long)&dsp->features;
> - if (ch->peer->ctrl(ch->peer, CONTROL_CHANNEL, &cq)) {
> - printk(KERN_DEBUG "%s: 2nd CONTROL_CHANNEL failed\n",
> - __func__);
> - }
> - } else
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: features not supported for %s\n",
> - __func__, dsp->name);
> -}
> -
> -static int
> -dsp_function(struct mISDNchannel *ch, struct sk_buff *skb)
> -{
> - struct dsp *dsp = container_of(ch, struct dsp, ch);
> - struct mISDNhead *hh;
> - int ret = 0;
> - u8 *digits = NULL;
> - u_long flags;
> -
> - hh = mISDN_HEAD_P(skb);
> - switch (hh->prim) {
> - /* FROM DOWN */
> - case (PH_DATA_CNF):
> - dsp->data_pending = 0;
> - /* trigger next hdlc frame, if any */
> - if (dsp->hdlc) {
> - spin_lock_irqsave(&dsp_lock, flags);
> - if (dsp->b_active)
> - schedule_work(&dsp->workq);
> - spin_unlock_irqrestore(&dsp_lock, flags);
> - }
> - break;
> - case (PH_DATA_IND):
> - case (DL_DATA_IND):
> - if (skb->len < 1) {
> - ret = -EINVAL;
> - break;
> - }
> - if (dsp->rx_is_off) {
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: rx-data during rx_off"
> - " for %s\n",
> - __func__, dsp->name);
> - }
> - if (dsp->hdlc) {
> - /* hdlc */
> - spin_lock_irqsave(&dsp_lock, flags);
> - dsp_cmx_hdlc(dsp, skb);
> - spin_unlock_irqrestore(&dsp_lock, flags);
> - if (dsp->rx_disabled) {
> - /* if receive is not allowed */
> - break;
> - }
> - hh->prim = DL_DATA_IND;
> - if (dsp->up)
> - return dsp->up->send(dsp->up, skb);
> - break;
> - }
> -
> - spin_lock_irqsave(&dsp_lock, flags);
> -
> - /* decrypt if enabled */
> - if (dsp->bf_enable)
> - dsp_bf_decrypt(dsp, skb->data, skb->len);
> - /* pipeline */
> - if (dsp->pipeline.inuse)
> - dsp_pipeline_process_rx(&dsp->pipeline, skb->data,
> - skb->len, hh->id);
> - /* change volume if requested */
> - if (dsp->rx_volume)
> - dsp_change_volume(skb, dsp->rx_volume);
> - /* check if dtmf soft decoding is turned on */
> - if (dsp->dtmf.software) {
> - digits = dsp_dtmf_goertzel_decode(dsp, skb->data,
> - skb->len, (dsp_options & DSP_OPT_ULAW) ? 1 : 0);
> - }
> - /* we need to process receive data if software */
> - if (dsp->conf && dsp->conf->software) {
> - /* process data from card at cmx */
> - dsp_cmx_receive(dsp, skb);
> - }
> -
> - spin_unlock_irqrestore(&dsp_lock, flags);
> -
> - /* send dtmf result, if any */
> - if (digits) {
> - while (*digits) {
> - int k;
> - struct sk_buff *nskb;
> - if (dsp_debug & DEBUG_DSP_DTMF)
> - printk(KERN_DEBUG "%s: digit"
> - "(%c) to layer %s\n",
> - __func__, *digits, dsp->name);
> - k = *digits | DTMF_TONE_VAL;
> - nskb = _alloc_mISDN_skb(PH_CONTROL_IND,
> - MISDN_ID_ANY, sizeof(int), &k,
> - GFP_ATOMIC);
> - if (nskb) {
> - if (dsp->up) {
> - if (dsp->up->send(
> - dsp->up, nskb))
> - dev_kfree_skb(nskb);
> - } else
> - dev_kfree_skb(nskb);
> - }
> - digits++;
> - }
> - }
> - if (dsp->rx_disabled) {
> - /* if receive is not allowed */
> - break;
> - }
> - hh->prim = DL_DATA_IND;
> - if (dsp->up)
> - return dsp->up->send(dsp->up, skb);
> - break;
> - case (PH_CONTROL_IND):
> - if (dsp_debug & DEBUG_DSP_DTMFCOEFF)
> - printk(KERN_DEBUG "%s: PH_CONTROL INDICATION "
> - "received: %x (len %d) %s\n", __func__,
> - hh->id, skb->len, dsp->name);
> - switch (hh->id) {
> - case (DTMF_HFC_COEF): /* getting coefficients */
> - if (!dsp->dtmf.hardware) {
> - if (dsp_debug & DEBUG_DSP_DTMFCOEFF)
> - printk(KERN_DEBUG "%s: ignoring DTMF "
> - "coefficients from HFC\n",
> - __func__);
> - break;
> - }
> - digits = dsp_dtmf_goertzel_decode(dsp, skb->data,
> - skb->len, 2);
> - while (*digits) {
> - int k;
> - struct sk_buff *nskb;
> - if (dsp_debug & DEBUG_DSP_DTMF)
> - printk(KERN_DEBUG "%s: digit"
> - "(%c) to layer %s\n",
> - __func__, *digits, dsp->name);
> - k = *digits | DTMF_TONE_VAL;
> - nskb = _alloc_mISDN_skb(PH_CONTROL_IND,
> - MISDN_ID_ANY, sizeof(int), &k,
> - GFP_ATOMIC);
> - if (nskb) {
> - if (dsp->up) {
> - if (dsp->up->send(
> - dsp->up, nskb))
> - dev_kfree_skb(nskb);
> - } else
> - dev_kfree_skb(nskb);
> - }
> - digits++;
> - }
> - break;
> - case (HFC_VOL_CHANGE_TX): /* change volume */
> - if (skb->len != sizeof(int)) {
> - ret = -EINVAL;
> - break;
> - }
> - spin_lock_irqsave(&dsp_lock, flags);
> - dsp->tx_volume = *((int *)skb->data);
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: change tx volume to "
> - "%d\n", __func__, dsp->tx_volume);
> - dsp_cmx_hardware(dsp->conf, dsp);
> - dsp_dtmf_hardware(dsp);
> - dsp_rx_off(dsp);
> - spin_unlock_irqrestore(&dsp_lock, flags);
> - break;
> - default:
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: ctrl ind %x unhandled "
> - "%s\n", __func__, hh->id, dsp->name);
> - ret = -EINVAL;
> - }
> - break;
> - case (PH_ACTIVATE_IND):
> - case (PH_ACTIVATE_CNF):
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: b_channel is now active %s\n",
> - __func__, dsp->name);
> - /* bchannel now active */
> - spin_lock_irqsave(&dsp_lock, flags);
> - dsp->b_active = 1;
> - dsp->data_pending = 0;
> - dsp->rx_init = 1;
> - /* rx_W and rx_R will be adjusted on first frame */
> - dsp->rx_W = 0;
> - dsp->rx_R = 0;
> - memset(dsp->rx_buff, 0, sizeof(dsp->rx_buff));
> - dsp_cmx_hardware(dsp->conf, dsp);
> - dsp_dtmf_hardware(dsp);
> - dsp_rx_off(dsp);
> - spin_unlock_irqrestore(&dsp_lock, flags);
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: done with activation, sending "
> - "confirm to user space. %s\n", __func__,
> - dsp->name);
> - /* send activation to upper layer */
> - hh->prim = DL_ESTABLISH_CNF;
> - if (dsp->up)
> - return dsp->up->send(dsp->up, skb);
> - break;
> - case (PH_DEACTIVATE_IND):
> - case (PH_DEACTIVATE_CNF):
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: b_channel is now inactive %s\n",
> - __func__, dsp->name);
> - /* bchannel now inactive */
> - spin_lock_irqsave(&dsp_lock, flags);
> - dsp->b_active = 0;
> - dsp->data_pending = 0;
> - dsp_cmx_hardware(dsp->conf, dsp);
> - dsp_rx_off(dsp);
> - spin_unlock_irqrestore(&dsp_lock, flags);
> - hh->prim = DL_RELEASE_CNF;
> - if (dsp->up)
> - return dsp->up->send(dsp->up, skb);
> - break;
> - /* FROM UP */
> - case (DL_DATA_REQ):
> - case (PH_DATA_REQ):
> - if (skb->len < 1) {
> - ret = -EINVAL;
> - break;
> - }
> - if (dsp->hdlc) {
> - /* hdlc */
> - if (!dsp->b_active) {
> - ret = -EIO;
> - break;
> - }
> - hh->prim = PH_DATA_REQ;
> - spin_lock_irqsave(&dsp_lock, flags);
> - skb_queue_tail(&dsp->sendq, skb);
> - schedule_work(&dsp->workq);
> - spin_unlock_irqrestore(&dsp_lock, flags);
> - return 0;
> - }
> - /* send data to tx-buffer (if no tone is played) */
> - if (!dsp->tone.tone) {
> - spin_lock_irqsave(&dsp_lock, flags);
> - dsp_cmx_transmit(dsp, skb);
> - spin_unlock_irqrestore(&dsp_lock, flags);
> - }
> - break;
> - case (PH_CONTROL_REQ):
> - spin_lock_irqsave(&dsp_lock, flags);
> - ret = dsp_control_req(dsp, hh, skb);
> - spin_unlock_irqrestore(&dsp_lock, flags);
> - break;
> - case (DL_ESTABLISH_REQ):
> - case (PH_ACTIVATE_REQ):
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: activating b_channel %s\n",
> - __func__, dsp->name);
> - if (dsp->dtmf.hardware || dsp->dtmf.software)
> - dsp_dtmf_goertzel_init(dsp);
> - get_features(ch);
> - /* enable fill_empty feature */
> - if (dsp->features_fill_empty)
> - dsp_fill_empty(dsp);
> - /* send ph_activate */
> - hh->prim = PH_ACTIVATE_REQ;
> - if (ch->peer)
> - return ch->recv(ch->peer, skb);
> - break;
> - case (DL_RELEASE_REQ):
> - case (PH_DEACTIVATE_REQ):
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: releasing b_channel %s\n",
> - __func__, dsp->name);
> - spin_lock_irqsave(&dsp_lock, flags);
> - dsp->tone.tone = 0;
> - dsp->tone.hardware = 0;
> - dsp->tone.software = 0;
> - if (timer_pending(&dsp->tone.tl))
> - timer_delete(&dsp->tone.tl);
> - if (dsp->conf)
> - dsp_cmx_conf(dsp, 0); /* dsp_cmx_hardware will also be
> - called here */
> - skb_queue_purge(&dsp->sendq);
> - spin_unlock_irqrestore(&dsp_lock, flags);
> - hh->prim = PH_DEACTIVATE_REQ;
> - if (ch->peer)
> - return ch->recv(ch->peer, skb);
> - break;
> - default:
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: msg %x unhandled %s\n",
> - __func__, hh->prim, dsp->name);
> - ret = -EINVAL;
> - }
> - if (!ret)
> - dev_kfree_skb(skb);
> - return ret;
> -}
> -
> -static int
> -dsp_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
> -{
> - struct dsp *dsp = container_of(ch, struct dsp, ch);
> - u_long flags;
> -
> - if (debug & DEBUG_DSP_CTRL)
> - printk(KERN_DEBUG "%s:(%x)\n", __func__, cmd);
> -
> - switch (cmd) {
> - case OPEN_CHANNEL:
> - break;
> - case CLOSE_CHANNEL:
> - if (dsp->ch.peer)
> - dsp->ch.peer->ctrl(dsp->ch.peer, CLOSE_CHANNEL, NULL);
> -
> - /* wait until workqueue has finished,
> - * must lock here, or we may hit send-process currently
> - * queueing. */
> - spin_lock_irqsave(&dsp_lock, flags);
> - dsp->b_active = 0;
> - spin_unlock_irqrestore(&dsp_lock, flags);
> - /* MUST not be locked, because it waits until queue is done. */
> - cancel_work_sync(&dsp->workq);
> - spin_lock_irqsave(&dsp_lock, flags);
> - if (timer_pending(&dsp->tone.tl))
> - timer_delete(&dsp->tone.tl);
> - skb_queue_purge(&dsp->sendq);
> - if (dsp_debug & DEBUG_DSP_CTRL)
> - printk(KERN_DEBUG "%s: releasing member %s\n",
> - __func__, dsp->name);
> - dsp->b_active = 0;
> - dsp_cmx_conf(dsp, 0); /* dsp_cmx_hardware will also be called
> - here */
> - dsp_pipeline_destroy(&dsp->pipeline);
> -
> - if (dsp_debug & DEBUG_DSP_CTRL)
> - printk(KERN_DEBUG "%s: remove & destroy object %s\n",
> - __func__, dsp->name);
> - list_del(&dsp->list);
> - spin_unlock_irqrestore(&dsp_lock, flags);
> -
> - if (dsp_debug & DEBUG_DSP_CTRL)
> - printk(KERN_DEBUG "%s: dsp instance released\n",
> - __func__);
> - vfree(dsp);
> - module_put(THIS_MODULE);
> - break;
> - }
> - return 0;
> -}
> -
> -static void
> -dsp_send_bh(struct work_struct *work)
> -{
> - struct dsp *dsp = container_of(work, struct dsp, workq);
> - struct sk_buff *skb;
> - struct mISDNhead *hh;
> -
> - if (dsp->hdlc && dsp->data_pending)
> - return; /* wait until data has been acknowledged */
> -
> - /* send queued data */
> - while ((skb = skb_dequeue(&dsp->sendq))) {
> - /* in locked date, we must have still data in queue */
> - if (dsp->data_pending) {
> - if (dsp_debug & DEBUG_DSP_CORE)
> - printk(KERN_DEBUG "%s: fifo full %s, this is "
> - "no bug!\n", __func__, dsp->name);
> - /* flush transparent data, if not acked */
> - dev_kfree_skb(skb);
> - continue;
> - }
> - hh = mISDN_HEAD_P(skb);
> - if (hh->prim == DL_DATA_REQ) {
> - /* send packet up */
> - if (dsp->up) {
> - if (dsp->up->send(dsp->up, skb))
> - dev_kfree_skb(skb);
> - } else
> - dev_kfree_skb(skb);
> - } else {
> - /* send packet down */
> - if (dsp->ch.peer) {
> - dsp->data_pending = 1;
> - if (dsp->ch.recv(dsp->ch.peer, skb)) {
> - dev_kfree_skb(skb);
> - dsp->data_pending = 0;
> - }
> - } else
> - dev_kfree_skb(skb);
> - }
> - }
> -}
> -
> -static int
> -dspcreate(struct channel_req *crq)
> -{
> - struct dsp *ndsp;
> - u_long flags;
> -
> - if (crq->protocol != ISDN_P_B_L2DSP
> - && crq->protocol != ISDN_P_B_L2DSPHDLC)
> - return -EPROTONOSUPPORT;
> - ndsp = vzalloc(sizeof(struct dsp));
> - if (!ndsp) {
> - printk(KERN_ERR "%s: vmalloc struct dsp failed\n", __func__);
> - return -ENOMEM;
> - }
> - if (dsp_debug & DEBUG_DSP_CTRL)
> - printk(KERN_DEBUG "%s: creating new dsp instance\n", __func__);
> -
> - /* default enabled */
> - INIT_WORK(&ndsp->workq, (void *)dsp_send_bh);
> - skb_queue_head_init(&ndsp->sendq);
> - ndsp->ch.send = dsp_function;
> - ndsp->ch.ctrl = dsp_ctrl;
> - ndsp->up = crq->ch;
> - crq->ch = &ndsp->ch;
> - if (crq->protocol == ISDN_P_B_L2DSP) {
> - crq->protocol = ISDN_P_B_RAW;
> - ndsp->hdlc = 0;
> - } else {
> - crq->protocol = ISDN_P_B_HDLC;
> - ndsp->hdlc = 1;
> - }
> - if (!try_module_get(THIS_MODULE))
> - printk(KERN_WARNING "%s:cannot get module\n",
> - __func__);
> -
> - sprintf(ndsp->name, "DSP_C%x(0x%p)",
> - ndsp->up->st->dev->id + 1, ndsp);
> - /* set frame size to start */
> - ndsp->features.hfc_id = -1; /* current PCM id */
> - ndsp->features.pcm_id = -1; /* current PCM id */
> - ndsp->pcm_slot_rx = -1; /* current CPM slot */
> - ndsp->pcm_slot_tx = -1;
> - ndsp->pcm_bank_rx = -1;
> - ndsp->pcm_bank_tx = -1;
> - ndsp->hfc_conf = -1; /* current conference number */
> - /* set tone timer */
> - timer_setup(&ndsp->tone.tl, dsp_tone_timeout, 0);
> -
> - if (dtmfthreshold < 20 || dtmfthreshold > 500)
> - dtmfthreshold = 200;
> - ndsp->dtmf.treshold = dtmfthreshold * 10000;
> -
> - /* init pipeline append to list */
> - spin_lock_irqsave(&dsp_lock, flags);
> - dsp_pipeline_init(&ndsp->pipeline);
> - list_add_tail(&ndsp->list, &dsp_ilist);
> - spin_unlock_irqrestore(&dsp_lock, flags);
> -
> - return 0;
> -}
> -
> -
> -static struct Bprotocol DSP = {
> - .Bprotocols = (1 << (ISDN_P_B_L2DSP & ISDN_P_B_MASK))
> - | (1 << (ISDN_P_B_L2DSPHDLC & ISDN_P_B_MASK)),
> - .name = "dsp",
> - .create = dspcreate
> -};
> -
> -static int __init dsp_init(void)
> -{
> - int err;
> - int tics;
> -
> - printk(KERN_INFO "DSP module %s\n", mISDN_dsp_revision);
> -
> - dsp_options = options;
> - dsp_debug = debug;
> -
> - /* set packet size */
> - dsp_poll = poll;
> - if (dsp_poll) {
> - if (dsp_poll > MAX_POLL) {
> - printk(KERN_ERR "%s: Wrong poll value (%d), use %d "
> - "maximum.\n", __func__, poll, MAX_POLL);
> - err = -EINVAL;
> - return err;
> - }
> - if (dsp_poll < 8) {
> - printk(KERN_ERR "%s: Wrong poll value (%d), use 8 "
> - "minimum.\n", __func__, dsp_poll);
> - err = -EINVAL;
> - return err;
> - }
> - dsp_tics = poll * HZ / 8000;
> - if (dsp_tics * 8000 != poll * HZ) {
> - printk(KERN_INFO "mISDN_dsp: Cannot clock every %d "
> - "samples (0,125 ms). It is not a multiple of "
> - "%d HZ.\n", poll, HZ);
> - err = -EINVAL;
> - return err;
> - }
> - } else {
> - poll = 8;
> - while (poll <= MAX_POLL) {
> - tics = (poll * HZ) / 8000;
> - if (tics * 8000 == poll * HZ) {
> - dsp_tics = tics;
> - dsp_poll = poll;
> - if (poll >= 64)
> - break;
> - }
> - poll++;
> - }
> - }
> - if (dsp_poll == 0) {
> - printk(KERN_INFO "mISDN_dsp: There is no multiple of kernel "
> - "clock that equals exactly the duration of 8-256 "
> - "samples. (Choose kernel clock speed like 100, 250, "
> - "300, 1000)\n");
> - err = -EINVAL;
> - return err;
> - }
> - printk(KERN_INFO "mISDN_dsp: DSP clocks every %d samples. This equals "
> - "%d jiffies.\n", dsp_poll, dsp_tics);
> -
> - /* init conversion tables */
> - dsp_audio_generate_law_tables();
> - dsp_silence = (dsp_options & DSP_OPT_ULAW) ? 0xff : 0x2a;
> - dsp_audio_law_to_s32 = (dsp_options & DSP_OPT_ULAW) ?
> - dsp_audio_ulaw_to_s32 : dsp_audio_alaw_to_s32;
> - dsp_audio_generate_s2law_table();
> - dsp_audio_generate_seven();
> - dsp_audio_generate_mix_table();
> - if (dsp_options & DSP_OPT_ULAW)
> - dsp_audio_generate_ulaw_samples();
> - dsp_audio_generate_volume_changes();
> -
> - err = dsp_pipeline_module_init();
> - if (err) {
> - printk(KERN_ERR "mISDN_dsp: Can't initialize pipeline, "
> - "error(%d)\n", err);
> - return err;
> - }
> -
> - err = mISDN_register_Bprotocol(&DSP);
> - if (err) {
> - printk(KERN_ERR "Can't register %s error(%d)\n", DSP.name, err);
> - return err;
> - }
> -
> - /* set sample timer */
> - timer_setup(&dsp_spl_tl, dsp_cmx_send, 0);
> - dsp_spl_tl.expires = jiffies + dsp_tics;
> - dsp_spl_jiffies = dsp_spl_tl.expires;
> - add_timer(&dsp_spl_tl);
> -
> - return 0;
> -}
> -
> -
> -static void __exit dsp_cleanup(void)
> -{
> - mISDN_unregister_Bprotocol(&DSP);
> -
> - timer_delete_sync(&dsp_spl_tl);
> -
> - if (!list_empty(&dsp_ilist)) {
> - printk(KERN_ERR "mISDN_dsp: Audio DSP object inst list not "
> - "empty.\n");
> - }
> - if (!list_empty(&conf_ilist)) {
> - printk(KERN_ERR "mISDN_dsp: Conference list not empty. Not "
> - "all memory freed.\n");
> - }
> -
> - dsp_pipeline_module_exit();
> -}
> -
> -module_init(dsp_init);
> -module_exit(dsp_cleanup);
> diff --git a/drivers/isdn/mISDN/dsp_dtmf.c b/drivers/isdn/mISDN/dsp_dtmf.c
> deleted file mode 100644
> index 642f30be5ce2..000000000000
> --- a/drivers/isdn/mISDN/dsp_dtmf.c
> +++ /dev/null
> @@ -1,313 +0,0 @@
> -/*
> - * DTMF decoder.
> - *
> - * Copyright by Andreas Eversberg (jolly@eversberg.eu)
> - * based on different decoders such as ISDN4Linux
> - *
> - * This software may be used and distributed according to the terms
> - * of the GNU General Public License, incorporated herein by reference.
> - *
> - */
> -
> -#include <linux/mISDNif.h>
> -#include <linux/mISDNdsp.h>
> -#include "core.h"
> -#include "dsp.h"
> -
> -#define NCOEFF 8 /* number of frequencies to be analyzed */
> -
> -/* For DTMF recognition:
> - * 2 * cos(2 * PI * k / N) precalculated for all k
> - */
> -static u64 cos2pik[NCOEFF] =
> -{
> - /* k << 15 (source: hfc-4s/8s documentation (www.colognechip.de)) */
> - 55960, 53912, 51402, 48438, 38146, 32650, 26170, 18630
> -};
> -
> -/* digit matrix */
> -static char dtmf_matrix[4][4] =
> -{
> - {'1', '2', '3', 'A'},
> - {'4', '5', '6', 'B'},
> - {'7', '8', '9', 'C'},
> - {'*', '0', '#', 'D'}
> -};
> -
> -/* dtmf detection using goertzel algorithm
> - * init function
> - */
> -void dsp_dtmf_goertzel_init(struct dsp *dsp)
> -{
> - dsp->dtmf.size = 0;
> - dsp->dtmf.lastwhat = '\0';
> - dsp->dtmf.lastdigit = '\0';
> - dsp->dtmf.count = 0;
> -}
> -
> -/* check for hardware or software features
> - */
> -void dsp_dtmf_hardware(struct dsp *dsp)
> -{
> - int hardware = 1;
> -
> - if (!dsp->dtmf.enable)
> - return;
> -
> - if (!dsp->features.hfc_dtmf)
> - hardware = 0;
> -
> - /* check for volume change */
> - if (dsp->tx_volume) {
> - if (dsp_debug & DEBUG_DSP_DTMF)
> - printk(KERN_DEBUG "%s dsp %s cannot do hardware DTMF, "
> - "because tx_volume is changed\n",
> - __func__, dsp->name);
> - hardware = 0;
> - }
> - if (dsp->rx_volume) {
> - if (dsp_debug & DEBUG_DSP_DTMF)
> - printk(KERN_DEBUG "%s dsp %s cannot do hardware DTMF, "
> - "because rx_volume is changed\n",
> - __func__, dsp->name);
> - hardware = 0;
> - }
> - /* check if encryption is enabled */
> - if (dsp->bf_enable) {
> - if (dsp_debug & DEBUG_DSP_DTMF)
> - printk(KERN_DEBUG "%s dsp %s cannot do hardware DTMF, "
> - "because encryption is enabled\n",
> - __func__, dsp->name);
> - hardware = 0;
> - }
> - /* check if pipeline exists */
> - if (dsp->pipeline.inuse) {
> - if (dsp_debug & DEBUG_DSP_DTMF)
> - printk(KERN_DEBUG "%s dsp %s cannot do hardware DTMF, "
> - "because pipeline exists.\n",
> - __func__, dsp->name);
> - hardware = 0;
> - }
> -
> - dsp->dtmf.hardware = hardware;
> - dsp->dtmf.software = !hardware;
> -}
> -
> -
> -/*************************************************************
> - * calculate the coefficients of the given sample and decode *
> - *************************************************************/
> -
> -/* the given sample is decoded. if the sample is not long enough for a
> - * complete frame, the decoding is finished and continued with the next
> - * call of this function.
> - *
> - * the algorithm is very good for detection with a minimum of errors. i
> - * tested it allot. it even works with very short tones (40ms). the only
> - * disadvantage is, that it doesn't work good with different volumes of both
> - * tones. this will happen, if accoustically coupled dialers are used.
> - * it sometimes detects tones during speech, which is normal for decoders.
> - * use sequences to given commands during calls.
> - *
> - * dtmf - points to a structure of the current dtmf state
> - * spl and len - the sample
> - * fmt - 0 = alaw, 1 = ulaw, 2 = coefficients from HFC DTMF hw-decoder
> - */
> -
> -u8
> -*dsp_dtmf_goertzel_decode(struct dsp *dsp, u8 *data, int len, int fmt)
> -{
> - u8 what;
> - int size;
> - signed short *buf;
> - s32 sk, sk1, sk2;
> - int k, n, i;
> - s32 *hfccoeff;
> - s32 result[NCOEFF], tresh, treshl;
> - int lowgroup, highgroup;
> - s64 cos2pik_;
> -
> - dsp->dtmf.digits[0] = '\0';
> -
> - /* Note: The function will loop until the buffer has not enough samples
> - * left to decode a full frame.
> - */
> -again:
> - /* convert samples */
> - size = dsp->dtmf.size;
> - buf = dsp->dtmf.buffer;
> - switch (fmt) {
> - case 0: /* alaw */
> - case 1: /* ulaw */
> - while (size < DSP_DTMF_NPOINTS && len) {
> - buf[size++] = dsp_audio_law_to_s32[*data++];
> - len--;
> - }
> - break;
> -
> - case 2: /* HFC coefficients */
> - default:
> - if (len < 64) {
> - if (len > 0)
> - printk(KERN_ERR "%s: coefficients have invalid "
> - "size. (is=%d < must=%d)\n",
> - __func__, len, 64);
> - return dsp->dtmf.digits;
> - }
> - hfccoeff = (s32 *)data;
> - for (k = 0; k < NCOEFF; k++) {
> - sk2 = (*hfccoeff++) >> 4;
> - sk = (*hfccoeff++) >> 4;
> - if (sk > 32767 || sk < -32767 || sk2 > 32767
> - || sk2 < -32767)
> - printk(KERN_WARNING
> - "DTMF-Detection overflow\n");
> - /* compute |X(k)|**2 */
> - result[k] =
> - (sk * sk) -
> - (((cos2pik[k] * sk) >> 15) * sk2) +
> - (sk2 * sk2);
> - }
> - data += 64;
> - len -= 64;
> - goto coefficients;
> - break;
> - }
> - dsp->dtmf.size = size;
> -
> - if (size < DSP_DTMF_NPOINTS)
> - return dsp->dtmf.digits;
> -
> - dsp->dtmf.size = 0;
> -
> - /* now we have a full buffer of signed long samples - we do goertzel */
> - for (k = 0; k < NCOEFF; k++) {
> - sk = 0;
> - sk1 = 0;
> - sk2 = 0;
> - buf = dsp->dtmf.buffer;
> - cos2pik_ = cos2pik[k];
> - for (n = 0; n < DSP_DTMF_NPOINTS; n++) {
> - sk = ((cos2pik_ * sk1) >> 15) - sk2 + (*buf++);
> - sk2 = sk1;
> - sk1 = sk;
> - }
> - sk >>= 8;
> - sk2 >>= 8;
> - if (sk > 32767 || sk < -32767 || sk2 > 32767 || sk2 < -32767)
> - printk(KERN_WARNING "DTMF-Detection overflow\n");
> - /* compute |X(k)|**2 */
> - result[k] =
> - (sk * sk) -
> - (((cos2pik[k] * sk) >> 15) * sk2) +
> - (sk2 * sk2);
> - }
> -
> - /* our (squared) coefficients have been calculated, we need to process
> - * them.
> - */
> -coefficients:
> - tresh = 0;
> - for (i = 0; i < NCOEFF; i++) {
> - if (result[i] < 0)
> - result[i] = 0;
> - if (result[i] > dsp->dtmf.treshold) {
> - if (result[i] > tresh)
> - tresh = result[i];
> - }
> - }
> -
> - if (tresh == 0) {
> - what = 0;
> - goto storedigit;
> - }
> -
> - if (dsp_debug & DEBUG_DSP_DTMFCOEFF) {
> - s32 tresh_100 = tresh/100;
> -
> - if (tresh_100 == 0) {
> - tresh_100 = 1;
> - printk(KERN_DEBUG
> - "tresh(%d) too small set tresh/100 to 1\n",
> - tresh);
> - }
> - printk(KERN_DEBUG "a %3d %3d %3d %3d %3d %3d %3d %3d"
> - " tr:%3d r %3d %3d %3d %3d %3d %3d %3d %3d\n",
> - result[0] / 10000, result[1] / 10000, result[2] / 10000,
> - result[3] / 10000, result[4] / 10000, result[5] / 10000,
> - result[6] / 10000, result[7] / 10000, tresh / 10000,
> - result[0] / (tresh_100), result[1] / (tresh_100),
> - result[2] / (tresh_100), result[3] / (tresh_100),
> - result[4] / (tresh_100), result[5] / (tresh_100),
> - result[6] / (tresh_100), result[7] / (tresh_100));
> - }
> -
> - /* calc digit (lowgroup/highgroup) */
> - lowgroup = -1;
> - highgroup = -1;
> - treshl = tresh >> 3; /* tones which are not on, must be below 9 dB */
> - tresh = tresh >> 2; /* touchtones must match within 6 dB */
> - for (i = 0; i < NCOEFF; i++) {
> - if (result[i] < treshl)
> - continue; /* ignore */
> - if (result[i] < tresh) {
> - lowgroup = -1;
> - highgroup = -1;
> - break; /* noise in between */
> - }
> - /* good level found. This is allowed only one time per group */
> - if (i < NCOEFF / 2) {
> - /* lowgroup */
> - if (lowgroup >= 0) {
> - /* Bad. Another tone found. */
> - lowgroup = -1;
> - break;
> - } else
> - lowgroup = i;
> - } else {
> - /* higroup */
> - if (highgroup >= 0) {
> - /* Bad. Another tone found. */
> - highgroup = -1;
> - break;
> - } else
> - highgroup = i - (NCOEFF / 2);
> - }
> - }
> -
> - /* get digit or null */
> - what = 0;
> - if (lowgroup >= 0 && highgroup >= 0)
> - what = dtmf_matrix[lowgroup][highgroup];
> -
> -storedigit:
> - if (what && (dsp_debug & DEBUG_DSP_DTMF))
> - printk(KERN_DEBUG "DTMF what: %c\n", what);
> -
> - if (dsp->dtmf.lastwhat != what)
> - dsp->dtmf.count = 0;
> -
> - /* the tone (or no tone) must remain 3 times without change */
> - if (dsp->dtmf.count == 2) {
> - if (dsp->dtmf.lastdigit != what) {
> - dsp->dtmf.lastdigit = what;
> - if (what) {
> - if (dsp_debug & DEBUG_DSP_DTMF)
> - printk(KERN_DEBUG "DTMF digit: %c\n",
> - what);
> - if ((strlen(dsp->dtmf.digits) + 1)
> - < sizeof(dsp->dtmf.digits)) {
> - dsp->dtmf.digits[strlen(
> - dsp->dtmf.digits) + 1] = '\0';
> - dsp->dtmf.digits[strlen(
> - dsp->dtmf.digits)] = what;
> - }
> - }
> - }
> - } else
> - dsp->dtmf.count++;
> -
> - dsp->dtmf.lastwhat = what;
> -
> - goto again;
> -}
> diff --git a/drivers/isdn/mISDN/dsp_hwec.c b/drivers/isdn/mISDN/dsp_hwec.c
> deleted file mode 100644
> index 0cd216e28f00..000000000000
> --- a/drivers/isdn/mISDN/dsp_hwec.c
> +++ /dev/null
> @@ -1,122 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-or-later
> -/*
> - * dsp_hwec.c:
> - * builtin mISDN dsp pipeline element for enabling the hw echocanceller
> - *
> - * Copyright (C) 2007, Nadi Sarrar
> - *
> - * Nadi Sarrar <nadi@beronet.com>
> - */
> -
> -#include <linux/kernel.h>
> -#include <linux/string.h>
> -#include <linux/mISDNdsp.h>
> -#include <linux/mISDNif.h>
> -#include "core.h"
> -#include "dsp.h"
> -#include "dsp_hwec.h"
> -
> -static struct mISDN_dsp_element_arg args[] = {
> - { "deftaps", "128", "Set the number of taps of cancellation." },
> -};
> -
> -static struct mISDN_dsp_element dsp_hwec_p = {
> - .name = "hwec",
> - .new = NULL,
> - .free = NULL,
> - .process_tx = NULL,
> - .process_rx = NULL,
> - .num_args = ARRAY_SIZE(args),
> - .args = args,
> -};
> -struct mISDN_dsp_element *dsp_hwec = &dsp_hwec_p;
> -
> -void dsp_hwec_enable(struct dsp *dsp, const char *arg)
> -{
> - int deftaps = 128,
> - len;
> - struct mISDN_ctrl_req cq;
> -
> - if (!dsp) {
> - printk(KERN_ERR "%s: failed to enable hwec: dsp is NULL\n",
> - __func__);
> - return;
> - }
> -
> - if (!arg)
> - goto _do;
> -
> - len = strlen(arg);
> - if (!len)
> - goto _do;
> -
> - {
> - char *dup, *next, *tok, *name, *val;
> - int tmp;
> -
> - dup = next = kstrdup(arg, GFP_ATOMIC);
> - if (!dup)
> - return;
> -
> - while ((tok = strsep(&next, ","))) {
> - if (!strlen(tok))
> - continue;
> - name = strsep(&tok, "=");
> - val = tok;
> -
> - if (!val)
> - continue;
> -
> - if (!strcmp(name, "deftaps")) {
> - if (sscanf(val, "%d", &tmp) == 1)
> - deftaps = tmp;
> - }
> - }
> -
> - kfree(dup);
> - }
> -
> -_do:
> - printk(KERN_DEBUG "%s: enabling hwec with deftaps=%d\n",
> - __func__, deftaps);
> - memset(&cq, 0, sizeof(cq));
> - cq.op = MISDN_CTRL_HFC_ECHOCAN_ON;
> - cq.p1 = deftaps;
> - if (!dsp->ch.peer->ctrl(&dsp->ch, CONTROL_CHANNEL, &cq)) {
> - printk(KERN_DEBUG "%s: CONTROL_CHANNEL failed\n",
> - __func__);
> - return;
> - }
> -}
> -
> -void dsp_hwec_disable(struct dsp *dsp)
> -{
> - struct mISDN_ctrl_req cq;
> -
> - if (!dsp) {
> - printk(KERN_ERR "%s: failed to disable hwec: dsp is NULL\n",
> - __func__);
> - return;
> - }
> -
> - printk(KERN_DEBUG "%s: disabling hwec\n", __func__);
> - memset(&cq, 0, sizeof(cq));
> - cq.op = MISDN_CTRL_HFC_ECHOCAN_OFF;
> - if (!dsp->ch.peer->ctrl(&dsp->ch, CONTROL_CHANNEL, &cq)) {
> - printk(KERN_DEBUG "%s: CONTROL_CHANNEL failed\n",
> - __func__);
> - return;
> - }
> -}
> -
> -int dsp_hwec_init(void)
> -{
> - mISDN_dsp_element_register(dsp_hwec);
> -
> - return 0;
> -}
> -
> -void dsp_hwec_exit(void)
> -{
> - mISDN_dsp_element_unregister(dsp_hwec);
> -}
> diff --git a/drivers/isdn/mISDN/dsp_pipeline.c b/drivers/isdn/mISDN/dsp_pipeline.c
> deleted file mode 100644
> index 55693dc7206b..000000000000
> --- a/drivers/isdn/mISDN/dsp_pipeline.c
> +++ /dev/null
> @@ -1,300 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-or-later
> -/*
> - * dsp_pipeline.c: pipelined audio processing
> - *
> - * Copyright (C) 2007, Nadi Sarrar
> - *
> - * Nadi Sarrar <nadi@beronet.com>
> - */
> -
> -#include <linux/kernel.h>
> -#include <linux/slab.h>
> -#include <linux/list.h>
> -#include <linux/string.h>
> -#include <linux/mISDNif.h>
> -#include <linux/mISDNdsp.h>
> -#include <linux/export.h>
> -#include "dsp.h"
> -#include "dsp_hwec.h"
> -
> -struct dsp_pipeline_entry {
> - struct mISDN_dsp_element *elem;
> - void *p;
> - struct list_head list;
> -};
> -struct dsp_element_entry {
> - struct mISDN_dsp_element *elem;
> - struct device dev;
> - struct list_head list;
> -};
> -
> -static LIST_HEAD(dsp_elements);
> -
> -/* sysfs */
> -static const struct class elements_class = {
> - .name = "dsp_pipeline",
> -};
> -
> -static ssize_t
> -attr_show_args(struct device *dev, struct device_attribute *attr, char *buf)
> -{
> - struct mISDN_dsp_element *elem = dev_get_drvdata(dev);
> - int i;
> - char *p = buf;
> -
> - *buf = 0;
> - for (i = 0; i < elem->num_args; i++)
> - p += sprintf(p, "Name: %s\n%s%s%sDescription: %s\n\n",
> - elem->args[i].name,
> - elem->args[i].def ? "Default: " : "",
> - elem->args[i].def ? elem->args[i].def : "",
> - elem->args[i].def ? "\n" : "",
> - elem->args[i].desc);
> -
> - return p - buf;
> -}
> -
> -static struct device_attribute element_attributes[] = {
> - __ATTR(args, 0444, attr_show_args, NULL),
> -};
> -
> -static void
> -mISDN_dsp_dev_release(struct device *dev)
> -{
> - struct dsp_element_entry *entry =
> - container_of(dev, struct dsp_element_entry, dev);
> - list_del(&entry->list);
> - kfree(entry);
> -}
> -
> -int mISDN_dsp_element_register(struct mISDN_dsp_element *elem)
> -{
> - struct dsp_element_entry *entry;
> - int ret, i;
> -
> - if (!elem)
> - return -EINVAL;
> -
> - entry = kzalloc_obj(struct dsp_element_entry, GFP_ATOMIC);
> - if (!entry)
> - return -ENOMEM;
> -
> - INIT_LIST_HEAD(&entry->list);
> - entry->elem = elem;
> -
> - entry->dev.class = &elements_class;
> - entry->dev.release = mISDN_dsp_dev_release;
> - dev_set_drvdata(&entry->dev, elem);
> - dev_set_name(&entry->dev, "%s", elem->name);
> - ret = device_register(&entry->dev);
> - if (ret) {
> - printk(KERN_ERR "%s: failed to register %s\n",
> - __func__, elem->name);
> - goto err1;
> - }
> - list_add_tail(&entry->list, &dsp_elements);
> -
> - for (i = 0; i < ARRAY_SIZE(element_attributes); ++i) {
> - ret = device_create_file(&entry->dev,
> - &element_attributes[i]);
> - if (ret) {
> - printk(KERN_ERR "%s: failed to create device file\n",
> - __func__);
> - goto err2;
> - }
> - }
> -
> - return 0;
> -
> -err2:
> - device_unregister(&entry->dev);
> - return ret;
> -err1:
> - put_device(&entry->dev);
> - return ret;
> -}
> -EXPORT_SYMBOL(mISDN_dsp_element_register);
> -
> -void mISDN_dsp_element_unregister(struct mISDN_dsp_element *elem)
> -{
> - struct dsp_element_entry *entry, *n;
> -
> - if (!elem)
> - return;
> -
> - list_for_each_entry_safe(entry, n, &dsp_elements, list)
> - if (entry->elem == elem) {
> - device_unregister(&entry->dev);
> - return;
> - }
> - printk(KERN_ERR "%s: element %s not in list.\n", __func__, elem->name);
> -}
> -EXPORT_SYMBOL(mISDN_dsp_element_unregister);
> -
> -int dsp_pipeline_module_init(void)
> -{
> - int err;
> -
> - err = class_register(&elements_class);
> - if (err)
> - return err;
> -
> - dsp_hwec_init();
> -
> - return 0;
> -}
> -
> -void dsp_pipeline_module_exit(void)
> -{
> - struct dsp_element_entry *entry, *n;
> -
> - dsp_hwec_exit();
> -
> - class_unregister(&elements_class);
> -
> - list_for_each_entry_safe(entry, n, &dsp_elements, list) {
> - list_del(&entry->list);
> - printk(KERN_WARNING "%s: element was still registered: %s\n",
> - __func__, entry->elem->name);
> - kfree(entry);
> - }
> -}
> -
> -int dsp_pipeline_init(struct dsp_pipeline *pipeline)
> -{
> - if (!pipeline)
> - return -EINVAL;
> -
> - INIT_LIST_HEAD(&pipeline->list);
> -
> - return 0;
> -}
> -
> -static inline void _dsp_pipeline_destroy(struct dsp_pipeline *pipeline)
> -{
> - struct dsp_pipeline_entry *entry, *n;
> -
> - list_for_each_entry_safe(entry, n, &pipeline->list, list) {
> - list_del(&entry->list);
> - if (entry->elem == dsp_hwec)
> - dsp_hwec_disable(container_of(pipeline, struct dsp,
> - pipeline));
> - else
> - entry->elem->free(entry->p);
> - kfree(entry);
> - }
> -}
> -
> -void dsp_pipeline_destroy(struct dsp_pipeline *pipeline)
> -{
> -
> - if (!pipeline)
> - return;
> -
> - _dsp_pipeline_destroy(pipeline);
> -}
> -
> -int dsp_pipeline_build(struct dsp_pipeline *pipeline, const char *cfg)
> -{
> - int found = 0;
> - char *dup, *next, *tok, *name, *args;
> - struct dsp_element_entry *entry, *n;
> - struct dsp_pipeline_entry *pipeline_entry;
> - struct mISDN_dsp_element *elem;
> -
> - if (!pipeline)
> - return -EINVAL;
> -
> - if (!list_empty(&pipeline->list))
> - _dsp_pipeline_destroy(pipeline);
> -
> - dup = next = kstrdup(cfg, GFP_ATOMIC);
> - if (!dup)
> - return 0;
> - while ((tok = strsep(&next, "|"))) {
> - if (!strlen(tok))
> - continue;
> - name = strsep(&tok, "(");
> - args = strsep(&tok, ")");
> - if (args && !*args)
> - args = NULL;
> -
> - list_for_each_entry_safe(entry, n, &dsp_elements, list)
> - if (!strcmp(entry->elem->name, name)) {
> - elem = entry->elem;
> -
> - pipeline_entry = kmalloc_obj(struct dsp_pipeline_entry,
> - GFP_ATOMIC);
> - if (!pipeline_entry) {
> - printk(KERN_ERR "%s: failed to add "
> - "entry to pipeline: %s (out of "
> - "memory)\n", __func__, elem->name);
> - goto _out;
> - }
> - pipeline_entry->elem = elem;
> -
> - if (elem == dsp_hwec) {
> - /* This is a hack to make the hwec
> - available as a pipeline module */
> - dsp_hwec_enable(container_of(pipeline,
> - struct dsp, pipeline), args);
> - list_add_tail(&pipeline_entry->list,
> - &pipeline->list);
> - } else {
> - pipeline_entry->p = elem->new(args);
> - if (pipeline_entry->p) {
> - list_add_tail(&pipeline_entry->
> - list, &pipeline->list);
> - } else {
> - printk(KERN_ERR "%s: failed "
> - "to add entry to pipeline: "
> - "%s (new() returned NULL)\n",
> - __func__, elem->name);
> - kfree(pipeline_entry);
> - }
> - }
> - found = 1;
> - break;
> - }
> -
> - if (found)
> - found = 0;
> - else
> - printk(KERN_ERR "%s: element not found, skipping: "
> - "%s\n", __func__, name);
> - }
> -
> -_out:
> - if (!list_empty(&pipeline->list))
> - pipeline->inuse = 1;
> - else
> - pipeline->inuse = 0;
> -
> - kfree(dup);
> - return 0;
> -}
> -
> -void dsp_pipeline_process_tx(struct dsp_pipeline *pipeline, u8 *data, int len)
> -{
> - struct dsp_pipeline_entry *entry;
> -
> - if (!pipeline)
> - return;
> -
> - list_for_each_entry(entry, &pipeline->list, list)
> - if (entry->elem->process_tx)
> - entry->elem->process_tx(entry->p, data, len);
> -}
> -
> -void dsp_pipeline_process_rx(struct dsp_pipeline *pipeline, u8 *data, int len,
> - unsigned int txlen)
> -{
> - struct dsp_pipeline_entry *entry;
> -
> - if (!pipeline)
> - return;
> -
> - list_for_each_entry_reverse(entry, &pipeline->list, list)
> - if (entry->elem->process_rx)
> - entry->elem->process_rx(entry->p, data, len, txlen);
> -}
> diff --git a/drivers/isdn/mISDN/dsp_tones.c b/drivers/isdn/mISDN/dsp_tones.c
> deleted file mode 100644
> index fa7813ae8d97..000000000000
> --- a/drivers/isdn/mISDN/dsp_tones.c
> +++ /dev/null
> @@ -1,550 +0,0 @@
> -/*
> - * Audio support data for ISDN4Linux.
> - *
> - * Copyright Andreas Eversberg (jolly@eversberg.eu)
> - *
> - * This software may be used and distributed according to the terms
> - * of the GNU General Public License, incorporated herein by reference.
> - *
> - */
> -
> -#include <linux/gfp.h>
> -#include <linux/mISDNif.h>
> -#include <linux/mISDNdsp.h>
> -#include "core.h"
> -#include "dsp.h"
> -
> -
> -#define DATA_S sample_silence
> -#define SIZE_S (&sizeof_silence)
> -#define DATA_GA sample_german_all
> -#define SIZE_GA (&sizeof_german_all)
> -#define DATA_GO sample_german_old
> -#define SIZE_GO (&sizeof_german_old)
> -#define DATA_DT sample_american_dialtone
> -#define SIZE_DT (&sizeof_american_dialtone)
> -#define DATA_RI sample_american_ringing
> -#define SIZE_RI (&sizeof_american_ringing)
> -#define DATA_BU sample_american_busy
> -#define SIZE_BU (&sizeof_american_busy)
> -#define DATA_S1 sample_special1
> -#define SIZE_S1 (&sizeof_special1)
> -#define DATA_S2 sample_special2
> -#define SIZE_S2 (&sizeof_special2)
> -#define DATA_S3 sample_special3
> -#define SIZE_S3 (&sizeof_special3)
> -
> -/***************/
> -/* tones loops */
> -/***************/
> -
> -/* all tones are alaw encoded */
> -/* the last sample+1 is in phase with the first sample. the error is low */
> -
> -static u8 sample_german_all[] = {
> - 0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
> - 0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
> - 0xdc, 0xfc, 0x6c,
> - 0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
> - 0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
> - 0xdc, 0xfc, 0x6c,
> - 0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
> - 0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
> - 0xdc, 0xfc, 0x6c,
> - 0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
> - 0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
> - 0xdc, 0xfc, 0x6c,
> -};
> -static u32 sizeof_german_all = sizeof(sample_german_all);
> -
> -static u8 sample_german_old[] = {
> - 0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
> - 0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
> - 0x8c,
> - 0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
> - 0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
> - 0x8c,
> - 0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
> - 0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
> - 0x8c,
> - 0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
> - 0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
> - 0x8c,
> -};
> -static u32 sizeof_german_old = sizeof(sample_german_old);
> -
> -static u8 sample_american_dialtone[] = {
> - 0x2a, 0x18, 0x90, 0x6c, 0x4c, 0xbc, 0x4c, 0x6c,
> - 0x10, 0x58, 0x32, 0xb9, 0x31, 0x2d, 0x8d, 0x0d,
> - 0x8d, 0x2d, 0x31, 0x99, 0x0f, 0x28, 0x60, 0xf0,
> - 0xd0, 0x50, 0xd0, 0x30, 0x60, 0x08, 0x8e, 0x67,
> - 0x09, 0x19, 0x21, 0xe1, 0xd9, 0xb9, 0x29, 0x67,
> - 0x83, 0x02, 0xce, 0xbe, 0xee, 0x1a, 0x1b, 0xef,
> - 0xbf, 0xcf, 0x03, 0x82, 0x66, 0x28, 0xb8, 0xd8,
> - 0xe0, 0x20, 0x18, 0x08, 0x66, 0x8f, 0x09, 0x61,
> - 0x31, 0xd1, 0x51, 0xd1, 0xf1, 0x61, 0x29, 0x0e,
> - 0x98, 0x30, 0x2c, 0x8c, 0x0c, 0x8c, 0x2c, 0x30,
> - 0xb8, 0x33, 0x59, 0x11, 0x6d, 0x4d, 0xbd, 0x4d,
> - 0x6d, 0x91, 0x19,
> -};
> -static u32 sizeof_american_dialtone = sizeof(sample_american_dialtone);
> -
> -static u8 sample_american_ringing[] = {
> - 0x2a, 0xe0, 0xac, 0x0c, 0xbc, 0x4c, 0x8c, 0x90,
> - 0x48, 0xc7, 0xc1, 0xed, 0xcd, 0x4d, 0xcd, 0xed,
> - 0xc1, 0xb7, 0x08, 0x30, 0xec, 0xcc, 0xcc, 0x8c,
> - 0x10, 0x58, 0x1a, 0x99, 0x71, 0xed, 0x8d, 0x8d,
> - 0x2d, 0x41, 0x89, 0x9e, 0x20, 0x70, 0x2c, 0xec,
> - 0x2c, 0x70, 0x20, 0x86, 0x77, 0xe1, 0x31, 0x11,
> - 0xd1, 0xf1, 0x81, 0x09, 0xa3, 0x56, 0x58, 0x00,
> - 0x40, 0xc0, 0x60, 0x38, 0x46, 0x43, 0x57, 0x39,
> - 0xd9, 0x59, 0x99, 0xc9, 0x77, 0x2f, 0x2e, 0xc6,
> - 0xd6, 0x28, 0xd6, 0x36, 0x26, 0x2e, 0x8a, 0xa3,
> - 0x43, 0x63, 0x4b, 0x4a, 0x62, 0x42, 0xa2, 0x8b,
> - 0x2f, 0x27, 0x37, 0xd7, 0x29, 0xd7, 0xc7, 0x2f,
> - 0x2e, 0x76, 0xc8, 0x98, 0x58, 0xd8, 0x38, 0x56,
> - 0x42, 0x47, 0x39, 0x61, 0xc1, 0x41, 0x01, 0x59,
> - 0x57, 0xa2, 0x08, 0x80, 0xf0, 0xd0, 0x10, 0x30,
> - 0xe0, 0x76, 0x87, 0x21, 0x71, 0x2d, 0xed, 0x2d,
> - 0x71, 0x21, 0x9f, 0x88, 0x40, 0x2c, 0x8c, 0x8c,
> - 0xec, 0x70, 0x98, 0x1b, 0x59, 0x11, 0x8d, 0xcd,
> - 0xcd, 0xed, 0x31, 0x09, 0xb6, 0xc0, 0xec, 0xcc,
> - 0x4c, 0xcc, 0xec, 0xc0, 0xc6, 0x49, 0x91, 0x8d,
> - 0x4d, 0xbd, 0x0d, 0xad, 0xe1,
> -};
> -static u32 sizeof_american_ringing = sizeof(sample_american_ringing);
> -
> -static u8 sample_american_busy[] = {
> - 0x2a, 0x00, 0x6c, 0x4c, 0x4c, 0x6c, 0xb0, 0x66,
> - 0x99, 0x11, 0x6d, 0x8d, 0x2d, 0x41, 0xd7, 0x96,
> - 0x60, 0xf0, 0x70, 0x40, 0x58, 0xf6, 0x53, 0x57,
> - 0x09, 0x89, 0xd7, 0x5f, 0xe3, 0x2a, 0xe3, 0x5f,
> - 0xd7, 0x89, 0x09, 0x57, 0x53, 0xf6, 0x58, 0x40,
> - 0x70, 0xf0, 0x60, 0x96, 0xd7, 0x41, 0x2d, 0x8d,
> - 0x6d, 0x11, 0x99, 0x66, 0xb0, 0x6c, 0x4c, 0x4c,
> - 0x6c, 0x00, 0x2a, 0x01, 0x6d, 0x4d, 0x4d, 0x6d,
> - 0xb1, 0x67, 0x98, 0x10, 0x6c, 0x8c, 0x2c, 0x40,
> - 0xd6, 0x97, 0x61, 0xf1, 0x71, 0x41, 0x59, 0xf7,
> - 0x52, 0x56, 0x08, 0x88, 0xd6, 0x5e, 0xe2, 0x2a,
> - 0xe2, 0x5e, 0xd6, 0x88, 0x08, 0x56, 0x52, 0xf7,
> - 0x59, 0x41, 0x71, 0xf1, 0x61, 0x97, 0xd6, 0x40,
> - 0x2c, 0x8c, 0x6c, 0x10, 0x98, 0x67, 0xb1, 0x6d,
> - 0x4d, 0x4d, 0x6d, 0x01,
> -};
> -static u32 sizeof_american_busy = sizeof(sample_american_busy);
> -
> -static u8 sample_special1[] = {
> - 0x2a, 0x2c, 0xbc, 0x6c, 0xd6, 0x71, 0xbd, 0x0d,
> - 0xd9, 0x80, 0xcc, 0x4c, 0x40, 0x39, 0x0d, 0xbd,
> - 0x11, 0x86, 0xec, 0xbc, 0xec, 0x0e, 0x51, 0xbd,
> - 0x8d, 0x89, 0x30, 0x4c, 0xcc, 0xe0, 0xe1, 0xcd,
> - 0x4d, 0x31, 0x88, 0x8c, 0xbc, 0x50, 0x0f, 0xed,
> - 0xbd, 0xed, 0x87, 0x10, 0xbc, 0x0c, 0x38, 0x41,
> - 0x4d, 0xcd, 0x81, 0xd8, 0x0c, 0xbc, 0x70, 0xd7,
> - 0x6d, 0xbd, 0x2d,
> -};
> -static u32 sizeof_special1 = sizeof(sample_special1);
> -
> -static u8 sample_special2[] = {
> - 0x2a, 0xcc, 0x8c, 0xd7, 0x4d, 0x2d, 0x18, 0xbc,
> - 0x10, 0xc1, 0xbd, 0xc1, 0x10, 0xbc, 0x18, 0x2d,
> - 0x4d, 0xd7, 0x8c, 0xcc, 0x2a, 0xcd, 0x8d, 0xd6,
> - 0x4c, 0x2c, 0x19, 0xbd, 0x11, 0xc0, 0xbc, 0xc0,
> - 0x11, 0xbd, 0x19, 0x2c, 0x4c, 0xd6, 0x8d, 0xcd,
> - 0x2a, 0xcc, 0x8c, 0xd7, 0x4d, 0x2d, 0x18, 0xbc,
> - 0x10, 0xc1, 0xbd, 0xc1, 0x10, 0xbc, 0x18, 0x2d,
> - 0x4d, 0xd7, 0x8c, 0xcc, 0x2a, 0xcd, 0x8d, 0xd6,
> - 0x4c, 0x2c, 0x19, 0xbd, 0x11, 0xc0, 0xbc, 0xc0,
> - 0x11, 0xbd, 0x19, 0x2c, 0x4c, 0xd6, 0x8d, 0xcd,
> -};
> -static u32 sizeof_special2 = sizeof(sample_special2);
> -
> -static u8 sample_special3[] = {
> - 0x2a, 0xbc, 0x18, 0xcd, 0x11, 0x2c, 0x8c, 0xc1,
> - 0x4d, 0xd6, 0xbc, 0xd6, 0x4d, 0xc1, 0x8c, 0x2c,
> - 0x11, 0xcd, 0x18, 0xbc, 0x2a, 0xbd, 0x19, 0xcc,
> - 0x10, 0x2d, 0x8d, 0xc0, 0x4c, 0xd7, 0xbd, 0xd7,
> - 0x4c, 0xc0, 0x8d, 0x2d, 0x10, 0xcc, 0x19, 0xbd,
> - 0x2a, 0xbc, 0x18, 0xcd, 0x11, 0x2c, 0x8c, 0xc1,
> - 0x4d, 0xd6, 0xbc, 0xd6, 0x4d, 0xc1, 0x8c, 0x2c,
> - 0x11, 0xcd, 0x18, 0xbc, 0x2a, 0xbd, 0x19, 0xcc,
> - 0x10, 0x2d, 0x8d, 0xc0, 0x4c, 0xd7, 0xbd, 0xd7,
> - 0x4c, 0xc0, 0x8d, 0x2d, 0x10, 0xcc, 0x19, 0xbd,
> -};
> -static u32 sizeof_special3 = sizeof(sample_special3);
> -
> -static u8 sample_silence[] = {
> - 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
> - 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
> - 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
> - 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
> - 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
> - 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
> - 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
> - 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
> - 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
> - 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
> - 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
> - 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
> -};
> -static u32 sizeof_silence = sizeof(sample_silence);
> -
> -struct tones_samples {
> - u32 *len;
> - u8 *data;
> -};
> -static struct
> -tones_samples samples[] = {
> - {&sizeof_german_all, sample_german_all},
> - {&sizeof_german_old, sample_german_old},
> - {&sizeof_american_dialtone, sample_american_dialtone},
> - {&sizeof_american_ringing, sample_american_ringing},
> - {&sizeof_american_busy, sample_american_busy},
> - {&sizeof_special1, sample_special1},
> - {&sizeof_special2, sample_special2},
> - {&sizeof_special3, sample_special3},
> - {NULL, NULL},
> -};
> -
> -/***********************************
> - * generate ulaw from alaw samples *
> - ***********************************/
> -
> -void
> -dsp_audio_generate_ulaw_samples(void)
> -{
> - int i, j;
> -
> - i = 0;
> - while (samples[i].len) {
> - j = 0;
> - while (j < (*samples[i].len)) {
> - samples[i].data[j] =
> - dsp_audio_alaw_to_ulaw[samples[i].data[j]];
> - j++;
> - }
> - i++;
> - }
> -}
> -
> -
> -/****************************
> - * tone sequence definition *
> - ****************************/
> -
> -static struct pattern {
> - int tone;
> - u8 *data[10];
> - u32 *siz[10];
> - u32 seq[10];
> -} pattern[] = {
> - {TONE_GERMAN_DIALTONE,
> - {DATA_GA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
> - {SIZE_GA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
> - {1900, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
> -
> - {TONE_GERMAN_OLDDIALTONE,
> - {DATA_GO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
> - {SIZE_GO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
> - {1998, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
> -
> - {TONE_AMERICAN_DIALTONE,
> - {DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
> - {SIZE_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
> - {8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
> -
> - {TONE_GERMAN_DIALPBX,
> - {DATA_GA, DATA_S, DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL,
> - NULL},
> - {SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL,
> - NULL},
> - {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
> -
> - {TONE_GERMAN_OLDDIALPBX,
> - {DATA_GO, DATA_S, DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL,
> - NULL},
> - {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL,
> - NULL},
> - {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
> -
> - {TONE_AMERICAN_DIALPBX,
> - {DATA_DT, DATA_S, DATA_DT, DATA_S, DATA_DT, DATA_S, NULL, NULL, NULL,
> - NULL},
> - {SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, NULL, NULL, NULL,
> - NULL},
> - {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
> -
> - {TONE_GERMAN_RINGING,
> - {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
> - {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
> - {8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} },
> -
> - {TONE_GERMAN_OLDRINGING,
> - {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
> - {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
> - {8000, 40000, 0, 0, 0, 0, 0, 0, 0, 0} },
> -
> - {TONE_AMERICAN_RINGING,
> - {DATA_RI, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
> - {SIZE_RI, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
> - {8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} },
> -
> - {TONE_GERMAN_RINGPBX,
> - {DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
> - {SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
> - {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
> -
> - {TONE_GERMAN_OLDRINGPBX,
> - {DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
> - {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
> - {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
> -
> - {TONE_AMERICAN_RINGPBX,
> - {DATA_RI, DATA_S, DATA_RI, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
> - {SIZE_RI, SIZE_S, SIZE_RI, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
> - {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
> -
> - {TONE_GERMAN_BUSY,
> - {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
> - {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
> - {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
> -
> - {TONE_GERMAN_OLDBUSY,
> - {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
> - {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
> - {1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} },
> -
> - {TONE_AMERICAN_BUSY,
> - {DATA_BU, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
> - {SIZE_BU, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
> - {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
> -
> - {TONE_GERMAN_HANGUP,
> - {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
> - {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
> - {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
> -
> - {TONE_GERMAN_OLDHANGUP,
> - {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
> - {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
> - {1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} },
> -
> - {TONE_AMERICAN_HANGUP,
> - {DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
> - {SIZE_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
> - {8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
> -
> - {TONE_SPECIAL_INFO,
> - {DATA_S1, DATA_S2, DATA_S3, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
> - {SIZE_S1, SIZE_S2, SIZE_S3, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
> - {2666, 2666, 2666, 8002, 0, 0, 0, 0, 0, 0} },
> -
> - {TONE_GERMAN_GASSENBESETZT,
> - {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
> - {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
> - {2000, 2000, 0, 0, 0, 0, 0, 0, 0, 0} },
> -
> - {TONE_GERMAN_AUFSCHALTTON,
> - {DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
> - {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
> - {1000, 5000, 1000, 17000, 0, 0, 0, 0, 0, 0} },
> -
> - {0,
> - {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
> - {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
> - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
> -};
> -
> -/******************
> - * copy tone data *
> - ******************/
> -
> -/* an sk_buff is generated from the number of samples needed.
> - * the count will be changed and may begin from 0 each pattern period.
> - * the clue is to precalculate the pointers and legths to use only one
> - * memcpy per function call, or two memcpy if the tone sequence changes.
> - *
> - * pattern - the type of the pattern
> - * count - the sample from the beginning of the pattern (phase)
> - * len - the number of bytes
> - *
> - * return - the sk_buff with the sample
> - *
> - * if tones has finished (e.g. knocking tone), dsp->tones is turned off
> - */
> -void dsp_tone_copy(struct dsp *dsp, u8 *data, int len)
> -{
> - int index, count, start, num;
> - struct pattern *pat;
> - struct dsp_tone *tone = &dsp->tone;
> -
> - /* if we have no tone, we copy silence */
> - if (!tone->tone) {
> - memset(data, dsp_silence, len);
> - return;
> - }
> -
> - /* process pattern */
> - pat = (struct pattern *)tone->pattern;
> - /* points to the current pattern */
> - index = tone->index; /* gives current sequence index */
> - count = tone->count; /* gives current sample */
> -
> - /* copy sample */
> - while (len) {
> - /* find sample to start with */
> - while (42) {
> - /* wrap around */
> - if (!pat->seq[index]) {
> - count = 0;
> - index = 0;
> - }
> - /* check if we are currently playing this tone */
> - if (count < pat->seq[index])
> - break;
> - if (dsp_debug & DEBUG_DSP_TONE)
> - printk(KERN_DEBUG "%s: reaching next sequence "
> - "(index=%d)\n", __func__, index);
> - count -= pat->seq[index];
> - index++;
> - }
> - /* calculate start and number of samples */
> - start = count % (*(pat->siz[index]));
> - num = len;
> - if (num + count > pat->seq[index])
> - num = pat->seq[index] - count;
> - if (num + start > (*(pat->siz[index])))
> - num = (*(pat->siz[index])) - start;
> - /* copy memory */
> - memcpy(data, pat->data[index] + start, num);
> - /* reduce length */
> - data += num;
> - count += num;
> - len -= num;
> - }
> - tone->index = index;
> - tone->count = count;
> -
> - /* return sk_buff */
> - return;
> -}
> -
> -
> -/*******************************
> - * send HW message to hfc card *
> - *******************************/
> -
> -static void
> -dsp_tone_hw_message(struct dsp *dsp, u8 *sample, int len)
> -{
> - struct sk_buff *nskb;
> -
> - /* unlocking is not required, because we don't expect a response */
> - nskb = _alloc_mISDN_skb(PH_CONTROL_REQ,
> - (len) ? HFC_SPL_LOOP_ON : HFC_SPL_LOOP_OFF, len, sample,
> - GFP_ATOMIC);
> - if (nskb) {
> - if (dsp->ch.peer) {
> - if (dsp->ch.recv(dsp->ch.peer, nskb))
> - dev_kfree_skb(nskb);
> - } else
> - dev_kfree_skb(nskb);
> - }
> -}
> -
> -
> -/*****************
> - * timer expires *
> - *****************/
> -void
> -dsp_tone_timeout(struct timer_list *t)
> -{
> - struct dsp *dsp = timer_container_of(dsp, t, tone.tl);
> - struct dsp_tone *tone = &dsp->tone;
> - struct pattern *pat = (struct pattern *)tone->pattern;
> - int index = tone->index;
> -
> - if (!tone->tone)
> - return;
> -
> - index++;
> - if (!pat->seq[index])
> - index = 0;
> - tone->index = index;
> -
> - /* set next tone */
> - if (pat->data[index] == DATA_S)
> - dsp_tone_hw_message(dsp, NULL, 0);
> - else
> - dsp_tone_hw_message(dsp, pat->data[index], *(pat->siz[index]));
> - /* set timer */
> - tone->tl.expires = jiffies + (pat->seq[index] * HZ) / 8000;
> - add_timer(&tone->tl);
> -}
> -
> -
> -/********************
> - * set/release tone *
> - ********************/
> -
> -/*
> - * tones are relaized by streaming or by special loop commands if supported
> - * by hardware. when hardware is used, the patterns will be controlled by
> - * timers.
> - */
> -int
> -dsp_tone(struct dsp *dsp, int tone)
> -{
> - struct pattern *pat;
> - int i;
> - struct dsp_tone *tonet = &dsp->tone;
> -
> - tonet->software = 0;
> - tonet->hardware = 0;
> -
> - /* we turn off the tone */
> - if (!tone) {
> - if (dsp->features.hfc_loops && timer_pending(&tonet->tl))
> - timer_delete(&tonet->tl);
> - if (dsp->features.hfc_loops)
> - dsp_tone_hw_message(dsp, NULL, 0);
> - tonet->tone = 0;
> - return 0;
> - }
> -
> - pat = NULL;
> - i = 0;
> - while (pattern[i].tone) {
> - if (pattern[i].tone == tone) {
> - pat = &pattern[i];
> - break;
> - }
> - i++;
> - }
> - if (!pat) {
> - printk(KERN_WARNING "dsp: given tone 0x%x is invalid\n", tone);
> - return -EINVAL;
> - }
> - if (dsp_debug & DEBUG_DSP_TONE)
> - printk(KERN_DEBUG "%s: now starting tone %d (index=%d)\n",
> - __func__, tone, 0);
> - tonet->tone = tone;
> - tonet->pattern = pat;
> - tonet->index = 0;
> - tonet->count = 0;
> -
> - if (dsp->features.hfc_loops) {
> - tonet->hardware = 1;
> - /* set first tone */
> - dsp_tone_hw_message(dsp, pat->data[0], *(pat->siz[0]));
> - /* set timer */
> - if (timer_pending(&tonet->tl))
> - timer_delete(&tonet->tl);
> - tonet->tl.expires = jiffies + (pat->seq[0] * HZ) / 8000;
> - add_timer(&tonet->tl);
> - } else {
> - tonet->software = 1;
> - }
> -
> - return 0;
> -}
> diff --git a/drivers/isdn/mISDN/fsm.c b/drivers/isdn/mISDN/fsm.c
> deleted file mode 100644
> index 825b686496d2..000000000000
> --- a/drivers/isdn/mISDN/fsm.c
> +++ /dev/null
> @@ -1,176 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * finite state machine implementation
> - *
> - * Author Karsten Keil <kkeil@novell.com>
> - *
> - * Thanks to Jan den Ouden
> - * Fritz Elfert
> - * Copyright 2008 by Karsten Keil <kkeil@novell.com>
> - */
> -
> -#include <linux/kernel.h>
> -#include <linux/slab.h>
> -#include <linux/module.h>
> -#include <linux/string.h>
> -#include "fsm.h"
> -
> -#define FSM_TIMER_DEBUG 0
> -
> -int
> -mISDN_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 == NULL)
> - return -ENOMEM;
> -
> - for (i = 0; i < fncount; i++)
> - if ((fnlist[i].state >= fsm->state_count) ||
> - (fnlist[i].event >= fsm->event_count)) {
> - printk(KERN_ERR
> - "mISDN_FsmNew Error: %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;
> -}
> -EXPORT_SYMBOL(mISDN_FsmNew);
> -
> -void
> -mISDN_FsmFree(struct Fsm *fsm)
> -{
> - kfree((void *) fsm->jumpmatrix);
> -}
> -EXPORT_SYMBOL(mISDN_FsmFree);
> -
> -int
> -mISDN_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
> - "mISDN_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 action",
> - fi->fsm->strState[fi->state],
> - fi->fsm->strEvent[event]);
> - return 1;
> - }
> -}
> -EXPORT_SYMBOL(mISDN_FsmEvent);
> -
> -void
> -mISDN_FsmChangeState(struct FsmInst *fi, int newstate)
> -{
> - fi->state = newstate;
> - if (fi->debug)
> - fi->printdebug(fi, "ChangeState %s",
> - fi->fsm->strState[newstate]);
> -}
> -EXPORT_SYMBOL(mISDN_FsmChangeState);
> -
> -static void
> -FsmExpireTimer(struct timer_list *t)
> -{
> - struct FsmTimer *ft = timer_container_of(ft, t, tl);
> -#if FSM_TIMER_DEBUG
> - if (ft->fi->debug)
> - ft->fi->printdebug(ft->fi, "FsmExpireTimer %lx", (long) ft);
> -#endif
> - mISDN_FsmEvent(ft->fi, ft->event, ft->arg);
> -}
> -
> -void
> -mISDN_FsmInitTimer(struct FsmInst *fi, struct FsmTimer *ft)
> -{
> - ft->fi = fi;
> -#if FSM_TIMER_DEBUG
> - if (ft->fi->debug)
> - ft->fi->printdebug(ft->fi, "mISDN_FsmInitTimer %lx", (long) ft);
> -#endif
> - timer_setup(&ft->tl, FsmExpireTimer, 0);
> -}
> -EXPORT_SYMBOL(mISDN_FsmInitTimer);
> -
> -void
> -mISDN_FsmDelTimer(struct FsmTimer *ft, int where)
> -{
> -#if FSM_TIMER_DEBUG
> - if (ft->fi->debug)
> - ft->fi->printdebug(ft->fi, "mISDN_FsmDelTimer %lx %d",
> - (long) ft, where);
> -#endif
> - timer_delete(&ft->tl);
> -}
> -EXPORT_SYMBOL(mISDN_FsmDelTimer);
> -
> -int
> -mISDN_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, "mISDN_FsmAddTimer %lx %d %d",
> - (long) ft, millisec, where);
> -#endif
> -
> - if (timer_pending(&ft->tl)) {
> - if (ft->fi->debug) {
> - printk(KERN_WARNING
> - "mISDN_FsmAddTimer: timer already active!\n");
> - ft->fi->printdebug(ft->fi,
> - "mISDN_FsmAddTimer already active!");
> - }
> - return -1;
> - }
> - ft->event = event;
> - ft->arg = arg;
> - ft->tl.expires = jiffies + (millisec * HZ) / 1000;
> - add_timer(&ft->tl);
> - return 0;
> -}
> -EXPORT_SYMBOL(mISDN_FsmAddTimer);
> -
> -void
> -mISDN_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, "mISDN_FsmRestartTimer %lx %d %d",
> - (long) ft, millisec, where);
> -#endif
> -
> - if (timer_pending(&ft->tl))
> - timer_delete(&ft->tl);
> - ft->event = event;
> - ft->arg = arg;
> - ft->tl.expires = jiffies + (millisec * HZ) / 1000;
> - add_timer(&ft->tl);
> -}
> -EXPORT_SYMBOL(mISDN_FsmRestartTimer);
> diff --git a/drivers/isdn/mISDN/hwchannel.c b/drivers/isdn/mISDN/hwchannel.c
> deleted file mode 100644
> index 8c93af06ed02..000000000000
> --- a/drivers/isdn/mISDN/hwchannel.c
> +++ /dev/null
> @@ -1,516 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - *
> - * Author Karsten Keil <kkeil@novell.com>
> - *
> - * Copyright 2008 by Karsten Keil <kkeil@novell.com>
> - */
> -
> -#include <linux/gfp.h>
> -#include <linux/module.h>
> -#include <linux/mISDNhw.h>
> -
> -static void
> -dchannel_bh(struct work_struct *ws)
> -{
> - struct dchannel *dch = container_of(ws, struct dchannel, workq);
> - struct sk_buff *skb;
> - int err;
> -
> - if (test_and_clear_bit(FLG_RECVQUEUE, &dch->Flags)) {
> - while ((skb = skb_dequeue(&dch->rqueue))) {
> - if (likely(dch->dev.D.peer)) {
> - err = dch->dev.D.recv(dch->dev.D.peer, skb);
> - if (err)
> - dev_kfree_skb(skb);
> - } else
> - dev_kfree_skb(skb);
> - }
> - }
> - if (test_and_clear_bit(FLG_PHCHANGE, &dch->Flags)) {
> - if (dch->phfunc)
> - dch->phfunc(dch);
> - }
> -}
> -
> -static void
> -bchannel_bh(struct work_struct *ws)
> -{
> - struct bchannel *bch = container_of(ws, struct bchannel, workq);
> - struct sk_buff *skb;
> - int err;
> -
> - if (test_and_clear_bit(FLG_RECVQUEUE, &bch->Flags)) {
> - while ((skb = skb_dequeue(&bch->rqueue))) {
> - bch->rcount--;
> - if (likely(bch->ch.peer)) {
> - err = bch->ch.recv(bch->ch.peer, skb);
> - if (err)
> - dev_kfree_skb(skb);
> - } else
> - dev_kfree_skb(skb);
> - }
> - }
> -}
> -
> -int
> -mISDN_initdchannel(struct dchannel *ch, int maxlen, void *phf)
> -{
> - test_and_set_bit(FLG_HDLC, &ch->Flags);
> - ch->maxlen = maxlen;
> - ch->hw = NULL;
> - ch->rx_skb = NULL;
> - ch->tx_skb = NULL;
> - ch->tx_idx = 0;
> - ch->phfunc = phf;
> - skb_queue_head_init(&ch->squeue);
> - skb_queue_head_init(&ch->rqueue);
> - INIT_LIST_HEAD(&ch->dev.bchannels);
> - INIT_WORK(&ch->workq, dchannel_bh);
> - return 0;
> -}
> -EXPORT_SYMBOL(mISDN_initdchannel);
> -
> -int
> -mISDN_initbchannel(struct bchannel *ch, unsigned short maxlen,
> - unsigned short minlen)
> -{
> - ch->Flags = 0;
> - ch->minlen = minlen;
> - ch->next_minlen = minlen;
> - ch->init_minlen = minlen;
> - ch->maxlen = maxlen;
> - ch->next_maxlen = maxlen;
> - ch->init_maxlen = maxlen;
> - ch->hw = NULL;
> - ch->rx_skb = NULL;
> - ch->tx_skb = NULL;
> - ch->tx_idx = 0;
> - skb_queue_head_init(&ch->rqueue);
> - ch->rcount = 0;
> - ch->next_skb = NULL;
> - INIT_WORK(&ch->workq, bchannel_bh);
> - return 0;
> -}
> -EXPORT_SYMBOL(mISDN_initbchannel);
> -
> -int
> -mISDN_freedchannel(struct dchannel *ch)
> -{
> - if (ch->tx_skb) {
> - dev_kfree_skb(ch->tx_skb);
> - ch->tx_skb = NULL;
> - }
> - if (ch->rx_skb) {
> - dev_kfree_skb(ch->rx_skb);
> - ch->rx_skb = NULL;
> - }
> - skb_queue_purge(&ch->squeue);
> - skb_queue_purge(&ch->rqueue);
> - flush_work(&ch->workq);
> - return 0;
> -}
> -EXPORT_SYMBOL(mISDN_freedchannel);
> -
> -void
> -mISDN_clear_bchannel(struct bchannel *ch)
> -{
> - if (ch->tx_skb) {
> - dev_kfree_skb(ch->tx_skb);
> - ch->tx_skb = NULL;
> - }
> - ch->tx_idx = 0;
> - if (ch->rx_skb) {
> - dev_kfree_skb(ch->rx_skb);
> - ch->rx_skb = NULL;
> - }
> - if (ch->next_skb) {
> - dev_kfree_skb(ch->next_skb);
> - ch->next_skb = NULL;
> - }
> - test_and_clear_bit(FLG_TX_BUSY, &ch->Flags);
> - test_and_clear_bit(FLG_TX_NEXT, &ch->Flags);
> - test_and_clear_bit(FLG_ACTIVE, &ch->Flags);
> - test_and_clear_bit(FLG_FILLEMPTY, &ch->Flags);
> - test_and_clear_bit(FLG_TX_EMPTY, &ch->Flags);
> - test_and_clear_bit(FLG_RX_OFF, &ch->Flags);
> - ch->dropcnt = 0;
> - ch->minlen = ch->init_minlen;
> - ch->next_minlen = ch->init_minlen;
> - ch->maxlen = ch->init_maxlen;
> - ch->next_maxlen = ch->init_maxlen;
> - skb_queue_purge(&ch->rqueue);
> - ch->rcount = 0;
> -}
> -EXPORT_SYMBOL(mISDN_clear_bchannel);
> -
> -void
> -mISDN_freebchannel(struct bchannel *ch)
> -{
> - cancel_work_sync(&ch->workq);
> - mISDN_clear_bchannel(ch);
> -}
> -EXPORT_SYMBOL(mISDN_freebchannel);
> -
> -int
> -mISDN_ctrl_bchannel(struct bchannel *bch, struct mISDN_ctrl_req *cq)
> -{
> - int ret = 0;
> -
> - switch (cq->op) {
> - case MISDN_CTRL_GETOP:
> - cq->op = MISDN_CTRL_RX_BUFFER | MISDN_CTRL_FILL_EMPTY |
> - MISDN_CTRL_RX_OFF;
> - break;
> - case MISDN_CTRL_FILL_EMPTY:
> - if (cq->p1) {
> - memset(bch->fill, cq->p2 & 0xff, MISDN_BCH_FILL_SIZE);
> - test_and_set_bit(FLG_FILLEMPTY, &bch->Flags);
> - } else {
> - test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);
> - }
> - break;
> - case MISDN_CTRL_RX_OFF:
> - /* read back dropped byte count */
> - cq->p2 = bch->dropcnt;
> - if (cq->p1)
> - test_and_set_bit(FLG_RX_OFF, &bch->Flags);
> - else
> - test_and_clear_bit(FLG_RX_OFF, &bch->Flags);
> - bch->dropcnt = 0;
> - break;
> - case MISDN_CTRL_RX_BUFFER:
> - if (cq->p2 > MISDN_CTRL_RX_SIZE_IGNORE)
> - bch->next_maxlen = cq->p2;
> - if (cq->p1 > MISDN_CTRL_RX_SIZE_IGNORE)
> - bch->next_minlen = cq->p1;
> - /* we return the old values */
> - cq->p1 = bch->minlen;
> - cq->p2 = bch->maxlen;
> - break;
> - default:
> - pr_info("mISDN unhandled control %x operation\n", cq->op);
> - ret = -EINVAL;
> - break;
> - }
> - return ret;
> -}
> -EXPORT_SYMBOL(mISDN_ctrl_bchannel);
> -
> -static inline u_int
> -get_sapi_tei(u_char *p)
> -{
> - u_int sapi, tei;
> -
> - sapi = *p >> 2;
> - tei = p[1] >> 1;
> - return sapi | (tei << 8);
> -}
> -
> -void
> -recv_Dchannel(struct dchannel *dch)
> -{
> - struct mISDNhead *hh;
> -
> - if (dch->rx_skb->len < 2) { /* at least 2 for sapi / tei */
> - dev_kfree_skb(dch->rx_skb);
> - dch->rx_skb = NULL;
> - return;
> - }
> - hh = mISDN_HEAD_P(dch->rx_skb);
> - hh->prim = PH_DATA_IND;
> - hh->id = get_sapi_tei(dch->rx_skb->data);
> - skb_queue_tail(&dch->rqueue, dch->rx_skb);
> - dch->rx_skb = NULL;
> - schedule_event(dch, FLG_RECVQUEUE);
> -}
> -EXPORT_SYMBOL(recv_Dchannel);
> -
> -void
> -recv_Echannel(struct dchannel *ech, struct dchannel *dch)
> -{
> - struct mISDNhead *hh;
> -
> - if (ech->rx_skb->len < 2) { /* at least 2 for sapi / tei */
> - dev_kfree_skb(ech->rx_skb);
> - ech->rx_skb = NULL;
> - return;
> - }
> - hh = mISDN_HEAD_P(ech->rx_skb);
> - hh->prim = PH_DATA_E_IND;
> - hh->id = get_sapi_tei(ech->rx_skb->data);
> - skb_queue_tail(&dch->rqueue, ech->rx_skb);
> - ech->rx_skb = NULL;
> - schedule_event(dch, FLG_RECVQUEUE);
> -}
> -EXPORT_SYMBOL(recv_Echannel);
> -
> -void
> -recv_Bchannel(struct bchannel *bch, unsigned int id, bool force)
> -{
> - struct mISDNhead *hh;
> -
> - /* if allocation did fail upper functions still may call us */
> - if (unlikely(!bch->rx_skb))
> - return;
> - if (unlikely(!bch->rx_skb->len)) {
> - /* we have no data to send - this may happen after recovery
> - * from overflow or too small allocation.
> - * We need to free the buffer here */
> - dev_kfree_skb(bch->rx_skb);
> - bch->rx_skb = NULL;
> - } else {
> - if (test_bit(FLG_TRANSPARENT, &bch->Flags) &&
> - (bch->rx_skb->len < bch->minlen) && !force)
> - return;
> - hh = mISDN_HEAD_P(bch->rx_skb);
> - hh->prim = PH_DATA_IND;
> - hh->id = id;
> - if (bch->rcount >= 64) {
> - printk(KERN_WARNING
> - "B%d receive queue overflow - flushing!\n",
> - bch->nr);
> - skb_queue_purge(&bch->rqueue);
> - }
> - bch->rcount++;
> - skb_queue_tail(&bch->rqueue, bch->rx_skb);
> - bch->rx_skb = NULL;
> - schedule_event(bch, FLG_RECVQUEUE);
> - }
> -}
> -EXPORT_SYMBOL(recv_Bchannel);
> -
> -void
> -recv_Dchannel_skb(struct dchannel *dch, struct sk_buff *skb)
> -{
> - skb_queue_tail(&dch->rqueue, skb);
> - schedule_event(dch, FLG_RECVQUEUE);
> -}
> -EXPORT_SYMBOL(recv_Dchannel_skb);
> -
> -void
> -recv_Bchannel_skb(struct bchannel *bch, struct sk_buff *skb)
> -{
> - if (bch->rcount >= 64) {
> - printk(KERN_WARNING "B-channel %p receive queue overflow, "
> - "flushing!\n", bch);
> - skb_queue_purge(&bch->rqueue);
> - bch->rcount = 0;
> - }
> - bch->rcount++;
> - skb_queue_tail(&bch->rqueue, skb);
> - schedule_event(bch, FLG_RECVQUEUE);
> -}
> -EXPORT_SYMBOL(recv_Bchannel_skb);
> -
> -static void
> -confirm_Dsend(struct dchannel *dch)
> -{
> - struct sk_buff *skb;
> -
> - skb = _alloc_mISDN_skb(PH_DATA_CNF, mISDN_HEAD_ID(dch->tx_skb),
> - 0, NULL, GFP_ATOMIC);
> - if (!skb) {
> - printk(KERN_ERR "%s: no skb id %x\n", __func__,
> - mISDN_HEAD_ID(dch->tx_skb));
> - return;
> - }
> - skb_queue_tail(&dch->rqueue, skb);
> - schedule_event(dch, FLG_RECVQUEUE);
> -}
> -
> -int
> -get_next_dframe(struct dchannel *dch)
> -{
> - dch->tx_idx = 0;
> - dch->tx_skb = skb_dequeue(&dch->squeue);
> - if (dch->tx_skb) {
> - confirm_Dsend(dch);
> - return 1;
> - }
> - dch->tx_skb = NULL;
> - test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
> - return 0;
> -}
> -EXPORT_SYMBOL(get_next_dframe);
> -
> -static void
> -confirm_Bsend(struct bchannel *bch)
> -{
> - struct sk_buff *skb;
> -
> - if (bch->rcount >= 64) {
> - printk(KERN_WARNING "B-channel %p receive queue overflow, "
> - "flushing!\n", bch);
> - skb_queue_purge(&bch->rqueue);
> - bch->rcount = 0;
> - }
> - skb = _alloc_mISDN_skb(PH_DATA_CNF, mISDN_HEAD_ID(bch->tx_skb),
> - 0, NULL, GFP_ATOMIC);
> - if (!skb) {
> - printk(KERN_ERR "%s: no skb id %x\n", __func__,
> - mISDN_HEAD_ID(bch->tx_skb));
> - return;
> - }
> - bch->rcount++;
> - skb_queue_tail(&bch->rqueue, skb);
> - schedule_event(bch, FLG_RECVQUEUE);
> -}
> -
> -int
> -get_next_bframe(struct bchannel *bch)
> -{
> - bch->tx_idx = 0;
> - if (test_bit(FLG_TX_NEXT, &bch->Flags)) {
> - bch->tx_skb = bch->next_skb;
> - if (bch->tx_skb) {
> - bch->next_skb = NULL;
> - test_and_clear_bit(FLG_TX_NEXT, &bch->Flags);
> - /* confirm imediately to allow next data */
> - confirm_Bsend(bch);
> - return 1;
> - } else {
> - test_and_clear_bit(FLG_TX_NEXT, &bch->Flags);
> - printk(KERN_WARNING "B TX_NEXT without skb\n");
> - }
> - }
> - bch->tx_skb = NULL;
> - test_and_clear_bit(FLG_TX_BUSY, &bch->Flags);
> - return 0;
> -}
> -EXPORT_SYMBOL(get_next_bframe);
> -
> -void
> -queue_ch_frame(struct mISDNchannel *ch, u_int pr, int id, struct sk_buff *skb)
> -{
> - struct mISDNhead *hh;
> -
> - if (!skb) {
> - _queue_data(ch, pr, id, 0, NULL, GFP_ATOMIC);
> - } else {
> - if (ch->peer) {
> - hh = mISDN_HEAD_P(skb);
> - hh->prim = pr;
> - hh->id = id;
> - if (!ch->recv(ch->peer, skb))
> - return;
> - }
> - dev_kfree_skb(skb);
> - }
> -}
> -EXPORT_SYMBOL(queue_ch_frame);
> -
> -int
> -dchannel_senddata(struct dchannel *ch, struct sk_buff *skb)
> -{
> - /* check oversize */
> - if (skb->len <= 0) {
> - printk(KERN_WARNING "%s: skb too small\n", __func__);
> - return -EINVAL;
> - }
> - if (skb->len > ch->maxlen) {
> - printk(KERN_WARNING "%s: skb too large(%d/%d)\n",
> - __func__, skb->len, ch->maxlen);
> - return -EINVAL;
> - }
> - /* HW lock must be obtained */
> - if (test_and_set_bit(FLG_TX_BUSY, &ch->Flags)) {
> - skb_queue_tail(&ch->squeue, skb);
> - return 0;
> - } else {
> - /* write to fifo */
> - ch->tx_skb = skb;
> - ch->tx_idx = 0;
> - return 1;
> - }
> -}
> -EXPORT_SYMBOL(dchannel_senddata);
> -
> -int
> -bchannel_senddata(struct bchannel *ch, struct sk_buff *skb)
> -{
> -
> - /* check oversize */
> - if (skb->len <= 0) {
> - printk(KERN_WARNING "%s: skb too small\n", __func__);
> - return -EINVAL;
> - }
> - if (skb->len > ch->maxlen) {
> - printk(KERN_WARNING "%s: skb too large(%d/%d)\n",
> - __func__, skb->len, ch->maxlen);
> - return -EINVAL;
> - }
> - /* HW lock must be obtained */
> - /* check for pending next_skb */
> - if (ch->next_skb) {
> - printk(KERN_WARNING
> - "%s: next_skb exist ERROR (skb->len=%d next_skb->len=%d)\n",
> - __func__, skb->len, ch->next_skb->len);
> - return -EBUSY;
> - }
> - if (test_and_set_bit(FLG_TX_BUSY, &ch->Flags)) {
> - test_and_set_bit(FLG_TX_NEXT, &ch->Flags);
> - ch->next_skb = skb;
> - return 0;
> - } else {
> - /* write to fifo */
> - ch->tx_skb = skb;
> - ch->tx_idx = 0;
> - confirm_Bsend(ch);
> - return 1;
> - }
> -}
> -EXPORT_SYMBOL(bchannel_senddata);
> -
> -/* The function allocates a new receive skb on demand with a size for the
> - * requirements of the current protocol. It returns the tailroom of the
> - * receive skb or an error.
> - */
> -int
> -bchannel_get_rxbuf(struct bchannel *bch, int reqlen)
> -{
> - int len;
> -
> - if (bch->rx_skb) {
> - len = skb_tailroom(bch->rx_skb);
> - if (len < reqlen) {
> - pr_warn("B%d no space for %d (only %d) bytes\n",
> - bch->nr, reqlen, len);
> - if (test_bit(FLG_TRANSPARENT, &bch->Flags)) {
> - /* send what we have now and try a new buffer */
> - recv_Bchannel(bch, 0, true);
> - } else {
> - /* on HDLC we have to drop too big frames */
> - return -EMSGSIZE;
> - }
> - } else {
> - return len;
> - }
> - }
> - /* update current min/max length first */
> - if (unlikely(bch->maxlen != bch->next_maxlen))
> - bch->maxlen = bch->next_maxlen;
> - if (unlikely(bch->minlen != bch->next_minlen))
> - bch->minlen = bch->next_minlen;
> - if (unlikely(reqlen > bch->maxlen))
> - return -EMSGSIZE;
> - if (test_bit(FLG_TRANSPARENT, &bch->Flags)) {
> - if (reqlen >= bch->minlen) {
> - len = reqlen;
> - } else {
> - len = 2 * bch->minlen;
> - if (len > bch->maxlen)
> - len = bch->maxlen;
> - }
> - } else {
> - /* with HDLC we do not know the length yet */
> - len = bch->maxlen;
> - }
> - bch->rx_skb = mI_alloc_skb(len, GFP_ATOMIC);
> - if (!bch->rx_skb) {
> - pr_warn("B%d receive no memory for %d bytes\n", bch->nr, len);
> - len = -ENOMEM;
> - }
> - return len;
> -}
> -EXPORT_SYMBOL(bchannel_get_rxbuf);
> diff --git a/drivers/isdn/mISDN/l1oip_codec.c b/drivers/isdn/mISDN/l1oip_codec.c
> deleted file mode 100644
> index 1059234fbc67..000000000000
> --- a/drivers/isdn/mISDN/l1oip_codec.c
> +++ /dev/null
> @@ -1,358 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-or-later
> -/*
> -
> - * l1oip_codec.c generic codec using lookup table
> - * -> conversion from a-Law to u-Law
> - * -> conversion from u-Law to a-Law
> - * -> compression by reducing the number of sample resolution to 4
> - *
> - * NOTE: It is not compatible with any standard codec like ADPCM.
> - *
> - * Author Andreas Eversberg (jolly@eversberg.eu)
> - *
> -
> - */
> -
> -/*
> -
> - How the codec works:
> - --------------------
> -
> - The volume is increased to increase the dynamic range of the audio signal.
> - Each sample is converted to a-LAW with only 16 steps of level resolution.
> - A pair of two samples are stored in one byte.
> -
> - The first byte is stored in the upper bits, the second byte is stored in the
> - lower bits.
> -
> - To speed up compression and decompression, two lookup tables are formed:
> -
> - - 16 bits index for two samples (law encoded) with 8 bit compressed result.
> - - 8 bits index for one compressed data with 16 bits decompressed result.
> -
> - NOTE: The bytes are handled as they are law-encoded.
> -
> -*/
> -
> -#include <linux/vmalloc.h>
> -#include <linux/mISDNif.h>
> -#include <linux/in.h>
> -#include "core.h"
> -#include "l1oip.h"
> -
> -/* definitions of codec. don't use calculations, code may run slower. */
> -
> -static u8 *table_com;
> -static u16 *table_dec;
> -
> -
> -/* alaw -> ulaw */
> -static u8 alaw_to_ulaw[256] =
> -{
> - 0xab, 0x2b, 0xe3, 0x63, 0x8b, 0x0b, 0xc9, 0x49,
> - 0xba, 0x3a, 0xf6, 0x76, 0x9b, 0x1b, 0xd7, 0x57,
> - 0xa3, 0x23, 0xdd, 0x5d, 0x83, 0x03, 0xc1, 0x41,
> - 0xb2, 0x32, 0xeb, 0x6b, 0x93, 0x13, 0xcf, 0x4f,
> - 0xaf, 0x2f, 0xe7, 0x67, 0x8f, 0x0f, 0xcd, 0x4d,
> - 0xbe, 0x3e, 0xfe, 0x7e, 0x9f, 0x1f, 0xdb, 0x5b,
> - 0xa7, 0x27, 0xdf, 0x5f, 0x87, 0x07, 0xc5, 0x45,
> - 0xb6, 0x36, 0xef, 0x6f, 0x97, 0x17, 0xd3, 0x53,
> - 0xa9, 0x29, 0xe1, 0x61, 0x89, 0x09, 0xc7, 0x47,
> - 0xb8, 0x38, 0xf2, 0x72, 0x99, 0x19, 0xd5, 0x55,
> - 0xa1, 0x21, 0xdc, 0x5c, 0x81, 0x01, 0xbf, 0x3f,
> - 0xb0, 0x30, 0xe9, 0x69, 0x91, 0x11, 0xce, 0x4e,
> - 0xad, 0x2d, 0xe5, 0x65, 0x8d, 0x0d, 0xcb, 0x4b,
> - 0xbc, 0x3c, 0xfa, 0x7a, 0x9d, 0x1d, 0xd9, 0x59,
> - 0xa5, 0x25, 0xde, 0x5e, 0x85, 0x05, 0xc3, 0x43,
> - 0xb4, 0x34, 0xed, 0x6d, 0x95, 0x15, 0xd1, 0x51,
> - 0xac, 0x2c, 0xe4, 0x64, 0x8c, 0x0c, 0xca, 0x4a,
> - 0xbb, 0x3b, 0xf8, 0x78, 0x9c, 0x1c, 0xd8, 0x58,
> - 0xa4, 0x24, 0xde, 0x5e, 0x84, 0x04, 0xc2, 0x42,
> - 0xb3, 0x33, 0xec, 0x6c, 0x94, 0x14, 0xd0, 0x50,
> - 0xb0, 0x30, 0xe8, 0x68, 0x90, 0x10, 0xce, 0x4e,
> - 0xbf, 0x3f, 0xfe, 0x7e, 0xa0, 0x20, 0xdc, 0x5c,
> - 0xa8, 0x28, 0xe0, 0x60, 0x88, 0x08, 0xc6, 0x46,
> - 0xb7, 0x37, 0xf0, 0x70, 0x98, 0x18, 0xd4, 0x54,
> - 0xaa, 0x2a, 0xe2, 0x62, 0x8a, 0x0a, 0xc8, 0x48,
> - 0xb9, 0x39, 0xf4, 0x74, 0x9a, 0x1a, 0xd6, 0x56,
> - 0xa2, 0x22, 0xdd, 0x5d, 0x82, 0x02, 0xc0, 0x40,
> - 0xb1, 0x31, 0xea, 0x6a, 0x92, 0x12, 0xcf, 0x4f,
> - 0xae, 0x2e, 0xe6, 0x66, 0x8e, 0x0e, 0xcc, 0x4c,
> - 0xbd, 0x3d, 0xfc, 0x7c, 0x9e, 0x1e, 0xda, 0x5a,
> - 0xa6, 0x26, 0xdf, 0x5f, 0x86, 0x06, 0xc4, 0x44,
> - 0xb5, 0x35, 0xee, 0x6e, 0x96, 0x16, 0xd2, 0x52
> -};
> -
> -/* ulaw -> alaw */
> -static u8 ulaw_to_alaw[256] =
> -{
> - 0xab, 0x55, 0xd5, 0x15, 0x95, 0x75, 0xf5, 0x35,
> - 0xb5, 0x45, 0xc5, 0x05, 0x85, 0x65, 0xe5, 0x25,
> - 0xa5, 0x5d, 0xdd, 0x1d, 0x9d, 0x7d, 0xfd, 0x3d,
> - 0xbd, 0x4d, 0xcd, 0x0d, 0x8d, 0x6d, 0xed, 0x2d,
> - 0xad, 0x51, 0xd1, 0x11, 0x91, 0x71, 0xf1, 0x31,
> - 0xb1, 0x41, 0xc1, 0x01, 0x81, 0x61, 0xe1, 0x21,
> - 0x59, 0xd9, 0x19, 0x99, 0x79, 0xf9, 0x39, 0xb9,
> - 0x49, 0xc9, 0x09, 0x89, 0x69, 0xe9, 0x29, 0xa9,
> - 0xd7, 0x17, 0x97, 0x77, 0xf7, 0x37, 0xb7, 0x47,
> - 0xc7, 0x07, 0x87, 0x67, 0xe7, 0x27, 0xa7, 0xdf,
> - 0x9f, 0x7f, 0xff, 0x3f, 0xbf, 0x4f, 0xcf, 0x0f,
> - 0x8f, 0x6f, 0xef, 0x2f, 0x53, 0x13, 0x73, 0x33,
> - 0xb3, 0x43, 0xc3, 0x03, 0x83, 0x63, 0xe3, 0x23,
> - 0xa3, 0x5b, 0xdb, 0x1b, 0x9b, 0x7b, 0xfb, 0x3b,
> - 0xbb, 0xbb, 0x4b, 0x4b, 0xcb, 0xcb, 0x0b, 0x0b,
> - 0x8b, 0x8b, 0x6b, 0x6b, 0xeb, 0xeb, 0x2b, 0x2b,
> - 0xab, 0x54, 0xd4, 0x14, 0x94, 0x74, 0xf4, 0x34,
> - 0xb4, 0x44, 0xc4, 0x04, 0x84, 0x64, 0xe4, 0x24,
> - 0xa4, 0x5c, 0xdc, 0x1c, 0x9c, 0x7c, 0xfc, 0x3c,
> - 0xbc, 0x4c, 0xcc, 0x0c, 0x8c, 0x6c, 0xec, 0x2c,
> - 0xac, 0x50, 0xd0, 0x10, 0x90, 0x70, 0xf0, 0x30,
> - 0xb0, 0x40, 0xc0, 0x00, 0x80, 0x60, 0xe0, 0x20,
> - 0x58, 0xd8, 0x18, 0x98, 0x78, 0xf8, 0x38, 0xb8,
> - 0x48, 0xc8, 0x08, 0x88, 0x68, 0xe8, 0x28, 0xa8,
> - 0xd6, 0x16, 0x96, 0x76, 0xf6, 0x36, 0xb6, 0x46,
> - 0xc6, 0x06, 0x86, 0x66, 0xe6, 0x26, 0xa6, 0xde,
> - 0x9e, 0x7e, 0xfe, 0x3e, 0xbe, 0x4e, 0xce, 0x0e,
> - 0x8e, 0x6e, 0xee, 0x2e, 0x52, 0x12, 0x72, 0x32,
> - 0xb2, 0x42, 0xc2, 0x02, 0x82, 0x62, 0xe2, 0x22,
> - 0xa2, 0x5a, 0xda, 0x1a, 0x9a, 0x7a, 0xfa, 0x3a,
> - 0xba, 0xba, 0x4a, 0x4a, 0xca, 0xca, 0x0a, 0x0a,
> - 0x8a, 0x8a, 0x6a, 0x6a, 0xea, 0xea, 0x2a, 0x2a
> -};
> -
> -/* alaw -> 4bit compression */
> -static u8 alaw_to_4bit[256] = {
> - 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
> - 0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
> - 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
> - 0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
> - 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
> - 0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
> - 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
> - 0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
> - 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
> - 0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
> - 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0d, 0x02,
> - 0x0e, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
> - 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
> - 0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
> - 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
> - 0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
> - 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
> - 0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
> - 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
> - 0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
> - 0x0e, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
> - 0x0d, 0x02, 0x08, 0x07, 0x0f, 0x01, 0x0a, 0x05,
> - 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
> - 0x0d, 0x02, 0x09, 0x07, 0x0f, 0x00, 0x0b, 0x04,
> - 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
> - 0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
> - 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
> - 0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
> - 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
> - 0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
> - 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
> - 0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
> -};
> -
> -/* 4bit -> alaw decompression */
> -static u8 _4bit_to_alaw[16] = {
> - 0x5d, 0x51, 0xd9, 0xd7, 0x5f, 0x53, 0xa3, 0x4b,
> - 0x2a, 0x3a, 0x22, 0x2e, 0x26, 0x56, 0x20, 0x2c,
> -};
> -
> -/* ulaw -> 4bit compression */
> -static u8 ulaw_to_4bit[256] = {
> - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
> - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
> - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
> - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
> - 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
> - 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04,
> - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
> - 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05,
> - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
> - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
> - 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
> - 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08,
> - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
> - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
> - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
> - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
> - 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
> - 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
> - 0x0e, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
> - 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
> - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
> - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b,
> - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
> - 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x0a,
> - 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
> - 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
> - 0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
> - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
> -};
> -
> -/* 4bit -> ulaw decompression */
> -static u8 _4bit_to_ulaw[16] = {
> - 0x11, 0x21, 0x31, 0x40, 0x4e, 0x5c, 0x68, 0x71,
> - 0xfe, 0xef, 0xe7, 0xdb, 0xcd, 0xbf, 0xaf, 0x9f,
> -};
> -
> -
> -/*
> - * Compresses data to the result buffer
> - * The result size must be at least half of the input buffer.
> - * The number of samples also must be even!
> - */
> -int
> -l1oip_law_to_4bit(u8 *data, int len, u8 *result, u32 *state)
> -{
> - int ii, i = 0, o = 0;
> -
> - if (!len)
> - return 0;
> -
> - /* send saved byte and first input byte */
> - if (*state) {
> - *result++ = table_com[(((*state) << 8) & 0xff00) | (*data++)];
> - len--;
> - o++;
> - }
> -
> - ii = len >> 1;
> -
> - while (i < ii) {
> - *result++ = table_com[(data[0]<<8) | (data[1])];
> - data += 2;
> - i++;
> - o++;
> - }
> -
> - /* if len has an odd number, we save byte for next call */
> - if (len & 1)
> - *state = 0x100 + *data;
> - else
> - *state = 0;
> -
> - return o;
> -}
> -
> -/* Decompress data to the result buffer
> - * The result size must be the number of sample in packet. (2 * input data)
> - * The number of samples in the result are even!
> - */
> -int
> -l1oip_4bit_to_law(u8 *data, int len, u8 *result)
> -{
> - int i = 0;
> - u16 r;
> -
> - while (i < len) {
> - r = table_dec[*data++];
> - *result++ = r >> 8;
> - *result++ = r;
> - i++;
> - }
> -
> - return len << 1;
> -}
> -
> -
> -/*
> - * law conversion
> - */
> -int
> -l1oip_alaw_to_ulaw(u8 *data, int len, u8 *result)
> -{
> - int i = 0;
> -
> - while (i < len) {
> - *result++ = alaw_to_ulaw[*data++];
> - i++;
> - }
> -
> - return len;
> -}
> -
> -int
> -l1oip_ulaw_to_alaw(u8 *data, int len, u8 *result)
> -{
> - int i = 0;
> -
> - while (i < len) {
> - *result++ = ulaw_to_alaw[*data++];
> - i++;
> - }
> -
> - return len;
> -}
> -
> -
> -/*
> - * generate/free compression and decompression table
> - */
> -void
> -l1oip_4bit_free(void)
> -{
> - vfree(table_dec);
> - vfree(table_com);
> - table_com = NULL;
> - table_dec = NULL;
> -}
> -
> -int
> -l1oip_4bit_alloc(int ulaw)
> -{
> - int i1, i2, c, sample;
> -
> - /* in case, it is called again */
> - if (table_dec)
> - return 0;
> -
> - /* alloc conversion tables */
> - table_com = vzalloc(65536);
> - table_dec = vzalloc(512);
> - if (!table_com || !table_dec) {
> - l1oip_4bit_free();
> - return -ENOMEM;
> - }
> - /* generate compression table */
> - i1 = 0;
> - while (i1 < 256) {
> - if (ulaw)
> - c = ulaw_to_4bit[i1];
> - else
> - c = alaw_to_4bit[i1];
> - i2 = 0;
> - while (i2 < 256) {
> - table_com[(i1 << 8) | i2] |= (c << 4);
> - table_com[(i2 << 8) | i1] |= c;
> - i2++;
> - }
> - i1++;
> - }
> -
> - /* generate decompression table */
> - i1 = 0;
> - while (i1 < 16) {
> - if (ulaw)
> - sample = _4bit_to_ulaw[i1];
> - else
> - sample = _4bit_to_alaw[i1];
> - i2 = 0;
> - while (i2 < 16) {
> - table_dec[(i1 << 4) | i2] |= (sample << 8);
> - table_dec[(i2 << 4) | i1] |= sample;
> - i2++;
> - }
> - i1++;
> - }
> -
> - return 0;
> -}
> diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c
> deleted file mode 100644
> index 6866a0d6b382..000000000000
> --- a/drivers/isdn/mISDN/l1oip_core.c
> +++ /dev/null
> @@ -1,1505 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-or-later
> -/*
> -
> - * l1oip.c low level driver for tunneling layer 1 over IP
> - *
> - * NOTE: It is not compatible with TDMoIP nor "ISDN over IP".
> - *
> - * Author Andreas Eversberg (jolly@eversberg.eu)
> - */
> -
> -/* module parameters:
> - * type:
> - Value 1 = BRI
> - Value 2 = PRI
> - Value 3 = BRI (multi channel frame, not supported yet)
> - Value 4 = PRI (multi channel frame, not supported yet)
> - A multi channel frame reduces overhead to a single frame for all
> - b-channels, but increases delay.
> - (NOTE: Multi channel frames are not implemented yet.)
> -
> - * codec:
> - Value 0 = transparent (default)
> - Value 1 = transfer ALAW
> - Value 2 = transfer ULAW
> - Value 3 = transfer generic 4 bit compression.
> -
> - * ulaw:
> - 0 = we use a-Law (default)
> - 1 = we use u-Law
> -
> - * limit:
> - limitation of B-channels to control bandwidth (1...126)
> - BRI: 1 or 2
> - PRI: 1-30, 31-126 (126, because dchannel ist not counted here)
> - Also limited ressources are used for stack, resulting in less channels.
> - It is possible to have more channels than 30 in PRI mode, this must
> - be supported by the application.
> -
> - * ip:
> - byte representation of remote ip address (127.0.0.1 -> 127,0,0,1)
> - If not given or four 0, no remote address is set.
> - For multiple interfaces, concat ip addresses. (127,0,0,1,127,0,0,1)
> -
> - * port:
> - port number (local interface)
> - If not given or 0, port 931 is used for fist instance, 932 for next...
> - For multiple interfaces, different ports must be given.
> -
> - * remoteport:
> - port number (remote interface)
> - If not given or 0, remote port equals local port
> - For multiple interfaces on equal sites, different ports must be given.
> -
> - * ondemand:
> - 0 = fixed (always transmit packets, even when remote side timed out)
> - 1 = on demand (only transmit packets, when remote side is detected)
> - the default is 0
> - NOTE: ID must also be set for on demand.
> -
> - * id:
> - optional value to identify frames. This value must be equal on both
> - peers and should be random. If omitted or 0, no ID is transmitted.
> -
> - * debug:
> - NOTE: only one debug value must be given for all cards
> - enable debugging (see l1oip.h for debug options)
> -
> -
> - Special mISDN controls:
> -
> - op = MISDN_CTRL_SETPEER*
> - p1 = bytes 0-3 : remote IP address in network order (left element first)
> - p2 = bytes 1-2 : remote port in network order (high byte first)
> - optional:
> - p2 = bytes 3-4 : local port in network order (high byte first)
> -
> - op = MISDN_CTRL_UNSETPEER*
> -
> - * Use l1oipctrl for comfortable setting or removing ip address.
> - (Layer 1 Over IP CTRL)
> -
> -
> - L1oIP-Protocol
> - --------------
> -
> - Frame Header:
> -
> - 7 6 5 4 3 2 1 0
> - +---------------+
> - |Ver|T|I|Coding |
> - +---------------+
> - | ID byte 3 * |
> - +---------------+
> - | ID byte 2 * |
> - +---------------+
> - | ID byte 1 * |
> - +---------------+
> - | ID byte 0 * |
> - +---------------+
> - |M| Channel |
> - +---------------+
> - | Length * |
> - +---------------+
> - | Time Base MSB |
> - +---------------+
> - | Time Base LSB |
> - +---------------+
> - | Data.... |
> -
> - ...
> -
> - | |
> - +---------------+
> - |M| Channel |
> - +---------------+
> - | Length * |
> - +---------------+
> - | Time Base MSB |
> - +---------------+
> - | Time Base LSB |
> - +---------------+
> - | Data.... |
> -
> - ...
> -
> -
> - * Only included in some cases.
> -
> - - Ver = Version
> - If version is missmatch, the frame must be ignored.
> -
> - - T = Type of interface
> - Must be 0 for S0 or 1 for E1.
> -
> - - I = Id present
> - If bit is set, four ID bytes are included in frame.
> -
> - - ID = Connection ID
> - Additional ID to prevent Denial of Service attacs. Also it prevents hijacking
> - connections with dynamic IP. The ID should be random and must not be 0.
> -
> - - Coding = Type of codec
> - Must be 0 for no transcoding. Also for D-channel and other HDLC frames.
> - 1 and 2 are reserved for explicitly use of a-LAW or u-LAW codec.
> - 3 is used for generic table compressor.
> -
> - - M = More channels to come. If this flag is 1, the following byte contains
> - the length of the channel data. After the data block, the next channel will
> - be defined. The flag for the last channel block (or if only one channel is
> - transmitted), must be 0 and no length is given.
> -
> - - Channel = Channel number
> - 0 reserved
> - 1-3 channel data for S0 (3 is D-channel)
> - 1-31 channel data for E1 (16 is D-channel)
> - 32-127 channel data for extended E1 (16 is D-channel)
> -
> - - The length is used if the M-flag is 1. It is used to find the next channel
> - inside frame.
> - NOTE: A value of 0 equals 256 bytes of data.
> - -> For larger data blocks, a single frame must be used.
> - -> For larger streams, a single frame or multiple blocks with same channel ID
> - must be used.
> -
> - - Time Base = Timestamp of first sample in frame
> - The "Time Base" is used to rearange packets and to detect packet loss.
> - The 16 bits are sent in network order (MSB first) and count 1/8000 th of a
> - second. This causes a wrap around each 8,192 seconds. There is no requirement
> - for the initial "Time Base", but 0 should be used for the first packet.
> - In case of HDLC data, this timestamp counts the packet or byte number.
> -
> -
> - Two Timers:
> -
> - After initialisation, a timer of 15 seconds is started. Whenever a packet is
> - transmitted, the timer is reset to 15 seconds again. If the timer expires, an
> - empty packet is transmitted. This keep the connection alive.
> -
> - When a valid packet is received, a timer 65 seconds is started. The interface
> - become ACTIVE. If the timer expires, the interface becomes INACTIVE.
> -
> -
> - Dynamic IP handling:
> -
> - To allow dynamic IP, the ID must be non 0. In this case, any packet with the
> - correct port number and ID will be accepted. If the remote side changes its IP
> - the new IP is used for all transmitted packets until it changes again.
> -
> -
> - On Demand:
> -
> - If the ondemand parameter is given, the remote IP is set to 0 on timeout.
> - This will stop keepalive traffic to remote. If the remote is online again,
> - traffic will continue to the remote address. This is useful for road warriors.
> - This feature only works with ID set, otherwhise it is highly unsecure.
> -
> -
> - Socket and Thread
> - -----------------
> -
> - The complete socket opening and closing is done by a thread.
> - When the thread opened a socket, the hc->socket descriptor is set. Whenever a
> - packet shall be sent to the socket, the hc->socket must be checked whether not
> - NULL. To prevent change in socket descriptor, the hc->socket_lock must be used.
> - To change the socket, a recall of l1oip_socket_open() will safely kill the
> - socket process and create a new one.
> -
> -*/
> -
> -#define L1OIP_VERSION 0 /* 0...3 */
> -
> -#include <linux/module.h>
> -#include <linux/delay.h>
> -#include <linux/mISDNif.h>
> -#include <linux/mISDNhw.h>
> -#include <linux/mISDNdsp.h>
> -#include <linux/init.h>
> -#include <linux/in.h>
> -#include <linux/inet.h>
> -#include <linux/workqueue.h>
> -#include <linux/kthread.h>
> -#include <linux/slab.h>
> -#include <linux/sched/signal.h>
> -
> -#include <net/sock.h>
> -#include "core.h"
> -#include "l1oip.h"
> -
> -static const char *l1oip_revision = "2.00";
> -
> -static int l1oip_cnt;
> -static DEFINE_SPINLOCK(l1oip_lock);
> -static LIST_HEAD(l1oip_ilist);
> -
> -#define MAX_CARDS 16
> -static u_int type[MAX_CARDS];
> -static u_int codec[MAX_CARDS];
> -static u_int ip[MAX_CARDS * 4];
> -static u_int port[MAX_CARDS];
> -static u_int remoteport[MAX_CARDS];
> -static u_int ondemand[MAX_CARDS];
> -static u_int limit[MAX_CARDS];
> -static u_int id[MAX_CARDS];
> -static int debug;
> -static int ulaw;
> -
> -MODULE_AUTHOR("Andreas Eversberg");
> -MODULE_DESCRIPTION("mISDN driver for tunneling layer 1 over IP");
> -MODULE_LICENSE("GPL");
> -module_param_array(type, uint, NULL, S_IRUGO | S_IWUSR);
> -module_param_array(codec, uint, NULL, S_IRUGO | S_IWUSR);
> -module_param_array(ip, uint, NULL, S_IRUGO | S_IWUSR);
> -module_param_array(port, uint, NULL, S_IRUGO | S_IWUSR);
> -module_param_array(remoteport, uint, NULL, S_IRUGO | S_IWUSR);
> -module_param_array(ondemand, uint, NULL, S_IRUGO | S_IWUSR);
> -module_param_array(limit, uint, NULL, S_IRUGO | S_IWUSR);
> -module_param_array(id, uint, NULL, S_IRUGO | S_IWUSR);
> -module_param(ulaw, uint, S_IRUGO | S_IWUSR);
> -module_param(debug, uint, S_IRUGO | S_IWUSR);
> -
> -/*
> - * send a frame via socket, if open and restart timer
> - */
> -static int
> -l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask,
> - u16 timebase, u8 *buf, int len)
> -{
> - u8 *p;
> - u8 frame[MAX_DFRAME_LEN_L1 + 32];
> - struct socket *socket = NULL;
> -
> - if (debug & DEBUG_L1OIP_MSG)
> - printk(KERN_DEBUG "%s: sending data to socket (len = %d)\n",
> - __func__, len);
> -
> - p = frame;
> -
> - /* restart timer */
> - if (time_before(hc->keep_tl.expires, jiffies + 5 * HZ) && !hc->shutdown)
> - mod_timer(&hc->keep_tl, jiffies + L1OIP_KEEPALIVE * HZ);
> - else
> - hc->keep_tl.expires = jiffies + L1OIP_KEEPALIVE * HZ;
> -
> - if (debug & DEBUG_L1OIP_MSG)
> - printk(KERN_DEBUG "%s: resetting timer\n", __func__);
> -
> - /* drop if we have no remote ip or port */
> - if (!hc->sin_remote.sin_addr.s_addr || !hc->sin_remote.sin_port) {
> - if (debug & DEBUG_L1OIP_MSG)
> - printk(KERN_DEBUG "%s: dropping frame, because remote "
> - "IP is not set.\n", __func__);
> - return len;
> - }
> -
> - /* assemble frame */
> - *p++ = (L1OIP_VERSION << 6) /* version and coding */
> - | (hc->pri ? 0x20 : 0x00) /* type */
> - | (hc->id ? 0x10 : 0x00) /* id */
> - | localcodec;
> - if (hc->id) {
> - *p++ = hc->id >> 24; /* id */
> - *p++ = hc->id >> 16;
> - *p++ = hc->id >> 8;
> - *p++ = hc->id;
> - }
> - *p++ = 0x00 + channel; /* m-flag, channel */
> - *p++ = timebase >> 8; /* time base */
> - *p++ = timebase;
> -
> - if (buf && len) { /* add data to frame */
> - if (localcodec == 1 && ulaw)
> - l1oip_ulaw_to_alaw(buf, len, p);
> - else if (localcodec == 2 && !ulaw)
> - l1oip_alaw_to_ulaw(buf, len, p);
> - else if (localcodec == 3)
> - len = l1oip_law_to_4bit(buf, len, p,
> - &hc->chan[channel].codecstate);
> - else
> - memcpy(p, buf, len);
> - }
> - len += p - frame;
> -
> - /* check for socket in safe condition */
> - spin_lock(&hc->socket_lock);
> - if (!hc->socket) {
> - spin_unlock(&hc->socket_lock);
> - return 0;
> - }
> - /* seize socket */
> - socket = hc->socket;
> - hc->socket = NULL;
> - spin_unlock(&hc->socket_lock);
> - /* send packet */
> - if (debug & DEBUG_L1OIP_MSG)
> - printk(KERN_DEBUG "%s: sending packet to socket (len "
> - "= %d)\n", __func__, len);
> - hc->sendiov.iov_base = frame;
> - hc->sendiov.iov_len = len;
> - len = kernel_sendmsg(socket, &hc->sendmsg, &hc->sendiov, 1, len);
> - /* give socket back */
> - hc->socket = socket; /* no locking required */
> -
> - return len;
> -}
> -
> -
> -/*
> - * receive channel data from socket
> - */
> -static void
> -l1oip_socket_recv(struct l1oip *hc, u8 remotecodec, u8 channel, u16 timebase,
> - u8 *buf, int len)
> -{
> - struct sk_buff *nskb;
> - struct bchannel *bch;
> - struct dchannel *dch;
> - u8 *p;
> - u32 rx_counter;
> -
> - if (len == 0) {
> - if (debug & DEBUG_L1OIP_MSG)
> - printk(KERN_DEBUG "%s: received empty keepalive data, "
> - "ignoring\n", __func__);
> - return;
> - }
> -
> - if (debug & DEBUG_L1OIP_MSG)
> - printk(KERN_DEBUG "%s: received data, sending to mISDN (%d)\n",
> - __func__, len);
> -
> - if (channel < 1 || channel > 127) {
> - printk(KERN_WARNING "%s: packet error - channel %d out of "
> - "range\n", __func__, channel);
> - return;
> - }
> - dch = hc->chan[channel].dch;
> - bch = hc->chan[channel].bch;
> - if (!dch && !bch) {
> - printk(KERN_WARNING "%s: packet error - channel %d not in "
> - "stack\n", __func__, channel);
> - return;
> - }
> -
> - /* prepare message */
> - nskb = mI_alloc_skb((remotecodec == 3) ? (len << 1) : len, GFP_ATOMIC);
> - if (!nskb) {
> - printk(KERN_ERR "%s: No mem for skb.\n", __func__);
> - return;
> - }
> - p = skb_put(nskb, (remotecodec == 3) ? (len << 1) : len);
> -
> - if (remotecodec == 1 && ulaw)
> - l1oip_alaw_to_ulaw(buf, len, p);
> - else if (remotecodec == 2 && !ulaw)
> - l1oip_ulaw_to_alaw(buf, len, p);
> - else if (remotecodec == 3)
> - len = l1oip_4bit_to_law(buf, len, p);
> - else
> - memcpy(p, buf, len);
> -
> - /* send message up */
> - if (dch && len >= 2) {
> - dch->rx_skb = nskb;
> - recv_Dchannel(dch);
> - }
> - if (bch) {
> - /* expand 16 bit sequence number to 32 bit sequence number */
> - rx_counter = hc->chan[channel].rx_counter;
> - if (((s16)(timebase - rx_counter)) >= 0) {
> - /* time has changed forward */
> - if (timebase >= (rx_counter & 0xffff))
> - rx_counter =
> - (rx_counter & 0xffff0000) | timebase;
> - else
> - rx_counter = ((rx_counter & 0xffff0000) + 0x10000)
> - | timebase;
> - } else {
> - /* time has changed backwards */
> - if (timebase < (rx_counter & 0xffff))
> - rx_counter =
> - (rx_counter & 0xffff0000) | timebase;
> - else
> - rx_counter = ((rx_counter & 0xffff0000) - 0x10000)
> - | timebase;
> - }
> - hc->chan[channel].rx_counter = rx_counter;
> -
> -#ifdef REORDER_DEBUG
> - if (hc->chan[channel].disorder_flag) {
> - swap(hc->chan[channel].disorder_skb, nskb);
> - swap(hc->chan[channel].disorder_cnt, rx_counter);
> - }
> - hc->chan[channel].disorder_flag ^= 1;
> - if (nskb)
> -#endif
> - queue_ch_frame(&bch->ch, PH_DATA_IND, rx_counter, nskb);
> - }
> -}
> -
> -
> -/*
> - * parse frame and extract channel data
> - */
> -static void
> -l1oip_socket_parse(struct l1oip *hc, struct sockaddr_in *sin, u8 *buf, int len)
> -{
> - u32 packet_id;
> - u8 channel;
> - u8 remotecodec;
> - u16 timebase;
> - int m, mlen;
> - int len_start = len; /* initial frame length */
> - struct dchannel *dch = hc->chan[hc->d_idx].dch;
> -
> - if (debug & DEBUG_L1OIP_MSG)
> - printk(KERN_DEBUG "%s: received frame, parsing... (%d)\n",
> - __func__, len);
> -
> - /* check length */
> - if (len < 1 + 1 + 2) {
> - printk(KERN_WARNING "%s: packet error - length %d below "
> - "4 bytes\n", __func__, len);
> - return;
> - }
> -
> - /* check version */
> - if (((*buf) >> 6) != L1OIP_VERSION) {
> - printk(KERN_WARNING "%s: packet error - unknown version %d\n",
> - __func__, buf[0]>>6);
> - return;
> - }
> -
> - /* check type */
> - if (((*buf) & 0x20) && !hc->pri) {
> - printk(KERN_WARNING "%s: packet error - received E1 packet "
> - "on S0 interface\n", __func__);
> - return;
> - }
> - if (!((*buf) & 0x20) && hc->pri) {
> - printk(KERN_WARNING "%s: packet error - received S0 packet "
> - "on E1 interface\n", __func__);
> - return;
> - }
> -
> - /* get id flag */
> - packet_id = (*buf >> 4) & 1;
> -
> - /* check coding */
> - remotecodec = (*buf) & 0x0f;
> - if (remotecodec > 3) {
> - printk(KERN_WARNING "%s: packet error - remotecodec %d "
> - "unsupported\n", __func__, remotecodec);
> - return;
> - }
> - buf++;
> - len--;
> -
> - /* check packet_id */
> - if (packet_id) {
> - if (!hc->id) {
> - printk(KERN_WARNING "%s: packet error - packet has id "
> - "0x%x, but we have not\n", __func__, packet_id);
> - return;
> - }
> - if (len < 4) {
> - printk(KERN_WARNING "%s: packet error - packet too "
> - "short for ID value\n", __func__);
> - return;
> - }
> - packet_id = (*buf++) << 24;
> - packet_id += (*buf++) << 16;
> - packet_id += (*buf++) << 8;
> - packet_id += (*buf++);
> - len -= 4;
> -
> - if (packet_id != hc->id) {
> - printk(KERN_WARNING "%s: packet error - ID mismatch, "
> - "got 0x%x, we 0x%x\n",
> - __func__, packet_id, hc->id);
> - return;
> - }
> - } else {
> - if (hc->id) {
> - printk(KERN_WARNING "%s: packet error - packet has no "
> - "ID, but we have\n", __func__);
> - return;
> - }
> - }
> -
> -multiframe:
> - if (len < 1) {
> - printk(KERN_WARNING "%s: packet error - packet too short, "
> - "channel expected at position %d.\n",
> - __func__, len-len_start + 1);
> - return;
> - }
> -
> - /* get channel and multiframe flag */
> - channel = *buf & 0x7f;
> - m = *buf >> 7;
> - buf++;
> - len--;
> -
> - /* check length on multiframe */
> - if (m) {
> - if (len < 1) {
> - printk(KERN_WARNING "%s: packet error - packet too "
> - "short, length expected at position %d.\n",
> - __func__, len_start - len - 1);
> - return;
> - }
> -
> - mlen = *buf++;
> - len--;
> - if (mlen == 0)
> - mlen = 256;
> - if (len < mlen + 3) {
> - printk(KERN_WARNING "%s: packet error - length %d at "
> - "position %d exceeds total length %d.\n",
> - __func__, mlen, len_start-len - 1, len_start);
> - return;
> - }
> - if (len == mlen + 3) {
> - printk(KERN_WARNING "%s: packet error - length %d at "
> - "position %d will not allow additional "
> - "packet.\n",
> - __func__, mlen, len_start-len + 1);
> - return;
> - }
> - } else
> - mlen = len - 2; /* single frame, subtract timebase */
> -
> - if (len < 2) {
> - printk(KERN_WARNING "%s: packet error - packet too short, time "
> - "base expected at position %d.\n",
> - __func__, len-len_start + 1);
> - return;
> - }
> -
> - /* get time base */
> - timebase = (*buf++) << 8;
> - timebase |= (*buf++);
> - len -= 2;
> -
> - /* if inactive, we send up a PH_ACTIVATE and activate */
> - if (!test_bit(FLG_ACTIVE, &dch->Flags)) {
> - if (debug & (DEBUG_L1OIP_MSG | DEBUG_L1OIP_SOCKET))
> - printk(KERN_DEBUG "%s: interface become active due to "
> - "received packet\n", __func__);
> - test_and_set_bit(FLG_ACTIVE, &dch->Flags);
> - _queue_data(&dch->dev.D, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
> - NULL, GFP_ATOMIC);
> - }
> -
> - /* distribute packet */
> - l1oip_socket_recv(hc, remotecodec, channel, timebase, buf, mlen);
> - buf += mlen;
> - len -= mlen;
> -
> - /* multiframe */
> - if (m)
> - goto multiframe;
> -
> - /* restart timer */
> - if ((time_before(hc->timeout_tl.expires, jiffies + 5 * HZ) ||
> - !hc->timeout_on) &&
> - !hc->shutdown) {
> - hc->timeout_on = 1;
> - mod_timer(&hc->timeout_tl, jiffies + L1OIP_TIMEOUT * HZ);
> - } else /* only adjust timer */
> - hc->timeout_tl.expires = jiffies + L1OIP_TIMEOUT * HZ;
> -
> - /* if ip or source port changes */
> - if ((hc->sin_remote.sin_addr.s_addr != sin->sin_addr.s_addr)
> - || (hc->sin_remote.sin_port != sin->sin_port)) {
> - if (debug & DEBUG_L1OIP_SOCKET)
> - printk(KERN_DEBUG "%s: remote address changes from "
> - "0x%08x to 0x%08x (port %d to %d)\n", __func__,
> - ntohl(hc->sin_remote.sin_addr.s_addr),
> - ntohl(sin->sin_addr.s_addr),
> - ntohs(hc->sin_remote.sin_port),
> - ntohs(sin->sin_port));
> - hc->sin_remote.sin_addr.s_addr = sin->sin_addr.s_addr;
> - hc->sin_remote.sin_port = sin->sin_port;
> - }
> -}
> -
> -
> -/*
> - * socket stuff
> - */
> -static int
> -l1oip_socket_thread(void *data)
> -{
> - struct l1oip *hc = (struct l1oip *)data;
> - int ret = 0;
> - struct sockaddr_in sin_rx;
> - struct kvec iov;
> - struct msghdr msg = {.msg_name = &sin_rx,
> - .msg_namelen = sizeof(sin_rx)};
> - unsigned char *recvbuf;
> - size_t recvbuf_size = 1500;
> - int recvlen;
> - struct socket *socket = NULL;
> - DECLARE_COMPLETION_ONSTACK(wait);
> -
> - /* allocate buffer memory */
> - recvbuf = kmalloc(recvbuf_size, GFP_KERNEL);
> - if (!recvbuf) {
> - printk(KERN_ERR "%s: Failed to alloc recvbuf.\n", __func__);
> - ret = -ENOMEM;
> - goto fail;
> - }
> -
> - iov.iov_base = recvbuf;
> - iov.iov_len = recvbuf_size;
> -
> - /* make daemon */
> - allow_signal(SIGTERM);
> -
> - /* create socket */
> - if (sock_create(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &socket)) {
> - printk(KERN_ERR "%s: Failed to create socket.\n", __func__);
> - ret = -EIO;
> - goto fail;
> - }
> -
> - /* set incoming address */
> - hc->sin_local.sin_family = AF_INET;
> - hc->sin_local.sin_addr.s_addr = INADDR_ANY;
> - hc->sin_local.sin_port = htons((unsigned short)hc->localport);
> -
> - /* set outgoing address */
> - hc->sin_remote.sin_family = AF_INET;
> - hc->sin_remote.sin_addr.s_addr = htonl(hc->remoteip);
> - hc->sin_remote.sin_port = htons((unsigned short)hc->remoteport);
> -
> - /* bind to incoming port */
> - if (socket->ops->bind(socket, (struct sockaddr_unsized *)&hc->sin_local,
> - sizeof(hc->sin_local))) {
> - printk(KERN_ERR "%s: Failed to bind socket to port %d.\n",
> - __func__, hc->localport);
> - ret = -EINVAL;
> - goto fail;
> - }
> -
> - /* check sk */
> - if (socket->sk == NULL) {
> - printk(KERN_ERR "%s: socket->sk == NULL\n", __func__);
> - ret = -EIO;
> - goto fail;
> - }
> -
> - /* build send message */
> - hc->sendmsg.msg_name = &hc->sin_remote;
> - hc->sendmsg.msg_namelen = sizeof(hc->sin_remote);
> - hc->sendmsg.msg_control = NULL;
> - hc->sendmsg.msg_controllen = 0;
> -
> - /* give away socket */
> - spin_lock(&hc->socket_lock);
> - hc->socket = socket;
> - spin_unlock(&hc->socket_lock);
> -
> - /* read loop */
> - if (debug & DEBUG_L1OIP_SOCKET)
> - printk(KERN_DEBUG "%s: socket created and open\n",
> - __func__);
> - while (!signal_pending(current)) {
> - iov_iter_kvec(&msg.msg_iter, ITER_DEST, &iov, 1, recvbuf_size);
> - recvlen = sock_recvmsg(socket, &msg, 0);
> - if (recvlen > 0) {
> - l1oip_socket_parse(hc, &sin_rx, recvbuf, recvlen);
> - } else {
> - if (debug & DEBUG_L1OIP_SOCKET)
> - printk(KERN_WARNING
> - "%s: broken pipe on socket\n", __func__);
> - }
> - }
> -
> - /* get socket back, check first if in use, maybe by send function */
> - spin_lock(&hc->socket_lock);
> - /* if hc->socket is NULL, it is in use until it is given back */
> - while (!hc->socket) {
> - spin_unlock(&hc->socket_lock);
> - schedule_timeout(HZ / 10);
> - spin_lock(&hc->socket_lock);
> - }
> - hc->socket = NULL;
> - spin_unlock(&hc->socket_lock);
> -
> - if (debug & DEBUG_L1OIP_SOCKET)
> - printk(KERN_DEBUG "%s: socket thread terminating\n",
> - __func__);
> -
> -fail:
> - /* free recvbuf */
> - kfree(recvbuf);
> -
> - /* close socket */
> - if (socket)
> - sock_release(socket);
> -
> - /* if we got killed, signal completion */
> - complete(&hc->socket_complete);
> - hc->socket_thread = NULL; /* show termination of thread */
> -
> - if (debug & DEBUG_L1OIP_SOCKET)
> - printk(KERN_DEBUG "%s: socket thread terminated\n",
> - __func__);
> - return ret;
> -}
> -
> -static void
> -l1oip_socket_close(struct l1oip *hc)
> -{
> - struct dchannel *dch = hc->chan[hc->d_idx].dch;
> -
> - /* kill thread */
> - if (hc->socket_thread) {
> - if (debug & DEBUG_L1OIP_SOCKET)
> - printk(KERN_DEBUG "%s: socket thread exists, "
> - "killing...\n", __func__);
> - send_sig(SIGTERM, hc->socket_thread, 0);
> - wait_for_completion(&hc->socket_complete);
> - }
> -
> - /* if active, we send up a PH_DEACTIVATE and deactivate */
> - if (test_bit(FLG_ACTIVE, &dch->Flags)) {
> - if (debug & (DEBUG_L1OIP_MSG | DEBUG_L1OIP_SOCKET))
> - printk(KERN_DEBUG "%s: interface become deactivated "
> - "due to timeout\n", __func__);
> - test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
> - _queue_data(&dch->dev.D, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
> - NULL, GFP_ATOMIC);
> - }
> -}
> -
> -static int
> -l1oip_socket_open(struct l1oip *hc)
> -{
> - /* in case of reopen, we need to close first */
> - l1oip_socket_close(hc);
> -
> - init_completion(&hc->socket_complete);
> -
> - /* create receive process */
> - hc->socket_thread = kthread_run(l1oip_socket_thread, hc, "l1oip_%s",
> - hc->name);
> - if (IS_ERR(hc->socket_thread)) {
> - int err = PTR_ERR(hc->socket_thread);
> - printk(KERN_ERR "%s: Failed (%d) to create socket process.\n",
> - __func__, err);
> - hc->socket_thread = NULL;
> - sock_release(hc->socket);
> - return err;
> - }
> - if (debug & DEBUG_L1OIP_SOCKET)
> - printk(KERN_DEBUG "%s: socket thread created\n", __func__);
> -
> - return 0;
> -}
> -
> -
> -static void
> -l1oip_send_bh(struct work_struct *work)
> -{
> - struct l1oip *hc = container_of(work, struct l1oip, workq);
> -
> - if (debug & (DEBUG_L1OIP_MSG | DEBUG_L1OIP_SOCKET))
> - printk(KERN_DEBUG "%s: keepalive timer expired, sending empty "
> - "frame on dchannel\n", __func__);
> -
> - /* send an empty l1oip frame at D-channel */
> - l1oip_socket_send(hc, 0, hc->d_idx, 0, 0, NULL, 0);
> -}
> -
> -
> -/*
> - * timer stuff
> - */
> -static void
> -l1oip_keepalive(struct timer_list *t)
> -{
> - struct l1oip *hc = timer_container_of(hc, t, keep_tl);
> -
> - schedule_work(&hc->workq);
> -}
> -
> -static void
> -l1oip_timeout(struct timer_list *t)
> -{
> - struct l1oip *hc = timer_container_of(hc, t,
> - timeout_tl);
> - struct dchannel *dch = hc->chan[hc->d_idx].dch;
> -
> - if (debug & DEBUG_L1OIP_MSG)
> - printk(KERN_DEBUG "%s: timeout timer expired, turn layer one "
> - "down.\n", __func__);
> -
> - hc->timeout_on = 0; /* state that timer must be initialized next time */
> -
> - /* if timeout, we send up a PH_DEACTIVATE and deactivate */
> - if (test_bit(FLG_ACTIVE, &dch->Flags)) {
> - if (debug & (DEBUG_L1OIP_MSG | DEBUG_L1OIP_SOCKET))
> - printk(KERN_DEBUG "%s: interface become deactivated "
> - "due to timeout\n", __func__);
> - test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
> - _queue_data(&dch->dev.D, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
> - NULL, GFP_ATOMIC);
> - }
> -
> - /* if we have ondemand set, we remove ip address */
> - if (hc->ondemand) {
> - if (debug & DEBUG_L1OIP_MSG)
> - printk(KERN_DEBUG "%s: on demand causes ip address to "
> - "be removed\n", __func__);
> - hc->sin_remote.sin_addr.s_addr = 0;
> - }
> -}
> -
> -
> -/*
> - * message handling
> - */
> -static int
> -handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
> -{
> - struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
> - struct dchannel *dch = container_of(dev, struct dchannel, dev);
> - struct l1oip *hc = dch->hw;
> - struct mISDNhead *hh = mISDN_HEAD_P(skb);
> - int ret = -EINVAL;
> - int l, ll;
> - unsigned char *p;
> -
> - switch (hh->prim) {
> - case PH_DATA_REQ:
> - if (skb->len < 1) {
> - printk(KERN_WARNING "%s: skb too small\n",
> - __func__);
> - break;
> - }
> - if (skb->len > MAX_DFRAME_LEN_L1 || skb->len > L1OIP_MAX_LEN) {
> - printk(KERN_WARNING "%s: skb too large\n",
> - __func__);
> - break;
> - }
> - /* send frame */
> - p = skb->data;
> - l = skb->len;
> - while (l) {
> - /*
> - * This is technically bounded by L1OIP_MAX_PERFRAME but
> - * MAX_DFRAME_LEN_L1 < L1OIP_MAX_PERFRAME
> - */
> - ll = (l < MAX_DFRAME_LEN_L1) ? l : MAX_DFRAME_LEN_L1;
> - l1oip_socket_send(hc, 0, dch->slot, 0,
> - hc->chan[dch->slot].tx_counter++, p, ll);
> - p += ll;
> - l -= ll;
> - }
> - skb_trim(skb, 0);
> - queue_ch_frame(ch, PH_DATA_CNF, hh->id, skb);
> - return 0;
> - case PH_ACTIVATE_REQ:
> - if (debug & (DEBUG_L1OIP_MSG | DEBUG_L1OIP_SOCKET))
> - printk(KERN_DEBUG "%s: PH_ACTIVATE channel %d (1..%d)\n"
> - , __func__, dch->slot, hc->b_num + 1);
> - skb_trim(skb, 0);
> - if (test_bit(FLG_ACTIVE, &dch->Flags))
> - queue_ch_frame(ch, PH_ACTIVATE_IND, hh->id, skb);
> - else
> - queue_ch_frame(ch, PH_DEACTIVATE_IND, hh->id, skb);
> - return 0;
> - case PH_DEACTIVATE_REQ:
> - if (debug & (DEBUG_L1OIP_MSG | DEBUG_L1OIP_SOCKET))
> - printk(KERN_DEBUG "%s: PH_DEACTIVATE channel %d "
> - "(1..%d)\n", __func__, dch->slot,
> - hc->b_num + 1);
> - skb_trim(skb, 0);
> - if (test_bit(FLG_ACTIVE, &dch->Flags))
> - queue_ch_frame(ch, PH_ACTIVATE_IND, hh->id, skb);
> - else
> - queue_ch_frame(ch, PH_DEACTIVATE_IND, hh->id, skb);
> - return 0;
> - }
> - if (!ret)
> - dev_kfree_skb(skb);
> - return ret;
> -}
> -
> -static int
> -channel_dctrl(struct dchannel *dch, struct mISDN_ctrl_req *cq)
> -{
> - int ret = 0;
> - struct l1oip *hc = dch->hw;
> -
> - switch (cq->op) {
> - case MISDN_CTRL_GETOP:
> - cq->op = MISDN_CTRL_SETPEER | MISDN_CTRL_UNSETPEER
> - | MISDN_CTRL_GETPEER;
> - break;
> - case MISDN_CTRL_SETPEER:
> - hc->remoteip = (u32)cq->p1;
> - hc->remoteport = cq->p2 & 0xffff;
> - hc->localport = cq->p2 >> 16;
> - if (!hc->remoteport)
> - hc->remoteport = hc->localport;
> - if (debug & DEBUG_L1OIP_SOCKET)
> - printk(KERN_DEBUG "%s: got new ip address from user "
> - "space.\n", __func__);
> - l1oip_socket_open(hc);
> - break;
> - case MISDN_CTRL_UNSETPEER:
> - if (debug & DEBUG_L1OIP_SOCKET)
> - printk(KERN_DEBUG "%s: removing ip address.\n",
> - __func__);
> - hc->remoteip = 0;
> - l1oip_socket_open(hc);
> - break;
> - case MISDN_CTRL_GETPEER:
> - if (debug & DEBUG_L1OIP_SOCKET)
> - printk(KERN_DEBUG "%s: getting ip address.\n",
> - __func__);
> - cq->p1 = hc->remoteip;
> - cq->p2 = hc->remoteport | (hc->localport << 16);
> - break;
> - default:
> - printk(KERN_WARNING "%s: unknown Op %x\n",
> - __func__, cq->op);
> - ret = -EINVAL;
> - break;
> - }
> - return ret;
> -}
> -
> -static int
> -open_dchannel(struct l1oip *hc, struct dchannel *dch, struct channel_req *rq)
> -{
> - if (debug & DEBUG_HW_OPEN)
> - printk(KERN_DEBUG "%s: dev(%d) open from %p\n", __func__,
> - dch->dev.id, __builtin_return_address(0));
> - if (rq->protocol == ISDN_P_NONE)
> - return -EINVAL;
> - if ((dch->dev.D.protocol != ISDN_P_NONE) &&
> - (dch->dev.D.protocol != rq->protocol)) {
> - if (debug & DEBUG_HW_OPEN)
> - printk(KERN_WARNING "%s: change protocol %x to %x\n",
> - __func__, dch->dev.D.protocol, rq->protocol);
> - }
> - if (dch->dev.D.protocol != rq->protocol)
> - dch->dev.D.protocol = rq->protocol;
> -
> - if (test_bit(FLG_ACTIVE, &dch->Flags)) {
> - _queue_data(&dch->dev.D, PH_ACTIVATE_IND, MISDN_ID_ANY,
> - 0, NULL, GFP_KERNEL);
> - }
> - rq->ch = &dch->dev.D;
> - if (!try_module_get(THIS_MODULE))
> - printk(KERN_WARNING "%s:cannot get module\n", __func__);
> - return 0;
> -}
> -
> -static int
> -open_bchannel(struct l1oip *hc, struct dchannel *dch, struct channel_req *rq)
> -{
> - struct bchannel *bch;
> - int ch;
> -
> - if (!test_channelmap(rq->adr.channel, dch->dev.channelmap))
> - return -EINVAL;
> - if (rq->protocol == ISDN_P_NONE)
> - return -EINVAL;
> - ch = rq->adr.channel; /* BRI: 1=B1 2=B2 PRI: 1..15,17.. */
> - bch = hc->chan[ch].bch;
> - if (!bch) {
> - printk(KERN_ERR "%s:internal error ch %d has no bch\n",
> - __func__, ch);
> - return -EINVAL;
> - }
> - if (test_and_set_bit(FLG_OPEN, &bch->Flags))
> - return -EBUSY; /* b-channel can be only open once */
> - bch->ch.protocol = rq->protocol;
> - rq->ch = &bch->ch;
> - if (!try_module_get(THIS_MODULE))
> - printk(KERN_WARNING "%s:cannot get module\n", __func__);
> - return 0;
> -}
> -
> -static int
> -l1oip_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
> -{
> - struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
> - struct dchannel *dch = container_of(dev, struct dchannel, dev);
> - struct l1oip *hc = dch->hw;
> - struct channel_req *rq;
> - int err = 0;
> -
> - if (dch->debug & DEBUG_HW)
> - printk(KERN_DEBUG "%s: cmd:%x %p\n",
> - __func__, cmd, arg);
> - switch (cmd) {
> - case OPEN_CHANNEL:
> - rq = arg;
> - switch (rq->protocol) {
> - case ISDN_P_TE_S0:
> - case ISDN_P_NT_S0:
> - if (hc->pri) {
> - err = -EINVAL;
> - break;
> - }
> - err = open_dchannel(hc, dch, rq);
> - break;
> - case ISDN_P_TE_E1:
> - case ISDN_P_NT_E1:
> - if (!hc->pri) {
> - err = -EINVAL;
> - break;
> - }
> - err = open_dchannel(hc, dch, rq);
> - break;
> - default:
> - err = open_bchannel(hc, dch, rq);
> - }
> - break;
> - case CLOSE_CHANNEL:
> - if (debug & DEBUG_HW_OPEN)
> - printk(KERN_DEBUG "%s: dev(%d) close from %p\n",
> - __func__, dch->dev.id,
> - __builtin_return_address(0));
> - module_put(THIS_MODULE);
> - break;
> - case CONTROL_CHANNEL:
> - err = channel_dctrl(dch, arg);
> - break;
> - default:
> - if (dch->debug & DEBUG_HW)
> - printk(KERN_DEBUG "%s: unknown command %x\n",
> - __func__, cmd);
> - err = -EINVAL;
> - }
> - return err;
> -}
> -
> -static int
> -handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb)
> -{
> - struct bchannel *bch = container_of(ch, struct bchannel, ch);
> - struct l1oip *hc = bch->hw;
> - int ret = -EINVAL;
> - struct mISDNhead *hh = mISDN_HEAD_P(skb);
> - int l, ll;
> - unsigned char *p;
> -
> - switch (hh->prim) {
> - case PH_DATA_REQ:
> - if (skb->len <= 0) {
> - printk(KERN_WARNING "%s: skb too small\n",
> - __func__);
> - break;
> - }
> - if (skb->len > MAX_DFRAME_LEN_L1 || skb->len > L1OIP_MAX_LEN) {
> - printk(KERN_WARNING "%s: skb too large\n",
> - __func__);
> - break;
> - }
> - /* check for AIS / ulaw-silence */
> - l = skb->len;
> - if (!memchr_inv(skb->data, 0xff, l)) {
> - if (debug & DEBUG_L1OIP_MSG)
> - printk(KERN_DEBUG "%s: got AIS, not sending, "
> - "but counting\n", __func__);
> - hc->chan[bch->slot].tx_counter += l;
> - skb_trim(skb, 0);
> - queue_ch_frame(ch, PH_DATA_CNF, hh->id, skb);
> - return 0;
> - }
> - /* check for silence */
> - l = skb->len;
> - if (!memchr_inv(skb->data, 0x2a, l)) {
> - if (debug & DEBUG_L1OIP_MSG)
> - printk(KERN_DEBUG "%s: got silence, not sending"
> - ", but counting\n", __func__);
> - hc->chan[bch->slot].tx_counter += l;
> - skb_trim(skb, 0);
> - queue_ch_frame(ch, PH_DATA_CNF, hh->id, skb);
> - return 0;
> - }
> -
> - /* send frame */
> - p = skb->data;
> - l = skb->len;
> - while (l) {
> - /*
> - * This is technically bounded by L1OIP_MAX_PERFRAME but
> - * MAX_DFRAME_LEN_L1 < L1OIP_MAX_PERFRAME
> - */
> - ll = (l < MAX_DFRAME_LEN_L1) ? l : MAX_DFRAME_LEN_L1;
> - l1oip_socket_send(hc, hc->codec, bch->slot, 0,
> - hc->chan[bch->slot].tx_counter, p, ll);
> - hc->chan[bch->slot].tx_counter += ll;
> - p += ll;
> - l -= ll;
> - }
> - skb_trim(skb, 0);
> - queue_ch_frame(ch, PH_DATA_CNF, hh->id, skb);
> - return 0;
> - case PH_ACTIVATE_REQ:
> - if (debug & (DEBUG_L1OIP_MSG | DEBUG_L1OIP_SOCKET))
> - printk(KERN_DEBUG "%s: PH_ACTIVATE channel %d (1..%d)\n"
> - , __func__, bch->slot, hc->b_num + 1);
> - hc->chan[bch->slot].codecstate = 0;
> - test_and_set_bit(FLG_ACTIVE, &bch->Flags);
> - skb_trim(skb, 0);
> - queue_ch_frame(ch, PH_ACTIVATE_IND, hh->id, skb);
> - return 0;
> - case PH_DEACTIVATE_REQ:
> - if (debug & (DEBUG_L1OIP_MSG | DEBUG_L1OIP_SOCKET))
> - printk(KERN_DEBUG "%s: PH_DEACTIVATE channel %d "
> - "(1..%d)\n", __func__, bch->slot,
> - hc->b_num + 1);
> - test_and_clear_bit(FLG_ACTIVE, &bch->Flags);
> - skb_trim(skb, 0);
> - queue_ch_frame(ch, PH_DEACTIVATE_IND, hh->id, skb);
> - return 0;
> - }
> - if (!ret)
> - dev_kfree_skb(skb);
> - return ret;
> -}
> -
> -static int
> -channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
> -{
> - int ret = 0;
> - struct dsp_features *features =
> - (struct dsp_features *)(*((u_long *)&cq->p1));
> -
> - switch (cq->op) {
> - case MISDN_CTRL_GETOP:
> - cq->op = MISDN_CTRL_HW_FEATURES_OP;
> - break;
> - case MISDN_CTRL_HW_FEATURES: /* fill features structure */
> - if (debug & DEBUG_L1OIP_MSG)
> - printk(KERN_DEBUG "%s: HW_FEATURE request\n",
> - __func__);
> - /* create confirm */
> - features->unclocked = 1;
> - features->unordered = 1;
> - break;
> - default:
> - printk(KERN_WARNING "%s: unknown Op %x\n",
> - __func__, cq->op);
> - ret = -EINVAL;
> - break;
> - }
> - return ret;
> -}
> -
> -static int
> -l1oip_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
> -{
> - struct bchannel *bch = container_of(ch, struct bchannel, ch);
> - int err = -EINVAL;
> -
> - if (bch->debug & DEBUG_HW)
> - printk(KERN_DEBUG "%s: cmd:%x %p\n",
> - __func__, cmd, arg);
> - switch (cmd) {
> - case CLOSE_CHANNEL:
> - test_and_clear_bit(FLG_OPEN, &bch->Flags);
> - test_and_clear_bit(FLG_ACTIVE, &bch->Flags);
> - ch->protocol = ISDN_P_NONE;
> - ch->peer = NULL;
> - module_put(THIS_MODULE);
> - err = 0;
> - break;
> - case CONTROL_CHANNEL:
> - err = channel_bctrl(bch, arg);
> - break;
> - default:
> - printk(KERN_WARNING "%s: unknown prim(%x)\n",
> - __func__, cmd);
> - }
> - return err;
> -}
> -
> -
> -/*
> - * cleanup module and stack
> - */
> -static void
> -release_card(struct l1oip *hc)
> -{
> - int ch;
> -
> - hc->shutdown = true;
> -
> - timer_shutdown_sync(&hc->keep_tl);
> - timer_shutdown_sync(&hc->timeout_tl);
> -
> - cancel_work_sync(&hc->workq);
> -
> - if (hc->socket_thread)
> - l1oip_socket_close(hc);
> -
> - if (hc->registered && hc->chan[hc->d_idx].dch)
> - mISDN_unregister_device(&hc->chan[hc->d_idx].dch->dev);
> - for (ch = 0; ch < 128; ch++) {
> - if (hc->chan[ch].dch) {
> - mISDN_freedchannel(hc->chan[ch].dch);
> - kfree(hc->chan[ch].dch);
> - }
> - if (hc->chan[ch].bch) {
> - mISDN_freebchannel(hc->chan[ch].bch);
> - kfree(hc->chan[ch].bch);
> -#ifdef REORDER_DEBUG
> - dev_kfree_skb(hc->chan[ch].disorder_skb);
> -#endif
> - }
> - }
> -
> - spin_lock(&l1oip_lock);
> - list_del(&hc->list);
> - spin_unlock(&l1oip_lock);
> -
> - kfree(hc);
> -}
> -
> -static void
> -l1oip_cleanup(void)
> -{
> - struct l1oip *hc, *next;
> -
> - list_for_each_entry_safe(hc, next, &l1oip_ilist, list)
> - release_card(hc);
> -
> - l1oip_4bit_free();
> -}
> -
> -
> -/*
> - * module and stack init
> - */
> -static int
> -init_card(struct l1oip *hc, int pri, int bundle)
> -{
> - struct dchannel *dch;
> - struct bchannel *bch;
> - int ret;
> - int i, ch;
> -
> - spin_lock_init(&hc->socket_lock);
> - hc->idx = l1oip_cnt;
> - hc->pri = pri;
> - hc->d_idx = pri ? 16 : 3;
> - hc->b_num = pri ? 30 : 2;
> - hc->bundle = bundle;
> - if (hc->pri)
> - sprintf(hc->name, "l1oip-e1.%d", l1oip_cnt + 1);
> - else
> - sprintf(hc->name, "l1oip-s0.%d", l1oip_cnt + 1);
> -
> - switch (codec[l1oip_cnt]) {
> - case 0: /* as is */
> - case 1: /* alaw */
> - case 2: /* ulaw */
> - case 3: /* 4bit */
> - break;
> - default:
> - printk(KERN_ERR "Codec(%d) not supported.\n",
> - codec[l1oip_cnt]);
> - return -EINVAL;
> - }
> - hc->codec = codec[l1oip_cnt];
> - if (debug & DEBUG_L1OIP_INIT)
> - printk(KERN_DEBUG "%s: using codec %d\n",
> - __func__, hc->codec);
> -
> - if (id[l1oip_cnt] == 0) {
> - printk(KERN_WARNING "Warning: No 'id' value given or "
> - "0, this is highly unsecure. Please use 32 "
> - "bit random number 0x...\n");
> - }
> - hc->id = id[l1oip_cnt];
> - if (debug & DEBUG_L1OIP_INIT)
> - printk(KERN_DEBUG "%s: using id 0x%x\n", __func__, hc->id);
> -
> - hc->ondemand = ondemand[l1oip_cnt];
> - if (hc->ondemand && !hc->id) {
> - printk(KERN_ERR "%s: ondemand option only allowed in "
> - "conjunction with non 0 ID\n", __func__);
> - return -EINVAL;
> - }
> -
> - if (limit[l1oip_cnt])
> - hc->b_num = limit[l1oip_cnt];
> - if (!pri && hc->b_num > 2) {
> - printk(KERN_ERR "Maximum limit for BRI interface is 2 "
> - "channels.\n");
> - return -EINVAL;
> - }
> - if (pri && hc->b_num > 126) {
> - printk(KERN_ERR "Maximum limit for PRI interface is 126 "
> - "channels.\n");
> - return -EINVAL;
> - }
> - if (pri && hc->b_num > 30) {
> - printk(KERN_WARNING "Maximum limit for BRI interface is 30 "
> - "channels.\n");
> - printk(KERN_WARNING "Your selection of %d channels must be "
> - "supported by application.\n", hc->limit);
> - }
> -
> - hc->remoteip = ip[l1oip_cnt << 2] << 24
> - | ip[(l1oip_cnt << 2) + 1] << 16
> - | ip[(l1oip_cnt << 2) + 2] << 8
> - | ip[(l1oip_cnt << 2) + 3];
> - hc->localport = port[l1oip_cnt]?:(L1OIP_DEFAULTPORT + l1oip_cnt);
> - if (remoteport[l1oip_cnt])
> - hc->remoteport = remoteport[l1oip_cnt];
> - else
> - hc->remoteport = hc->localport;
> - if (debug & DEBUG_L1OIP_INIT)
> - printk(KERN_DEBUG "%s: using local port %d remote ip "
> - "%d.%d.%d.%d port %d ondemand %d\n", __func__,
> - hc->localport, hc->remoteip >> 24,
> - (hc->remoteip >> 16) & 0xff,
> - (hc->remoteip >> 8) & 0xff, hc->remoteip & 0xff,
> - hc->remoteport, hc->ondemand);
> -
> - dch = kzalloc_obj(struct dchannel);
> - if (!dch)
> - return -ENOMEM;
> - dch->debug = debug;
> - mISDN_initdchannel(dch, MAX_DFRAME_LEN_L1, NULL);
> - dch->hw = hc;
> - if (pri)
> - dch->dev.Dprotocols = (1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1);
> - else
> - dch->dev.Dprotocols = (1 << ISDN_P_TE_S0) | (1 << ISDN_P_NT_S0);
> - dch->dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
> - (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
> - dch->dev.D.send = handle_dmsg;
> - dch->dev.D.ctrl = l1oip_dctrl;
> - dch->dev.nrbchan = hc->b_num;
> - dch->slot = hc->d_idx;
> - hc->chan[hc->d_idx].dch = dch;
> - i = 1;
> - for (ch = 0; ch < dch->dev.nrbchan; ch++) {
> - if (ch == 15)
> - i++;
> - bch = kzalloc_obj(struct bchannel);
> - if (!bch) {
> - printk(KERN_ERR "%s: no memory for bchannel\n",
> - __func__);
> - return -ENOMEM;
> - }
> - bch->nr = i + ch;
> - bch->slot = i + ch;
> - bch->debug = debug;
> - mISDN_initbchannel(bch, MAX_DATA_MEM, 0);
> - bch->hw = hc;
> - bch->ch.send = handle_bmsg;
> - bch->ch.ctrl = l1oip_bctrl;
> - bch->ch.nr = i + ch;
> - list_add(&bch->ch.list, &dch->dev.bchannels);
> - hc->chan[i + ch].bch = bch;
> - set_channelmap(bch->nr, dch->dev.channelmap);
> - }
> - /* TODO: create a parent device for this driver */
> - ret = mISDN_register_device(&dch->dev, NULL, hc->name);
> - if (ret)
> - return ret;
> - hc->registered = 1;
> -
> - if (debug & DEBUG_L1OIP_INIT)
> - printk(KERN_DEBUG "%s: Setting up network card(%d)\n",
> - __func__, l1oip_cnt + 1);
> - ret = l1oip_socket_open(hc);
> - if (ret)
> - return ret;
> -
> - timer_setup(&hc->keep_tl, l1oip_keepalive, 0);
> - hc->keep_tl.expires = jiffies + 2 * HZ; /* two seconds first time */
> - add_timer(&hc->keep_tl);
> -
> - timer_setup(&hc->timeout_tl, l1oip_timeout, 0);
> - hc->timeout_on = 0; /* state that we have timer off */
> -
> - return 0;
> -}
> -
> -static int __init
> -l1oip_init(void)
> -{
> - int pri, bundle;
> - struct l1oip *hc;
> - int ret;
> -
> - printk(KERN_INFO "mISDN: Layer-1-over-IP driver Rev. %s\n",
> - l1oip_revision);
> -
> - if (l1oip_4bit_alloc(ulaw))
> - return -ENOMEM;
> -
> - l1oip_cnt = 0;
> - while (l1oip_cnt < MAX_CARDS && type[l1oip_cnt]) {
> - switch (type[l1oip_cnt] & 0xff) {
> - case 1:
> - pri = 0;
> - bundle = 0;
> - break;
> - case 2:
> - pri = 1;
> - bundle = 0;
> - break;
> - case 3:
> - pri = 0;
> - bundle = 1;
> - break;
> - case 4:
> - pri = 1;
> - bundle = 1;
> - break;
> - default:
> - printk(KERN_ERR "Card type(%d) not supported.\n",
> - type[l1oip_cnt] & 0xff);
> - l1oip_cleanup();
> - return -EINVAL;
> - }
> -
> - if (debug & DEBUG_L1OIP_INIT)
> - printk(KERN_DEBUG "%s: interface %d is %s with %s.\n",
> - __func__, l1oip_cnt, pri ? "PRI" : "BRI",
> - bundle ? "bundled IP packet for all B-channels" :
> - "separate IP packets for every B-channel");
> -
> - hc = kzalloc_obj(struct l1oip, GFP_ATOMIC);
> - if (!hc) {
> - printk(KERN_ERR "No kmem for L1-over-IP driver.\n");
> - l1oip_cleanup();
> - return -ENOMEM;
> - }
> - INIT_WORK(&hc->workq, (void *)l1oip_send_bh);
> -
> - spin_lock(&l1oip_lock);
> - list_add_tail(&hc->list, &l1oip_ilist);
> - spin_unlock(&l1oip_lock);
> -
> - ret = init_card(hc, pri, bundle);
> - if (ret) {
> - l1oip_cleanup();
> - return ret;
> - }
> -
> - l1oip_cnt++;
> - }
> - printk(KERN_INFO "%d virtual devices registered\n", l1oip_cnt);
> - return 0;
> -}
> -
> -module_init(l1oip_init);
> -module_exit(l1oip_cleanup);
> diff --git a/drivers/isdn/mISDN/layer1.c b/drivers/isdn/mISDN/layer1.c
> deleted file mode 100644
> index 3fbc170acf9a..000000000000
> --- a/drivers/isdn/mISDN/layer1.c
> +++ /dev/null
> @@ -1,415 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - *
> - * Author Karsten Keil <kkeil@novell.com>
> - *
> - * Copyright 2008 by Karsten Keil <kkeil@novell.com>
> - */
> -
> -
> -#include <linux/slab.h>
> -#include <linux/module.h>
> -#include <linux/mISDNhw.h>
> -#include "core.h"
> -#include "layer1.h"
> -#include "fsm.h"
> -
> -static u_int *debug;
> -
> -struct layer1 {
> - u_long Flags;
> - struct FsmInst l1m;
> - struct FsmTimer timer3;
> - struct FsmTimer timerX;
> - int delay;
> - int t3_value;
> - struct dchannel *dch;
> - dchannel_l1callback *dcb;
> -};
> -
> -#define TIMER3_DEFAULT_VALUE 7000
> -
> -static
> -struct Fsm l1fsm_s = {NULL, 0, 0, NULL, NULL};
> -
> -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",
> -};
> -
> -enum {
> - EV_PH_ACTIVATE,
> - EV_PH_DEACTIVATE,
> - EV_RESET_IND,
> - EV_DEACT_CNF,
> - EV_DEACT_IND,
> - EV_POWER_UP,
> - EV_ANYSIG_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_ANYSIG_IND",
> - "EV_INFO2_IND",
> - "EV_INFO4_IND",
> - "EV_TIMER_DEACT",
> - "EV_TIMER_ACT",
> - "EV_TIMER3",
> -};
> -
> -static void
> -l1m_debug(struct FsmInst *fi, char *fmt, ...)
> -{
> - struct layer1 *l1 = fi->userdata;
> - struct va_format vaf;
> - va_list va;
> -
> - va_start(va, fmt);
> -
> - vaf.fmt = fmt;
> - vaf.va = &va;
> -
> - printk(KERN_DEBUG "%s: %pV\n", dev_name(&l1->dch->dev.dev), &vaf);
> -
> - va_end(va);
> -}
> -
> -static void
> -l1_reset(struct FsmInst *fi, int event, void *arg)
> -{
> - mISDN_FsmChangeState(fi, ST_L1_F3);
> -}
> -
> -static void
> -l1_deact_cnf(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer1 *l1 = fi->userdata;
> -
> - mISDN_FsmChangeState(fi, ST_L1_F3);
> - if (test_bit(FLG_L1_ACTIVATING, &l1->Flags))
> - l1->dcb(l1->dch, HW_POWERUP_REQ);
> -}
> -
> -static void
> -l1_deact_req_s(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer1 *l1 = fi->userdata;
> -
> - mISDN_FsmChangeState(fi, ST_L1_F3);
> - mISDN_FsmRestartTimer(&l1->timerX, 550, EV_TIMER_DEACT, NULL, 2);
> - test_and_set_bit(FLG_L1_DEACTTIMER, &l1->Flags);
> -}
> -
> -static void
> -l1_power_up_s(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer1 *l1 = fi->userdata;
> -
> - if (test_bit(FLG_L1_ACTIVATING, &l1->Flags)) {
> - mISDN_FsmChangeState(fi, ST_L1_F4);
> - l1->dcb(l1->dch, INFO3_P8);
> - } else
> - mISDN_FsmChangeState(fi, ST_L1_F3);
> -}
> -
> -static void
> -l1_go_F5(struct FsmInst *fi, int event, void *arg)
> -{
> - mISDN_FsmChangeState(fi, ST_L1_F5);
> -}
> -
> -static void
> -l1_go_F8(struct FsmInst *fi, int event, void *arg)
> -{
> - mISDN_FsmChangeState(fi, ST_L1_F8);
> -}
> -
> -static void
> -l1_info2_ind(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer1 *l1 = fi->userdata;
> -
> - mISDN_FsmChangeState(fi, ST_L1_F6);
> - l1->dcb(l1->dch, INFO3_P8);
> -}
> -
> -static void
> -l1_info4_ind(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer1 *l1 = fi->userdata;
> -
> - mISDN_FsmChangeState(fi, ST_L1_F7);
> - l1->dcb(l1->dch, INFO3_P8);
> - if (test_and_clear_bit(FLG_L1_DEACTTIMER, &l1->Flags))
> - mISDN_FsmDelTimer(&l1->timerX, 4);
> - if (!test_bit(FLG_L1_ACTIVATED, &l1->Flags)) {
> - if (test_and_clear_bit(FLG_L1_T3RUN, &l1->Flags))
> - mISDN_FsmDelTimer(&l1->timer3, 3);
> - mISDN_FsmRestartTimer(&l1->timerX, 110, EV_TIMER_ACT, NULL, 2);
> - test_and_set_bit(FLG_L1_ACTTIMER, &l1->Flags);
> - }
> -}
> -
> -static void
> -l1_timer3(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer1 *l1 = fi->userdata;
> -
> - test_and_clear_bit(FLG_L1_T3RUN, &l1->Flags);
> - if (test_and_clear_bit(FLG_L1_ACTIVATING, &l1->Flags)) {
> - if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags))
> - l1->dcb(l1->dch, HW_D_NOBLOCKED);
> - l1->dcb(l1->dch, PH_DEACTIVATE_IND);
> - }
> - if (l1->l1m.state != ST_L1_F6) {
> - mISDN_FsmChangeState(fi, ST_L1_F3);
> - /* do not force anything here, we need send INFO 0 */
> - }
> -}
> -
> -static void
> -l1_timer_act(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer1 *l1 = fi->userdata;
> -
> - test_and_clear_bit(FLG_L1_ACTTIMER, &l1->Flags);
> - test_and_set_bit(FLG_L1_ACTIVATED, &l1->Flags);
> - l1->dcb(l1->dch, PH_ACTIVATE_IND);
> -}
> -
> -static void
> -l1_timer_deact(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer1 *l1 = fi->userdata;
> -
> - test_and_clear_bit(FLG_L1_DEACTTIMER, &l1->Flags);
> - test_and_clear_bit(FLG_L1_ACTIVATED, &l1->Flags);
> - if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags))
> - l1->dcb(l1->dch, HW_D_NOBLOCKED);
> - l1->dcb(l1->dch, PH_DEACTIVATE_IND);
> - l1->dcb(l1->dch, HW_DEACT_REQ);
> -}
> -
> -static void
> -l1_activate_s(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer1 *l1 = fi->userdata;
> -
> - mISDN_FsmRestartTimer(&l1->timer3, l1->t3_value, EV_TIMER3, NULL, 2);
> - test_and_set_bit(FLG_L1_T3RUN, &l1->Flags);
> - /* Tell HW to send INFO 1 */
> - l1->dcb(l1->dch, HW_RESET_REQ);
> -}
> -
> -static void
> -l1_activate_no(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer1 *l1 = fi->userdata;
> -
> - if ((!test_bit(FLG_L1_DEACTTIMER, &l1->Flags)) &&
> - (!test_bit(FLG_L1_T3RUN, &l1->Flags))) {
> - test_and_clear_bit(FLG_L1_ACTIVATING, &l1->Flags);
> - if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags))
> - l1->dcb(l1->dch, HW_D_NOBLOCKED);
> - l1->dcb(l1->dch, PH_DEACTIVATE_IND);
> - }
> -}
> -
> -static struct FsmNode L1SFnList[] =
> -{
> - {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_ANYSIG_IND, l1_go_F5},
> - {ST_L1_F6, EV_ANYSIG_IND, l1_go_F8},
> - {ST_L1_F7, EV_ANYSIG_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},
> -};
> -
> -static void
> -release_l1(struct layer1 *l1) {
> - mISDN_FsmDelTimer(&l1->timerX, 0);
> - mISDN_FsmDelTimer(&l1->timer3, 0);
> - if (l1->dch)
> - l1->dch->l1 = NULL;
> - module_put(THIS_MODULE);
> - kfree(l1);
> -}
> -
> -int
> -l1_event(struct layer1 *l1, u_int event)
> -{
> - int err = 0;
> -
> - if (!l1)
> - return -EINVAL;
> - switch (event) {
> - case HW_RESET_IND:
> - mISDN_FsmEvent(&l1->l1m, EV_RESET_IND, NULL);
> - break;
> - case HW_DEACT_IND:
> - mISDN_FsmEvent(&l1->l1m, EV_DEACT_IND, NULL);
> - break;
> - case HW_POWERUP_IND:
> - mISDN_FsmEvent(&l1->l1m, EV_POWER_UP, NULL);
> - break;
> - case HW_DEACT_CNF:
> - mISDN_FsmEvent(&l1->l1m, EV_DEACT_CNF, NULL);
> - break;
> - case ANYSIGNAL:
> - mISDN_FsmEvent(&l1->l1m, EV_ANYSIG_IND, NULL);
> - break;
> - case LOSTFRAMING:
> - mISDN_FsmEvent(&l1->l1m, EV_ANYSIG_IND, NULL);
> - break;
> - case INFO2:
> - mISDN_FsmEvent(&l1->l1m, EV_INFO2_IND, NULL);
> - break;
> - case INFO4_P8:
> - mISDN_FsmEvent(&l1->l1m, EV_INFO4_IND, NULL);
> - break;
> - case INFO4_P10:
> - mISDN_FsmEvent(&l1->l1m, EV_INFO4_IND, NULL);
> - break;
> - case PH_ACTIVATE_REQ:
> - if (test_bit(FLG_L1_ACTIVATED, &l1->Flags))
> - l1->dcb(l1->dch, PH_ACTIVATE_IND);
> - else {
> - test_and_set_bit(FLG_L1_ACTIVATING, &l1->Flags);
> - mISDN_FsmEvent(&l1->l1m, EV_PH_ACTIVATE, NULL);
> - }
> - break;
> - case CLOSE_CHANNEL:
> - release_l1(l1);
> - break;
> - default:
> - if ((event & ~HW_TIMER3_VMASK) == HW_TIMER3_VALUE) {
> - int val = event & HW_TIMER3_VMASK;
> -
> - if (val < 5)
> - val = 5;
> - if (val > 30)
> - val = 30;
> - l1->t3_value = val;
> - break;
> - }
> - if (*debug & DEBUG_L1)
> - printk(KERN_DEBUG "%s %x unhandled\n",
> - __func__, event);
> - err = -EINVAL;
> - }
> - return err;
> -}
> -EXPORT_SYMBOL(l1_event);
> -
> -int
> -create_l1(struct dchannel *dch, dchannel_l1callback *dcb) {
> - struct layer1 *nl1;
> -
> - nl1 = kzalloc_obj(struct layer1, GFP_ATOMIC);
> - if (!nl1) {
> - printk(KERN_ERR "kmalloc struct layer1 failed\n");
> - return -ENOMEM;
> - }
> - nl1->l1m.fsm = &l1fsm_s;
> - nl1->l1m.state = ST_L1_F3;
> - nl1->Flags = 0;
> - nl1->t3_value = TIMER3_DEFAULT_VALUE;
> - nl1->l1m.debug = *debug & DEBUG_L1_FSM;
> - nl1->l1m.userdata = nl1;
> - nl1->l1m.userint = 0;
> - nl1->l1m.printdebug = l1m_debug;
> - nl1->dch = dch;
> - nl1->dcb = dcb;
> - mISDN_FsmInitTimer(&nl1->l1m, &nl1->timer3);
> - mISDN_FsmInitTimer(&nl1->l1m, &nl1->timerX);
> - __module_get(THIS_MODULE);
> - dch->l1 = nl1;
> - return 0;
> -}
> -EXPORT_SYMBOL(create_l1);
> -
> -int
> -Isdnl1_Init(u_int *deb)
> -{
> - debug = deb;
> - l1fsm_s.state_count = L1S_STATE_COUNT;
> - l1fsm_s.event_count = L1_EVENT_COUNT;
> - l1fsm_s.strEvent = strL1Event;
> - l1fsm_s.strState = strL1SState;
> - return mISDN_FsmNew(&l1fsm_s, L1SFnList, ARRAY_SIZE(L1SFnList));
> -}
> -
> -void
> -Isdnl1_cleanup(void)
> -{
> - mISDN_FsmFree(&l1fsm_s);
> -}
> diff --git a/drivers/isdn/mISDN/layer2.c b/drivers/isdn/mISDN/layer2.c
> deleted file mode 100644
> index b75869c9f78f..000000000000
> --- a/drivers/isdn/mISDN/layer2.c
> +++ /dev/null
> @@ -1,2266 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - *
> - * Author Karsten Keil <kkeil@novell.com>
> - *
> - * Copyright 2008 by Karsten Keil <kkeil@novell.com>
> - */
> -
> -#include <linux/mISDNif.h>
> -#include <linux/slab.h>
> -#include "core.h"
> -#include "fsm.h"
> -#include "layer2.h"
> -
> -static u_int *debug;
> -
> -static
> -struct Fsm l2fsm = {NULL, 0, 0, NULL, NULL};
> -
> -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_UNITDATA,
> - 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_T200I,
> - EV_L2_T203I,
> - 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_UNITDATA",
> - "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_T200I",
> - "EV_L2_T203I",
> - "EV_L2_SET_OWN_BUSY",
> - "EV_L2_CLEAR_OWN_BUSY",
> - "EV_L2_FRAME_ERROR",
> -};
> -
> -static void
> -l2m_debug(struct FsmInst *fi, char *fmt, ...)
> -{
> - struct layer2 *l2 = fi->userdata;
> - struct va_format vaf;
> - va_list va;
> -
> - if (!(*debug & DEBUG_L2_FSM))
> - return;
> -
> - va_start(va, fmt);
> -
> - vaf.fmt = fmt;
> - vaf.va = &va;
> -
> - printk(KERN_DEBUG "%s l2 (sapi %d tei %d): %pV\n",
> - mISDNDevName4ch(&l2->ch), l2->sapi, l2->tei, &vaf);
> -
> - va_end(va);
> -}
> -
> -inline u_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 u_int
> -l2addrsize(struct layer2 *l2)
> -{
> - return test_bit(FLG_LAPD, &l2->flag) ? 2 : 1;
> -}
> -
> -static u_int
> -l2_newid(struct layer2 *l2)
> -{
> - u_int id;
> -
> - id = l2->next_id++;
> - if (id == 0x7fff)
> - l2->next_id = 1;
> - id <<= 16;
> - id |= l2->tei << 8;
> - id |= l2->sapi;
> - return id;
> -}
> -
> -static void
> -l2up(struct layer2 *l2, u_int prim, struct sk_buff *skb)
> -{
> - int err;
> -
> - if (!l2->up)
> - return;
> - mISDN_HEAD_PRIM(skb) = prim;
> - mISDN_HEAD_ID(skb) = (l2->ch.nr << 16) | l2->ch.addr;
> - err = l2->up->send(l2->up, skb);
> - if (err) {
> - printk(KERN_WARNING "%s: dev %s err=%d\n", __func__,
> - mISDNDevName4ch(&l2->ch), err);
> - dev_kfree_skb(skb);
> - }
> -}
> -
> -static void
> -l2up_create(struct layer2 *l2, u_int prim, int len, void *arg)
> -{
> - struct sk_buff *skb;
> - struct mISDNhead *hh;
> - int err;
> -
> - if (!l2->up)
> - return;
> - skb = mI_alloc_skb(len, GFP_ATOMIC);
> - if (!skb)
> - return;
> - hh = mISDN_HEAD_P(skb);
> - hh->prim = prim;
> - hh->id = (l2->ch.nr << 16) | l2->ch.addr;
> - if (len)
> - skb_put_data(skb, arg, len);
> - err = l2->up->send(l2->up, skb);
> - if (err) {
> - printk(KERN_WARNING "%s: dev %s err=%d\n", __func__,
> - mISDNDevName4ch(&l2->ch), err);
> - dev_kfree_skb(skb);
> - }
> -}
> -
> -static int
> -l2down_skb(struct layer2 *l2, struct sk_buff *skb) {
> - int ret;
> -
> - ret = l2->ch.recv(l2->ch.peer, skb);
> - if (ret && (*debug & DEBUG_L2_RECV))
> - printk(KERN_DEBUG "l2down_skb: dev %s ret(%d)\n",
> - mISDNDevName4ch(&l2->ch), ret);
> - return ret;
> -}
> -
> -static int
> -l2down_raw(struct layer2 *l2, struct sk_buff *skb)
> -{
> - struct mISDNhead *hh = mISDN_HEAD_P(skb);
> -
> - if (hh->prim == PH_DATA_REQ) {
> - if (test_and_set_bit(FLG_L1_NOTREADY, &l2->flag)) {
> - skb_queue_tail(&l2->down_queue, skb);
> - return 0;
> - }
> - l2->down_id = mISDN_HEAD_ID(skb);
> - }
> - return l2down_skb(l2, skb);
> -}
> -
> -static int
> -l2down(struct layer2 *l2, u_int prim, u_int id, struct sk_buff *skb)
> -{
> - struct mISDNhead *hh = mISDN_HEAD_P(skb);
> -
> - hh->prim = prim;
> - hh->id = id;
> - return l2down_raw(l2, skb);
> -}
> -
> -static int
> -l2down_create(struct layer2 *l2, u_int prim, u_int id, int len, void *arg)
> -{
> - struct sk_buff *skb;
> - int err;
> - struct mISDNhead *hh;
> -
> - skb = mI_alloc_skb(len, GFP_ATOMIC);
> - if (!skb)
> - return -ENOMEM;
> - hh = mISDN_HEAD_P(skb);
> - hh->prim = prim;
> - hh->id = id;
> - if (len)
> - skb_put_data(skb, arg, len);
> - err = l2down_raw(l2, skb);
> - if (err)
> - dev_kfree_skb(skb);
> - return err;
> -}
> -
> -static int
> -ph_data_confirm(struct layer2 *l2, struct mISDNhead *hh, struct sk_buff *skb) {
> - struct sk_buff *nskb = skb;
> - int ret = -EAGAIN;
> -
> - if (test_bit(FLG_L1_NOTREADY, &l2->flag)) {
> - if (hh->id == l2->down_id) {
> - nskb = skb_dequeue(&l2->down_queue);
> - if (nskb) {
> - l2->down_id = mISDN_HEAD_ID(nskb);
> - if (l2down_skb(l2, nskb)) {
> - dev_kfree_skb(nskb);
> - l2->down_id = MISDN_ID_NONE;
> - }
> - } else
> - l2->down_id = MISDN_ID_NONE;
> - if (ret) {
> - dev_kfree_skb(skb);
> - ret = 0;
> - }
> - if (l2->down_id == MISDN_ID_NONE) {
> - test_and_clear_bit(FLG_L1_NOTREADY, &l2->flag);
> - mISDN_FsmEvent(&l2->l2m, EV_L2_ACK_PULL, NULL);
> - }
> - }
> - }
> - if (!test_and_set_bit(FLG_L1_NOTREADY, &l2->flag)) {
> - nskb = skb_dequeue(&l2->down_queue);
> - if (nskb) {
> - l2->down_id = mISDN_HEAD_ID(nskb);
> - if (l2down_skb(l2, nskb)) {
> - dev_kfree_skb(nskb);
> - l2->down_id = MISDN_ID_NONE;
> - test_and_clear_bit(FLG_L1_NOTREADY, &l2->flag);
> - }
> - } else
> - test_and_clear_bit(FLG_L1_NOTREADY, &l2->flag);
> - }
> - return ret;
> -}
> -
> -static void
> -l2_timeout(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> - struct sk_buff *skb;
> - struct mISDNhead *hh;
> -
> - skb = mI_alloc_skb(0, GFP_ATOMIC);
> - if (!skb) {
> - printk(KERN_WARNING "%s: L2(%d,%d) nr:%x timer %s no skb\n",
> - mISDNDevName4ch(&l2->ch), l2->sapi, l2->tei,
> - l2->ch.nr, event == EV_L2_T200 ? "T200" : "T203");
> - return;
> - }
> - hh = mISDN_HEAD_P(skb);
> - hh->prim = event == EV_L2_T200 ? DL_TIMER200_IND : DL_TIMER203_IND;
> - hh->id = l2->ch.nr;
> - if (*debug & DEBUG_TIMER)
> - printk(KERN_DEBUG "%s: L2(%d,%d) nr:%x timer %s expired\n",
> - mISDNDevName4ch(&l2->ch), l2->sapi, l2->tei,
> - l2->ch.nr, event == EV_L2_T200 ? "T200" : "T203");
> - if (l2->ch.st)
> - l2->ch.st->own.recv(&l2->ch.st->own, skb);
> -}
> -
> -static int
> -l2mgr(struct layer2 *l2, u_int prim, void *arg) {
> - long c = (long)arg;
> -
> - printk(KERN_WARNING "l2mgr: dev %s addr:%x prim %x %c\n",
> - mISDNDevName4ch(&l2->ch), l2->id, prim, (char)c);
> - if (test_bit(FLG_LAPD, &l2->flag) &&
> - !test_bit(FLG_FIXED_TEI, &l2->flag)) {
> - switch (c) {
> - case 'C':
> - case 'D':
> - case 'G':
> - case 'H':
> - l2_tei(l2, prim, (u_long)arg);
> - break;
> - }
> - }
> - return 0;
> -}
> -
> -static void
> -set_peer_busy(struct layer2 *l2) {
> - test_and_set_bit(FLG_PEER_BUSY, &l2->flag);
> - if (skb_queue_len(&l2->i_queue) || skb_queue_len(&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
> -freewin(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 void
> -ReleaseWin(struct layer2 *l2)
> -{
> - int cnt = freewin(l2);
> -
> - if (cnt)
> - printk(KERN_WARNING
> - "isdnl2 freed %d skbuffs in release\n", cnt);
> -}
> -
> -inline unsigned int
> -cansend(struct layer2 *l2)
> -{
> - unsigned int p1;
> -
> - if (test_bit(FLG_MOD128, &l2->flag))
> - p1 = (l2->vs - l2->va) % 128;
> - else
> - p1 = (l2->vs - l2->va) % 8;
> - return (p1 < l2->window) && !test_bit(FLG_PEER_BUSY, &l2->flag);
> -}
> -
> -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 int
> -sethdraddr(struct layer2 *l2, u_char *header, int rsp)
> -{
> - u_char *ptr = header;
> - int crbit = rsp;
> -
> - if (test_bit(FLG_LAPD, &l2->flag)) {
> - if (test_bit(FLG_LAPD_NET, &l2->flag))
> - crbit = !crbit;
> - *ptr++ = (l2->sapi << 2) | (crbit ? 2 : 0);
> - *ptr++ = (l2->tei << 1) | 1;
> - return 2;
> - } else {
> - if (test_bit(FLG_ORIG, &l2->flag))
> - crbit = !crbit;
> - if (crbit)
> - *ptr++ = l2->addr.B;
> - else
> - *ptr++ = l2->addr.A;
> - return 1;
> - }
> -}
> -
> -static inline void
> -enqueue_super(struct layer2 *l2, struct sk_buff *skb)
> -{
> - if (l2down(l2, PH_DATA_REQ, l2_newid(l2), skb))
> - dev_kfree_skb(skb);
> -}
> -
> -static inline void
> -enqueue_ui(struct layer2 *l2, struct sk_buff *skb)
> -{
> - if (l2->tm)
> - l2_tei(l2, MDL_STATUS_UI_IND, 0);
> - if (l2down(l2, PH_DATA_REQ, l2_newid(l2), skb))
> - dev_kfree_skb(skb);
> -}
> -
> -inline int
> -IsUI(u_char *data)
> -{
> - return (data[0] & 0xef) == UI;
> -}
> -
> -inline int
> -IsUA(u_char *data)
> -{
> - return (data[0] & 0xef) == UA;
> -}
> -
> -inline int
> -IsDM(u_char *data)
> -{
> - return (data[0] & 0xef) == DM;
> -}
> -
> -inline int
> -IsDISC(u_char *data)
> -{
> - return (data[0] & 0xef) == DISC;
> -}
> -
> -inline int
> -IsRR(u_char *data, struct layer2 *l2)
> -{
> - if (test_bit(FLG_MOD128, &l2->flag))
> - return data[0] == RR;
> - else
> - return (data[0] & 0xf) == 1;
> -}
> -
> -inline int
> -IsSFrame(u_char *data, struct layer2 *l2)
> -{
> - register u_char d = *data;
> -
> - if (!test_bit(FLG_MOD128, &l2->flag))
> - d &= 0xf;
> - return ((d & 0xf3) == 1) && ((d & 0x0c) != 0x0c);
> -}
> -
> -inline int
> -IsSABME(u_char *data, struct layer2 *l2)
> -{
> - u_char d = data[0] & ~0x10;
> -
> - return test_bit(FLG_MOD128, &l2->flag) ? d == SABME : d == SABM;
> -}
> -
> -inline int
> -IsREJ(u_char *data, struct layer2 *l2)
> -{
> - return test_bit(FLG_MOD128, &l2->flag) ?
> - data[0] == REJ : (data[0] & 0xf) == REJ;
> -}
> -
> -inline int
> -IsFRMR(u_char *data)
> -{
> - return (data[0] & 0xef) == FRMR;
> -}
> -
> -inline int
> -IsRNR(u_char *data, struct layer2 *l2)
> -{
> - return test_bit(FLG_MOD128, &l2->flag) ?
> - data[0] == RNR : (data[0] & 0xf) == RNR;
> -}
> -
> -static int
> -iframe_error(struct layer2 *l2, struct sk_buff *skb)
> -{
> - u_int i;
> - int rsp = *skb->data & 0x2;
> -
> - i = l2addrsize(l2) + (test_bit(FLG_MOD128, &l2->flag) ? 2 : 1);
> - if (test_bit(FLG_ORIG, &l2->flag))
> - rsp = !rsp;
> - if (rsp)
> - return 'L';
> - if (skb->len < i)
> - return 'N';
> - if ((skb->len - i) > l2->maxlen)
> - return 'O';
> - return 0;
> -}
> -
> -static int
> -super_error(struct layer2 *l2, struct sk_buff *skb)
> -{
> - if (skb->len != l2addrsize(l2) +
> - (test_bit(FLG_MOD128, &l2->flag) ? 2 : 1))
> - return 'N';
> - return 0;
> -}
> -
> -static int
> -unnum_error(struct layer2 *l2, struct sk_buff *skb, int wantrsp)
> -{
> - int rsp = (*skb->data & 0x2) >> 1;
> - if (test_bit(FLG_ORIG, &l2->flag))
> - rsp = !rsp;
> - if (rsp != wantrsp)
> - return 'L';
> - if (skb->len != l2addrsize(l2) + 1)
> - return 'N';
> - return 0;
> -}
> -
> -static int
> -UI_error(struct layer2 *l2, struct sk_buff *skb)
> -{
> - int rsp = *skb->data & 0x2;
> - if (test_bit(FLG_ORIG, &l2->flag))
> - rsp = !rsp;
> - if (rsp)
> - return 'L';
> - if (skb->len > l2->maxlen + l2addrsize(l2) + 1)
> - return 'O';
> - return 0;
> -}
> -
> -static int
> -FRMR_error(struct layer2 *l2, struct sk_buff *skb)
> -{
> - u_int headers = l2addrsize(l2) + 1;
> - u_char *datap = skb->data + headers;
> - int rsp = *skb->data & 0x2;
> -
> - if (test_bit(FLG_ORIG, &l2->flag))
> - rsp = !rsp;
> - if (!rsp)
> - return 'L';
> - if (test_bit(FLG_MOD128, &l2->flag)) {
> - if (skb->len < headers + 5)
> - return 'N';
> - else if (*debug & DEBUG_L2)
> - l2m_debug(&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 if (*debug & DEBUG_L2)
> - l2m_debug(&l2->l2m,
> - "FRMR information %2x %2x %2x",
> - datap[0], datap[1], datap[2]);
> - }
> - return 0;
> -}
> -
> -static unsigned int
> -legalnr(struct layer2 *l2, unsigned int nr)
> -{
> - 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 layer2 *l2, unsigned int nr)
> -{
> - struct sk_buff *skb;
> -
> - while (l2->va != nr) {
> - l2->va++;
> - if (test_bit(FLG_MOD128, &l2->flag))
> - l2->va %= 128;
> - else
> - l2->va %= 8;
> - if (l2->windowar[l2->sow]) {
> - skb_trim(l2->windowar[l2->sow], 0);
> - skb_queue_tail(&l2->tmp_queue, l2->windowar[l2->sow]);
> - l2->windowar[l2->sow] = NULL;
> - }
> - l2->sow = (l2->sow + 1) % l2->window;
> - }
> - skb = skb_dequeue(&l2->tmp_queue);
> - while (skb) {
> - dev_kfree_skb(skb);
> - skb = skb_dequeue(&l2->tmp_queue);
> - }
> -}
> -
> -static void
> -send_uframe(struct layer2 *l2, struct sk_buff *skb, u_char cmd, u_char cr)
> -{
> - u_char tmp[MAX_L2HEADER_LEN];
> - int i;
> -
> - i = sethdraddr(l2, tmp, cr);
> - tmp[i++] = cmd;
> - if (skb)
> - skb_trim(skb, 0);
> - else {
> - skb = mI_alloc_skb(i, GFP_ATOMIC);
> - if (!skb) {
> - printk(KERN_WARNING "%s: can't alloc skbuff in %s\n",
> - mISDNDevName4ch(&l2->ch), __func__);
> - return;
> - }
> - }
> - skb_put_data(skb, tmp, i);
> - enqueue_super(l2, skb);
> -}
> -
> -
> -inline u_char
> -get_PollFlag(struct layer2 *l2, struct sk_buff *skb)
> -{
> - return skb->data[l2addrsize(l2)] & 0x10;
> -}
> -
> -inline u_char
> -get_PollFlagFree(struct layer2 *l2, struct sk_buff *skb)
> -{
> - u_char PF;
> -
> - PF = get_PollFlag(l2, skb);
> - dev_kfree_skb(skb);
> - return PF;
> -}
> -
> -inline void
> -start_t200(struct layer2 *l2, int i)
> -{
> - mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, i);
> - test_and_set_bit(FLG_T200_RUN, &l2->flag);
> -}
> -
> -inline void
> -restart_t200(struct layer2 *l2, int i)
> -{
> - mISDN_FsmRestartTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, i);
> - test_and_set_bit(FLG_T200_RUN, &l2->flag);
> -}
> -
> -inline void
> -stop_t200(struct layer2 *l2, int i)
> -{
> - if (test_and_clear_bit(FLG_T200_RUN, &l2->flag))
> - mISDN_FsmDelTimer(&l2->t200, i);
> -}
> -
> -inline void
> -st5_dl_release_l2l3(struct layer2 *l2)
> -{
> - int pr;
> -
> - if (test_and_clear_bit(FLG_PEND_REL, &l2->flag))
> - pr = DL_RELEASE_CNF;
> - else
> - pr = DL_RELEASE_IND;
> - l2up_create(l2, pr, 0, NULL);
> -}
> -
> -inline void
> -lapb_dl_release_l2l3(struct layer2 *l2, int f)
> -{
> - if (test_bit(FLG_LAPB, &l2->flag))
> - l2down_create(l2, PH_DEACTIVATE_REQ, l2_newid(l2), 0, NULL);
> - l2up_create(l2, f, 0, NULL);
> -}
> -
> -static void
> -establishlink(struct FsmInst *fi)
> -{
> - struct layer2 *l2 = fi->userdata;
> - u_char cmd;
> -
> - clear_exception(l2);
> - l2->rc = 0;
> - cmd = (test_bit(FLG_MOD128, &l2->flag) ? SABME : SABM) | 0x10;
> - send_uframe(l2, NULL, cmd, CMD);
> - mISDN_FsmDelTimer(&l2->t203, 1);
> - restart_t200(l2, 1);
> - test_and_clear_bit(FLG_PEND_REL, &l2->flag);
> - freewin(l2);
> - mISDN_FsmChangeState(fi, ST_L2_5);
> -}
> -
> -static void
> -l2_mdl_error_ua(struct FsmInst *fi, int event, void *arg)
> -{
> - struct sk_buff *skb = arg;
> - struct layer2 *l2 = fi->userdata;
> -
> - if (get_PollFlagFree(l2, skb))
> - l2mgr(l2, MDL_ERROR_IND, (void *) 'C');
> - else
> - l2mgr(l2, MDL_ERROR_IND, (void *) 'D');
> -
> -}
> -
> -static void
> -l2_mdl_error_dm(struct FsmInst *fi, int event, void *arg)
> -{
> - struct sk_buff *skb = arg;
> - struct layer2 *l2 = fi->userdata;
> -
> - if (get_PollFlagFree(l2, skb))
> - l2mgr(l2, MDL_ERROR_IND, (void *) 'B');
> - else {
> - l2mgr(l2, MDL_ERROR_IND, (void *) 'E');
> - establishlink(fi);
> - test_and_clear_bit(FLG_L3_INIT, &l2->flag);
> - }
> -}
> -
> -static void
> -l2_st8_mdl_error_dm(struct FsmInst *fi, int event, void *arg)
> -{
> - struct sk_buff *skb = arg;
> - struct layer2 *l2 = fi->userdata;
> -
> - if (get_PollFlagFree(l2, skb))
> - l2mgr(l2, MDL_ERROR_IND, (void *) 'B');
> - else
> - l2mgr(l2, MDL_ERROR_IND, (void *) 'E');
> - establishlink(fi);
> - test_and_clear_bit(FLG_L3_INIT, &l2->flag);
> -}
> -
> -static void
> -l2_go_st3(struct FsmInst *fi, int event, void *arg)
> -{
> - dev_kfree_skb((struct sk_buff *)arg);
> - mISDN_FsmChangeState(fi, ST_L2_3);
> -}
> -
> -static void
> -l2_mdl_assign(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> -
> - mISDN_FsmChangeState(fi, ST_L2_3);
> - dev_kfree_skb((struct sk_buff *)arg);
> - l2_tei(l2, MDL_ASSIGN_IND, 0);
> -}
> -
> -static void
> -l2_queue_ui_assign(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> - struct sk_buff *skb = arg;
> -
> - skb_queue_tail(&l2->ui_queue, skb);
> - mISDN_FsmChangeState(fi, ST_L2_2);
> - l2_tei(l2, MDL_ASSIGN_IND, 0);
> -}
> -
> -static void
> -l2_queue_ui(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> - struct sk_buff *skb = arg;
> -
> - skb_queue_tail(&l2->ui_queue, skb);
> -}
> -
> -static void
> -tx_ui(struct layer2 *l2)
> -{
> - struct sk_buff *skb;
> - u_char header[MAX_L2HEADER_LEN];
> - int i;
> -
> - i = sethdraddr(l2, header, CMD);
> - if (test_bit(FLG_LAPD_NET, &l2->flag))
> - header[1] = 0xff; /* tei 127 */
> - header[i++] = UI;
> - while ((skb = skb_dequeue(&l2->ui_queue))) {
> - memcpy(skb_push(skb, i), header, i);
> - enqueue_ui(l2, skb);
> - }
> -}
> -
> -static void
> -l2_send_ui(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> - struct sk_buff *skb = arg;
> -
> - skb_queue_tail(&l2->ui_queue, skb);
> - tx_ui(l2);
> -}
> -
> -static void
> -l2_got_ui(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> - struct sk_buff *skb = arg;
> -
> - skb_pull(skb, l2headersize(l2, 1));
> -/*
> - * in states 1-3 for broadcast
> - */
> -
> - if (l2->tm)
> - l2_tei(l2, MDL_STATUS_UI_IND, 0);
> - l2up(l2, DL_UNITDATA_IND, skb);
> -}
> -
> -static void
> -l2_establish(struct FsmInst *fi, int event, void *arg)
> -{
> - struct sk_buff *skb = arg;
> - struct layer2 *l2 = fi->userdata;
> -
> - establishlink(fi);
> - test_and_set_bit(FLG_L3_INIT, &l2->flag);
> - dev_kfree_skb(skb);
> -}
> -
> -static void
> -l2_discard_i_setl3(struct FsmInst *fi, int event, void *arg)
> -{
> - struct sk_buff *skb = arg;
> - struct layer2 *l2 = fi->userdata;
> -
> - skb_queue_purge(&l2->i_queue);
> - test_and_set_bit(FLG_L3_INIT, &l2->flag);
> - test_and_clear_bit(FLG_PEND_REL, &l2->flag);
> - dev_kfree_skb(skb);
> -}
> -
> -static void
> -l2_l3_reestablish(struct FsmInst *fi, int event, void *arg)
> -{
> - struct sk_buff *skb = arg;
> - struct layer2 *l2 = fi->userdata;
> -
> - skb_queue_purge(&l2->i_queue);
> - establishlink(fi);
> - test_and_set_bit(FLG_L3_INIT, &l2->flag);
> - dev_kfree_skb(skb);
> -}
> -
> -static void
> -l2_release(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> - struct sk_buff *skb = arg;
> -
> - skb_trim(skb, 0);
> - l2up(l2, DL_RELEASE_CNF, skb);
> -}
> -
> -static void
> -l2_pend_rel(struct FsmInst *fi, int event, void *arg)
> -{
> - struct sk_buff *skb = arg;
> - struct layer2 *l2 = fi->userdata;
> -
> - test_and_set_bit(FLG_PEND_REL, &l2->flag);
> - dev_kfree_skb(skb);
> -}
> -
> -static void
> -l2_disconnect(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> - struct sk_buff *skb = arg;
> -
> - skb_queue_purge(&l2->i_queue);
> - freewin(l2);
> - mISDN_FsmChangeState(fi, ST_L2_6);
> - l2->rc = 0;
> - send_uframe(l2, NULL, DISC | 0x10, CMD);
> - mISDN_FsmDelTimer(&l2->t203, 1);
> - restart_t200(l2, 2);
> - dev_kfree_skb(skb);
> -}
> -
> -static void
> -l2_start_multi(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> - struct sk_buff *skb = arg;
> -
> - l2->vs = 0;
> - l2->va = 0;
> - l2->vr = 0;
> - l2->sow = 0;
> - clear_exception(l2);
> - send_uframe(l2, NULL, UA | get_PollFlag(l2, skb), RSP);
> - mISDN_FsmChangeState(fi, ST_L2_7);
> - mISDN_FsmAddTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 3);
> - skb_trim(skb, 0);
> - l2up(l2, DL_ESTABLISH_IND, skb);
> - if (l2->tm)
> - l2_tei(l2, MDL_STATUS_UP_IND, 0);
> -}
> -
> -static void
> -l2_send_UA(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> - struct sk_buff *skb = arg;
> -
> - send_uframe(l2, skb, UA | get_PollFlag(l2, skb), RSP);
> -}
> -
> -static void
> -l2_send_DM(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> - struct sk_buff *skb = arg;
> -
> - send_uframe(l2, skb, DM | get_PollFlag(l2, skb), RSP);
> -}
> -
> -static void
> -l2_restart_multi(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> - struct sk_buff *skb = arg;
> - int est = 0;
> -
> - send_uframe(l2, skb, UA | get_PollFlag(l2, skb), RSP);
> -
> - l2mgr(l2, MDL_ERROR_IND, (void *) 'F');
> -
> - if (l2->vs != l2->va) {
> - skb_queue_purge(&l2->i_queue);
> - est = 1;
> - }
> -
> - clear_exception(l2);
> - l2->vs = 0;
> - l2->va = 0;
> - l2->vr = 0;
> - l2->sow = 0;
> - mISDN_FsmChangeState(fi, ST_L2_7);
> - stop_t200(l2, 3);
> - mISDN_FsmRestartTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 3);
> -
> - if (est)
> - l2up_create(l2, DL_ESTABLISH_IND, 0, NULL);
> -/* mISDN_queue_data(&l2->inst, l2->inst.id | MSG_BROADCAST,
> - * MGR_SHORTSTATUS | INDICATION, SSTATUS_L2_ESTABLISHED,
> - * 0, NULL, 0);
> - */
> - if (skb_queue_len(&l2->i_queue) && cansend(l2))
> - mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);
> -}
> -
> -static void
> -l2_stop_multi(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> - struct sk_buff *skb = arg;
> -
> - mISDN_FsmChangeState(fi, ST_L2_4);
> - mISDN_FsmDelTimer(&l2->t203, 3);
> - stop_t200(l2, 4);
> -
> - send_uframe(l2, skb, UA | get_PollFlag(l2, skb), RSP);
> - skb_queue_purge(&l2->i_queue);
> - freewin(l2);
> - lapb_dl_release_l2l3(l2, DL_RELEASE_IND);
> - if (l2->tm)
> - l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
> -}
> -
> -static void
> -l2_connected(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> - struct sk_buff *skb = arg;
> - int pr = -1;
> -
> - if (!get_PollFlag(l2, skb)) {
> - l2_mdl_error_ua(fi, event, arg);
> - return;
> - }
> - dev_kfree_skb(skb);
> - if (test_and_clear_bit(FLG_PEND_REL, &l2->flag))
> - l2_disconnect(fi, event, NULL);
> - if (test_and_clear_bit(FLG_L3_INIT, &l2->flag)) {
> - pr = DL_ESTABLISH_CNF;
> - } else if (l2->vs != l2->va) {
> - skb_queue_purge(&l2->i_queue);
> - pr = DL_ESTABLISH_IND;
> - }
> - stop_t200(l2, 5);
> - l2->vr = 0;
> - l2->vs = 0;
> - l2->va = 0;
> - l2->sow = 0;
> - mISDN_FsmChangeState(fi, ST_L2_7);
> - mISDN_FsmAddTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 4);
> - if (pr != -1)
> - l2up_create(l2, pr, 0, NULL);
> -
> - if (skb_queue_len(&l2->i_queue) && cansend(l2))
> - mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);
> -
> - if (l2->tm)
> - l2_tei(l2, MDL_STATUS_UP_IND, 0);
> -}
> -
> -static void
> -l2_released(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> - struct sk_buff *skb = arg;
> -
> - if (!get_PollFlag(l2, skb)) {
> - l2_mdl_error_ua(fi, event, arg);
> - return;
> - }
> - dev_kfree_skb(skb);
> - stop_t200(l2, 6);
> - lapb_dl_release_l2l3(l2, DL_RELEASE_CNF);
> - mISDN_FsmChangeState(fi, ST_L2_4);
> - if (l2->tm)
> - l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
> -}
> -
> -static void
> -l2_reestablish(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> - struct sk_buff *skb = arg;
> -
> - if (!get_PollFlagFree(l2, skb)) {
> - establishlink(fi);
> - test_and_set_bit(FLG_L3_INIT, &l2->flag);
> - }
> -}
> -
> -static void
> -l2_st5_dm_release(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> - struct sk_buff *skb = arg;
> -
> - if (get_PollFlagFree(l2, skb)) {
> - stop_t200(l2, 7);
> - if (!test_bit(FLG_L3_INIT, &l2->flag))
> - skb_queue_purge(&l2->i_queue);
> - if (test_bit(FLG_LAPB, &l2->flag))
> - l2down_create(l2, PH_DEACTIVATE_REQ,
> - l2_newid(l2), 0, NULL);
> - st5_dl_release_l2l3(l2);
> - mISDN_FsmChangeState(fi, ST_L2_4);
> - if (l2->tm)
> - l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
> - }
> -}
> -
> -static void
> -l2_st6_dm_release(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> - struct sk_buff *skb = arg;
> -
> - if (get_PollFlagFree(l2, skb)) {
> - stop_t200(l2, 8);
> - lapb_dl_release_l2l3(l2, DL_RELEASE_CNF);
> - mISDN_FsmChangeState(fi, ST_L2_4);
> - if (l2->tm)
> - l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
> - }
> -}
> -
> -static void
> -enquiry_cr(struct layer2 *l2, u_char typ, u_char cr, u_char pf)
> -{
> - struct sk_buff *skb;
> - u_char tmp[MAX_L2HEADER_LEN];
> - int i;
> -
> - 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);
> - skb = mI_alloc_skb(i, GFP_ATOMIC);
> - if (!skb) {
> - printk(KERN_WARNING "%s: isdnl2 can't alloc sbbuff in %s\n",
> - mISDNDevName4ch(&l2->ch), __func__);
> - return;
> - }
> - skb_put_data(skb, tmp, i);
> - enqueue_super(l2, skb);
> -}
> -
> -inline void
> -enquiry_response(struct layer2 *l2)
> -{
> - if (test_bit(FLG_OWN_BUSY, &l2->flag))
> - enquiry_cr(l2, RNR, RSP, 1);
> - else
> - enquiry_cr(l2, RR, RSP, 1);
> - test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
> -}
> -
> -inline void
> -transmit_enquiry(struct layer2 *l2)
> -{
> - if (test_bit(FLG_OWN_BUSY, &l2->flag))
> - enquiry_cr(l2, RNR, CMD, 1);
> - else
> - enquiry_cr(l2, RR, CMD, 1);
> - test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
> - start_t200(l2, 9);
> -}
> -
> -
> -static void
> -nrerrorrecovery(struct FsmInst *fi)
> -{
> - struct layer2 *l2 = fi->userdata;
> -
> - l2mgr(l2, MDL_ERROR_IND, (void *) 'J');
> - establishlink(fi);
> - test_and_clear_bit(FLG_L3_INIT, &l2->flag);
> -}
> -
> -static void
> -invoke_retransmission(struct layer2 *l2, unsigned int nr)
> -{
> - u_int p1;
> -
> - 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 (l2->windowar[p1])
> - skb_queue_head(&l2->i_queue, l2->windowar[p1]);
> - else
> - printk(KERN_WARNING
> - "%s: windowar[%d] is NULL\n",
> - mISDNDevName4ch(&l2->ch), p1);
> - l2->windowar[p1] = NULL;
> - }
> - mISDN_FsmEvent(&l2->l2m, EV_L2_ACK_PULL, NULL);
> - }
> -}
> -
> -static void
> -l2_st7_got_super(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> - struct sk_buff *skb = arg;
> - int PollFlag, rsp, typ = RR;
> - unsigned int nr;
> -
> - rsp = *skb->data & 0x2;
> - if (test_bit(FLG_ORIG, &l2->flag))
> - rsp = !rsp;
> -
> - skb_pull(skb, l2addrsize(l2));
> - if (IsRNR(skb->data, l2)) {
> - set_peer_busy(l2);
> - typ = RNR;
> - } else
> - clear_peer_busy(l2);
> - if (IsREJ(skb->data, l2))
> - 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)
> - l2mgr(l2, MDL_ERROR_IND, (void *) 'A');
> - else
> - enquiry_response(l2);
> - }
> - if (legalnr(l2, nr)) {
> - if (typ == REJ) {
> - setva(l2, nr);
> - invoke_retransmission(l2, nr);
> - stop_t200(l2, 10);
> - if (mISDN_FsmAddTimer(&l2->t203, l2->T203,
> - EV_L2_T203, NULL, 6))
> - l2m_debug(&l2->l2m, "Restart T203 ST7 REJ");
> - } else if ((nr == l2->vs) && (typ == RR)) {
> - setva(l2, nr);
> - stop_t200(l2, 11);
> - mISDN_FsmRestartTimer(&l2->t203, l2->T203,
> - EV_L2_T203, NULL, 7);
> - } else if ((l2->va != nr) || (typ == RNR)) {
> - setva(l2, nr);
> - if (typ != RR)
> - mISDN_FsmDelTimer(&l2->t203, 9);
> - restart_t200(l2, 12);
> - }
> - if (skb_queue_len(&l2->i_queue) && (typ == RR))
> - mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);
> - } else
> - nrerrorrecovery(fi);
> -}
> -
> -static void
> -l2_feed_i_if_reest(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> - struct sk_buff *skb = arg;
> -
> - if (!test_bit(FLG_L3_INIT, &l2->flag))
> - skb_queue_tail(&l2->i_queue, skb);
> - else
> - dev_kfree_skb(skb);
> -}
> -
> -static void
> -l2_feed_i_pull(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> - struct sk_buff *skb = arg;
> -
> - skb_queue_tail(&l2->i_queue, skb);
> - mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);
> -}
> -
> -static void
> -l2_feed_iqueue(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> - struct sk_buff *skb = arg;
> -
> - skb_queue_tail(&l2->i_queue, skb);
> -}
> -
> -static void
> -l2_got_iframe(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> - struct sk_buff *skb = arg;
> - int PollFlag, i;
> - u_int ns, 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(l2);
> - } 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(l2);
> - else
> - test_and_set_bit(FLG_ACK_PEND, &l2->flag);
> - skb_pull(skb, l2headersize(l2, 0));
> - l2up(l2, DL_DATA_IND, skb);
> - } else {
> - /* n(s)!=v(r) */
> - dev_kfree_skb(skb);
> - if (test_and_set_bit(FLG_REJEXC, &l2->flag)) {
> - if (PollFlag)
> - enquiry_response(l2);
> - } else {
> - enquiry_cr(l2, REJ, RSP, PollFlag);
> - test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
> - }
> - }
> - }
> - if (legalnr(l2, nr)) {
> - if (!test_bit(FLG_PEER_BUSY, &l2->flag) &&
> - (fi->state == ST_L2_7)) {
> - if (nr == l2->vs) {
> - stop_t200(l2, 13);
> - mISDN_FsmRestartTimer(&l2->t203, l2->T203,
> - EV_L2_T203, NULL, 7);
> - } else if (nr != l2->va)
> - restart_t200(l2, 14);
> - }
> - setva(l2, nr);
> - } else {
> - nrerrorrecovery(fi);
> - return;
> - }
> - if (skb_queue_len(&l2->i_queue) && (fi->state == ST_L2_7))
> - mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);
> - if (test_and_clear_bit(FLG_ACK_PEND, &l2->flag))
> - enquiry_cr(l2, RR, RSP, 0);
> -}
> -
> -static void
> -l2_got_tei(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> - u_int info;
> -
> - l2->tei = (signed char)(long)arg;
> - set_channel_address(&l2->ch, l2->sapi, l2->tei);
> - info = DL_INFO_L2_CONNECT;
> - l2up_create(l2, DL_INFORMATION_IND, sizeof(info), &info);
> - if (fi->state == ST_L2_3) {
> - establishlink(fi);
> - test_and_set_bit(FLG_L3_INIT, &l2->flag);
> - } else
> - mISDN_FsmChangeState(fi, ST_L2_4);
> - if (skb_queue_len(&l2->ui_queue))
> - tx_ui(l2);
> -}
> -
> -static void
> -l2_st5_tout_200(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> -
> - if (test_bit(FLG_LAPD, &l2->flag) &&
> - test_bit(FLG_DCHAN_BUSY, &l2->flag)) {
> - mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9);
> - } else if (l2->rc == l2->N200) {
> - mISDN_FsmChangeState(fi, ST_L2_4);
> - test_and_clear_bit(FLG_T200_RUN, &l2->flag);
> - skb_queue_purge(&l2->i_queue);
> - l2mgr(l2, MDL_ERROR_IND, (void *) 'G');
> - if (test_bit(FLG_LAPB, &l2->flag))
> - l2down_create(l2, PH_DEACTIVATE_REQ,
> - l2_newid(l2), 0, NULL);
> - st5_dl_release_l2l3(l2);
> - if (l2->tm)
> - l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
> - } else {
> - l2->rc++;
> - mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9);
> - send_uframe(l2, NULL, (test_bit(FLG_MOD128, &l2->flag) ?
> - SABME : SABM) | 0x10, CMD);
> - }
> -}
> -
> -static void
> -l2_st6_tout_200(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> -
> - if (test_bit(FLG_LAPD, &l2->flag) &&
> - test_bit(FLG_DCHAN_BUSY, &l2->flag)) {
> - mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9);
> - } else if (l2->rc == l2->N200) {
> - mISDN_FsmChangeState(fi, ST_L2_4);
> - test_and_clear_bit(FLG_T200_RUN, &l2->flag);
> - l2mgr(l2, MDL_ERROR_IND, (void *) 'H');
> - lapb_dl_release_l2l3(l2, DL_RELEASE_CNF);
> - if (l2->tm)
> - l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
> - } else {
> - l2->rc++;
> - mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200,
> - NULL, 9);
> - send_uframe(l2, NULL, DISC | 0x10, CMD);
> - }
> -}
> -
> -static void
> -l2_st7_tout_200(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> -
> - if (test_bit(FLG_LAPD, &l2->flag) &&
> - test_bit(FLG_DCHAN_BUSY, &l2->flag)) {
> - mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9);
> - return;
> - }
> - test_and_clear_bit(FLG_T200_RUN, &l2->flag);
> - l2->rc = 0;
> - mISDN_FsmChangeState(fi, ST_L2_8);
> - transmit_enquiry(l2);
> - l2->rc++;
> -}
> -
> -static void
> -l2_st8_tout_200(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> -
> - if (test_bit(FLG_LAPD, &l2->flag) &&
> - test_bit(FLG_DCHAN_BUSY, &l2->flag)) {
> - mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9);
> - return;
> - }
> - test_and_clear_bit(FLG_T200_RUN, &l2->flag);
> - if (l2->rc == l2->N200) {
> - l2mgr(l2, MDL_ERROR_IND, (void *) 'I');
> - establishlink(fi);
> - test_and_clear_bit(FLG_L3_INIT, &l2->flag);
> - } else {
> - transmit_enquiry(l2);
> - l2->rc++;
> - }
> -}
> -
> -static void
> -l2_st7_tout_203(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> -
> - if (test_bit(FLG_LAPD, &l2->flag) &&
> - test_bit(FLG_DCHAN_BUSY, &l2->flag)) {
> - mISDN_FsmAddTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 9);
> - return;
> - }
> - mISDN_FsmChangeState(fi, ST_L2_8);
> - transmit_enquiry(l2);
> - l2->rc = 0;
> -}
> -
> -static void
> -l2_pull_iqueue(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> - struct sk_buff *skb, *nskb;
> - u_char header[MAX_L2HEADER_LEN];
> - u_int i, p1;
> -
> - if (!cansend(l2))
> - return;
> -
> - skb = skb_dequeue(&l2->i_queue);
> - if (!skb)
> - return;
> - i = sethdraddr(l2, header, CMD);
> - if (test_bit(FLG_MOD128, &l2->flag)) {
> - header[i++] = l2->vs << 1;
> - header[i++] = l2->vr << 1;
> - } else
> - header[i++] = (l2->vr << 5) | (l2->vs << 1);
> - nskb = skb_realloc_headroom(skb, i);
> - if (!nskb) {
> - printk(KERN_WARNING "%s: no headroom(%d) copy for IFrame\n",
> - mISDNDevName4ch(&l2->ch), i);
> - skb_queue_head(&l2->i_queue, skb);
> - return;
> - }
> - if (test_bit(FLG_MOD128, &l2->flag)) {
> - p1 = (l2->vs - l2->va) % 128;
> - l2->vs = (l2->vs + 1) % 128;
> - } else {
> - p1 = (l2->vs - l2->va) % 8;
> - l2->vs = (l2->vs + 1) % 8;
> - }
> - p1 = (p1 + l2->sow) % l2->window;
> - if (l2->windowar[p1]) {
> - printk(KERN_WARNING "%s: l2 try overwrite ack queue entry %d\n",
> - mISDNDevName4ch(&l2->ch), p1);
> - dev_kfree_skb(l2->windowar[p1]);
> - }
> - l2->windowar[p1] = skb;
> - memcpy(skb_push(nskb, i), header, i);
> - l2down(l2, PH_DATA_REQ, l2_newid(l2), nskb);
> - test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
> - if (!test_and_set_bit(FLG_T200_RUN, &l2->flag)) {
> - mISDN_FsmDelTimer(&l2->t203, 13);
> - mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 11);
> - }
> -}
> -
> -static void
> -l2_st8_got_super(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> - struct sk_buff *skb = arg;
> - int PollFlag, rsp, rnr = 0;
> - unsigned int nr;
> -
> - rsp = *skb->data & 0x2;
> - if (test_bit(FLG_ORIG, &l2->flag))
> - rsp = !rsp;
> -
> - skb_pull(skb, l2addrsize(l2));
> -
> - if (IsRNR(skb->data, l2)) {
> - 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(l2, nr)) {
> - if (rnr) {
> - restart_t200(l2, 15);
> - } else {
> - stop_t200(l2, 16);
> - mISDN_FsmAddTimer(&l2->t203, l2->T203,
> - EV_L2_T203, NULL, 5);
> - setva(l2, nr);
> - }
> - invoke_retransmission(l2, nr);
> - mISDN_FsmChangeState(fi, ST_L2_7);
> - if (skb_queue_len(&l2->i_queue) && cansend(l2))
> - mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);
> - } else
> - nrerrorrecovery(fi);
> - } else {
> - if (!rsp && PollFlag)
> - enquiry_response(l2);
> - if (legalnr(l2, nr))
> - setva(l2, nr);
> - else
> - nrerrorrecovery(fi);
> - }
> -}
> -
> -static void
> -l2_got_FRMR(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> - struct sk_buff *skb = arg;
> -
> - skb_pull(skb, l2addrsize(l2) + 1);
> -
> - if (!(skb->data[0] & 1) || ((skb->data[0] & 3) == 1) || /* I or S */
> - (IsUA(skb->data) && (fi->state == ST_L2_7))) {
> - l2mgr(l2, MDL_ERROR_IND, (void *) 'K');
> - establishlink(fi);
> - test_and_clear_bit(FLG_L3_INIT, &l2->flag);
> - }
> - dev_kfree_skb(skb);
> -}
> -
> -static void
> -l2_st24_tei_remove(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> -
> - skb_queue_purge(&l2->ui_queue);
> - l2->tei = GROUP_TEI;
> - mISDN_FsmChangeState(fi, ST_L2_1);
> -}
> -
> -static void
> -l2_st3_tei_remove(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> -
> - skb_queue_purge(&l2->ui_queue);
> - l2->tei = GROUP_TEI;
> - l2up_create(l2, DL_RELEASE_IND, 0, NULL);
> - mISDN_FsmChangeState(fi, ST_L2_1);
> -}
> -
> -static void
> -l2_st5_tei_remove(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> -
> - skb_queue_purge(&l2->i_queue);
> - skb_queue_purge(&l2->ui_queue);
> - freewin(l2);
> - l2->tei = GROUP_TEI;
> - stop_t200(l2, 17);
> - st5_dl_release_l2l3(l2);
> - mISDN_FsmChangeState(fi, ST_L2_1);
> -}
> -
> -static void
> -l2_st6_tei_remove(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> -
> - skb_queue_purge(&l2->ui_queue);
> - l2->tei = GROUP_TEI;
> - stop_t200(l2, 18);
> - l2up_create(l2, DL_RELEASE_IND, 0, NULL);
> - mISDN_FsmChangeState(fi, ST_L2_1);
> -}
> -
> -static void
> -l2_tei_remove(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> -
> - skb_queue_purge(&l2->i_queue);
> - skb_queue_purge(&l2->ui_queue);
> - freewin(l2);
> - l2->tei = GROUP_TEI;
> - stop_t200(l2, 17);
> - mISDN_FsmDelTimer(&l2->t203, 19);
> - l2up_create(l2, DL_RELEASE_IND, 0, NULL);
> -/* mISDN_queue_data(&l2->inst, l2->inst.id | MSG_BROADCAST,
> - * MGR_SHORTSTATUS_IND, SSTATUS_L2_RELEASED,
> - * 0, NULL, 0);
> - */
> - mISDN_FsmChangeState(fi, ST_L2_1);
> -}
> -
> -static void
> -l2_st14_persistent_da(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> - struct sk_buff *skb = arg;
> -
> - skb_queue_purge(&l2->i_queue);
> - skb_queue_purge(&l2->ui_queue);
> - if (test_and_clear_bit(FLG_ESTAB_PEND, &l2->flag))
> - l2up(l2, DL_RELEASE_IND, skb);
> - else
> - dev_kfree_skb(skb);
> -}
> -
> -static void
> -l2_st5_persistent_da(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> - struct sk_buff *skb = arg;
> -
> - skb_queue_purge(&l2->i_queue);
> - skb_queue_purge(&l2->ui_queue);
> - freewin(l2);
> - stop_t200(l2, 19);
> - st5_dl_release_l2l3(l2);
> - mISDN_FsmChangeState(fi, ST_L2_4);
> - if (l2->tm)
> - l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
> - dev_kfree_skb(skb);
> -}
> -
> -static void
> -l2_st6_persistent_da(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> - struct sk_buff *skb = arg;
> -
> - skb_queue_purge(&l2->ui_queue);
> - stop_t200(l2, 20);
> - l2up(l2, DL_RELEASE_CNF, skb);
> - mISDN_FsmChangeState(fi, ST_L2_4);
> - if (l2->tm)
> - l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
> -}
> -
> -static void
> -l2_persistent_da(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> - struct sk_buff *skb = arg;
> -
> - skb_queue_purge(&l2->i_queue);
> - skb_queue_purge(&l2->ui_queue);
> - freewin(l2);
> - stop_t200(l2, 19);
> - mISDN_FsmDelTimer(&l2->t203, 19);
> - l2up(l2, DL_RELEASE_IND, skb);
> - mISDN_FsmChangeState(fi, ST_L2_4);
> - if (l2->tm)
> - l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
> -}
> -
> -static void
> -l2_set_own_busy(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> - struct sk_buff *skb = arg;
> -
> - if (!test_and_set_bit(FLG_OWN_BUSY, &l2->flag)) {
> - enquiry_cr(l2, RNR, RSP, 0);
> - test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
> - }
> - dev_kfree_skb(skb);
> -}
> -
> -static void
> -l2_clear_own_busy(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> - struct sk_buff *skb = arg;
> -
> - if (!test_and_clear_bit(FLG_OWN_BUSY, &l2->flag)) {
> - enquiry_cr(l2, RR, RSP, 0);
> - test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
> - }
> - dev_kfree_skb(skb);
> -}
> -
> -static void
> -l2_frame_error(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> -
> - l2mgr(l2, MDL_ERROR_IND, arg);
> -}
> -
> -static void
> -l2_frame_error_reest(struct FsmInst *fi, int event, void *arg)
> -{
> - struct layer2 *l2 = fi->userdata;
> -
> - l2mgr(l2, MDL_ERROR_IND, arg);
> - establishlink(fi);
> - test_and_clear_bit(FLG_L3_INIT, &l2->flag);
> -}
> -
> -static struct FsmNode L2FnList[] =
> -{
> - {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_UNITDATA, l2_queue_ui_assign},
> - {ST_L2_2, EV_L2_DL_UNITDATA, l2_queue_ui},
> - {ST_L2_3, EV_L2_DL_UNITDATA, l2_queue_ui},
> - {ST_L2_4, EV_L2_DL_UNITDATA, l2_send_ui},
> - {ST_L2_5, EV_L2_DL_UNITDATA, l2_send_ui},
> - {ST_L2_6, EV_L2_DL_UNITDATA, l2_send_ui},
> - {ST_L2_7, EV_L2_DL_UNITDATA, l2_send_ui},
> - {ST_L2_8, EV_L2_DL_UNITDATA, 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_timeout},
> - {ST_L2_6, EV_L2_T200, l2_timeout},
> - {ST_L2_7, EV_L2_T200, l2_timeout},
> - {ST_L2_8, EV_L2_T200, l2_timeout},
> - {ST_L2_7, EV_L2_T203, l2_timeout},
> - {ST_L2_5, EV_L2_T200I, l2_st5_tout_200},
> - {ST_L2_6, EV_L2_T200I, l2_st6_tout_200},
> - {ST_L2_7, EV_L2_T200I, l2_st7_tout_200},
> - {ST_L2_8, EV_L2_T200I, l2_st8_tout_200},
> - {ST_L2_7, EV_L2_T203I, 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 int
> -ph_data_indication(struct layer2 *l2, struct mISDNhead *hh, struct sk_buff *skb)
> -{
> - u_char *datap = skb->data;
> - int ret = -EINVAL;
> - int psapi, ptei;
> - u_int l;
> - int c = 0;
> -
> - l = l2addrsize(l2);
> - if (skb->len <= l) {
> - mISDN_FsmEvent(&l2->l2m, EV_L2_FRAME_ERROR, (void *) 'N');
> - return ret;
> - }
> - if (test_bit(FLG_LAPD, &l2->flag)) { /* Maybe not needed */
> - psapi = *datap++;
> - ptei = *datap++;
> - if ((psapi & 1) || !(ptei & 1)) {
> - printk(KERN_WARNING
> - "%s l2 D-channel frame wrong EA0/EA1\n",
> - mISDNDevName4ch(&l2->ch));
> - return ret;
> - }
> - psapi >>= 2;
> - ptei >>= 1;
> - if (psapi != l2->sapi) {
> - /* not our business */
> - if (*debug & DEBUG_L2)
> - printk(KERN_DEBUG "%s: sapi %d/%d mismatch\n",
> - mISDNDevName4ch(&l2->ch), psapi,
> - l2->sapi);
> - dev_kfree_skb(skb);
> - return 0;
> - }
> - if ((ptei != l2->tei) && (ptei != GROUP_TEI)) {
> - /* not our business */
> - if (*debug & DEBUG_L2)
> - printk(KERN_DEBUG "%s: tei %d/%d mismatch\n",
> - mISDNDevName4ch(&l2->ch), ptei, l2->tei);
> - dev_kfree_skb(skb);
> - return 0;
> - }
> - } else
> - datap += l;
> - if (!(*datap & 1)) { /* I-Frame */
> - c = iframe_error(l2, skb);
> - if (!c)
> - ret = mISDN_FsmEvent(&l2->l2m, EV_L2_I, skb);
> - } else if (IsSFrame(datap, l2)) { /* S-Frame */
> - c = super_error(l2, skb);
> - if (!c)
> - ret = mISDN_FsmEvent(&l2->l2m, EV_L2_SUPER, skb);
> - } else if (IsUI(datap)) {
> - c = UI_error(l2, skb);
> - if (!c)
> - ret = mISDN_FsmEvent(&l2->l2m, EV_L2_UI, skb);
> - } else if (IsSABME(datap, l2)) {
> - c = unnum_error(l2, skb, CMD);
> - if (!c)
> - ret = mISDN_FsmEvent(&l2->l2m, EV_L2_SABME, skb);
> - } else if (IsUA(datap)) {
> - c = unnum_error(l2, skb, RSP);
> - if (!c)
> - ret = mISDN_FsmEvent(&l2->l2m, EV_L2_UA, skb);
> - } else if (IsDISC(datap)) {
> - c = unnum_error(l2, skb, CMD);
> - if (!c)
> - ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DISC, skb);
> - } else if (IsDM(datap)) {
> - c = unnum_error(l2, skb, RSP);
> - if (!c)
> - ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DM, skb);
> - } else if (IsFRMR(datap)) {
> - c = FRMR_error(l2, skb);
> - if (!c)
> - ret = mISDN_FsmEvent(&l2->l2m, EV_L2_FRMR, skb);
> - } else
> - c = 'L';
> - if (c) {
> - printk(KERN_WARNING "%s:l2 D-channel frame error %c\n",
> - mISDNDevName4ch(&l2->ch), c);
> - mISDN_FsmEvent(&l2->l2m, EV_L2_FRAME_ERROR, (void *)(long)c);
> - }
> - return ret;
> -}
> -
> -static int
> -l2_send(struct mISDNchannel *ch, struct sk_buff *skb)
> -{
> - struct layer2 *l2 = container_of(ch, struct layer2, ch);
> - struct mISDNhead *hh = mISDN_HEAD_P(skb);
> - int ret = -EINVAL;
> -
> - if (*debug & DEBUG_L2_RECV)
> - printk(KERN_DEBUG "%s: %s prim(%x) id(%x) sapi(%d) tei(%d)\n",
> - __func__, mISDNDevName4ch(&l2->ch), hh->prim, hh->id,
> - l2->sapi, l2->tei);
> - if (hh->prim == DL_INTERN_MSG) {
> - struct mISDNhead *chh = hh + 1; /* saved copy */
> -
> - *hh = *chh;
> - if (*debug & DEBUG_L2_RECV)
> - printk(KERN_DEBUG "%s: prim(%x) id(%x) internal msg\n",
> - mISDNDevName4ch(&l2->ch), hh->prim, hh->id);
> - }
> - switch (hh->prim) {
> - case PH_DATA_IND:
> - ret = ph_data_indication(l2, hh, skb);
> - break;
> - case PH_DATA_CNF:
> - ret = ph_data_confirm(l2, hh, skb);
> - break;
> - case PH_ACTIVATE_IND:
> - test_and_set_bit(FLG_L1_ACTIV, &l2->flag);
> - l2up_create(l2, MPH_ACTIVATE_IND, 0, NULL);
> - if (test_and_clear_bit(FLG_ESTAB_PEND, &l2->flag))
> - ret = mISDN_FsmEvent(&l2->l2m,
> - EV_L2_DL_ESTABLISH_REQ, skb);
> - break;
> - case PH_DEACTIVATE_IND:
> - test_and_clear_bit(FLG_L1_ACTIV, &l2->flag);
> - l2up_create(l2, MPH_DEACTIVATE_IND, 0, NULL);
> - ret = mISDN_FsmEvent(&l2->l2m, EV_L1_DEACTIVATE, skb);
> - break;
> - case MPH_INFORMATION_IND:
> - if (!l2->up)
> - break;
> - ret = l2->up->send(l2->up, skb);
> - break;
> - case DL_DATA_REQ:
> - ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DL_DATA, skb);
> - break;
> - case DL_UNITDATA_REQ:
> - ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DL_UNITDATA, skb);
> - break;
> - case DL_ESTABLISH_REQ:
> - if (test_bit(FLG_LAPB, &l2->flag))
> - test_and_set_bit(FLG_ORIG, &l2->flag);
> - if (test_bit(FLG_L1_ACTIV, &l2->flag)) {
> - if (test_bit(FLG_LAPD, &l2->flag) ||
> - test_bit(FLG_ORIG, &l2->flag))
> - ret = mISDN_FsmEvent(&l2->l2m,
> - EV_L2_DL_ESTABLISH_REQ, skb);
> - } else {
> - if (test_bit(FLG_LAPD, &l2->flag) ||
> - test_bit(FLG_ORIG, &l2->flag)) {
> - test_and_set_bit(FLG_ESTAB_PEND,
> - &l2->flag);
> - }
> - ret = l2down(l2, PH_ACTIVATE_REQ, l2_newid(l2),
> - skb);
> - }
> - break;
> - case DL_RELEASE_REQ:
> - if (test_bit(FLG_LAPB, &l2->flag))
> - l2down_create(l2, PH_DEACTIVATE_REQ,
> - l2_newid(l2), 0, NULL);
> - ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DL_RELEASE_REQ,
> - skb);
> - break;
> - case DL_TIMER200_IND:
> - mISDN_FsmEvent(&l2->l2m, EV_L2_T200I, NULL);
> - break;
> - case DL_TIMER203_IND:
> - mISDN_FsmEvent(&l2->l2m, EV_L2_T203I, NULL);
> - break;
> - default:
> - if (*debug & DEBUG_L2)
> - l2m_debug(&l2->l2m, "l2 unknown pr %04x",
> - hh->prim);
> - }
> - if (ret) {
> - dev_kfree_skb(skb);
> - ret = 0;
> - }
> - return ret;
> -}
> -
> -int
> -tei_l2(struct layer2 *l2, u_int cmd, u_long arg)
> -{
> - int ret = -EINVAL;
> -
> - if (*debug & DEBUG_L2_TEI)
> - printk(KERN_DEBUG "%s: cmd(%x) in %s\n",
> - mISDNDevName4ch(&l2->ch), cmd, __func__);
> - switch (cmd) {
> - case (MDL_ASSIGN_REQ):
> - ret = mISDN_FsmEvent(&l2->l2m, EV_L2_MDL_ASSIGN, (void *)arg);
> - break;
> - case (MDL_REMOVE_REQ):
> - ret = mISDN_FsmEvent(&l2->l2m, EV_L2_MDL_REMOVE, NULL);
> - break;
> - case (MDL_ERROR_IND):
> - ret = mISDN_FsmEvent(&l2->l2m, EV_L2_MDL_ERROR, NULL);
> - break;
> - case (MDL_ERROR_RSP):
> - /* ETS 300-125 5.3.2.1 Test: TC13010 */
> - printk(KERN_NOTICE "%s: MDL_ERROR|REQ (tei_l2)\n",
> - mISDNDevName4ch(&l2->ch));
> - ret = mISDN_FsmEvent(&l2->l2m, EV_L2_MDL_ERROR, NULL);
> - break;
> - }
> - return ret;
> -}
> -
> -static void
> -release_l2(struct layer2 *l2)
> -{
> - mISDN_FsmDelTimer(&l2->t200, 21);
> - mISDN_FsmDelTimer(&l2->t203, 16);
> - skb_queue_purge(&l2->i_queue);
> - skb_queue_purge(&l2->ui_queue);
> - skb_queue_purge(&l2->down_queue);
> - ReleaseWin(l2);
> - if (test_bit(FLG_LAPD, &l2->flag)) {
> - TEIrelease(l2);
> - if (l2->ch.st)
> - l2->ch.st->dev->D.ctrl(&l2->ch.st->dev->D,
> - CLOSE_CHANNEL, NULL);
> - }
> - kfree(l2);
> -}
> -
> -static int
> -l2_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
> -{
> - struct layer2 *l2 = container_of(ch, struct layer2, ch);
> - u_int info;
> -
> - if (*debug & DEBUG_L2_CTRL)
> - printk(KERN_DEBUG "%s: %s cmd(%x)\n",
> - mISDNDevName4ch(ch), __func__, cmd);
> -
> - switch (cmd) {
> - case OPEN_CHANNEL:
> - if (test_bit(FLG_LAPD, &l2->flag)) {
> - set_channel_address(&l2->ch, l2->sapi, l2->tei);
> - info = DL_INFO_L2_CONNECT;
> - l2up_create(l2, DL_INFORMATION_IND,
> - sizeof(info), &info);
> - }
> - break;
> - case CLOSE_CHANNEL:
> - if (l2->ch.peer)
> - l2->ch.peer->ctrl(l2->ch.peer, CLOSE_CHANNEL, NULL);
> - release_l2(l2);
> - break;
> - }
> - return 0;
> -}
> -
> -struct layer2 *
> -create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, int tei,
> - int sapi)
> -{
> - struct layer2 *l2;
> - struct channel_req rq;
> -
> - l2 = kzalloc_obj(struct layer2);
> - if (!l2) {
> - printk(KERN_ERR "kzalloc layer2 failed\n");
> - return NULL;
> - }
> - l2->next_id = 1;
> - l2->down_id = MISDN_ID_NONE;
> - l2->up = ch;
> - l2->ch.st = ch->st;
> - l2->ch.send = l2_send;
> - l2->ch.ctrl = l2_ctrl;
> - switch (protocol) {
> - case ISDN_P_LAPD_NT:
> - test_and_set_bit(FLG_LAPD, &l2->flag);
> - test_and_set_bit(FLG_LAPD_NET, &l2->flag);
> - test_and_set_bit(FLG_MOD128, &l2->flag);
> - l2->sapi = sapi;
> - l2->maxlen = MAX_DFRAME_LEN;
> - if (test_bit(OPTION_L2_PMX, &options))
> - l2->window = 7;
> - else
> - l2->window = 1;
> - if (test_bit(OPTION_L2_PTP, &options))
> - test_and_set_bit(FLG_PTP, &l2->flag);
> - if (test_bit(OPTION_L2_FIXEDTEI, &options))
> - test_and_set_bit(FLG_FIXED_TEI, &l2->flag);
> - l2->tei = tei;
> - l2->T200 = 1000;
> - l2->N200 = 3;
> - l2->T203 = 10000;
> - if (test_bit(OPTION_L2_PMX, &options))
> - rq.protocol = ISDN_P_NT_E1;
> - else
> - rq.protocol = ISDN_P_NT_S0;
> - rq.adr.channel = 0;
> - l2->ch.st->dev->D.ctrl(&l2->ch.st->dev->D, OPEN_CHANNEL, &rq);
> - break;
> - case ISDN_P_LAPD_TE:
> - test_and_set_bit(FLG_LAPD, &l2->flag);
> - test_and_set_bit(FLG_MOD128, &l2->flag);
> - test_and_set_bit(FLG_ORIG, &l2->flag);
> - l2->sapi = sapi;
> - l2->maxlen = MAX_DFRAME_LEN;
> - if (test_bit(OPTION_L2_PMX, &options))
> - l2->window = 7;
> - else
> - l2->window = 1;
> - if (test_bit(OPTION_L2_PTP, &options))
> - test_and_set_bit(FLG_PTP, &l2->flag);
> - if (test_bit(OPTION_L2_FIXEDTEI, &options))
> - test_and_set_bit(FLG_FIXED_TEI, &l2->flag);
> - l2->tei = tei;
> - l2->T200 = 1000;
> - l2->N200 = 3;
> - l2->T203 = 10000;
> - if (test_bit(OPTION_L2_PMX, &options))
> - rq.protocol = ISDN_P_TE_E1;
> - else
> - rq.protocol = ISDN_P_TE_S0;
> - rq.adr.channel = 0;
> - l2->ch.st->dev->D.ctrl(&l2->ch.st->dev->D, OPEN_CHANNEL, &rq);
> - break;
> - case ISDN_P_B_X75SLP:
> - test_and_set_bit(FLG_LAPB, &l2->flag);
> - l2->window = 7;
> - l2->maxlen = MAX_DATA_SIZE;
> - l2->T200 = 1000;
> - l2->N200 = 4;
> - l2->T203 = 5000;
> - l2->addr.A = 3;
> - l2->addr.B = 1;
> - break;
> - default:
> - printk(KERN_ERR "layer2 create failed prt %x\n",
> - protocol);
> - kfree(l2);
> - return NULL;
> - }
> - skb_queue_head_init(&l2->i_queue);
> - skb_queue_head_init(&l2->ui_queue);
> - skb_queue_head_init(&l2->down_queue);
> - skb_queue_head_init(&l2->tmp_queue);
> - InitWin(l2);
> - l2->l2m.fsm = &l2fsm;
> - if (test_bit(FLG_LAPB, &l2->flag) ||
> - test_bit(FLG_FIXED_TEI, &l2->flag) ||
> - test_bit(FLG_LAPD_NET, &l2->flag))
> - l2->l2m.state = ST_L2_4;
> - else
> - l2->l2m.state = ST_L2_1;
> - l2->l2m.debug = *debug;
> - l2->l2m.userdata = l2;
> - l2->l2m.userint = 0;
> - l2->l2m.printdebug = l2m_debug;
> -
> - mISDN_FsmInitTimer(&l2->l2m, &l2->t200);
> - mISDN_FsmInitTimer(&l2->l2m, &l2->t203);
> - return l2;
> -}
> -
> -static int
> -x75create(struct channel_req *crq)
> -{
> - struct layer2 *l2;
> -
> - if (crq->protocol != ISDN_P_B_X75SLP)
> - return -EPROTONOSUPPORT;
> - l2 = create_l2(crq->ch, crq->protocol, 0, 0, 0);
> - if (!l2)
> - return -ENOMEM;
> - crq->ch = &l2->ch;
> - crq->protocol = ISDN_P_B_HDLC;
> - return 0;
> -}
> -
> -static struct Bprotocol X75SLP = {
> - .Bprotocols = (1 << (ISDN_P_B_X75SLP & ISDN_P_B_MASK)),
> - .name = "X75SLP",
> - .create = x75create
> -};
> -
> -int
> -Isdnl2_Init(u_int *deb)
> -{
> - int res;
> - debug = deb;
> - mISDN_register_Bprotocol(&X75SLP);
> - l2fsm.state_count = L2_STATE_COUNT;
> - l2fsm.event_count = L2_EVENT_COUNT;
> - l2fsm.strEvent = strL2Event;
> - l2fsm.strState = strL2State;
> - res = mISDN_FsmNew(&l2fsm, L2FnList, ARRAY_SIZE(L2FnList));
> - if (res)
> - goto error;
> - res = TEIInit(deb);
> - if (res)
> - goto error_fsm;
> - return 0;
> -
> -error_fsm:
> - mISDN_FsmFree(&l2fsm);
> -error:
> - mISDN_unregister_Bprotocol(&X75SLP);
> - return res;
> -}
> -
> -void
> -Isdnl2_cleanup(void)
> -{
> - mISDN_unregister_Bprotocol(&X75SLP);
> - TEIFree();
> - mISDN_FsmFree(&l2fsm);
> -}
> diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c
> deleted file mode 100644
> index 77b900db1cac..000000000000
> --- a/drivers/isdn/mISDN/socket.c
> +++ /dev/null
> @@ -1,825 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - *
> - * Author Karsten Keil <kkeil@novell.com>
> - *
> - * Copyright 2008 by Karsten Keil <kkeil@novell.com>
> - */
> -
> -#include <linux/mISDNif.h>
> -#include <linux/slab.h>
> -#include <linux/export.h>
> -#include "core.h"
> -
> -static u_int *debug;
> -
> -static struct proto mISDN_proto = {
> - .name = "misdn",
> - .owner = THIS_MODULE,
> - .obj_size = sizeof(struct mISDN_sock)
> -};
> -
> -#define _pms(sk) ((struct mISDN_sock *)sk)
> -
> -static struct mISDN_sock_list data_sockets = {
> - .lock = __RW_LOCK_UNLOCKED(data_sockets.lock)
> -};
> -
> -static struct mISDN_sock_list base_sockets = {
> - .lock = __RW_LOCK_UNLOCKED(base_sockets.lock)
> -};
> -
> -#define L2_HEADER_LEN 4
> -
> -static inline struct sk_buff *
> -_l2_alloc_skb(unsigned int len, gfp_t gfp_mask)
> -{
> - struct sk_buff *skb;
> -
> - skb = alloc_skb(len + L2_HEADER_LEN, gfp_mask);
> - if (likely(skb))
> - skb_reserve(skb, L2_HEADER_LEN);
> - return skb;
> -}
> -
> -static void
> -mISDN_sock_link(struct mISDN_sock_list *l, struct sock *sk)
> -{
> - write_lock_bh(&l->lock);
> - sk_add_node(sk, &l->head);
> - write_unlock_bh(&l->lock);
> -}
> -
> -static void mISDN_sock_unlink(struct mISDN_sock_list *l, struct sock *sk)
> -{
> - write_lock_bh(&l->lock);
> - sk_del_node_init(sk);
> - write_unlock_bh(&l->lock);
> -}
> -
> -static int
> -mISDN_send(struct mISDNchannel *ch, struct sk_buff *skb)
> -{
> - struct mISDN_sock *msk;
> - int err;
> -
> - msk = container_of(ch, struct mISDN_sock, ch);
> - if (*debug & DEBUG_SOCKET)
> - printk(KERN_DEBUG "%s len %d %p\n", __func__, skb->len, skb);
> - if (msk->sk.sk_state == MISDN_CLOSED)
> - return -EUNATCH;
> - __net_timestamp(skb);
> - err = sock_queue_rcv_skb(&msk->sk, skb);
> - if (err)
> - printk(KERN_WARNING "%s: error %d\n", __func__, err);
> - return err;
> -}
> -
> -static int
> -mISDN_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
> -{
> - struct mISDN_sock *msk;
> -
> - msk = container_of(ch, struct mISDN_sock, ch);
> - if (*debug & DEBUG_SOCKET)
> - printk(KERN_DEBUG "%s(%p, %x, %p)\n", __func__, ch, cmd, arg);
> - switch (cmd) {
> - case CLOSE_CHANNEL:
> - msk->sk.sk_state = MISDN_CLOSED;
> - break;
> - }
> - return 0;
> -}
> -
> -static inline void
> -mISDN_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
> -{
> - struct __kernel_old_timeval tv;
> -
> - if (_pms(sk)->cmask & MISDN_TIME_STAMP) {
> - skb_get_timestamp(skb, &tv);
> - put_cmsg(msg, SOL_MISDN, MISDN_TIME_STAMP, sizeof(tv), &tv);
> - }
> -}
> -
> -static int
> -mISDN_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
> - int flags)
> -{
> - struct sk_buff *skb;
> - struct sock *sk = sock->sk;
> -
> - int copied, err;
> -
> - if (*debug & DEBUG_SOCKET)
> - printk(KERN_DEBUG "%s: len %d, flags %x ch.nr %d, proto %x\n",
> - __func__, (int)len, flags, _pms(sk)->ch.nr,
> - sk->sk_protocol);
> - if (flags & (MSG_OOB))
> - return -EOPNOTSUPP;
> -
> - if (sk->sk_state == MISDN_CLOSED)
> - return 0;
> -
> - skb = skb_recv_datagram(sk, flags, &err);
> - if (!skb)
> - return err;
> -
> - if (msg->msg_name) {
> - DECLARE_SOCKADDR(struct sockaddr_mISDN *, maddr, msg->msg_name);
> -
> - maddr->family = AF_ISDN;
> - maddr->dev = _pms(sk)->dev->id;
> - if ((sk->sk_protocol == ISDN_P_LAPD_TE) ||
> - (sk->sk_protocol == ISDN_P_LAPD_NT)) {
> - maddr->channel = (mISDN_HEAD_ID(skb) >> 16) & 0xff;
> - maddr->tei = (mISDN_HEAD_ID(skb) >> 8) & 0xff;
> - maddr->sapi = mISDN_HEAD_ID(skb) & 0xff;
> - } else {
> - maddr->channel = _pms(sk)->ch.nr;
> - maddr->sapi = _pms(sk)->ch.addr & 0xFF;
> - maddr->tei = (_pms(sk)->ch.addr >> 8) & 0xFF;
> - }
> - msg->msg_namelen = sizeof(*maddr);
> - }
> -
> - copied = skb->len + MISDN_HEADER_LEN;
> - if (len < copied) {
> - if (flags & MSG_PEEK)
> - refcount_dec(&skb->users);
> - else
> - skb_queue_head(&sk->sk_receive_queue, skb);
> - return -ENOSPC;
> - }
> - memcpy(skb_push(skb, MISDN_HEADER_LEN), mISDN_HEAD_P(skb),
> - MISDN_HEADER_LEN);
> -
> - err = skb_copy_datagram_msg(skb, 0, msg, copied);
> -
> - mISDN_sock_cmsg(sk, msg, skb);
> -
> - skb_free_datagram(sk, skb);
> -
> - return err ? : copied;
> -}
> -
> -static int
> -mISDN_sock_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
> -{
> - struct sock *sk = sock->sk;
> - struct sk_buff *skb;
> - int err = -ENOMEM;
> -
> - if (*debug & DEBUG_SOCKET)
> - printk(KERN_DEBUG "%s: len %d flags %x ch %d proto %x\n",
> - __func__, (int)len, msg->msg_flags, _pms(sk)->ch.nr,
> - sk->sk_protocol);
> -
> - if (msg->msg_flags & MSG_OOB)
> - return -EOPNOTSUPP;
> -
> - if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_NOSIGNAL | MSG_ERRQUEUE))
> - return -EINVAL;
> -
> - if (len < MISDN_HEADER_LEN)
> - return -EINVAL;
> -
> - if (sk->sk_state != MISDN_BOUND)
> - return -EBADFD;
> -
> - lock_sock(sk);
> -
> - skb = _l2_alloc_skb(len, GFP_KERNEL);
> - if (!skb)
> - goto done;
> -
> - if (memcpy_from_msg(skb_put(skb, len), msg, len)) {
> - err = -EFAULT;
> - goto done;
> - }
> -
> - memcpy(mISDN_HEAD_P(skb), skb->data, MISDN_HEADER_LEN);
> - skb_pull(skb, MISDN_HEADER_LEN);
> -
> - if (msg->msg_namelen >= sizeof(struct sockaddr_mISDN)) {
> - /* if we have a address, we use it */
> - DECLARE_SOCKADDR(struct sockaddr_mISDN *, maddr, msg->msg_name);
> - mISDN_HEAD_ID(skb) = maddr->channel;
> - } else { /* use default for L2 messages */
> - if ((sk->sk_protocol == ISDN_P_LAPD_TE) ||
> - (sk->sk_protocol == ISDN_P_LAPD_NT))
> - mISDN_HEAD_ID(skb) = _pms(sk)->ch.nr;
> - }
> -
> - if (*debug & DEBUG_SOCKET)
> - printk(KERN_DEBUG "%s: ID:%x\n",
> - __func__, mISDN_HEAD_ID(skb));
> -
> - err = -ENODEV;
> - if (!_pms(sk)->ch.peer)
> - goto done;
> - err = _pms(sk)->ch.recv(_pms(sk)->ch.peer, skb);
> - if (err)
> - goto done;
> - else {
> - skb = NULL;
> - err = len;
> - }
> -
> -done:
> - kfree_skb(skb);
> - release_sock(sk);
> - return err;
> -}
> -
> -static int
> -data_sock_release(struct socket *sock)
> -{
> - struct sock *sk = sock->sk;
> -
> - if (*debug & DEBUG_SOCKET)
> - printk(KERN_DEBUG "%s(%p) sk=%p\n", __func__, sock, sk);
> - if (!sk)
> - return 0;
> - switch (sk->sk_protocol) {
> - case ISDN_P_TE_S0:
> - case ISDN_P_NT_S0:
> - case ISDN_P_TE_E1:
> - case ISDN_P_NT_E1:
> - if (sk->sk_state == MISDN_BOUND)
> - delete_channel(&_pms(sk)->ch);
> - else
> - mISDN_sock_unlink(&data_sockets, sk);
> - break;
> - case ISDN_P_LAPD_TE:
> - case ISDN_P_LAPD_NT:
> - case ISDN_P_B_RAW:
> - case ISDN_P_B_HDLC:
> - case ISDN_P_B_X75SLP:
> - case ISDN_P_B_L2DTMF:
> - case ISDN_P_B_L2DSP:
> - case ISDN_P_B_L2DSPHDLC:
> - delete_channel(&_pms(sk)->ch);
> - mISDN_sock_unlink(&data_sockets, sk);
> - break;
> - }
> -
> - lock_sock(sk);
> -
> - sock_orphan(sk);
> - skb_queue_purge(&sk->sk_receive_queue);
> -
> - release_sock(sk);
> - sock_put(sk);
> -
> - return 0;
> -}
> -
> -static int
> -data_sock_ioctl_bound(struct sock *sk, unsigned int cmd, void __user *p)
> -{
> - struct mISDN_ctrl_req cq;
> - int err = -EINVAL, val[2];
> - struct mISDNchannel *bchan, *next;
> -
> - lock_sock(sk);
> - if (!_pms(sk)->dev) {
> - err = -ENODEV;
> - goto done;
> - }
> - switch (cmd) {
> - case IMCTRLREQ:
> - if (copy_from_user(&cq, p, sizeof(cq))) {
> - err = -EFAULT;
> - break;
> - }
> - if ((sk->sk_protocol & ~ISDN_P_B_MASK) == ISDN_P_B_START) {
> - list_for_each_entry_safe(bchan, next,
> - &_pms(sk)->dev->bchannels, list) {
> - if (bchan->nr == cq.channel) {
> - err = bchan->ctrl(bchan,
> - CONTROL_CHANNEL, &cq);
> - break;
> - }
> - }
> - } else
> - err = _pms(sk)->dev->D.ctrl(&_pms(sk)->dev->D,
> - CONTROL_CHANNEL, &cq);
> - if (err)
> - break;
> - if (copy_to_user(p, &cq, sizeof(cq)))
> - err = -EFAULT;
> - break;
> - case IMCLEAR_L2:
> - if (sk->sk_protocol != ISDN_P_LAPD_NT) {
> - err = -EINVAL;
> - break;
> - }
> - val[0] = cmd;
> - if (get_user(val[1], (int __user *)p)) {
> - err = -EFAULT;
> - break;
> - }
> - err = _pms(sk)->dev->teimgr->ctrl(_pms(sk)->dev->teimgr,
> - CONTROL_CHANNEL, val);
> - break;
> - case IMHOLD_L1:
> - if (sk->sk_protocol != ISDN_P_LAPD_NT
> - && sk->sk_protocol != ISDN_P_LAPD_TE) {
> - err = -EINVAL;
> - break;
> - }
> - val[0] = cmd;
> - if (get_user(val[1], (int __user *)p)) {
> - err = -EFAULT;
> - break;
> - }
> - err = _pms(sk)->dev->teimgr->ctrl(_pms(sk)->dev->teimgr,
> - CONTROL_CHANNEL, val);
> - break;
> - default:
> - err = -EINVAL;
> - break;
> - }
> -done:
> - release_sock(sk);
> - return err;
> -}
> -
> -static int
> -data_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
> -{
> - int err = 0, id;
> - struct sock *sk = sock->sk;
> - struct mISDNdevice *dev;
> - struct mISDNversion ver;
> -
> - switch (cmd) {
> - case IMGETVERSION:
> - ver.major = MISDN_MAJOR_VERSION;
> - ver.minor = MISDN_MINOR_VERSION;
> - ver.release = MISDN_RELEASE;
> - if (copy_to_user((void __user *)arg, &ver, sizeof(ver)))
> - err = -EFAULT;
> - break;
> - case IMGETCOUNT:
> - id = get_mdevice_count();
> - if (put_user(id, (int __user *)arg))
> - err = -EFAULT;
> - break;
> - case IMGETDEVINFO:
> - if (get_user(id, (int __user *)arg)) {
> - err = -EFAULT;
> - break;
> - }
> - dev = get_mdevice(id);
> - if (dev) {
> - struct mISDN_devinfo di;
> -
> - memset(&di, 0, sizeof(di));
> - di.id = dev->id;
> - di.Dprotocols = dev->Dprotocols;
> - di.Bprotocols = dev->Bprotocols | get_all_Bprotocols();
> - di.protocol = dev->D.protocol;
> - memcpy(di.channelmap, dev->channelmap,
> - sizeof(di.channelmap));
> - di.nrbchan = dev->nrbchan;
> - strscpy(di.name, dev_name(&dev->dev), sizeof(di.name));
> - if (copy_to_user((void __user *)arg, &di, sizeof(di)))
> - err = -EFAULT;
> - } else
> - err = -ENODEV;
> - break;
> - default:
> - if (sk->sk_state == MISDN_BOUND)
> - err = data_sock_ioctl_bound(sk, cmd,
> - (void __user *)arg);
> - else
> - err = -ENOTCONN;
> - }
> - return err;
> -}
> -
> -static int data_sock_setsockopt(struct socket *sock, int level, int optname,
> - sockptr_t optval, unsigned int optlen)
> -{
> - struct sock *sk = sock->sk;
> - int err = 0, opt = 0;
> -
> - if (*debug & DEBUG_SOCKET)
> - printk(KERN_DEBUG "%s(%p, %d, %x, optval, %d)\n", __func__, sock,
> - level, optname, optlen);
> -
> - lock_sock(sk);
> -
> - switch (optname) {
> - case MISDN_TIME_STAMP:
> - err = copy_safe_from_sockptr(&opt, sizeof(opt),
> - optval, optlen);
> - if (err)
> - break;
> -
> - if (opt)
> - _pms(sk)->cmask |= MISDN_TIME_STAMP;
> - else
> - _pms(sk)->cmask &= ~MISDN_TIME_STAMP;
> - break;
> - default:
> - err = -ENOPROTOOPT;
> - break;
> - }
> - release_sock(sk);
> - return err;
> -}
> -
> -static int data_sock_getsockopt(struct socket *sock, int level, int optname,
> - char __user *optval, int __user *optlen)
> -{
> - struct sock *sk = sock->sk;
> - int len, opt;
> -
> - if (get_user(len, optlen))
> - return -EFAULT;
> -
> - if (len != sizeof(char))
> - return -EINVAL;
> -
> - switch (optname) {
> - case MISDN_TIME_STAMP:
> - if (_pms(sk)->cmask & MISDN_TIME_STAMP)
> - opt = 1;
> - else
> - opt = 0;
> -
> - if (put_user(opt, optval))
> - return -EFAULT;
> - break;
> - default:
> - return -ENOPROTOOPT;
> - }
> -
> - return 0;
> -}
> -
> -static int
> -data_sock_bind(struct socket *sock, struct sockaddr_unsized *addr, int addr_len)
> -{
> - struct sockaddr_mISDN *maddr = (struct sockaddr_mISDN *) addr;
> - struct sock *sk = sock->sk;
> - struct sock *csk;
> - int err = 0;
> -
> - if (*debug & DEBUG_SOCKET)
> - printk(KERN_DEBUG "%s(%p) sk=%p\n", __func__, sock, sk);
> - if (addr_len != sizeof(struct sockaddr_mISDN))
> - return -EINVAL;
> - if (!maddr || maddr->family != AF_ISDN)
> - return -EINVAL;
> -
> - lock_sock(sk);
> -
> - if (_pms(sk)->dev) {
> - err = -EALREADY;
> - goto done;
> - }
> - _pms(sk)->dev = get_mdevice(maddr->dev);
> - if (!_pms(sk)->dev) {
> - err = -ENODEV;
> - goto done;
> - }
> -
> - if (sk->sk_protocol < ISDN_P_B_START) {
> - read_lock_bh(&data_sockets.lock);
> - sk_for_each(csk, &data_sockets.head) {
> - if (sk == csk)
> - continue;
> - if (_pms(csk)->dev != _pms(sk)->dev)
> - continue;
> - if (csk->sk_protocol >= ISDN_P_B_START)
> - continue;
> - if (IS_ISDN_P_TE(csk->sk_protocol)
> - == IS_ISDN_P_TE(sk->sk_protocol))
> - continue;
> - read_unlock_bh(&data_sockets.lock);
> - err = -EBUSY;
> - goto done;
> - }
> - read_unlock_bh(&data_sockets.lock);
> - }
> -
> - _pms(sk)->ch.send = mISDN_send;
> - _pms(sk)->ch.ctrl = mISDN_ctrl;
> -
> - switch (sk->sk_protocol) {
> - case ISDN_P_TE_S0:
> - case ISDN_P_NT_S0:
> - case ISDN_P_TE_E1:
> - case ISDN_P_NT_E1:
> - mISDN_sock_unlink(&data_sockets, sk);
> - err = connect_layer1(_pms(sk)->dev, &_pms(sk)->ch,
> - sk->sk_protocol, maddr);
> - if (err)
> - mISDN_sock_link(&data_sockets, sk);
> - break;
> - case ISDN_P_LAPD_TE:
> - case ISDN_P_LAPD_NT:
> - err = create_l2entity(_pms(sk)->dev, &_pms(sk)->ch,
> - sk->sk_protocol, maddr);
> - break;
> - case ISDN_P_B_RAW:
> - case ISDN_P_B_HDLC:
> - case ISDN_P_B_X75SLP:
> - case ISDN_P_B_L2DTMF:
> - case ISDN_P_B_L2DSP:
> - case ISDN_P_B_L2DSPHDLC:
> - err = connect_Bstack(_pms(sk)->dev, &_pms(sk)->ch,
> - sk->sk_protocol, maddr);
> - break;
> - default:
> - err = -EPROTONOSUPPORT;
> - }
> - if (err)
> - goto done;
> - sk->sk_state = MISDN_BOUND;
> - _pms(sk)->ch.protocol = sk->sk_protocol;
> -
> -done:
> - release_sock(sk);
> - return err;
> -}
> -
> -static int
> -data_sock_getname(struct socket *sock, struct sockaddr *addr,
> - int peer)
> -{
> - struct sockaddr_mISDN *maddr = (struct sockaddr_mISDN *) addr;
> - struct sock *sk = sock->sk;
> -
> - if (!_pms(sk)->dev)
> - return -EBADFD;
> -
> - lock_sock(sk);
> -
> - maddr->family = AF_ISDN;
> - maddr->dev = _pms(sk)->dev->id;
> - maddr->channel = _pms(sk)->ch.nr;
> - maddr->sapi = _pms(sk)->ch.addr & 0xff;
> - maddr->tei = (_pms(sk)->ch.addr >> 8) & 0xff;
> - release_sock(sk);
> - return sizeof(*maddr);
> -}
> -
> -static const struct proto_ops data_sock_ops = {
> - .family = PF_ISDN,
> - .owner = THIS_MODULE,
> - .release = data_sock_release,
> - .ioctl = data_sock_ioctl,
> - .bind = data_sock_bind,
> - .getname = data_sock_getname,
> - .sendmsg = mISDN_sock_sendmsg,
> - .recvmsg = mISDN_sock_recvmsg,
> - .poll = datagram_poll,
> - .listen = sock_no_listen,
> - .shutdown = sock_no_shutdown,
> - .setsockopt = data_sock_setsockopt,
> - .getsockopt = data_sock_getsockopt,
> - .connect = sock_no_connect,
> - .socketpair = sock_no_socketpair,
> - .accept = sock_no_accept,
> - .mmap = sock_no_mmap
> -};
> -
> -static int
> -data_sock_create(struct net *net, struct socket *sock, int protocol, int kern)
> -{
> - struct sock *sk;
> -
> - if (sock->type != SOCK_DGRAM)
> - return -ESOCKTNOSUPPORT;
> -
> - sk = sk_alloc(net, PF_ISDN, GFP_KERNEL, &mISDN_proto, kern);
> - if (!sk)
> - return -ENOMEM;
> -
> - sock_init_data(sock, sk);
> -
> - sock->ops = &data_sock_ops;
> - sock->state = SS_UNCONNECTED;
> - sock_reset_flag(sk, SOCK_ZAPPED);
> -
> - sk->sk_protocol = protocol;
> - sk->sk_state = MISDN_OPEN;
> - mISDN_sock_link(&data_sockets, sk);
> -
> - return 0;
> -}
> -
> -static int
> -base_sock_release(struct socket *sock)
> -{
> - struct sock *sk = sock->sk;
> -
> - printk(KERN_DEBUG "%s(%p) sk=%p\n", __func__, sock, sk);
> - if (!sk)
> - return 0;
> -
> - mISDN_sock_unlink(&base_sockets, sk);
> - sock_orphan(sk);
> - sock_put(sk);
> -
> - return 0;
> -}
> -
> -static int
> -base_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
> -{
> - int err = 0, id;
> - struct mISDNdevice *dev;
> - struct mISDNversion ver;
> -
> - switch (cmd) {
> - case IMGETVERSION:
> - ver.major = MISDN_MAJOR_VERSION;
> - ver.minor = MISDN_MINOR_VERSION;
> - ver.release = MISDN_RELEASE;
> - if (copy_to_user((void __user *)arg, &ver, sizeof(ver)))
> - err = -EFAULT;
> - break;
> - case IMGETCOUNT:
> - id = get_mdevice_count();
> - if (put_user(id, (int __user *)arg))
> - err = -EFAULT;
> - break;
> - case IMGETDEVINFO:
> - if (get_user(id, (int __user *)arg)) {
> - err = -EFAULT;
> - break;
> - }
> - dev = get_mdevice(id);
> - if (dev) {
> - struct mISDN_devinfo di;
> -
> - memset(&di, 0, sizeof(di));
> - di.id = dev->id;
> - di.Dprotocols = dev->Dprotocols;
> - di.Bprotocols = dev->Bprotocols | get_all_Bprotocols();
> - di.protocol = dev->D.protocol;
> - memcpy(di.channelmap, dev->channelmap,
> - sizeof(di.channelmap));
> - di.nrbchan = dev->nrbchan;
> - strscpy(di.name, dev_name(&dev->dev), sizeof(di.name));
> - if (copy_to_user((void __user *)arg, &di, sizeof(di)))
> - err = -EFAULT;
> - } else
> - err = -ENODEV;
> - break;
> - case IMSETDEVNAME:
> - {
> - struct mISDN_devrename dn;
> - if (copy_from_user(&dn, (void __user *)arg,
> - sizeof(dn))) {
> - err = -EFAULT;
> - break;
> - }
> - dn.name[sizeof(dn.name) - 1] = '\0';
> - dev = get_mdevice(dn.id);
> - if (dev)
> - err = device_rename(&dev->dev, dn.name);
> - else
> - err = -ENODEV;
> - }
> - break;
> - default:
> - err = -EINVAL;
> - }
> - return err;
> -}
> -
> -static int
> -base_sock_bind(struct socket *sock, struct sockaddr_unsized *addr, int addr_len)
> -{
> - struct sockaddr_mISDN *maddr = (struct sockaddr_mISDN *) addr;
> - struct sock *sk = sock->sk;
> - int err = 0;
> -
> - if (addr_len < sizeof(struct sockaddr_mISDN))
> - return -EINVAL;
> -
> - if (!maddr || maddr->family != AF_ISDN)
> - return -EINVAL;
> -
> - lock_sock(sk);
> -
> - if (_pms(sk)->dev) {
> - err = -EALREADY;
> - goto done;
> - }
> -
> - _pms(sk)->dev = get_mdevice(maddr->dev);
> - if (!_pms(sk)->dev) {
> - err = -ENODEV;
> - goto done;
> - }
> - sk->sk_state = MISDN_BOUND;
> -
> -done:
> - release_sock(sk);
> - return err;
> -}
> -
> -static const struct proto_ops base_sock_ops = {
> - .family = PF_ISDN,
> - .owner = THIS_MODULE,
> - .release = base_sock_release,
> - .ioctl = base_sock_ioctl,
> - .bind = base_sock_bind,
> - .getname = sock_no_getname,
> - .sendmsg = sock_no_sendmsg,
> - .recvmsg = sock_no_recvmsg,
> - .listen = sock_no_listen,
> - .shutdown = sock_no_shutdown,
> - .connect = sock_no_connect,
> - .socketpair = sock_no_socketpair,
> - .accept = sock_no_accept,
> - .mmap = sock_no_mmap
> -};
> -
> -
> -static int
> -base_sock_create(struct net *net, struct socket *sock, int protocol, int kern)
> -{
> - struct sock *sk;
> -
> - if (sock->type != SOCK_RAW)
> - return -ESOCKTNOSUPPORT;
> - if (!capable(CAP_NET_RAW))
> - return -EPERM;
> -
> - sk = sk_alloc(net, PF_ISDN, GFP_KERNEL, &mISDN_proto, kern);
> - if (!sk)
> - return -ENOMEM;
> -
> - sock_init_data(sock, sk);
> - sock->ops = &base_sock_ops;
> - sock->state = SS_UNCONNECTED;
> - sock_reset_flag(sk, SOCK_ZAPPED);
> - sk->sk_protocol = protocol;
> - sk->sk_state = MISDN_OPEN;
> - mISDN_sock_link(&base_sockets, sk);
> -
> - return 0;
> -}
> -
> -static int
> -mISDN_sock_create(struct net *net, struct socket *sock, int proto, int kern)
> -{
> - int err = -EPROTONOSUPPORT;
> -
> - switch (proto) {
> - case ISDN_P_BASE:
> - err = base_sock_create(net, sock, proto, kern);
> - break;
> - case ISDN_P_TE_S0:
> - case ISDN_P_NT_S0:
> - case ISDN_P_TE_E1:
> - case ISDN_P_NT_E1:
> - case ISDN_P_LAPD_TE:
> - case ISDN_P_LAPD_NT:
> - case ISDN_P_B_RAW:
> - case ISDN_P_B_HDLC:
> - case ISDN_P_B_X75SLP:
> - case ISDN_P_B_L2DTMF:
> - case ISDN_P_B_L2DSP:
> - case ISDN_P_B_L2DSPHDLC:
> - err = data_sock_create(net, sock, proto, kern);
> - break;
> - default:
> - return err;
> - }
> -
> - return err;
> -}
> -
> -static const struct net_proto_family mISDN_sock_family_ops = {
> - .owner = THIS_MODULE,
> - .family = PF_ISDN,
> - .create = mISDN_sock_create,
> -};
> -
> -int
> -misdn_sock_init(u_int *deb)
> -{
> - int err;
> -
> - debug = deb;
> - err = sock_register(&mISDN_sock_family_ops);
> - if (err)
> - printk(KERN_ERR "%s: error(%d)\n", __func__, err);
> - return err;
> -}
> -
> -void
> -misdn_sock_cleanup(void)
> -{
> - sock_unregister(PF_ISDN);
> -}
> diff --git a/drivers/isdn/mISDN/stack.c b/drivers/isdn/mISDN/stack.c
> deleted file mode 100644
> index 4e96684af0aa..000000000000
> --- a/drivers/isdn/mISDN/stack.c
> +++ /dev/null
> @@ -1,654 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - *
> - * Author Karsten Keil <kkeil@novell.com>
> - *
> - * Copyright 2008 by Karsten Keil <kkeil@novell.com>
> - */
> -
> -#include <linux/slab.h>
> -#include <linux/mISDNif.h>
> -#include <linux/kthread.h>
> -#include <linux/sched.h>
> -#include <linux/sched/cputime.h>
> -#include <linux/signal.h>
> -
> -#include "core.h"
> -
> -static u_int *debug;
> -
> -static inline void
> -_queue_message(struct mISDNstack *st, struct sk_buff *skb)
> -{
> - struct mISDNhead *hh = mISDN_HEAD_P(skb);
> -
> - if (*debug & DEBUG_QUEUE_FUNC)
> - printk(KERN_DEBUG "%s prim(%x) id(%x) %p\n",
> - __func__, hh->prim, hh->id, skb);
> - skb_queue_tail(&st->msgq, skb);
> - if (likely(!test_bit(mISDN_STACK_STOPPED, &st->status))) {
> - test_and_set_bit(mISDN_STACK_WORK, &st->status);
> - wake_up_interruptible(&st->workq);
> - }
> -}
> -
> -static int
> -mISDN_queue_message(struct mISDNchannel *ch, struct sk_buff *skb)
> -{
> - _queue_message(ch->st, skb);
> - return 0;
> -}
> -
> -static struct mISDNchannel *
> -get_channel4id(struct mISDNstack *st, u_int id)
> -{
> - struct mISDNchannel *ch;
> -
> - mutex_lock(&st->lmutex);
> - list_for_each_entry(ch, &st->layer2, list) {
> - if (id == ch->nr)
> - goto unlock;
> - }
> - ch = NULL;
> -unlock:
> - mutex_unlock(&st->lmutex);
> - return ch;
> -}
> -
> -static void
> -send_socklist(struct mISDN_sock_list *sl, struct sk_buff *skb)
> -{
> - struct sock *sk;
> - struct sk_buff *cskb = NULL;
> -
> - read_lock(&sl->lock);
> - sk_for_each(sk, &sl->head) {
> - if (sk->sk_state != MISDN_BOUND)
> - continue;
> - if (!cskb)
> - cskb = skb_copy(skb, GFP_ATOMIC);
> - if (!cskb) {
> - printk(KERN_WARNING "%s no skb\n", __func__);
> - break;
> - }
> - if (!sock_queue_rcv_skb(sk, cskb))
> - cskb = NULL;
> - }
> - read_unlock(&sl->lock);
> - dev_kfree_skb(cskb);
> -}
> -
> -static void
> -send_layer2(struct mISDNstack *st, struct sk_buff *skb)
> -{
> - struct sk_buff *cskb;
> - struct mISDNhead *hh = mISDN_HEAD_P(skb);
> - struct mISDNchannel *ch;
> - int ret;
> -
> - if (!st)
> - return;
> - mutex_lock(&st->lmutex);
> - if ((hh->id & MISDN_ID_ADDR_MASK) == MISDN_ID_ANY) { /* L2 for all */
> - list_for_each_entry(ch, &st->layer2, list) {
> - if (list_is_last(&ch->list, &st->layer2)) {
> - cskb = skb;
> - skb = NULL;
> - } else {
> - cskb = skb_copy(skb, GFP_KERNEL);
> - }
> - if (cskb) {
> - ret = ch->send(ch, cskb);
> - if (ret) {
> - if (*debug & DEBUG_SEND_ERR)
> - printk(KERN_DEBUG
> - "%s ch%d prim(%x) addr(%x)"
> - " err %d\n",
> - __func__, ch->nr,
> - hh->prim, ch->addr, ret);
> - dev_kfree_skb(cskb);
> - }
> - } else {
> - printk(KERN_WARNING "%s ch%d addr %x no mem\n",
> - __func__, ch->nr, ch->addr);
> - goto out;
> - }
> - }
> - } else {
> - list_for_each_entry(ch, &st->layer2, list) {
> - if ((hh->id & MISDN_ID_ADDR_MASK) == ch->addr) {
> - ret = ch->send(ch, skb);
> - if (!ret)
> - skb = NULL;
> - goto out;
> - }
> - }
> - ret = st->dev->teimgr->ctrl(st->dev->teimgr, CHECK_DATA, skb);
> - if (!ret)
> - skb = NULL;
> - else if (*debug & DEBUG_SEND_ERR)
> - printk(KERN_DEBUG
> - "%s mgr prim(%x) err %d\n",
> - __func__, hh->prim, ret);
> - }
> -out:
> - mutex_unlock(&st->lmutex);
> - dev_kfree_skb(skb);
> -}
> -
> -static inline int
> -send_msg_to_layer(struct mISDNstack *st, struct sk_buff *skb)
> -{
> - struct mISDNhead *hh = mISDN_HEAD_P(skb);
> - struct mISDNchannel *ch;
> - int lm;
> -
> - lm = hh->prim & MISDN_LAYERMASK;
> - if (*debug & DEBUG_QUEUE_FUNC)
> - printk(KERN_DEBUG "%s prim(%x) id(%x) %p\n",
> - __func__, hh->prim, hh->id, skb);
> - if (lm == 0x1) {
> - if (!hlist_empty(&st->l1sock.head)) {
> - __net_timestamp(skb);
> - send_socklist(&st->l1sock, skb);
> - }
> - return st->layer1->send(st->layer1, skb);
> - } else if (lm == 0x2) {
> - if (!hlist_empty(&st->l1sock.head))
> - send_socklist(&st->l1sock, skb);
> - send_layer2(st, skb);
> - return 0;
> - } else if (lm == 0x4) {
> - ch = get_channel4id(st, hh->id);
> - if (ch)
> - return ch->send(ch, skb);
> - else
> - printk(KERN_WARNING
> - "%s: dev(%s) prim(%x) id(%x) no channel\n",
> - __func__, dev_name(&st->dev->dev), hh->prim,
> - hh->id);
> - } else if (lm == 0x8) {
> - WARN_ON(lm == 0x8);
> - ch = get_channel4id(st, hh->id);
> - if (ch)
> - return ch->send(ch, skb);
> - else
> - printk(KERN_WARNING
> - "%s: dev(%s) prim(%x) id(%x) no channel\n",
> - __func__, dev_name(&st->dev->dev), hh->prim,
> - hh->id);
> - } else {
> - /* broadcast not handled yet */
> - printk(KERN_WARNING "%s: dev(%s) prim %x not delivered\n",
> - __func__, dev_name(&st->dev->dev), hh->prim);
> - }
> - return -ESRCH;
> -}
> -
> -static void
> -do_clear_stack(struct mISDNstack *st)
> -{
> -}
> -
> -static int
> -mISDNStackd(void *data)
> -{
> - struct mISDNstack *st = data;
> -#ifdef MISDN_MSG_STATS
> - u64 utime, stime;
> -#endif
> - int err = 0;
> -
> - sigfillset(¤t->blocked);
> - if (*debug & DEBUG_MSG_THREAD)
> - printk(KERN_DEBUG "mISDNStackd %s started\n",
> - dev_name(&st->dev->dev));
> -
> - if (st->notify != NULL) {
> - complete(st->notify);
> - st->notify = NULL;
> - }
> -
> - for (;;) {
> - struct sk_buff *skb;
> -
> - if (unlikely(test_bit(mISDN_STACK_STOPPED, &st->status))) {
> - test_and_clear_bit(mISDN_STACK_WORK, &st->status);
> - test_and_clear_bit(mISDN_STACK_RUNNING, &st->status);
> - } else
> - test_and_set_bit(mISDN_STACK_RUNNING, &st->status);
> - while (test_bit(mISDN_STACK_WORK, &st->status)) {
> - skb = skb_dequeue(&st->msgq);
> - if (!skb) {
> - test_and_clear_bit(mISDN_STACK_WORK,
> - &st->status);
> - /* test if a race happens */
> - skb = skb_dequeue(&st->msgq);
> - if (!skb)
> - continue;
> - test_and_set_bit(mISDN_STACK_WORK,
> - &st->status);
> - }
> -#ifdef MISDN_MSG_STATS
> - st->msg_cnt++;
> -#endif
> - err = send_msg_to_layer(st, skb);
> - if (unlikely(err)) {
> - if (*debug & DEBUG_SEND_ERR)
> - printk(KERN_DEBUG
> - "%s: %s prim(%x) id(%x) "
> - "send call(%d)\n",
> - __func__, dev_name(&st->dev->dev),
> - mISDN_HEAD_PRIM(skb),
> - mISDN_HEAD_ID(skb), err);
> - dev_kfree_skb(skb);
> - continue;
> - }
> - if (unlikely(test_bit(mISDN_STACK_STOPPED,
> - &st->status))) {
> - test_and_clear_bit(mISDN_STACK_WORK,
> - &st->status);
> - test_and_clear_bit(mISDN_STACK_RUNNING,
> - &st->status);
> - break;
> - }
> - }
> - if (test_bit(mISDN_STACK_CLEARING, &st->status)) {
> - test_and_set_bit(mISDN_STACK_STOPPED, &st->status);
> - test_and_clear_bit(mISDN_STACK_RUNNING, &st->status);
> - do_clear_stack(st);
> - test_and_clear_bit(mISDN_STACK_CLEARING, &st->status);
> - test_and_set_bit(mISDN_STACK_RESTART, &st->status);
> - }
> - if (test_and_clear_bit(mISDN_STACK_RESTART, &st->status)) {
> - test_and_clear_bit(mISDN_STACK_STOPPED, &st->status);
> - test_and_set_bit(mISDN_STACK_RUNNING, &st->status);
> - if (!skb_queue_empty(&st->msgq))
> - test_and_set_bit(mISDN_STACK_WORK,
> - &st->status);
> - }
> - if (test_bit(mISDN_STACK_ABORT, &st->status))
> - break;
> - if (st->notify != NULL) {
> - complete(st->notify);
> - st->notify = NULL;
> - }
> -#ifdef MISDN_MSG_STATS
> - st->sleep_cnt++;
> -#endif
> - test_and_clear_bit(mISDN_STACK_ACTIVE, &st->status);
> - wait_event_interruptible(st->workq, (st->status &
> - mISDN_STACK_ACTION_MASK));
> - if (*debug & DEBUG_MSG_THREAD)
> - printk(KERN_DEBUG "%s: %s wake status %08lx\n",
> - __func__, dev_name(&st->dev->dev), st->status);
> - test_and_set_bit(mISDN_STACK_ACTIVE, &st->status);
> -
> - test_and_clear_bit(mISDN_STACK_WAKEUP, &st->status);
> -
> - if (test_bit(mISDN_STACK_STOPPED, &st->status)) {
> - test_and_clear_bit(mISDN_STACK_RUNNING, &st->status);
> -#ifdef MISDN_MSG_STATS
> - st->stopped_cnt++;
> -#endif
> - }
> - }
> -#ifdef MISDN_MSG_STATS
> - printk(KERN_DEBUG "mISDNStackd daemon for %s proceed %d "
> - "msg %d sleep %d stopped\n",
> - dev_name(&st->dev->dev), st->msg_cnt, st->sleep_cnt,
> - st->stopped_cnt);
> - task_cputime(st->thread, &utime, &stime);
> - printk(KERN_DEBUG
> - "mISDNStackd daemon for %s utime(%llu) stime(%llu)\n",
> - dev_name(&st->dev->dev), utime, stime);
> - printk(KERN_DEBUG
> - "mISDNStackd daemon for %s nvcsw(%ld) nivcsw(%ld)\n",
> - dev_name(&st->dev->dev), st->thread->nvcsw, st->thread->nivcsw);
> - printk(KERN_DEBUG "mISDNStackd daemon for %s killed now\n",
> - dev_name(&st->dev->dev));
> -#endif
> - test_and_set_bit(mISDN_STACK_KILLED, &st->status);
> - test_and_clear_bit(mISDN_STACK_RUNNING, &st->status);
> - test_and_clear_bit(mISDN_STACK_ACTIVE, &st->status);
> - test_and_clear_bit(mISDN_STACK_ABORT, &st->status);
> - skb_queue_purge(&st->msgq);
> - st->thread = NULL;
> - if (st->notify != NULL) {
> - complete(st->notify);
> - st->notify = NULL;
> - }
> - return 0;
> -}
> -
> -static int
> -l1_receive(struct mISDNchannel *ch, struct sk_buff *skb)
> -{
> - if (!ch->st)
> - return -ENODEV;
> - __net_timestamp(skb);
> - _queue_message(ch->st, skb);
> - return 0;
> -}
> -
> -void
> -set_channel_address(struct mISDNchannel *ch, u_int sapi, u_int tei)
> -{
> - ch->addr = sapi | (tei << 8);
> -}
> -
> -void
> -__add_layer2(struct mISDNchannel *ch, struct mISDNstack *st)
> -{
> - list_add_tail(&ch->list, &st->layer2);
> -}
> -
> -void
> -add_layer2(struct mISDNchannel *ch, struct mISDNstack *st)
> -{
> - mutex_lock(&st->lmutex);
> - __add_layer2(ch, st);
> - mutex_unlock(&st->lmutex);
> -}
> -
> -static int
> -st_own_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
> -{
> - if (!ch->st || !ch->st->layer1)
> - return -EINVAL;
> - return ch->st->layer1->ctrl(ch->st->layer1, cmd, arg);
> -}
> -
> -int
> -create_stack(struct mISDNdevice *dev)
> -{
> - struct mISDNstack *newst;
> - int err;
> - DECLARE_COMPLETION_ONSTACK(done);
> -
> - newst = kzalloc_obj(struct mISDNstack);
> - if (!newst) {
> - printk(KERN_ERR "kmalloc mISDN_stack failed\n");
> - return -ENOMEM;
> - }
> - newst->dev = dev;
> - INIT_LIST_HEAD(&newst->layer2);
> - INIT_HLIST_HEAD(&newst->l1sock.head);
> - rwlock_init(&newst->l1sock.lock);
> - init_waitqueue_head(&newst->workq);
> - skb_queue_head_init(&newst->msgq);
> - mutex_init(&newst->lmutex);
> - dev->D.st = newst;
> - err = create_teimanager(dev);
> - if (err) {
> - printk(KERN_ERR "kmalloc teimanager failed\n");
> - kfree(newst);
> - return err;
> - }
> - dev->teimgr->peer = &newst->own;
> - dev->teimgr->recv = mISDN_queue_message;
> - dev->teimgr->st = newst;
> - newst->layer1 = &dev->D;
> - dev->D.recv = l1_receive;
> - dev->D.peer = &newst->own;
> - newst->own.st = newst;
> - newst->own.ctrl = st_own_ctrl;
> - newst->own.send = mISDN_queue_message;
> - newst->own.recv = mISDN_queue_message;
> - if (*debug & DEBUG_CORE_FUNC)
> - printk(KERN_DEBUG "%s: st(%s)\n", __func__,
> - dev_name(&newst->dev->dev));
> - newst->notify = &done;
> - newst->thread = kthread_run(mISDNStackd, (void *)newst, "mISDN_%s",
> - dev_name(&newst->dev->dev));
> - if (IS_ERR(newst->thread)) {
> - err = PTR_ERR(newst->thread);
> - printk(KERN_ERR
> - "mISDN:cannot create kernel thread for %s (%d)\n",
> - dev_name(&newst->dev->dev), err);
> - delete_teimanager(dev->teimgr);
> - kfree(newst);
> - } else
> - wait_for_completion(&done);
> - return err;
> -}
> -
> -int
> -connect_layer1(struct mISDNdevice *dev, struct mISDNchannel *ch,
> - u_int protocol, struct sockaddr_mISDN *adr)
> -{
> - struct mISDN_sock *msk = container_of(ch, struct mISDN_sock, ch);
> - struct channel_req rq;
> - int err;
> -
> -
> - if (*debug & DEBUG_CORE_FUNC)
> - printk(KERN_DEBUG "%s: %s proto(%x) adr(%d %d %d %d)\n",
> - __func__, dev_name(&dev->dev), protocol, adr->dev,
> - adr->channel, adr->sapi, adr->tei);
> - switch (protocol) {
> - case ISDN_P_NT_S0:
> - case ISDN_P_NT_E1:
> - case ISDN_P_TE_S0:
> - case ISDN_P_TE_E1:
> - ch->recv = mISDN_queue_message;
> - ch->peer = &dev->D.st->own;
> - ch->st = dev->D.st;
> - rq.protocol = protocol;
> - rq.adr.channel = adr->channel;
> - err = dev->D.ctrl(&dev->D, OPEN_CHANNEL, &rq);
> - printk(KERN_DEBUG "%s: ret %d (dev %d)\n", __func__, err,
> - dev->id);
> - if (err)
> - return err;
> - write_lock_bh(&dev->D.st->l1sock.lock);
> - sk_add_node(&msk->sk, &dev->D.st->l1sock.head);
> - write_unlock_bh(&dev->D.st->l1sock.lock);
> - break;
> - default:
> - return -ENOPROTOOPT;
> - }
> - return 0;
> -}
> -
> -int
> -connect_Bstack(struct mISDNdevice *dev, struct mISDNchannel *ch,
> - u_int protocol, struct sockaddr_mISDN *adr)
> -{
> - struct channel_req rq, rq2;
> - int pmask, err;
> - struct Bprotocol *bp;
> -
> - if (*debug & DEBUG_CORE_FUNC)
> - printk(KERN_DEBUG "%s: %s proto(%x) adr(%d %d %d %d)\n",
> - __func__, dev_name(&dev->dev), protocol,
> - adr->dev, adr->channel, adr->sapi,
> - adr->tei);
> - ch->st = dev->D.st;
> - pmask = 1 << (protocol & ISDN_P_B_MASK);
> - if (pmask & dev->Bprotocols) {
> - rq.protocol = protocol;
> - rq.adr = *adr;
> - err = dev->D.ctrl(&dev->D, OPEN_CHANNEL, &rq);
> - if (err)
> - return err;
> - ch->recv = rq.ch->send;
> - ch->peer = rq.ch;
> - rq.ch->recv = ch->send;
> - rq.ch->peer = ch;
> - rq.ch->st = dev->D.st;
> - } else {
> - bp = get_Bprotocol4mask(pmask);
> - if (!bp)
> - return -ENOPROTOOPT;
> - rq2.protocol = protocol;
> - rq2.adr = *adr;
> - rq2.ch = ch;
> - err = bp->create(&rq2);
> - if (err)
> - return err;
> - ch->recv = rq2.ch->send;
> - ch->peer = rq2.ch;
> - rq2.ch->st = dev->D.st;
> - rq.protocol = rq2.protocol;
> - rq.adr = *adr;
> - err = dev->D.ctrl(&dev->D, OPEN_CHANNEL, &rq);
> - if (err) {
> - rq2.ch->ctrl(rq2.ch, CLOSE_CHANNEL, NULL);
> - return err;
> - }
> - rq2.ch->recv = rq.ch->send;
> - rq2.ch->peer = rq.ch;
> - rq.ch->recv = rq2.ch->send;
> - rq.ch->peer = rq2.ch;
> - rq.ch->st = dev->D.st;
> - }
> - ch->protocol = protocol;
> - ch->nr = rq.ch->nr;
> - return 0;
> -}
> -
> -int
> -create_l2entity(struct mISDNdevice *dev, struct mISDNchannel *ch,
> - u_int protocol, struct sockaddr_mISDN *adr)
> -{
> - struct channel_req rq;
> - int err;
> -
> - if (*debug & DEBUG_CORE_FUNC)
> - printk(KERN_DEBUG "%s: %s proto(%x) adr(%d %d %d %d)\n",
> - __func__, dev_name(&dev->dev), protocol,
> - adr->dev, adr->channel, adr->sapi,
> - adr->tei);
> - rq.protocol = ISDN_P_TE_S0;
> - if (dev->Dprotocols & (1 << ISDN_P_TE_E1))
> - rq.protocol = ISDN_P_TE_E1;
> - switch (protocol) {
> - case ISDN_P_LAPD_NT:
> - rq.protocol = ISDN_P_NT_S0;
> - if (dev->Dprotocols & (1 << ISDN_P_NT_E1))
> - rq.protocol = ISDN_P_NT_E1;
> - fallthrough;
> - case ISDN_P_LAPD_TE:
> - ch->recv = mISDN_queue_message;
> - ch->peer = &dev->D.st->own;
> - ch->st = dev->D.st;
> - rq.adr.channel = 0;
> - err = dev->D.ctrl(&dev->D, OPEN_CHANNEL, &rq);
> - printk(KERN_DEBUG "%s: ret 1 %d\n", __func__, err);
> - if (err)
> - break;
> - rq.protocol = protocol;
> - rq.adr = *adr;
> - rq.ch = ch;
> - err = dev->teimgr->ctrl(dev->teimgr, OPEN_CHANNEL, &rq);
> - printk(KERN_DEBUG "%s: ret 2 %d\n", __func__, err);
> - if (!err) {
> - if ((protocol == ISDN_P_LAPD_NT) && !rq.ch)
> - break;
> - add_layer2(rq.ch, dev->D.st);
> - rq.ch->recv = mISDN_queue_message;
> - rq.ch->peer = &dev->D.st->own;
> - rq.ch->ctrl(rq.ch, OPEN_CHANNEL, NULL); /* can't fail */
> - }
> - break;
> - default:
> - err = -EPROTONOSUPPORT;
> - }
> - return err;
> -}
> -
> -void
> -delete_channel(struct mISDNchannel *ch)
> -{
> - struct mISDN_sock *msk = container_of(ch, struct mISDN_sock, ch);
> - struct mISDNchannel *pch;
> -
> - if (!ch->st) {
> - printk(KERN_WARNING "%s: no stack\n", __func__);
> - return;
> - }
> - if (*debug & DEBUG_CORE_FUNC)
> - printk(KERN_DEBUG "%s: st(%s) protocol(%x)\n", __func__,
> - dev_name(&ch->st->dev->dev), ch->protocol);
> - if (ch->protocol >= ISDN_P_B_START) {
> - if (ch->peer) {
> - ch->peer->ctrl(ch->peer, CLOSE_CHANNEL, NULL);
> - ch->peer = NULL;
> - }
> - return;
> - }
> - switch (ch->protocol) {
> - case ISDN_P_NT_S0:
> - case ISDN_P_TE_S0:
> - case ISDN_P_NT_E1:
> - case ISDN_P_TE_E1:
> - write_lock_bh(&ch->st->l1sock.lock);
> - sk_del_node_init(&msk->sk);
> - write_unlock_bh(&ch->st->l1sock.lock);
> - ch->st->dev->D.ctrl(&ch->st->dev->D, CLOSE_CHANNEL, NULL);
> - break;
> - case ISDN_P_LAPD_TE:
> - pch = get_channel4id(ch->st, ch->nr);
> - if (pch) {
> - mutex_lock(&ch->st->lmutex);
> - list_del(&pch->list);
> - mutex_unlock(&ch->st->lmutex);
> - pch->ctrl(pch, CLOSE_CHANNEL, NULL);
> - pch = ch->st->dev->teimgr;
> - pch->ctrl(pch, CLOSE_CHANNEL, NULL);
> - } else
> - printk(KERN_WARNING "%s: no l2 channel\n",
> - __func__);
> - break;
> - case ISDN_P_LAPD_NT:
> - pch = ch->st->dev->teimgr;
> - if (pch) {
> - pch->ctrl(pch, CLOSE_CHANNEL, NULL);
> - } else
> - printk(KERN_WARNING "%s: no l2 channel\n",
> - __func__);
> - break;
> - default:
> - break;
> - }
> - return;
> -}
> -
> -void
> -delete_stack(struct mISDNdevice *dev)
> -{
> - struct mISDNstack *st = dev->D.st;
> - DECLARE_COMPLETION_ONSTACK(done);
> -
> - if (*debug & DEBUG_CORE_FUNC)
> - printk(KERN_DEBUG "%s: st(%s)\n", __func__,
> - dev_name(&st->dev->dev));
> - if (dev->teimgr)
> - delete_teimanager(dev->teimgr);
> - if (st->thread) {
> - if (st->notify) {
> - printk(KERN_WARNING "%s: notifier in use\n",
> - __func__);
> - complete(st->notify);
> - }
> - st->notify = &done;
> - test_and_set_bit(mISDN_STACK_ABORT, &st->status);
> - test_and_set_bit(mISDN_STACK_WAKEUP, &st->status);
> - wake_up_interruptible(&st->workq);
> - wait_for_completion(&done);
> - }
> - if (!list_empty(&st->layer2))
> - printk(KERN_WARNING "%s: layer2 list not empty\n",
> - __func__);
> - if (!hlist_empty(&st->l1sock.head))
> - printk(KERN_WARNING "%s: layer1 list not empty\n",
> - __func__);
> - kfree(st);
> -}
> -
> -void
> -mISDN_initstack(u_int *dp)
> -{
> - debug = dp;
> -}
> diff --git a/drivers/isdn/mISDN/tei.c b/drivers/isdn/mISDN/tei.c
> deleted file mode 100644
> index 2bad3083be90..000000000000
> --- a/drivers/isdn/mISDN/tei.c
> +++ /dev/null
> @@ -1,1416 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - *
> - * Author Karsten Keil <kkeil@novell.com>
> - *
> - * Copyright 2008 by Karsten Keil <kkeil@novell.com>
> - */
> -#include "layer2.h"
> -#include <linux/random.h>
> -#include <linux/slab.h>
> -#include "core.h"
> -
> -#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
> -
> -#define MGR_PH_ACTIVE 16
> -#define MGR_PH_NOTREADY 17
> -
> -#define DATIMER_VAL 10000
> -
> -static u_int *debug;
> -
> -static struct Fsm deactfsm = {NULL, 0, 0, NULL, NULL};
> -static struct Fsm teifsmu = {NULL, 0, 0, NULL, NULL};
> -static struct Fsm teifsmn = {NULL, 0, 0, NULL, NULL};
> -
> -enum {
> - ST_L1_DEACT,
> - ST_L1_DEACT_PENDING,
> - ST_L1_ACTIV,
> -};
> -#define DEACT_STATE_COUNT (ST_L1_ACTIV + 1)
> -
> -static char *strDeactState[] =
> -{
> - "ST_L1_DEACT",
> - "ST_L1_DEACT_PENDING",
> - "ST_L1_ACTIV",
> -};
> -
> -enum {
> - EV_ACTIVATE,
> - EV_ACTIVATE_IND,
> - EV_DEACTIVATE,
> - EV_DEACTIVATE_IND,
> - EV_UI,
> - EV_DATIMER,
> -};
> -
> -#define DEACT_EVENT_COUNT (EV_DATIMER + 1)
> -
> -static char *strDeactEvent[] =
> -{
> - "EV_ACTIVATE",
> - "EV_ACTIVATE_IND",
> - "EV_DEACTIVATE",
> - "EV_DEACTIVATE_IND",
> - "EV_UI",
> - "EV_DATIMER",
> -};
> -
> -static void
> -da_debug(struct FsmInst *fi, char *fmt, ...)
> -{
> - struct manager *mgr = fi->userdata;
> - struct va_format vaf;
> - va_list va;
> -
> - if (!(*debug & DEBUG_L2_TEIFSM))
> - return;
> -
> - va_start(va, fmt);
> -
> - vaf.fmt = fmt;
> - vaf.va = &va;
> -
> - printk(KERN_DEBUG "mgr(%d): %pV\n", mgr->ch.st->dev->id, &vaf);
> -
> - va_end(va);
> -}
> -
> -static void
> -da_activate(struct FsmInst *fi, int event, void *arg)
> -{
> - struct manager *mgr = fi->userdata;
> -
> - if (fi->state == ST_L1_DEACT_PENDING)
> - mISDN_FsmDelTimer(&mgr->datimer, 1);
> - mISDN_FsmChangeState(fi, ST_L1_ACTIV);
> -}
> -
> -static void
> -da_deactivate_ind(struct FsmInst *fi, int event, void *arg)
> -{
> - mISDN_FsmChangeState(fi, ST_L1_DEACT);
> -}
> -
> -static void
> -da_deactivate(struct FsmInst *fi, int event, void *arg)
> -{
> - struct manager *mgr = fi->userdata;
> - struct layer2 *l2;
> - u_long flags;
> -
> - read_lock_irqsave(&mgr->lock, flags);
> - list_for_each_entry(l2, &mgr->layer2, list) {
> - if (l2->l2m.state > ST_L2_4) {
> - /* have still activ TEI */
> - read_unlock_irqrestore(&mgr->lock, flags);
> - return;
> - }
> - }
> - read_unlock_irqrestore(&mgr->lock, flags);
> - /* All TEI are inactiv */
> - if (!test_bit(OPTION_L1_HOLD, &mgr->options)) {
> - mISDN_FsmAddTimer(&mgr->datimer, DATIMER_VAL, EV_DATIMER,
> - NULL, 1);
> - mISDN_FsmChangeState(fi, ST_L1_DEACT_PENDING);
> - }
> -}
> -
> -static void
> -da_ui(struct FsmInst *fi, int event, void *arg)
> -{
> - struct manager *mgr = fi->userdata;
> -
> - /* restart da timer */
> - if (!test_bit(OPTION_L1_HOLD, &mgr->options)) {
> - mISDN_FsmDelTimer(&mgr->datimer, 2);
> - mISDN_FsmAddTimer(&mgr->datimer, DATIMER_VAL, EV_DATIMER,
> - NULL, 2);
> - }
> -}
> -
> -static void
> -da_timer(struct FsmInst *fi, int event, void *arg)
> -{
> - struct manager *mgr = fi->userdata;
> - struct layer2 *l2;
> - u_long flags;
> -
> - /* check again */
> - read_lock_irqsave(&mgr->lock, flags);
> - list_for_each_entry(l2, &mgr->layer2, list) {
> - if (l2->l2m.state > ST_L2_4) {
> - /* have still activ TEI */
> - read_unlock_irqrestore(&mgr->lock, flags);
> - mISDN_FsmChangeState(fi, ST_L1_ACTIV);
> - return;
> - }
> - }
> - read_unlock_irqrestore(&mgr->lock, flags);
> - /* All TEI are inactiv */
> - mISDN_FsmChangeState(fi, ST_L1_DEACT);
> - _queue_data(&mgr->ch, PH_DEACTIVATE_REQ, MISDN_ID_ANY, 0, NULL,
> - GFP_ATOMIC);
> -}
> -
> -static struct FsmNode DeactFnList[] =
> -{
> - {ST_L1_DEACT, EV_ACTIVATE_IND, da_activate},
> - {ST_L1_ACTIV, EV_DEACTIVATE_IND, da_deactivate_ind},
> - {ST_L1_ACTIV, EV_DEACTIVATE, da_deactivate},
> - {ST_L1_DEACT_PENDING, EV_ACTIVATE, da_activate},
> - {ST_L1_DEACT_PENDING, EV_UI, da_ui},
> - {ST_L1_DEACT_PENDING, EV_DATIMER, da_timer},
> -};
> -
> -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_ASSIGN_REQ,
> - EV_DENIED,
> - EV_CHKREQ,
> - EV_CHKRESP,
> - EV_REMOVE,
> - EV_VERIFY,
> - EV_TIMER,
> -};
> -
> -#define TEI_EVENT_COUNT (EV_TIMER + 1)
> -
> -static char *strTeiEvent[] =
> -{
> - "EV_IDREQ",
> - "EV_ASSIGN",
> - "EV_ASSIGN_REQ",
> - "EV_DENIED",
> - "EV_CHKREQ",
> - "EV_CHKRESP",
> - "EV_REMOVE",
> - "EV_VERIFY",
> - "EV_TIMER",
> -};
> -
> -static void
> -tei_debug(struct FsmInst *fi, char *fmt, ...)
> -{
> - struct teimgr *tm = fi->userdata;
> - struct va_format vaf;
> - va_list va;
> -
> - if (!(*debug & DEBUG_L2_TEIFSM))
> - return;
> -
> - va_start(va, fmt);
> -
> - vaf.fmt = fmt;
> - vaf.va = &va;
> -
> - printk(KERN_DEBUG "sapi(%d) tei(%d): %pV\n",
> - tm->l2->sapi, tm->l2->tei, &vaf);
> -
> - va_end(va);
> -}
> -
> -
> -
> -static int
> -get_free_id(struct manager *mgr)
> -{
> - DECLARE_BITMAP(ids, 64) = { [0 ... BITS_TO_LONGS(64) - 1] = 0 };
> - int i;
> - struct layer2 *l2;
> -
> - list_for_each_entry(l2, &mgr->layer2, list) {
> - if (l2->ch.nr > 63) {
> - printk(KERN_WARNING
> - "%s: more as 63 layer2 for one device\n",
> - __func__);
> - return -EBUSY;
> - }
> - __set_bit(l2->ch.nr, ids);
> - }
> - i = find_next_zero_bit(ids, 64, 1);
> - if (i < 64)
> - return i;
> - printk(KERN_WARNING "%s: more as 63 layer2 for one device\n",
> - __func__);
> - return -EBUSY;
> -}
> -
> -static int
> -get_free_tei(struct manager *mgr)
> -{
> - DECLARE_BITMAP(ids, 64) = { [0 ... BITS_TO_LONGS(64) - 1] = 0 };
> - int i;
> - struct layer2 *l2;
> -
> - list_for_each_entry(l2, &mgr->layer2, list) {
> - if (l2->ch.nr == 0)
> - continue;
> - if ((l2->ch.addr & 0xff) != 0)
> - continue;
> - i = l2->ch.addr >> 8;
> - if (i < 64)
> - continue;
> - i -= 64;
> -
> - __set_bit(i, ids);
> - }
> - i = find_first_zero_bit(ids, 64);
> - if (i < 64)
> - return i + 64;
> - printk(KERN_WARNING "%s: more as 63 dynamic tei for one device\n",
> - __func__);
> - return -1;
> -}
> -
> -static void
> -teiup_create(struct manager *mgr, u_int prim, int len, void *arg)
> -{
> - struct sk_buff *skb;
> - struct mISDNhead *hh;
> - int err;
> -
> - skb = mI_alloc_skb(len, GFP_ATOMIC);
> - if (!skb)
> - return;
> - hh = mISDN_HEAD_P(skb);
> - hh->prim = prim;
> - hh->id = (mgr->ch.nr << 16) | mgr->ch.addr;
> - if (len)
> - skb_put_data(skb, arg, len);
> - err = mgr->up->send(mgr->up, skb);
> - if (err) {
> - printk(KERN_WARNING "%s: err=%d\n", __func__, err);
> - dev_kfree_skb(skb);
> - }
> -}
> -
> -static u_int
> -new_id(struct manager *mgr)
> -{
> - u_int id;
> -
> - id = mgr->nextid++;
> - if (id == 0x7fff)
> - mgr->nextid = 1;
> - id <<= 16;
> - id |= GROUP_TEI << 8;
> - id |= TEI_SAPI;
> - return id;
> -}
> -
> -static void
> -do_send(struct manager *mgr)
> -{
> - if (!test_bit(MGR_PH_ACTIVE, &mgr->options))
> - return;
> -
> - if (!test_and_set_bit(MGR_PH_NOTREADY, &mgr->options)) {
> - struct sk_buff *skb = skb_dequeue(&mgr->sendq);
> -
> - if (!skb) {
> - test_and_clear_bit(MGR_PH_NOTREADY, &mgr->options);
> - return;
> - }
> - mgr->lastid = mISDN_HEAD_ID(skb);
> - mISDN_FsmEvent(&mgr->deact, EV_UI, NULL);
> - if (mgr->ch.recv(mgr->ch.peer, skb)) {
> - dev_kfree_skb(skb);
> - test_and_clear_bit(MGR_PH_NOTREADY, &mgr->options);
> - mgr->lastid = MISDN_ID_NONE;
> - }
> - }
> -}
> -
> -static void
> -do_ack(struct manager *mgr, u_int id)
> -{
> - if (test_bit(MGR_PH_NOTREADY, &mgr->options)) {
> - if (id == mgr->lastid) {
> - if (test_bit(MGR_PH_ACTIVE, &mgr->options)) {
> - struct sk_buff *skb;
> -
> - skb = skb_dequeue(&mgr->sendq);
> - if (skb) {
> - mgr->lastid = mISDN_HEAD_ID(skb);
> - if (!mgr->ch.recv(mgr->ch.peer, skb))
> - return;
> - dev_kfree_skb(skb);
> - }
> - }
> - mgr->lastid = MISDN_ID_NONE;
> - test_and_clear_bit(MGR_PH_NOTREADY, &mgr->options);
> - }
> - }
> -}
> -
> -static void
> -mgr_send_down(struct manager *mgr, struct sk_buff *skb)
> -{
> - skb_queue_tail(&mgr->sendq, skb);
> - if (!test_bit(MGR_PH_ACTIVE, &mgr->options)) {
> - _queue_data(&mgr->ch, PH_ACTIVATE_REQ, MISDN_ID_ANY, 0,
> - NULL, GFP_KERNEL);
> - } else {
> - do_send(mgr);
> - }
> -}
> -
> -static int
> -dl_unit_data(struct manager *mgr, struct sk_buff *skb)
> -{
> - if (!test_bit(MGR_OPT_NETWORK, &mgr->options)) /* only net send UI */
> - return -EINVAL;
> - if (!test_bit(MGR_PH_ACTIVE, &mgr->options))
> - _queue_data(&mgr->ch, PH_ACTIVATE_REQ, MISDN_ID_ANY, 0,
> - NULL, GFP_KERNEL);
> - skb_push(skb, 3);
> - skb->data[0] = 0x02; /* SAPI 0 C/R = 1 */
> - skb->data[1] = 0xff; /* TEI 127 */
> - skb->data[2] = UI; /* UI frame */
> - mISDN_HEAD_PRIM(skb) = PH_DATA_REQ;
> - mISDN_HEAD_ID(skb) = new_id(mgr);
> - skb_queue_tail(&mgr->sendq, skb);
> - do_send(mgr);
> - return 0;
> -}
> -
> -static unsigned int
> -random_ri(void)
> -{
> - u16 x;
> -
> - get_random_bytes(&x, sizeof(x));
> - return x;
> -}
> -
> -static struct layer2 *
> -findtei(struct manager *mgr, int tei)
> -{
> - struct layer2 *l2;
> - u_long flags;
> -
> - read_lock_irqsave(&mgr->lock, flags);
> - list_for_each_entry(l2, &mgr->layer2, list) {
> - if ((l2->sapi == 0) && (l2->tei > 0) &&
> - (l2->tei != GROUP_TEI) && (l2->tei == tei))
> - goto done;
> - }
> - l2 = NULL;
> -done:
> - read_unlock_irqrestore(&mgr->lock, flags);
> - return l2;
> -}
> -
> -static void
> -put_tei_msg(struct manager *mgr, u_char m_id, unsigned int ri, int tei)
> -{
> - struct sk_buff *skb;
> - u_char bp[8];
> -
> - bp[0] = (TEI_SAPI << 2);
> - if (test_bit(MGR_OPT_NETWORK, &mgr->options))
> - bp[0] |= 2; /* CR:=1 for net command */
> - bp[1] = (GROUP_TEI << 1) | 0x1;
> - bp[2] = UI;
> - bp[3] = TEI_ENTITY_ID;
> - bp[4] = ri >> 8;
> - bp[5] = ri & 0xff;
> - bp[6] = m_id;
> - bp[7] = ((tei << 1) & 0xff) | 1;
> - skb = _alloc_mISDN_skb(PH_DATA_REQ, new_id(mgr), 8, bp, GFP_ATOMIC);
> - if (!skb) {
> - printk(KERN_WARNING "%s: no skb for tei msg\n", __func__);
> - return;
> - }
> - mgr_send_down(mgr, skb);
> -}
> -
> -static void
> -tei_id_request(struct FsmInst *fi, int event, void *arg)
> -{
> - struct teimgr *tm = fi->userdata;
> -
> - if (tm->l2->tei != GROUP_TEI) {
> - tm->tei_m.printdebug(&tm->tei_m,
> - "assign request for already assigned tei %d",
> - tm->l2->tei);
> - return;
> - }
> - tm->ri = random_ri();
> - if (*debug & DEBUG_L2_TEI)
> - tm->tei_m.printdebug(&tm->tei_m,
> - "assign request ri %d", tm->ri);
> - put_tei_msg(tm->mgr, ID_REQUEST, tm->ri, GROUP_TEI);
> - mISDN_FsmChangeState(fi, ST_TEI_IDREQ);
> - mISDN_FsmAddTimer(&tm->timer, tm->tval, EV_TIMER, NULL, 1);
> - tm->nval = 3;
> -}
> -
> -static void
> -tei_id_assign(struct FsmInst *fi, int event, void *arg)
> -{
> - struct teimgr *tm = fi->userdata;
> - struct layer2 *l2;
> - u_char *dp = arg;
> - int ri, tei;
> -
> - ri = ((unsigned int) *dp++ << 8);
> - ri += *dp++;
> - dp++;
> - tei = *dp >> 1;
> - if (*debug & DEBUG_L2_TEI)
> - tm->tei_m.printdebug(fi, "identity assign ri %d tei %d",
> - ri, tei);
> - l2 = findtei(tm->mgr, tei);
> - if (l2) { /* same tei is in use */
> - if (ri != l2->tm->ri) {
> - tm->tei_m.printdebug(fi,
> - "possible duplicate assignment tei %d", tei);
> - tei_l2(l2, MDL_ERROR_RSP, 0);
> - }
> - } else if (ri == tm->ri) {
> - mISDN_FsmDelTimer(&tm->timer, 1);
> - mISDN_FsmChangeState(fi, ST_TEI_NOP);
> - tei_l2(tm->l2, MDL_ASSIGN_REQ, tei);
> - }
> -}
> -
> -static void
> -tei_id_test_dup(struct FsmInst *fi, int event, void *arg)
> -{
> - struct teimgr *tm = fi->userdata;
> - struct layer2 *l2;
> - u_char *dp = arg;
> - int tei, ri;
> -
> - ri = ((unsigned int) *dp++ << 8);
> - ri += *dp++;
> - dp++;
> - tei = *dp >> 1;
> - if (*debug & DEBUG_L2_TEI)
> - tm->tei_m.printdebug(fi, "foreign identity assign ri %d tei %d",
> - ri, tei);
> - l2 = findtei(tm->mgr, tei);
> - if (l2) { /* same tei is in use */
> - if (ri != l2->tm->ri) { /* and it wasn't our request */
> - tm->tei_m.printdebug(fi,
> - "possible duplicate assignment tei %d", tei);
> - mISDN_FsmEvent(&l2->tm->tei_m, EV_VERIFY, NULL);
> - }
> - }
> -}
> -
> -static void
> -tei_id_denied(struct FsmInst *fi, int event, void *arg)
> -{
> - struct teimgr *tm = fi->userdata;
> - u_char *dp = arg;
> - int ri, tei;
> -
> - ri = ((unsigned int) *dp++ << 8);
> - ri += *dp++;
> - dp++;
> - tei = *dp >> 1;
> - if (*debug & DEBUG_L2_TEI)
> - tm->tei_m.printdebug(fi, "identity denied ri %d tei %d",
> - ri, tei);
> -}
> -
> -static void
> -tei_id_chk_req(struct FsmInst *fi, int event, void *arg)
> -{
> - struct teimgr *tm = fi->userdata;
> - u_char *dp = arg;
> - int tei;
> -
> - tei = *(dp + 3) >> 1;
> - if (*debug & DEBUG_L2_TEI)
> - tm->tei_m.printdebug(fi, "identity check req tei %d", tei);
> - if ((tm->l2->tei != GROUP_TEI) && ((tei == GROUP_TEI) ||
> - (tei == tm->l2->tei))) {
> - mISDN_FsmDelTimer(&tm->timer, 4);
> - mISDN_FsmChangeState(&tm->tei_m, ST_TEI_NOP);
> - put_tei_msg(tm->mgr, ID_CHK_RES, random_ri(), tm->l2->tei);
> - }
> -}
> -
> -static void
> -tei_id_remove(struct FsmInst *fi, int event, void *arg)
> -{
> - struct teimgr *tm = fi->userdata;
> - u_char *dp = arg;
> - int tei;
> -
> - tei = *(dp + 3) >> 1;
> - if (*debug & DEBUG_L2_TEI)
> - tm->tei_m.printdebug(fi, "identity remove tei %d", tei);
> - if ((tm->l2->tei != GROUP_TEI) &&
> - ((tei == GROUP_TEI) || (tei == tm->l2->tei))) {
> - mISDN_FsmDelTimer(&tm->timer, 5);
> - mISDN_FsmChangeState(&tm->tei_m, ST_TEI_NOP);
> - tei_l2(tm->l2, MDL_REMOVE_REQ, 0);
> - }
> -}
> -
> -static void
> -tei_id_verify(struct FsmInst *fi, int event, void *arg)
> -{
> - struct teimgr *tm = fi->userdata;
> -
> - if (*debug & DEBUG_L2_TEI)
> - tm->tei_m.printdebug(fi, "id verify request for tei %d",
> - tm->l2->tei);
> - put_tei_msg(tm->mgr, ID_VERIFY, 0, tm->l2->tei);
> - mISDN_FsmChangeState(&tm->tei_m, ST_TEI_IDVERIFY);
> - mISDN_FsmAddTimer(&tm->timer, tm->tval, EV_TIMER, NULL, 2);
> - tm->nval = 2;
> -}
> -
> -static void
> -tei_id_req_tout(struct FsmInst *fi, int event, void *arg)
> -{
> - struct teimgr *tm = fi->userdata;
> -
> - if (--tm->nval) {
> - tm->ri = random_ri();
> - if (*debug & DEBUG_L2_TEI)
> - tm->tei_m.printdebug(fi, "assign req(%d) ri %d",
> - 4 - tm->nval, tm->ri);
> - put_tei_msg(tm->mgr, ID_REQUEST, tm->ri, GROUP_TEI);
> - mISDN_FsmAddTimer(&tm->timer, tm->tval, EV_TIMER, NULL, 3);
> - } else {
> - tm->tei_m.printdebug(fi, "assign req failed");
> - tei_l2(tm->l2, MDL_ERROR_RSP, 0);
> - mISDN_FsmChangeState(fi, ST_TEI_NOP);
> - }
> -}
> -
> -static void
> -tei_id_ver_tout(struct FsmInst *fi, int event, void *arg)
> -{
> - struct teimgr *tm = fi->userdata;
> -
> - if (--tm->nval) {
> - if (*debug & DEBUG_L2_TEI)
> - tm->tei_m.printdebug(fi,
> - "id verify req(%d) for tei %d",
> - 3 - tm->nval, tm->l2->tei);
> - put_tei_msg(tm->mgr, ID_VERIFY, 0, tm->l2->tei);
> - mISDN_FsmAddTimer(&tm->timer, tm->tval, EV_TIMER, NULL, 4);
> - } else {
> - tm->tei_m.printdebug(fi, "verify req for tei %d failed",
> - tm->l2->tei);
> - tei_l2(tm->l2, MDL_REMOVE_REQ, 0);
> - mISDN_FsmChangeState(fi, ST_TEI_NOP);
> - }
> -}
> -
> -static struct FsmNode TeiFnListUser[] =
> -{
> - {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_TIMER, tei_id_req_tout},
> - {ST_TEI_IDREQ, EV_ASSIGN, tei_id_assign},
> - {ST_TEI_IDREQ, EV_DENIED, tei_id_denied},
> - {ST_TEI_IDVERIFY, EV_TIMER, tei_id_ver_tout},
> - {ST_TEI_IDVERIFY, EV_REMOVE, tei_id_remove},
> - {ST_TEI_IDVERIFY, EV_CHKREQ, tei_id_chk_req},
> -};
> -
> -static void
> -tei_l2remove(struct layer2 *l2)
> -{
> - put_tei_msg(l2->tm->mgr, ID_REMOVE, 0, l2->tei);
> - tei_l2(l2, MDL_REMOVE_REQ, 0);
> - list_del(&l2->ch.list);
> - l2->ch.ctrl(&l2->ch, CLOSE_CHANNEL, NULL);
> -}
> -
> -static void
> -tei_assign_req(struct FsmInst *fi, int event, void *arg)
> -{
> - struct teimgr *tm = fi->userdata;
> - u_char *dp = arg;
> -
> - if (tm->l2->tei == GROUP_TEI) {
> - tm->tei_m.printdebug(&tm->tei_m,
> - "net tei assign request without tei");
> - return;
> - }
> - tm->ri = ((unsigned int) *dp++ << 8);
> - tm->ri += *dp++;
> - if (*debug & DEBUG_L2_TEI)
> - tm->tei_m.printdebug(&tm->tei_m,
> - "net assign request ri %d teim %d", tm->ri, *dp);
> - put_tei_msg(tm->mgr, ID_ASSIGNED, tm->ri, tm->l2->tei);
> - mISDN_FsmChangeState(fi, ST_TEI_NOP);
> -}
> -
> -static void
> -tei_id_chk_req_net(struct FsmInst *fi, int event, void *arg)
> -{
> - struct teimgr *tm = fi->userdata;
> -
> - if (*debug & DEBUG_L2_TEI)
> - tm->tei_m.printdebug(fi, "id check request for tei %d",
> - tm->l2->tei);
> - tm->rcnt = 0;
> - put_tei_msg(tm->mgr, ID_CHK_REQ, 0, tm->l2->tei);
> - mISDN_FsmChangeState(&tm->tei_m, ST_TEI_IDVERIFY);
> - mISDN_FsmAddTimer(&tm->timer, tm->tval, EV_TIMER, NULL, 2);
> - tm->nval = 2;
> -}
> -
> -static void
> -tei_id_chk_resp(struct FsmInst *fi, int event, void *arg)
> -{
> - struct teimgr *tm = fi->userdata;
> - u_char *dp = arg;
> - int tei;
> -
> - tei = dp[3] >> 1;
> - if (*debug & DEBUG_L2_TEI)
> - tm->tei_m.printdebug(fi, "identity check resp tei %d", tei);
> - if (tei == tm->l2->tei)
> - tm->rcnt++;
> -}
> -
> -static void
> -tei_id_verify_net(struct FsmInst *fi, int event, void *arg)
> -{
> - struct teimgr *tm = fi->userdata;
> - u_char *dp = arg;
> - int tei;
> -
> - tei = dp[3] >> 1;
> - if (*debug & DEBUG_L2_TEI)
> - tm->tei_m.printdebug(fi, "identity verify req tei %d/%d",
> - tei, tm->l2->tei);
> - if (tei == tm->l2->tei)
> - tei_id_chk_req_net(fi, event, arg);
> -}
> -
> -static void
> -tei_id_ver_tout_net(struct FsmInst *fi, int event, void *arg)
> -{
> - struct teimgr *tm = fi->userdata;
> -
> - if (tm->rcnt == 1) {
> - if (*debug & DEBUG_L2_TEI)
> - tm->tei_m.printdebug(fi,
> - "check req for tei %d successful\n", tm->l2->tei);
> - mISDN_FsmChangeState(fi, ST_TEI_NOP);
> - } else if (tm->rcnt > 1) {
> - /* duplicate assignment; remove */
> - tei_l2remove(tm->l2);
> - } else if (--tm->nval) {
> - if (*debug & DEBUG_L2_TEI)
> - tm->tei_m.printdebug(fi,
> - "id check req(%d) for tei %d",
> - 3 - tm->nval, tm->l2->tei);
> - put_tei_msg(tm->mgr, ID_CHK_REQ, 0, tm->l2->tei);
> - mISDN_FsmAddTimer(&tm->timer, tm->tval, EV_TIMER, NULL, 4);
> - } else {
> - tm->tei_m.printdebug(fi, "check req for tei %d failed",
> - tm->l2->tei);
> - mISDN_FsmChangeState(fi, ST_TEI_NOP);
> - tei_l2remove(tm->l2);
> - }
> -}
> -
> -static struct FsmNode TeiFnListNet[] =
> -{
> - {ST_TEI_NOP, EV_ASSIGN_REQ, tei_assign_req},
> - {ST_TEI_NOP, EV_VERIFY, tei_id_verify_net},
> - {ST_TEI_NOP, EV_CHKREQ, tei_id_chk_req_net},
> - {ST_TEI_IDVERIFY, EV_TIMER, tei_id_ver_tout_net},
> - {ST_TEI_IDVERIFY, EV_CHKRESP, tei_id_chk_resp},
> -};
> -
> -static void
> -tei_ph_data_ind(struct teimgr *tm, u_int mt, u_char *dp, int len)
> -{
> - if (test_bit(FLG_FIXED_TEI, &tm->l2->flag))
> - return;
> - if (*debug & DEBUG_L2_TEI)
> - tm->tei_m.printdebug(&tm->tei_m, "tei handler mt %x", mt);
> - if (mt == ID_ASSIGNED)
> - mISDN_FsmEvent(&tm->tei_m, EV_ASSIGN, dp);
> - else if (mt == ID_DENIED)
> - mISDN_FsmEvent(&tm->tei_m, EV_DENIED, dp);
> - else if (mt == ID_CHK_REQ)
> - mISDN_FsmEvent(&tm->tei_m, EV_CHKREQ, dp);
> - else if (mt == ID_REMOVE)
> - mISDN_FsmEvent(&tm->tei_m, EV_REMOVE, dp);
> - else if (mt == ID_VERIFY)
> - mISDN_FsmEvent(&tm->tei_m, EV_VERIFY, dp);
> - else if (mt == ID_CHK_RES)
> - mISDN_FsmEvent(&tm->tei_m, EV_CHKRESP, dp);
> -}
> -
> -static struct layer2 *
> -create_new_tei(struct manager *mgr, int tei, int sapi)
> -{
> - unsigned long opt = 0;
> - unsigned long flags;
> - int id;
> - struct layer2 *l2;
> - struct channel_req rq;
> -
> - if (!mgr->up)
> - return NULL;
> - if ((tei >= 0) && (tei < 64))
> - test_and_set_bit(OPTION_L2_FIXEDTEI, &opt);
> - if (mgr->ch.st->dev->Dprotocols & ((1 << ISDN_P_TE_E1) |
> - (1 << ISDN_P_NT_E1))) {
> - test_and_set_bit(OPTION_L2_PMX, &opt);
> - rq.protocol = ISDN_P_NT_E1;
> - } else {
> - rq.protocol = ISDN_P_NT_S0;
> - }
> - l2 = create_l2(mgr->up, ISDN_P_LAPD_NT, opt, tei, sapi);
> - if (!l2) {
> - printk(KERN_WARNING "%s:no memory for layer2\n", __func__);
> - return NULL;
> - }
> - l2->tm = kzalloc_obj(struct teimgr);
> - if (!l2->tm) {
> - kfree(l2);
> - printk(KERN_WARNING "%s:no memory for teimgr\n", __func__);
> - return NULL;
> - }
> - l2->tm->mgr = mgr;
> - l2->tm->l2 = l2;
> - l2->tm->tei_m.debug = *debug & DEBUG_L2_TEIFSM;
> - l2->tm->tei_m.userdata = l2->tm;
> - l2->tm->tei_m.printdebug = tei_debug;
> - l2->tm->tei_m.fsm = &teifsmn;
> - l2->tm->tei_m.state = ST_TEI_NOP;
> - l2->tm->tval = 2000; /* T202 2 sec */
> - mISDN_FsmInitTimer(&l2->tm->tei_m, &l2->tm->timer);
> - write_lock_irqsave(&mgr->lock, flags);
> - id = get_free_id(mgr);
> - list_add_tail(&l2->list, &mgr->layer2);
> - write_unlock_irqrestore(&mgr->lock, flags);
> - if (id < 0) {
> - l2->ch.ctrl(&l2->ch, CLOSE_CHANNEL, NULL);
> - printk(KERN_WARNING "%s:no free id\n", __func__);
> - return NULL;
> - } else {
> - l2->ch.nr = id;
> - __add_layer2(&l2->ch, mgr->ch.st);
> - l2->ch.recv = mgr->ch.recv;
> - l2->ch.peer = mgr->ch.peer;
> - l2->ch.ctrl(&l2->ch, OPEN_CHANNEL, NULL);
> - /* We need open here L1 for the manager as well (refcounting) */
> - rq.adr.dev = mgr->ch.st->dev->id;
> - id = mgr->ch.st->own.ctrl(&mgr->ch.st->own, OPEN_CHANNEL, &rq);
> - if (id < 0) {
> - printk(KERN_WARNING "%s: cannot open L1\n", __func__);
> - l2->ch.ctrl(&l2->ch, CLOSE_CHANNEL, NULL);
> - l2 = NULL;
> - }
> - }
> - return l2;
> -}
> -
> -static void
> -new_tei_req(struct manager *mgr, u_char *dp)
> -{
> - int tei, ri;
> - struct layer2 *l2;
> -
> - ri = dp[0] << 8;
> - ri += dp[1];
> - if (!mgr->up)
> - goto denied;
> - if (!(dp[3] & 1)) /* Extension bit != 1 */
> - goto denied;
> - if (dp[3] != 0xff)
> - tei = dp[3] >> 1; /* 3GPP TS 08.56 6.1.11.2 */
> - else
> - tei = get_free_tei(mgr);
> - if (tei < 0) {
> - printk(KERN_WARNING "%s:No free tei\n", __func__);
> - goto denied;
> - }
> - l2 = create_new_tei(mgr, tei, CTRL_SAPI);
> - if (!l2)
> - goto denied;
> - else
> - mISDN_FsmEvent(&l2->tm->tei_m, EV_ASSIGN_REQ, dp);
> - return;
> -denied:
> - put_tei_msg(mgr, ID_DENIED, ri, GROUP_TEI);
> -}
> -
> -static int
> -ph_data_ind(struct manager *mgr, struct sk_buff *skb)
> -{
> - int ret = -EINVAL;
> - struct layer2 *l2, *nl2;
> - u_char mt;
> -
> - if (skb->len < 8) {
> - if (*debug & DEBUG_L2_TEI)
> - printk(KERN_DEBUG "%s: short mgr frame %d/8\n",
> - __func__, skb->len);
> - goto done;
> - }
> -
> - if ((skb->data[0] >> 2) != TEI_SAPI) /* not for us */
> - goto done;
> - if (skb->data[0] & 1) /* EA0 formal error */
> - goto done;
> - if (!(skb->data[1] & 1)) /* EA1 formal error */
> - goto done;
> - if ((skb->data[1] >> 1) != GROUP_TEI) /* not for us */
> - goto done;
> - if ((skb->data[2] & 0xef) != UI) /* not UI */
> - goto done;
> - if (skb->data[3] != TEI_ENTITY_ID) /* not tei entity */
> - goto done;
> - mt = skb->data[6];
> - switch (mt) {
> - case ID_REQUEST:
> - case ID_CHK_RES:
> - case ID_VERIFY:
> - if (!test_bit(MGR_OPT_NETWORK, &mgr->options))
> - goto done;
> - break;
> - case ID_ASSIGNED:
> - case ID_DENIED:
> - case ID_CHK_REQ:
> - case ID_REMOVE:
> - if (test_bit(MGR_OPT_NETWORK, &mgr->options))
> - goto done;
> - break;
> - default:
> - goto done;
> - }
> - ret = 0;
> - if (mt == ID_REQUEST) {
> - new_tei_req(mgr, &skb->data[4]);
> - goto done;
> - }
> - list_for_each_entry_safe(l2, nl2, &mgr->layer2, list) {
> - tei_ph_data_ind(l2->tm, mt, &skb->data[4], skb->len - 4);
> - }
> -done:
> - return ret;
> -}
> -
> -int
> -l2_tei(struct layer2 *l2, u_int cmd, u_long arg)
> -{
> - struct teimgr *tm = l2->tm;
> -
> - if (test_bit(FLG_FIXED_TEI, &l2->flag))
> - return 0;
> - if (*debug & DEBUG_L2_TEI)
> - printk(KERN_DEBUG "%s: cmd(%x)\n", __func__, cmd);
> - switch (cmd) {
> - case MDL_ASSIGN_IND:
> - mISDN_FsmEvent(&tm->tei_m, EV_IDREQ, NULL);
> - break;
> - case MDL_ERROR_IND:
> - if (test_bit(MGR_OPT_NETWORK, &tm->mgr->options))
> - mISDN_FsmEvent(&tm->tei_m, EV_CHKREQ, &l2->tei);
> - if (test_bit(MGR_OPT_USER, &tm->mgr->options))
> - mISDN_FsmEvent(&tm->tei_m, EV_VERIFY, NULL);
> - break;
> - case MDL_STATUS_UP_IND:
> - if (test_bit(MGR_OPT_NETWORK, &tm->mgr->options))
> - mISDN_FsmEvent(&tm->mgr->deact, EV_ACTIVATE, NULL);
> - break;
> - case MDL_STATUS_DOWN_IND:
> - if (test_bit(MGR_OPT_NETWORK, &tm->mgr->options))
> - mISDN_FsmEvent(&tm->mgr->deact, EV_DEACTIVATE, NULL);
> - break;
> - case MDL_STATUS_UI_IND:
> - if (test_bit(MGR_OPT_NETWORK, &tm->mgr->options))
> - mISDN_FsmEvent(&tm->mgr->deact, EV_UI, NULL);
> - break;
> - }
> - return 0;
> -}
> -
> -void
> -TEIrelease(struct layer2 *l2)
> -{
> - struct teimgr *tm = l2->tm;
> - u_long flags;
> -
> - mISDN_FsmDelTimer(&tm->timer, 1);
> - write_lock_irqsave(&tm->mgr->lock, flags);
> - list_del(&l2->list);
> - write_unlock_irqrestore(&tm->mgr->lock, flags);
> - l2->tm = NULL;
> - kfree(tm);
> -}
> -
> -static int
> -create_teimgr(struct manager *mgr, struct channel_req *crq)
> -{
> - struct layer2 *l2;
> - unsigned long opt = 0;
> - unsigned long flags;
> - int id;
> - struct channel_req l1rq;
> -
> - if (*debug & DEBUG_L2_TEI)
> - printk(KERN_DEBUG "%s: %s proto(%x) adr(%d %d %d %d)\n",
> - __func__, dev_name(&mgr->ch.st->dev->dev),
> - crq->protocol, crq->adr.dev, crq->adr.channel,
> - crq->adr.sapi, crq->adr.tei);
> - if (crq->adr.tei > GROUP_TEI)
> - return -EINVAL;
> - if (crq->adr.tei < 64)
> - test_and_set_bit(OPTION_L2_FIXEDTEI, &opt);
> - if (crq->adr.tei == 0)
> - test_and_set_bit(OPTION_L2_PTP, &opt);
> - if (test_bit(MGR_OPT_NETWORK, &mgr->options)) {
> - if (crq->protocol == ISDN_P_LAPD_TE)
> - return -EPROTONOSUPPORT;
> - if ((crq->adr.tei != 0) && (crq->adr.tei != 127))
> - return -EINVAL;
> - if (mgr->up) {
> - printk(KERN_WARNING
> - "%s: only one network manager is allowed\n",
> - __func__);
> - return -EBUSY;
> - }
> - } else if (test_bit(MGR_OPT_USER, &mgr->options)) {
> - if (crq->protocol == ISDN_P_LAPD_NT)
> - return -EPROTONOSUPPORT;
> - if ((crq->adr.tei >= 64) && (crq->adr.tei < GROUP_TEI))
> - return -EINVAL; /* dyn tei */
> - } else {
> - if (crq->protocol == ISDN_P_LAPD_NT)
> - test_and_set_bit(MGR_OPT_NETWORK, &mgr->options);
> - if (crq->protocol == ISDN_P_LAPD_TE)
> - test_and_set_bit(MGR_OPT_USER, &mgr->options);
> - }
> - l1rq.adr = crq->adr;
> - if (mgr->ch.st->dev->Dprotocols
> - & ((1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1)))
> - test_and_set_bit(OPTION_L2_PMX, &opt);
> - if ((crq->protocol == ISDN_P_LAPD_NT) && (crq->adr.tei == 127)) {
> - mgr->up = crq->ch;
> - id = DL_INFO_L2_CONNECT;
> - teiup_create(mgr, DL_INFORMATION_IND, sizeof(id), &id);
> - if (test_bit(MGR_PH_ACTIVE, &mgr->options))
> - teiup_create(mgr, PH_ACTIVATE_IND, 0, NULL);
> - crq->ch = NULL;
> - if (!list_empty(&mgr->layer2)) {
> - read_lock_irqsave(&mgr->lock, flags);
> - list_for_each_entry(l2, &mgr->layer2, list) {
> - l2->up = mgr->up;
> - l2->ch.ctrl(&l2->ch, OPEN_CHANNEL, NULL);
> - }
> - read_unlock_irqrestore(&mgr->lock, flags);
> - }
> - return 0;
> - }
> - l2 = create_l2(crq->ch, crq->protocol, opt,
> - crq->adr.tei, crq->adr.sapi);
> - if (!l2)
> - return -ENOMEM;
> - l2->tm = kzalloc_obj(struct teimgr);
> - if (!l2->tm) {
> - kfree(l2);
> - printk(KERN_ERR "kmalloc teimgr failed\n");
> - return -ENOMEM;
> - }
> - l2->tm->mgr = mgr;
> - l2->tm->l2 = l2;
> - l2->tm->tei_m.debug = *debug & DEBUG_L2_TEIFSM;
> - l2->tm->tei_m.userdata = l2->tm;
> - l2->tm->tei_m.printdebug = tei_debug;
> - if (crq->protocol == ISDN_P_LAPD_TE) {
> - l2->tm->tei_m.fsm = &teifsmu;
> - l2->tm->tei_m.state = ST_TEI_NOP;
> - l2->tm->tval = 1000; /* T201 1 sec */
> - if (test_bit(OPTION_L2_PMX, &opt))
> - l1rq.protocol = ISDN_P_TE_E1;
> - else
> - l1rq.protocol = ISDN_P_TE_S0;
> - } else {
> - l2->tm->tei_m.fsm = &teifsmn;
> - l2->tm->tei_m.state = ST_TEI_NOP;
> - l2->tm->tval = 2000; /* T202 2 sec */
> - if (test_bit(OPTION_L2_PMX, &opt))
> - l1rq.protocol = ISDN_P_NT_E1;
> - else
> - l1rq.protocol = ISDN_P_NT_S0;
> - }
> - mISDN_FsmInitTimer(&l2->tm->tei_m, &l2->tm->timer);
> - write_lock_irqsave(&mgr->lock, flags);
> - id = get_free_id(mgr);
> - list_add_tail(&l2->list, &mgr->layer2);
> - write_unlock_irqrestore(&mgr->lock, flags);
> - if (id >= 0) {
> - l2->ch.nr = id;
> - l2->up->nr = id;
> - crq->ch = &l2->ch;
> - /* We need open here L1 for the manager as well (refcounting) */
> - id = mgr->ch.st->own.ctrl(&mgr->ch.st->own, OPEN_CHANNEL,
> - &l1rq);
> - }
> - if (id < 0)
> - l2->ch.ctrl(&l2->ch, CLOSE_CHANNEL, NULL);
> - return id;
> -}
> -
> -static int
> -mgr_send(struct mISDNchannel *ch, struct sk_buff *skb)
> -{
> - struct manager *mgr;
> - struct mISDNhead *hh = mISDN_HEAD_P(skb);
> - int ret = -EINVAL;
> -
> - mgr = container_of(ch, struct manager, ch);
> - if (*debug & DEBUG_L2_RECV)
> - printk(KERN_DEBUG "%s: prim(%x) id(%x)\n",
> - __func__, hh->prim, hh->id);
> - switch (hh->prim) {
> - case PH_DATA_IND:
> - mISDN_FsmEvent(&mgr->deact, EV_UI, NULL);
> - ret = ph_data_ind(mgr, skb);
> - break;
> - case PH_DATA_CNF:
> - do_ack(mgr, hh->id);
> - ret = 0;
> - break;
> - case PH_ACTIVATE_IND:
> - test_and_set_bit(MGR_PH_ACTIVE, &mgr->options);
> - if (mgr->up)
> - teiup_create(mgr, PH_ACTIVATE_IND, 0, NULL);
> - mISDN_FsmEvent(&mgr->deact, EV_ACTIVATE_IND, NULL);
> - do_send(mgr);
> - ret = 0;
> - break;
> - case PH_DEACTIVATE_IND:
> - test_and_clear_bit(MGR_PH_ACTIVE, &mgr->options);
> - if (mgr->up)
> - teiup_create(mgr, PH_DEACTIVATE_IND, 0, NULL);
> - mISDN_FsmEvent(&mgr->deact, EV_DEACTIVATE_IND, NULL);
> - ret = 0;
> - break;
> - case DL_UNITDATA_REQ:
> - return dl_unit_data(mgr, skb);
> - }
> - if (!ret)
> - dev_kfree_skb(skb);
> - return ret;
> -}
> -
> -static int
> -free_teimanager(struct manager *mgr)
> -{
> - struct layer2 *l2, *nl2;
> -
> - test_and_clear_bit(OPTION_L1_HOLD, &mgr->options);
> - if (test_bit(MGR_OPT_NETWORK, &mgr->options)) {
> - /* not locked lock is taken in release tei */
> - mgr->up = NULL;
> - if (test_bit(OPTION_L2_CLEANUP, &mgr->options)) {
> - list_for_each_entry_safe(l2, nl2, &mgr->layer2, list) {
> - put_tei_msg(mgr, ID_REMOVE, 0, l2->tei);
> - mutex_lock(&mgr->ch.st->lmutex);
> - list_del(&l2->ch.list);
> - mutex_unlock(&mgr->ch.st->lmutex);
> - l2->ch.ctrl(&l2->ch, CLOSE_CHANNEL, NULL);
> - }
> - test_and_clear_bit(MGR_OPT_NETWORK, &mgr->options);
> - } else {
> - list_for_each_entry_safe(l2, nl2, &mgr->layer2, list) {
> - l2->up = NULL;
> - }
> - }
> - }
> - if (test_bit(MGR_OPT_USER, &mgr->options)) {
> - if (list_empty(&mgr->layer2))
> - test_and_clear_bit(MGR_OPT_USER, &mgr->options);
> - }
> - mgr->ch.st->dev->D.ctrl(&mgr->ch.st->dev->D, CLOSE_CHANNEL, NULL);
> - return 0;
> -}
> -
> -static int
> -ctrl_teimanager(struct manager *mgr, void *arg)
> -{
> - /* currently we only have one option */
> - unsigned int *val = (unsigned int *)arg;
> -
> - switch (val[0]) {
> - case IMCLEAR_L2:
> - if (val[1])
> - test_and_set_bit(OPTION_L2_CLEANUP, &mgr->options);
> - else
> - test_and_clear_bit(OPTION_L2_CLEANUP, &mgr->options);
> - break;
> - case IMHOLD_L1:
> - if (val[1])
> - test_and_set_bit(OPTION_L1_HOLD, &mgr->options);
> - else
> - test_and_clear_bit(OPTION_L1_HOLD, &mgr->options);
> - break;
> - default:
> - return -EINVAL;
> - }
> - return 0;
> -}
> -
> -/* This function does create a L2 for fixed TEI in NT Mode */
> -static int
> -check_data(struct manager *mgr, struct sk_buff *skb)
> -{
> - struct mISDNhead *hh = mISDN_HEAD_P(skb);
> - int ret, tei, sapi;
> - struct layer2 *l2;
> -
> - if (*debug & DEBUG_L2_CTRL)
> - printk(KERN_DEBUG "%s: prim(%x) id(%x)\n",
> - __func__, hh->prim, hh->id);
> - if (test_bit(MGR_OPT_USER, &mgr->options))
> - return -ENOTCONN;
> - if (hh->prim != PH_DATA_IND)
> - return -ENOTCONN;
> - if (skb->len != 3)
> - return -ENOTCONN;
> - if (skb->data[0] & 3) /* EA0 and CR must be 0 */
> - return -EINVAL;
> - sapi = skb->data[0] >> 2;
> - if (!(skb->data[1] & 1)) /* invalid EA1 */
> - return -EINVAL;
> - tei = skb->data[1] >> 1;
> - if (tei > 63) /* not a fixed tei */
> - return -ENOTCONN;
> - if ((skb->data[2] & ~0x10) != SABME)
> - return -ENOTCONN;
> - /* We got a SABME for a fixed TEI */
> - if (*debug & DEBUG_L2_CTRL)
> - printk(KERN_DEBUG "%s: SABME sapi(%d) tei(%d)\n",
> - __func__, sapi, tei);
> - l2 = create_new_tei(mgr, tei, sapi);
> - if (!l2) {
> - if (*debug & DEBUG_L2_CTRL)
> - printk(KERN_DEBUG "%s: failed to create new tei\n",
> - __func__);
> - return -ENOMEM;
> - }
> - ret = l2->ch.send(&l2->ch, skb);
> - return ret;
> -}
> -
> -void
> -delete_teimanager(struct mISDNchannel *ch)
> -{
> - struct manager *mgr;
> - struct layer2 *l2, *nl2;
> -
> - mgr = container_of(ch, struct manager, ch);
> - /* not locked lock is taken in release tei */
> - list_for_each_entry_safe(l2, nl2, &mgr->layer2, list) {
> - mutex_lock(&mgr->ch.st->lmutex);
> - list_del(&l2->ch.list);
> - mutex_unlock(&mgr->ch.st->lmutex);
> - l2->ch.ctrl(&l2->ch, CLOSE_CHANNEL, NULL);
> - }
> - list_del(&mgr->ch.list);
> - list_del(&mgr->bcast.list);
> - skb_queue_purge(&mgr->sendq);
> - kfree(mgr);
> -}
> -
> -static int
> -mgr_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
> -{
> - struct manager *mgr;
> - int ret = -EINVAL;
> -
> - mgr = container_of(ch, struct manager, ch);
> - if (*debug & DEBUG_L2_CTRL)
> - printk(KERN_DEBUG "%s(%x, %p)\n", __func__, cmd, arg);
> - switch (cmd) {
> - case OPEN_CHANNEL:
> - ret = create_teimgr(mgr, arg);
> - break;
> - case CLOSE_CHANNEL:
> - ret = free_teimanager(mgr);
> - break;
> - case CONTROL_CHANNEL:
> - ret = ctrl_teimanager(mgr, arg);
> - break;
> - case CHECK_DATA:
> - ret = check_data(mgr, arg);
> - break;
> - }
> - return ret;
> -}
> -
> -static int
> -mgr_bcast(struct mISDNchannel *ch, struct sk_buff *skb)
> -{
> - struct manager *mgr = container_of(ch, struct manager, bcast);
> - struct mISDNhead *hhc, *hh = mISDN_HEAD_P(skb);
> - struct sk_buff *cskb = NULL;
> - struct layer2 *l2;
> - u_long flags;
> - int ret;
> -
> - read_lock_irqsave(&mgr->lock, flags);
> - list_for_each_entry(l2, &mgr->layer2, list) {
> - if ((hh->id & MISDN_ID_SAPI_MASK) ==
> - (l2->ch.addr & MISDN_ID_SAPI_MASK)) {
> - if (list_is_last(&l2->list, &mgr->layer2)) {
> - cskb = skb;
> - skb = NULL;
> - } else {
> - if (!cskb)
> - cskb = skb_copy(skb, GFP_ATOMIC);
> - }
> - if (cskb) {
> - hhc = mISDN_HEAD_P(cskb);
> - /* save original header behind normal header */
> - hhc++;
> - *hhc = *hh;
> - hhc--;
> - hhc->prim = DL_INTERN_MSG;
> - hhc->id = l2->ch.nr;
> - ret = ch->st->own.recv(&ch->st->own, cskb);
> - if (ret) {
> - if (*debug & DEBUG_SEND_ERR)
> - printk(KERN_DEBUG
> - "%s ch%d prim(%x) addr(%x)"
> - " err %d\n",
> - __func__, l2->ch.nr,
> - hh->prim, l2->ch.addr, ret);
> - } else
> - cskb = NULL;
> - } else {
> - printk(KERN_WARNING "%s ch%d addr %x no mem\n",
> - __func__, ch->nr, ch->addr);
> - goto out;
> - }
> - }
> - }
> -out:
> - read_unlock_irqrestore(&mgr->lock, flags);
> - dev_kfree_skb(cskb);
> - dev_kfree_skb(skb);
> - return 0;
> -}
> -
> -static int
> -mgr_bcast_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
> -{
> -
> - return -EINVAL;
> -}
> -
> -int
> -create_teimanager(struct mISDNdevice *dev)
> -{
> - struct manager *mgr;
> -
> - mgr = kzalloc_obj(struct manager);
> - if (!mgr)
> - return -ENOMEM;
> - INIT_LIST_HEAD(&mgr->layer2);
> - rwlock_init(&mgr->lock);
> - skb_queue_head_init(&mgr->sendq);
> - mgr->nextid = 1;
> - mgr->lastid = MISDN_ID_NONE;
> - mgr->ch.send = mgr_send;
> - mgr->ch.ctrl = mgr_ctrl;
> - mgr->ch.st = dev->D.st;
> - set_channel_address(&mgr->ch, TEI_SAPI, GROUP_TEI);
> - add_layer2(&mgr->ch, dev->D.st);
> - mgr->bcast.send = mgr_bcast;
> - mgr->bcast.ctrl = mgr_bcast_ctrl;
> - mgr->bcast.st = dev->D.st;
> - set_channel_address(&mgr->bcast, 0, GROUP_TEI);
> - add_layer2(&mgr->bcast, dev->D.st);
> - mgr->deact.debug = *debug & DEBUG_MANAGER;
> - mgr->deact.userdata = mgr;
> - mgr->deact.printdebug = da_debug;
> - mgr->deact.fsm = &deactfsm;
> - mgr->deact.state = ST_L1_DEACT;
> - mISDN_FsmInitTimer(&mgr->deact, &mgr->datimer);
> - dev->teimgr = &mgr->ch;
> - return 0;
> -}
> -
> -int TEIInit(u_int *deb)
> -{
> - int res;
> - debug = deb;
> - teifsmu.state_count = TEI_STATE_COUNT;
> - teifsmu.event_count = TEI_EVENT_COUNT;
> - teifsmu.strEvent = strTeiEvent;
> - teifsmu.strState = strTeiState;
> - res = mISDN_FsmNew(&teifsmu, TeiFnListUser, ARRAY_SIZE(TeiFnListUser));
> - if (res)
> - goto error;
> - teifsmn.state_count = TEI_STATE_COUNT;
> - teifsmn.event_count = TEI_EVENT_COUNT;
> - teifsmn.strEvent = strTeiEvent;
> - teifsmn.strState = strTeiState;
> - res = mISDN_FsmNew(&teifsmn, TeiFnListNet, ARRAY_SIZE(TeiFnListNet));
> - if (res)
> - goto error_smn;
> - deactfsm.state_count = DEACT_STATE_COUNT;
> - deactfsm.event_count = DEACT_EVENT_COUNT;
> - deactfsm.strEvent = strDeactEvent;
> - deactfsm.strState = strDeactState;
> - res = mISDN_FsmNew(&deactfsm, DeactFnList, ARRAY_SIZE(DeactFnList));
> - if (res)
> - goto error_deact;
> - return 0;
> -
> -error_deact:
> - mISDN_FsmFree(&teifsmn);
> -error_smn:
> - mISDN_FsmFree(&teifsmu);
> -error:
> - return res;
> -}
> -
> -void TEIFree(void)
> -{
> - mISDN_FsmFree(&teifsmu);
> - mISDN_FsmFree(&teifsmn);
> - mISDN_FsmFree(&deactfsm);
> -}
> diff --git a/drivers/isdn/mISDN/timerdev.c b/drivers/isdn/mISDN/timerdev.c
> deleted file mode 100644
> index a18845755633..000000000000
> --- a/drivers/isdn/mISDN/timerdev.c
> +++ /dev/null
> @@ -1,295 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - *
> - * general timer device for using in ISDN stacks
> - *
> - * Author Karsten Keil <kkeil@novell.com>
> - *
> - * Copyright 2008 by Karsten Keil <kkeil@novell.com>
> - */
> -
> -#include <linux/poll.h>
> -#include <linux/vmalloc.h>
> -#include <linux/slab.h>
> -#include <linux/timer.h>
> -#include <linux/miscdevice.h>
> -#include <linux/module.h>
> -#include <linux/mISDNif.h>
> -#include <linux/mutex.h>
> -#include <linux/sched/signal.h>
> -
> -#include "core.h"
> -
> -static DEFINE_MUTEX(mISDN_mutex);
> -static u_int *debug;
> -
> -
> -struct mISDNtimerdev {
> - int next_id;
> - struct list_head pending;
> - struct list_head expired;
> - wait_queue_head_t wait;
> - u_int work;
> - spinlock_t lock; /* protect lists */
> -};
> -
> -struct mISDNtimer {
> - struct list_head list;
> - struct mISDNtimerdev *dev;
> - struct timer_list tl;
> - int id;
> -};
> -
> -static int
> -mISDN_open(struct inode *ino, struct file *filep)
> -{
> - struct mISDNtimerdev *dev;
> -
> - if (*debug & DEBUG_TIMER)
> - printk(KERN_DEBUG "%s(%p,%p)\n", __func__, ino, filep);
> - dev = kmalloc_obj(struct mISDNtimerdev);
> - if (!dev)
> - return -ENOMEM;
> - dev->next_id = 1;
> - INIT_LIST_HEAD(&dev->pending);
> - INIT_LIST_HEAD(&dev->expired);
> - spin_lock_init(&dev->lock);
> - dev->work = 0;
> - init_waitqueue_head(&dev->wait);
> - filep->private_data = dev;
> - return nonseekable_open(ino, filep);
> -}
> -
> -static int
> -mISDN_close(struct inode *ino, struct file *filep)
> -{
> - struct mISDNtimerdev *dev = filep->private_data;
> - struct list_head *list = &dev->pending;
> - struct mISDNtimer *timer, *next;
> -
> - if (*debug & DEBUG_TIMER)
> - printk(KERN_DEBUG "%s(%p,%p)\n", __func__, ino, filep);
> -
> - spin_lock_irq(&dev->lock);
> - while (!list_empty(list)) {
> - timer = list_first_entry(list, struct mISDNtimer, list);
> - spin_unlock_irq(&dev->lock);
> - timer_shutdown_sync(&timer->tl);
> - spin_lock_irq(&dev->lock);
> - /* it might have been moved to ->expired */
> - list_del(&timer->list);
> - kfree(timer);
> - }
> - spin_unlock_irq(&dev->lock);
> -
> - list_for_each_entry_safe(timer, next, &dev->expired, list) {
> - kfree(timer);
> - }
> - kfree(dev);
> - return 0;
> -}
> -
> -static ssize_t
> -mISDN_read(struct file *filep, char __user *buf, size_t count, loff_t *off)
> -{
> - struct mISDNtimerdev *dev = filep->private_data;
> - struct list_head *list = &dev->expired;
> - struct mISDNtimer *timer;
> - int ret = 0;
> -
> - if (*debug & DEBUG_TIMER)
> - printk(KERN_DEBUG "%s(%p, %p, %d, %p)\n", __func__,
> - filep, buf, (int)count, off);
> -
> - if (count < sizeof(int))
> - return -ENOSPC;
> -
> - spin_lock_irq(&dev->lock);
> - while (list_empty(list) && (dev->work == 0)) {
> - spin_unlock_irq(&dev->lock);
> - if (filep->f_flags & O_NONBLOCK)
> - return -EAGAIN;
> - wait_event_interruptible(dev->wait, (READ_ONCE(dev->work) ||
> - !list_empty(list)));
> - if (signal_pending(current))
> - return -ERESTARTSYS;
> - spin_lock_irq(&dev->lock);
> - }
> - if (dev->work)
> - WRITE_ONCE(dev->work, 0);
> - if (!list_empty(list)) {
> - timer = list_first_entry(list, struct mISDNtimer, list);
> - list_del(&timer->list);
> - spin_unlock_irq(&dev->lock);
> - if (put_user(timer->id, (int __user *)buf))
> - ret = -EFAULT;
> - else
> - ret = sizeof(int);
> - kfree(timer);
> - } else {
> - spin_unlock_irq(&dev->lock);
> - }
> - return ret;
> -}
> -
> -static __poll_t
> -mISDN_poll(struct file *filep, poll_table *wait)
> -{
> - struct mISDNtimerdev *dev = filep->private_data;
> - __poll_t mask = EPOLLERR;
> -
> - if (*debug & DEBUG_TIMER)
> - printk(KERN_DEBUG "%s(%p, %p)\n", __func__, filep, wait);
> - if (dev) {
> - u32 work;
> -
> - poll_wait(filep, &dev->wait, wait);
> - mask = 0;
> - work = READ_ONCE(dev->work);
> - if (work || !list_empty(&dev->expired))
> - mask |= (EPOLLIN | EPOLLRDNORM);
> - if (*debug & DEBUG_TIMER)
> - printk(KERN_DEBUG "%s work(%d) empty(%d)\n", __func__,
> - work, list_empty(&dev->expired));
> - }
> - return mask;
> -}
> -
> -static void
> -dev_expire_timer(struct timer_list *t)
> -{
> - struct mISDNtimer *timer = timer_container_of(timer, t, tl);
> - u_long flags;
> -
> - spin_lock_irqsave(&timer->dev->lock, flags);
> - if (timer->id >= 0)
> - list_move_tail(&timer->list, &timer->dev->expired);
> - wake_up_interruptible(&timer->dev->wait);
> - spin_unlock_irqrestore(&timer->dev->lock, flags);
> -}
> -
> -static int
> -misdn_add_timer(struct mISDNtimerdev *dev, int timeout)
> -{
> - int id;
> - struct mISDNtimer *timer;
> -
> - if (!timeout) {
> - WRITE_ONCE(dev->work, 1);
> - wake_up_interruptible(&dev->wait);
> - id = 0;
> - } else {
> - timer = kzalloc_obj(struct mISDNtimer);
> - if (!timer)
> - return -ENOMEM;
> - timer->dev = dev;
> - timer_setup(&timer->tl, dev_expire_timer, 0);
> - spin_lock_irq(&dev->lock);
> - id = timer->id = dev->next_id++;
> - if (dev->next_id < 0)
> - dev->next_id = 1;
> - list_add_tail(&timer->list, &dev->pending);
> - timer->tl.expires = jiffies + ((HZ * (u_long)timeout) / 1000);
> - add_timer(&timer->tl);
> - spin_unlock_irq(&dev->lock);
> - }
> - return id;
> -}
> -
> -static int
> -misdn_del_timer(struct mISDNtimerdev *dev, int id)
> -{
> - struct mISDNtimer *timer;
> -
> - spin_lock_irq(&dev->lock);
> - list_for_each_entry(timer, &dev->pending, list) {
> - if (timer->id == id) {
> - list_del_init(&timer->list);
> - timer->id = -1;
> - spin_unlock_irq(&dev->lock);
> - timer_shutdown_sync(&timer->tl);
> - kfree(timer);
> - return id;
> - }
> - }
> - spin_unlock_irq(&dev->lock);
> - return 0;
> -}
> -
> -static long
> -mISDN_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
> -{
> - struct mISDNtimerdev *dev = filep->private_data;
> - int id, tout, ret = 0;
> -
> -
> - if (*debug & DEBUG_TIMER)
> - printk(KERN_DEBUG "%s(%p, %x, %lx)\n", __func__,
> - filep, cmd, arg);
> - mutex_lock(&mISDN_mutex);
> - switch (cmd) {
> - case IMADDTIMER:
> - if (get_user(tout, (int __user *)arg)) {
> - ret = -EFAULT;
> - break;
> - }
> - id = misdn_add_timer(dev, tout);
> - if (*debug & DEBUG_TIMER)
> - printk(KERN_DEBUG "%s add %d id %d\n", __func__,
> - tout, id);
> - if (id < 0) {
> - ret = id;
> - break;
> - }
> - if (put_user(id, (int __user *)arg))
> - ret = -EFAULT;
> - break;
> - case IMDELTIMER:
> - if (get_user(id, (int __user *)arg)) {
> - ret = -EFAULT;
> - break;
> - }
> - if (*debug & DEBUG_TIMER)
> - printk(KERN_DEBUG "%s del id %d\n", __func__, id);
> - id = misdn_del_timer(dev, id);
> - if (put_user(id, (int __user *)arg))
> - ret = -EFAULT;
> - break;
> - default:
> - ret = -EINVAL;
> - }
> - mutex_unlock(&mISDN_mutex);
> - return ret;
> -}
> -
> -static const struct file_operations mISDN_fops = {
> - .owner = THIS_MODULE,
> - .read = mISDN_read,
> - .poll = mISDN_poll,
> - .unlocked_ioctl = mISDN_ioctl,
> - .open = mISDN_open,
> - .release = mISDN_close,
> -};
> -
> -static struct miscdevice mISDNtimer = {
> - .minor = MISC_DYNAMIC_MINOR,
> - .name = "mISDNtimer",
> - .fops = &mISDN_fops,
> -};
> -
> -int
> -mISDN_inittimer(u_int *deb)
> -{
> - int err;
> -
> - debug = deb;
> - err = misc_register(&mISDNtimer);
> - if (err)
> - printk(KERN_WARNING "mISDN: Could not register timer device\n");
> - return err;
> -}
> -
> -void mISDN_timer_cleanup(void)
> -{
> - misc_deregister(&mISDNtimer);
> -}
> diff --git a/net/bluetooth/cmtp/capi.c b/net/bluetooth/cmtp/capi.c
> deleted file mode 100644
> index b95413bffa16..000000000000
> --- a/net/bluetooth/cmtp/capi.c
> +++ /dev/null
> @@ -1,579 +0,0 @@
> -/*
> - CMTP implementation for Linux Bluetooth stack (BlueZ).
> - Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
> -
> - This program is free software; you can redistribute it and/or modify
> - it under the terms of the GNU General Public License version 2 as
> - published by the Free Software Foundation;
> -
> - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
> - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
> - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
> - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
> - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> -
> - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
> - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
> - SOFTWARE IS DISCLAIMED.
> -*/
> -
> -#include <linux/export.h>
> -#include <linux/proc_fs.h>
> -#include <linux/seq_file.h>
> -#include <linux/types.h>
> -#include <linux/errno.h>
> -#include <linux/kernel.h>
> -#include <linux/sched/signal.h>
> -#include <linux/slab.h>
> -#include <linux/poll.h>
> -#include <linux/fcntl.h>
> -#include <linux/skbuff.h>
> -#include <linux/socket.h>
> -#include <linux/ioctl.h>
> -#include <linux/file.h>
> -#include <linux/wait.h>
> -#include <linux/kthread.h>
> -#include <net/sock.h>
> -
> -#include <linux/isdn/capilli.h>
> -#include <linux/isdn/capicmd.h>
> -#include <linux/isdn/capiutil.h>
> -
> -#include "cmtp.h"
> -
> -#define CAPI_INTEROPERABILITY 0x20
> -
> -#define CAPI_INTEROPERABILITY_REQ CAPICMD(CAPI_INTEROPERABILITY, CAPI_REQ)
> -#define CAPI_INTEROPERABILITY_CONF CAPICMD(CAPI_INTEROPERABILITY, CAPI_CONF)
> -#define CAPI_INTEROPERABILITY_IND CAPICMD(CAPI_INTEROPERABILITY, CAPI_IND)
> -#define CAPI_INTEROPERABILITY_RESP CAPICMD(CAPI_INTEROPERABILITY, CAPI_RESP)
> -
> -#define CAPI_INTEROPERABILITY_REQ_LEN (CAPI_MSG_BASELEN + 2)
> -#define CAPI_INTEROPERABILITY_CONF_LEN (CAPI_MSG_BASELEN + 4)
> -#define CAPI_INTEROPERABILITY_IND_LEN (CAPI_MSG_BASELEN + 2)
> -#define CAPI_INTEROPERABILITY_RESP_LEN (CAPI_MSG_BASELEN + 2)
> -
> -#define CAPI_FUNCTION_REGISTER 0
> -#define CAPI_FUNCTION_RELEASE 1
> -#define CAPI_FUNCTION_GET_PROFILE 2
> -#define CAPI_FUNCTION_GET_MANUFACTURER 3
> -#define CAPI_FUNCTION_GET_VERSION 4
> -#define CAPI_FUNCTION_GET_SERIAL_NUMBER 5
> -#define CAPI_FUNCTION_MANUFACTURER 6
> -#define CAPI_FUNCTION_LOOPBACK 7
> -
> -
> -#define CMTP_MSGNUM 1
> -#define CMTP_APPLID 2
> -#define CMTP_MAPPING 3
> -
> -static struct cmtp_application *cmtp_application_add(struct cmtp_session *session, __u16 appl)
> -{
> - struct cmtp_application *app = kzalloc_obj(*app);
> -
> - BT_DBG("session %p application %p appl %u", session, app, appl);
> -
> - if (!app)
> - return NULL;
> -
> - app->state = BT_OPEN;
> - app->appl = appl;
> -
> - list_add_tail(&app->list, &session->applications);
> -
> - return app;
> -}
> -
> -static void cmtp_application_del(struct cmtp_session *session, struct cmtp_application *app)
> -{
> - BT_DBG("session %p application %p", session, app);
> -
> - if (app) {
> - list_del(&app->list);
> - kfree(app);
> - }
> -}
> -
> -static struct cmtp_application *cmtp_application_get(struct cmtp_session *session, int pattern, __u16 value)
> -{
> - struct cmtp_application *app;
> -
> - list_for_each_entry(app, &session->applications, list) {
> - switch (pattern) {
> - case CMTP_MSGNUM:
> - if (app->msgnum == value)
> - return app;
> - break;
> - case CMTP_APPLID:
> - if (app->appl == value)
> - return app;
> - break;
> - case CMTP_MAPPING:
> - if (app->mapping == value)
> - return app;
> - break;
> - }
> - }
> -
> - return NULL;
> -}
> -
> -static int cmtp_msgnum_get(struct cmtp_session *session)
> -{
> - session->msgnum++;
> -
> - if ((session->msgnum & 0xff) > 200)
> - session->msgnum = CMTP_INITIAL_MSGNUM + 1;
> -
> - return session->msgnum;
> -}
> -
> -static void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb)
> -{
> - struct cmtp_scb *scb = (void *) skb->cb;
> -
> - BT_DBG("session %p skb %p len %u", session, skb, skb->len);
> -
> - scb->id = -1;
> - scb->data = (CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3);
> -
> - skb_queue_tail(&session->transmit, skb);
> -
> - wake_up_interruptible(sk_sleep(session->sock->sk));
> -}
> -
> -static void cmtp_send_interopmsg(struct cmtp_session *session,
> - __u8 subcmd, __u16 appl, __u16 msgnum,
> - __u16 function, unsigned char *buf, int len)
> -{
> - struct sk_buff *skb;
> - unsigned char *s;
> -
> - BT_DBG("session %p subcmd 0x%02x appl %u msgnum %u", session, subcmd, appl, msgnum);
> -
> - skb = alloc_skb(CAPI_MSG_BASELEN + 6 + len, GFP_ATOMIC);
> - if (!skb) {
> - BT_ERR("Can't allocate memory for interoperability packet");
> - return;
> - }
> -
> - s = skb_put(skb, CAPI_MSG_BASELEN + 6 + len);
> -
> - capimsg_setu16(s, 0, CAPI_MSG_BASELEN + 6 + len);
> - capimsg_setu16(s, 2, appl);
> - capimsg_setu8 (s, 4, CAPI_INTEROPERABILITY);
> - capimsg_setu8 (s, 5, subcmd);
> - capimsg_setu16(s, 6, msgnum);
> -
> - /* Interoperability selector (Bluetooth Device Management) */
> - capimsg_setu16(s, 8, 0x0001);
> -
> - capimsg_setu8 (s, 10, 3 + len);
> - capimsg_setu16(s, 11, function);
> - capimsg_setu8 (s, 13, len);
> -
> - if (len > 0)
> - memcpy(s + 14, buf, len);
> -
> - cmtp_send_capimsg(session, skb);
> -}
> -
> -static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *skb)
> -{
> - struct capi_ctr *ctrl = &session->ctrl;
> - struct cmtp_application *application;
> - __u16 appl, msgnum, func, info;
> - __u32 controller;
> -
> - BT_DBG("session %p skb %p len %u", session, skb, skb->len);
> -
> - switch (CAPIMSG_SUBCOMMAND(skb->data)) {
> - case CAPI_CONF:
> - if (skb->len < CAPI_MSG_BASELEN + 10)
> - break;
> -
> - func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 5);
> - info = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 8);
> -
> - switch (func) {
> - case CAPI_FUNCTION_REGISTER:
> - msgnum = CAPIMSG_MSGID(skb->data);
> -
> - application = cmtp_application_get(session, CMTP_MSGNUM, msgnum);
> - if (application) {
> - application->state = BT_CONNECTED;
> - application->msgnum = 0;
> - application->mapping = CAPIMSG_APPID(skb->data);
> - wake_up_interruptible(&session->wait);
> - }
> -
> - break;
> -
> - case CAPI_FUNCTION_RELEASE:
> - appl = CAPIMSG_APPID(skb->data);
> -
> - application = cmtp_application_get(session, CMTP_MAPPING, appl);
> - if (application) {
> - application->state = BT_CLOSED;
> - application->msgnum = 0;
> - wake_up_interruptible(&session->wait);
> - }
> -
> - break;
> -
> - case CAPI_FUNCTION_GET_PROFILE:
> - if (skb->len < CAPI_MSG_BASELEN + 11 + sizeof(capi_profile))
> - break;
> -
> - controller = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 11);
> - msgnum = CAPIMSG_MSGID(skb->data);
> -
> - if (!info && (msgnum == CMTP_INITIAL_MSGNUM)) {
> - session->ncontroller = controller;
> - wake_up_interruptible(&session->wait);
> - break;
> - }
> -
> - if (!info && ctrl) {
> - memcpy(&ctrl->profile,
> - skb->data + CAPI_MSG_BASELEN + 11,
> - sizeof(capi_profile));
> - session->state = BT_CONNECTED;
> - capi_ctr_ready(ctrl);
> - }
> -
> - break;
> -
> - case CAPI_FUNCTION_GET_MANUFACTURER:
> - if (!info && ctrl && skb->len > CAPI_MSG_BASELEN + 14)
> - strscpy_pad(ctrl->manu,
> - skb->data + CAPI_MSG_BASELEN + 15,
> - skb->data[CAPI_MSG_BASELEN + 14]);
> - break;
> -
> - case CAPI_FUNCTION_GET_VERSION:
> - if (skb->len < CAPI_MSG_BASELEN + 32)
> - break;
> -
> - if (!info && ctrl) {
> - ctrl->version.majorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 16);
> - ctrl->version.minorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 20);
> - ctrl->version.majormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 24);
> - ctrl->version.minormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 28);
> - }
> -
> - break;
> -
> - case CAPI_FUNCTION_GET_SERIAL_NUMBER:
> - if (!info && ctrl && skb->len > CAPI_MSG_BASELEN + 16)
> - strscpy_pad(ctrl->serial,
> - skb->data + CAPI_MSG_BASELEN + 17,
> - skb->data[CAPI_MSG_BASELEN + 16]);
> - break;
> - }
> -
> - break;
> -
> - case CAPI_IND:
> - if (skb->len < CAPI_MSG_BASELEN + 6)
> - break;
> -
> - func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 3);
> -
> - if (func == CAPI_FUNCTION_LOOPBACK) {
> - int len = min_t(uint, skb->len - CAPI_MSG_BASELEN - 6,
> - skb->data[CAPI_MSG_BASELEN + 5]);
> - appl = CAPIMSG_APPID(skb->data);
> - msgnum = CAPIMSG_MSGID(skb->data);
> - cmtp_send_interopmsg(session, CAPI_RESP, appl, msgnum, func,
> - skb->data + CAPI_MSG_BASELEN + 6, len);
> - }
> -
> - break;
> - }
> -
> - kfree_skb(skb);
> -}
> -
> -void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb)
> -{
> - struct capi_ctr *ctrl = &session->ctrl;
> - struct cmtp_application *application;
> - __u16 appl;
> - __u32 contr;
> -
> - BT_DBG("session %p skb %p len %u", session, skb, skb->len);
> -
> - if (skb->len < CAPI_MSG_BASELEN)
> - return;
> -
> - if (CAPIMSG_COMMAND(skb->data) == CAPI_INTEROPERABILITY) {
> - cmtp_recv_interopmsg(session, skb);
> - return;
> - }
> -
> - if (session->flags & BIT(CMTP_LOOPBACK)) {
> - kfree_skb(skb);
> - return;
> - }
> -
> - appl = CAPIMSG_APPID(skb->data);
> - contr = CAPIMSG_CONTROL(skb->data);
> -
> - application = cmtp_application_get(session, CMTP_MAPPING, appl);
> - if (application) {
> - appl = application->appl;
> - CAPIMSG_SETAPPID(skb->data, appl);
> - } else {
> - BT_ERR("Can't find application with id %u", appl);
> - kfree_skb(skb);
> - return;
> - }
> -
> - if ((contr & 0x7f) == 0x01) {
> - contr = (contr & 0xffffff80) | session->num;
> - CAPIMSG_SETCONTROL(skb->data, contr);
> - }
> -
> - capi_ctr_handle_message(ctrl, appl, skb);
> -}
> -
> -static int cmtp_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
> -{
> - BT_DBG("ctrl %p data %p", ctrl, data);
> -
> - return 0;
> -}
> -
> -static void cmtp_reset_ctr(struct capi_ctr *ctrl)
> -{
> - struct cmtp_session *session = ctrl->driverdata;
> -
> - BT_DBG("ctrl %p", ctrl);
> -
> - capi_ctr_down(ctrl);
> -
> - atomic_inc(&session->terminate);
> - wake_up_process(session->task);
> -}
> -
> -static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp)
> -{
> - DECLARE_WAITQUEUE(wait, current);
> - struct cmtp_session *session = ctrl->driverdata;
> - struct cmtp_application *application;
> - unsigned long timeo = CMTP_INTEROP_TIMEOUT;
> - unsigned char buf[8];
> - int err = 0, nconn, want = rp->level3cnt;
> -
> - BT_DBG("ctrl %p appl %u level3cnt %u datablkcnt %u datablklen %u",
> - ctrl, appl, rp->level3cnt, rp->datablkcnt, rp->datablklen);
> -
> - application = cmtp_application_add(session, appl);
> - if (!application) {
> - BT_ERR("Can't allocate memory for new application");
> - return;
> - }
> -
> - if (want < 0)
> - nconn = ctrl->profile.nbchannel * -want;
> - else
> - nconn = want;
> -
> - if (nconn == 0)
> - nconn = ctrl->profile.nbchannel;
> -
> - capimsg_setu16(buf, 0, nconn);
> - capimsg_setu16(buf, 2, rp->datablkcnt);
> - capimsg_setu16(buf, 4, rp->datablklen);
> -
> - application->state = BT_CONFIG;
> - application->msgnum = cmtp_msgnum_get(session);
> -
> - cmtp_send_interopmsg(session, CAPI_REQ, 0x0000, application->msgnum,
> - CAPI_FUNCTION_REGISTER, buf, 6);
> -
> - add_wait_queue(&session->wait, &wait);
> - while (1) {
> - set_current_state(TASK_INTERRUPTIBLE);
> -
> - if (!timeo) {
> - err = -EAGAIN;
> - break;
> - }
> -
> - if (application->state == BT_CLOSED) {
> - err = -application->err;
> - break;
> - }
> -
> - if (application->state == BT_CONNECTED)
> - break;
> -
> - if (signal_pending(current)) {
> - err = -EINTR;
> - break;
> - }
> -
> - timeo = schedule_timeout(timeo);
> - }
> - set_current_state(TASK_RUNNING);
> - remove_wait_queue(&session->wait, &wait);
> -
> - if (err) {
> - cmtp_application_del(session, application);
> - return;
> - }
> -}
> -
> -static void cmtp_release_appl(struct capi_ctr *ctrl, __u16 appl)
> -{
> - struct cmtp_session *session = ctrl->driverdata;
> - struct cmtp_application *application;
> -
> - BT_DBG("ctrl %p appl %u", ctrl, appl);
> -
> - application = cmtp_application_get(session, CMTP_APPLID, appl);
> - if (!application) {
> - BT_ERR("Can't find application");
> - return;
> - }
> -
> - application->msgnum = cmtp_msgnum_get(session);
> -
> - cmtp_send_interopmsg(session, CAPI_REQ, application->mapping, application->msgnum,
> - CAPI_FUNCTION_RELEASE, NULL, 0);
> -
> - wait_event_interruptible_timeout(session->wait,
> - (application->state == BT_CLOSED), CMTP_INTEROP_TIMEOUT);
> -
> - cmtp_application_del(session, application);
> -}
> -
> -static u16 cmtp_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
> -{
> - struct cmtp_session *session = ctrl->driverdata;
> - struct cmtp_application *application;
> - __u16 appl;
> - __u32 contr;
> -
> - BT_DBG("ctrl %p skb %p", ctrl, skb);
> -
> - appl = CAPIMSG_APPID(skb->data);
> - contr = CAPIMSG_CONTROL(skb->data);
> -
> - application = cmtp_application_get(session, CMTP_APPLID, appl);
> - if ((!application) || (application->state != BT_CONNECTED)) {
> - BT_ERR("Can't find application with id %u", appl);
> - return CAPI_ILLAPPNR;
> - }
> -
> - CAPIMSG_SETAPPID(skb->data, application->mapping);
> -
> - if ((contr & 0x7f) == session->num) {
> - contr = (contr & 0xffffff80) | 0x01;
> - CAPIMSG_SETCONTROL(skb->data, contr);
> - }
> -
> - cmtp_send_capimsg(session, skb);
> -
> - return CAPI_NOERROR;
> -}
> -
> -static char *cmtp_procinfo(struct capi_ctr *ctrl)
> -{
> - return "CAPI Message Transport Protocol";
> -}
> -
> -static int cmtp_proc_show(struct seq_file *m, void *v)
> -{
> - struct capi_ctr *ctrl = m->private;
> - struct cmtp_session *session = ctrl->driverdata;
> - struct cmtp_application *app;
> -
> - seq_printf(m, "%s\n\n", cmtp_procinfo(ctrl));
> - seq_printf(m, "addr %s\n", session->name);
> - seq_printf(m, "ctrl %d\n", session->num);
> -
> - list_for_each_entry(app, &session->applications, list) {
> - seq_printf(m, "appl %u -> %u\n", app->appl, app->mapping);
> - }
> -
> - return 0;
> -}
> -
> -int cmtp_attach_device(struct cmtp_session *session)
> -{
> - unsigned char buf[4];
> - long ret;
> -
> - BT_DBG("session %p", session);
> -
> - capimsg_setu32(buf, 0, 0);
> -
> - cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, CMTP_INITIAL_MSGNUM,
> - CAPI_FUNCTION_GET_PROFILE, buf, 4);
> -
> - ret = wait_event_interruptible_timeout(session->wait,
> - session->ncontroller, CMTP_INTEROP_TIMEOUT);
> -
> - BT_INFO("Found %d CAPI controller(s) on device %s", session->ncontroller, session->name);
> -
> - if (!ret)
> - return -ETIMEDOUT;
> -
> - if (!session->ncontroller)
> - return -ENODEV;
> -
> - if (session->ncontroller > 1)
> - BT_INFO("Setting up only CAPI controller 1");
> -
> - session->ctrl.owner = THIS_MODULE;
> - session->ctrl.driverdata = session;
> - strcpy(session->ctrl.name, session->name);
> -
> - session->ctrl.driver_name = "cmtp";
> - session->ctrl.load_firmware = cmtp_load_firmware;
> - session->ctrl.reset_ctr = cmtp_reset_ctr;
> - session->ctrl.register_appl = cmtp_register_appl;
> - session->ctrl.release_appl = cmtp_release_appl;
> - session->ctrl.send_message = cmtp_send_message;
> -
> - session->ctrl.procinfo = cmtp_procinfo;
> - session->ctrl.proc_show = cmtp_proc_show;
> -
> - if (attach_capi_ctr(&session->ctrl) < 0) {
> - BT_ERR("Can't attach new controller");
> - return -EBUSY;
> - }
> -
> - session->num = session->ctrl.cnr;
> -
> - BT_DBG("session %p num %d", session, session->num);
> -
> - capimsg_setu32(buf, 0, 1);
> -
> - cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
> - CAPI_FUNCTION_GET_MANUFACTURER, buf, 4);
> -
> - cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
> - CAPI_FUNCTION_GET_VERSION, buf, 4);
> -
> - cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
> - CAPI_FUNCTION_GET_SERIAL_NUMBER, buf, 4);
> -
> - cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
> - CAPI_FUNCTION_GET_PROFILE, buf, 4);
> -
> - return 0;
> -}
> -
> -void cmtp_detach_device(struct cmtp_session *session)
> -{
> - BT_DBG("session %p", session);
> -
> - detach_capi_ctr(&session->ctrl);
> -}
> diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c
> deleted file mode 100644
> index 261aeeda3236..000000000000
> --- a/net/bluetooth/cmtp/core.c
> +++ /dev/null
> @@ -1,519 +0,0 @@
> -/*
> - CMTP implementation for Linux Bluetooth stack (BlueZ).
> - Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
> -
> - This program is free software; you can redistribute it and/or modify
> - it under the terms of the GNU General Public License version 2 as
> - published by the Free Software Foundation;
> -
> - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
> - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
> - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
> - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
> - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> -
> - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
> - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
> - SOFTWARE IS DISCLAIMED.
> -*/
> -
> -#include <linux/module.h>
> -
> -#include <linux/types.h>
> -#include <linux/errno.h>
> -#include <linux/kernel.h>
> -#include <linux/sched.h>
> -#include <linux/slab.h>
> -#include <linux/poll.h>
> -#include <linux/fcntl.h>
> -#include <linux/freezer.h>
> -#include <linux/skbuff.h>
> -#include <linux/socket.h>
> -#include <linux/ioctl.h>
> -#include <linux/file.h>
> -#include <linux/init.h>
> -#include <linux/kthread.h>
> -#include <net/sock.h>
> -
> -#include <linux/isdn/capilli.h>
> -
> -#include <net/bluetooth/bluetooth.h>
> -#include <net/bluetooth/l2cap.h>
> -
> -#include "cmtp.h"
> -
> -#define VERSION "1.0"
> -
> -static DECLARE_RWSEM(cmtp_session_sem);
> -static LIST_HEAD(cmtp_session_list);
> -
> -static struct cmtp_session *__cmtp_get_session(bdaddr_t *bdaddr)
> -{
> - struct cmtp_session *session;
> -
> - BT_DBG("");
> -
> - list_for_each_entry(session, &cmtp_session_list, list)
> - if (!bacmp(bdaddr, &session->bdaddr))
> - return session;
> -
> - return NULL;
> -}
> -
> -static void __cmtp_link_session(struct cmtp_session *session)
> -{
> - list_add(&session->list, &cmtp_session_list);
> -}
> -
> -static void __cmtp_unlink_session(struct cmtp_session *session)
> -{
> - list_del(&session->list);
> -}
> -
> -static void __cmtp_copy_session(struct cmtp_session *session, struct cmtp_conninfo *ci)
> -{
> - u32 valid_flags = BIT(CMTP_LOOPBACK);
> - memset(ci, 0, sizeof(*ci));
> - bacpy(&ci->bdaddr, &session->bdaddr);
> -
> - ci->flags = session->flags & valid_flags;
> - ci->state = session->state;
> -
> - ci->num = session->num;
> -}
> -
> -
> -static inline int cmtp_alloc_block_id(struct cmtp_session *session)
> -{
> - int i, id = -1;
> -
> - for (i = 0; i < 16; i++)
> - if (!test_and_set_bit(i, &session->blockids)) {
> - id = i;
> - break;
> - }
> -
> - return id;
> -}
> -
> -static inline void cmtp_free_block_id(struct cmtp_session *session, int id)
> -{
> - clear_bit(id, &session->blockids);
> -}
> -
> -static inline void cmtp_add_msgpart(struct cmtp_session *session, int id, const unsigned char *buf, int count)
> -{
> - struct sk_buff *skb = session->reassembly[id], *nskb;
> - int size;
> -
> - BT_DBG("session %p buf %p count %d", session, buf, count);
> -
> - size = (skb) ? skb->len + count : count;
> -
> - nskb = alloc_skb(size, GFP_ATOMIC);
> - if (!nskb) {
> - BT_ERR("Can't allocate memory for CAPI message");
> - return;
> - }
> -
> - if (skb && (skb->len > 0))
> - skb_copy_from_linear_data(skb, skb_put(nskb, skb->len), skb->len);
> -
> - skb_put_data(nskb, buf, count);
> -
> - session->reassembly[id] = nskb;
> -
> - kfree_skb(skb);
> -}
> -
> -static inline int cmtp_recv_frame(struct cmtp_session *session, struct sk_buff *skb)
> -{
> - __u8 hdr, hdrlen, id;
> - __u16 len;
> -
> - BT_DBG("session %p skb %p len %d", session, skb, skb->len);
> -
> - while (skb->len > 0) {
> - hdr = skb->data[0];
> -
> - switch (hdr & 0xc0) {
> - case 0x40:
> - hdrlen = 2;
> - len = skb->data[1];
> - break;
> - case 0x80:
> - hdrlen = 3;
> - len = skb->data[1] | (skb->data[2] << 8);
> - break;
> - default:
> - hdrlen = 1;
> - len = 0;
> - break;
> - }
> -
> - id = (hdr & 0x3c) >> 2;
> -
> - BT_DBG("hdr 0x%02x hdrlen %d len %d id %d", hdr, hdrlen, len, id);
> -
> - if (hdrlen + len > skb->len) {
> - BT_ERR("Wrong size or header information in CMTP frame");
> - break;
> - }
> -
> - if (len == 0) {
> - skb_pull(skb, hdrlen);
> - continue;
> - }
> -
> - switch (hdr & 0x03) {
> - case 0x00:
> - cmtp_add_msgpart(session, id, skb->data + hdrlen, len);
> - cmtp_recv_capimsg(session, session->reassembly[id]);
> - session->reassembly[id] = NULL;
> - break;
> - case 0x01:
> - cmtp_add_msgpart(session, id, skb->data + hdrlen, len);
> - break;
> - default:
> - kfree_skb(session->reassembly[id]);
> - session->reassembly[id] = NULL;
> - break;
> - }
> -
> - skb_pull(skb, hdrlen + len);
> - }
> -
> - kfree_skb(skb);
> - return 0;
> -}
> -
> -static int cmtp_send_frame(struct cmtp_session *session, unsigned char *data, int len)
> -{
> - struct socket *sock = session->sock;
> - struct kvec iv = { data, len };
> - struct msghdr msg;
> -
> - BT_DBG("session %p data %p len %d", session, data, len);
> -
> - if (!len)
> - return 0;
> -
> - memset(&msg, 0, sizeof(msg));
> -
> - return kernel_sendmsg(sock, &msg, &iv, 1, len);
> -}
> -
> -static void cmtp_process_transmit(struct cmtp_session *session)
> -{
> - struct sk_buff *skb, *nskb;
> - unsigned char *hdr;
> - unsigned int size, tail;
> -
> - BT_DBG("session %p", session);
> -
> - nskb = alloc_skb(session->mtu, GFP_ATOMIC);
> - if (!nskb) {
> - BT_ERR("Can't allocate memory for new frame");
> - return;
> - }
> -
> - while ((skb = skb_dequeue(&session->transmit))) {
> - struct cmtp_scb *scb = (void *) skb->cb;
> -
> - tail = session->mtu - nskb->len;
> - if (tail < 5) {
> - cmtp_send_frame(session, nskb->data, nskb->len);
> - skb_trim(nskb, 0);
> - tail = session->mtu;
> - }
> -
> - size = min_t(uint, ((tail < 258) ? (tail - 2) : (tail - 3)), skb->len);
> -
> - if (scb->id < 0) {
> - scb->id = cmtp_alloc_block_id(session);
> - if (scb->id < 0) {
> - skb_queue_head(&session->transmit, skb);
> - break;
> - }
> - }
> -
> - if (size < 256) {
> - hdr = skb_put(nskb, 2);
> - hdr[0] = 0x40
> - | ((scb->id << 2) & 0x3c)
> - | ((skb->len == size) ? 0x00 : 0x01);
> - hdr[1] = size;
> - } else {
> - hdr = skb_put(nskb, 3);
> - hdr[0] = 0x80
> - | ((scb->id << 2) & 0x3c)
> - | ((skb->len == size) ? 0x00 : 0x01);
> - hdr[1] = size & 0xff;
> - hdr[2] = size >> 8;
> - }
> -
> - skb_copy_from_linear_data(skb, skb_put(nskb, size), size);
> - skb_pull(skb, size);
> -
> - if (skb->len > 0) {
> - skb_queue_head(&session->transmit, skb);
> - } else {
> - cmtp_free_block_id(session, scb->id);
> - if (scb->data) {
> - cmtp_send_frame(session, nskb->data, nskb->len);
> - skb_trim(nskb, 0);
> - }
> - kfree_skb(skb);
> - }
> - }
> -
> - cmtp_send_frame(session, nskb->data, nskb->len);
> -
> - kfree_skb(nskb);
> -}
> -
> -static int cmtp_session(void *arg)
> -{
> - struct cmtp_session *session = arg;
> - struct sock *sk = session->sock->sk;
> - struct sk_buff *skb;
> - DEFINE_WAIT_FUNC(wait, woken_wake_function);
> -
> - BT_DBG("session %p", session);
> -
> - set_user_nice(current, -15);
> -
> - add_wait_queue(sk_sleep(sk), &wait);
> - while (1) {
> - if (atomic_read(&session->terminate))
> - break;
> - if (sk->sk_state != BT_CONNECTED)
> - break;
> -
> - while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
> - skb_orphan(skb);
> - if (!skb_linearize(skb))
> - cmtp_recv_frame(session, skb);
> - else
> - kfree_skb(skb);
> - }
> -
> - cmtp_process_transmit(session);
> -
> - /*
> - * wait_woken() performs the necessary memory barriers
> - * for us; see the header comment for this primitive.
> - */
> - wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT);
> - }
> - remove_wait_queue(sk_sleep(sk), &wait);
> -
> - down_write(&cmtp_session_sem);
> -
> - if (!(session->flags & BIT(CMTP_LOOPBACK)))
> - cmtp_detach_device(session);
> -
> - fput(session->sock->file);
> -
> - __cmtp_unlink_session(session);
> -
> - up_write(&cmtp_session_sem);
> -
> - kfree(session);
> - module_put_and_kthread_exit(0);
> - return 0;
> -}
> -
> -int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock)
> -{
> - u32 valid_flags = BIT(CMTP_LOOPBACK);
> - struct cmtp_session *session, *s;
> - int i, err;
> -
> - BT_DBG("");
> -
> - if (!l2cap_is_socket(sock))
> - return -EBADFD;
> -
> - if (req->flags & ~valid_flags)
> - return -EINVAL;
> -
> - session = kzalloc_obj(struct cmtp_session);
> - if (!session)
> - return -ENOMEM;
> -
> - down_write(&cmtp_session_sem);
> -
> - s = __cmtp_get_session(&l2cap_pi(sock->sk)->chan->dst);
> - if (s && s->state == BT_CONNECTED) {
> - err = -EEXIST;
> - goto failed;
> - }
> -
> - bacpy(&session->bdaddr, &l2cap_pi(sock->sk)->chan->dst);
> -
> - session->mtu = min_t(uint, l2cap_pi(sock->sk)->chan->omtu,
> - l2cap_pi(sock->sk)->chan->imtu);
> -
> - BT_DBG("mtu %d", session->mtu);
> -
> - sprintf(session->name, "%pMR", &session->bdaddr);
> -
> - session->sock = sock;
> - session->state = BT_CONFIG;
> -
> - init_waitqueue_head(&session->wait);
> -
> - session->msgnum = CMTP_INITIAL_MSGNUM;
> -
> - INIT_LIST_HEAD(&session->applications);
> -
> - skb_queue_head_init(&session->transmit);
> -
> - for (i = 0; i < 16; i++)
> - session->reassembly[i] = NULL;
> -
> - session->flags = req->flags;
> -
> - __cmtp_link_session(session);
> -
> - __module_get(THIS_MODULE);
> - session->task = kthread_run(cmtp_session, session, "kcmtpd_ctr_%d",
> - session->num);
> - if (IS_ERR(session->task)) {
> - module_put(THIS_MODULE);
> - err = PTR_ERR(session->task);
> - goto unlink;
> - }
> -
> - if (!(session->flags & BIT(CMTP_LOOPBACK))) {
> - err = cmtp_attach_device(session);
> - if (err < 0) {
> - /* Caller will call fput in case of failure, and so
> - * will cmtp_session kthread.
> - */
> - get_file(session->sock->file);
> -
> - atomic_inc(&session->terminate);
> - wake_up_interruptible(sk_sleep(session->sock->sk));
> - up_write(&cmtp_session_sem);
> - return err;
> - }
> - }
> -
> - up_write(&cmtp_session_sem);
> - return 0;
> -
> -unlink:
> - __cmtp_unlink_session(session);
> -
> -failed:
> - up_write(&cmtp_session_sem);
> - kfree(session);
> - return err;
> -}
> -
> -int cmtp_del_connection(struct cmtp_conndel_req *req)
> -{
> - u32 valid_flags = 0;
> - struct cmtp_session *session;
> - int err = 0;
> -
> - BT_DBG("");
> -
> - if (req->flags & ~valid_flags)
> - return -EINVAL;
> -
> - down_read(&cmtp_session_sem);
> -
> - session = __cmtp_get_session(&req->bdaddr);
> - if (session) {
> - /* Flush the transmit queue */
> - skb_queue_purge(&session->transmit);
> -
> - /* Stop session thread */
> - atomic_inc(&session->terminate);
> -
> - /*
> - * See the comment preceding the call to wait_woken()
> - * in cmtp_session().
> - */
> - wake_up_interruptible(sk_sleep(session->sock->sk));
> - } else
> - err = -ENOENT;
> -
> - up_read(&cmtp_session_sem);
> - return err;
> -}
> -
> -int cmtp_get_connlist(struct cmtp_connlist_req *req)
> -{
> - struct cmtp_session *session;
> - int err = 0, n = 0;
> -
> - BT_DBG("");
> -
> - down_read(&cmtp_session_sem);
> -
> - list_for_each_entry(session, &cmtp_session_list, list) {
> - struct cmtp_conninfo ci;
> -
> - __cmtp_copy_session(session, &ci);
> -
> - if (copy_to_user(req->ci, &ci, sizeof(ci))) {
> - err = -EFAULT;
> - break;
> - }
> -
> - if (++n >= req->cnum)
> - break;
> -
> - req->ci++;
> - }
> - req->cnum = n;
> -
> - up_read(&cmtp_session_sem);
> - return err;
> -}
> -
> -int cmtp_get_conninfo(struct cmtp_conninfo *ci)
> -{
> - struct cmtp_session *session;
> - int err = 0;
> -
> - down_read(&cmtp_session_sem);
> -
> - session = __cmtp_get_session(&ci->bdaddr);
> - if (session)
> - __cmtp_copy_session(session, ci);
> - else
> - err = -ENOENT;
> -
> - up_read(&cmtp_session_sem);
> - return err;
> -}
> -
> -
> -static int __init cmtp_init(void)
> -{
> - BT_INFO("CMTP (CAPI Emulation) ver %s", VERSION);
> -
> - return cmtp_init_sockets();
> -}
> -
> -static void __exit cmtp_exit(void)
> -{
> - cmtp_cleanup_sockets();
> -}
> -
> -module_init(cmtp_init);
> -module_exit(cmtp_exit);
> -
> -MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
> -MODULE_DESCRIPTION("Bluetooth CMTP ver " VERSION);
> -MODULE_VERSION(VERSION);
> -MODULE_LICENSE("GPL");
> -MODULE_ALIAS("bt-proto-5");
> diff --git a/net/bluetooth/cmtp/sock.c b/net/bluetooth/cmtp/sock.c
> deleted file mode 100644
> index 96d49d9fae96..000000000000
> --- a/net/bluetooth/cmtp/sock.c
> +++ /dev/null
> @@ -1,271 +0,0 @@
> -/*
> - CMTP implementation for Linux Bluetooth stack (BlueZ).
> - Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
> -
> - This program is free software; you can redistribute it and/or modify
> - it under the terms of the GNU General Public License version 2 as
> - published by the Free Software Foundation;
> -
> - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
> - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
> - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
> - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
> - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> -
> - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
> - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
> - SOFTWARE IS DISCLAIMED.
> -*/
> -
> -#include <linux/export.h>
> -
> -#include <linux/types.h>
> -#include <linux/capability.h>
> -#include <linux/errno.h>
> -#include <linux/kernel.h>
> -#include <linux/poll.h>
> -#include <linux/fcntl.h>
> -#include <linux/skbuff.h>
> -#include <linux/socket.h>
> -#include <linux/ioctl.h>
> -#include <linux/file.h>
> -#include <linux/compat.h>
> -#include <linux/gfp.h>
> -#include <linux/uaccess.h>
> -#include <net/sock.h>
> -
> -#include <linux/isdn/capilli.h>
> -
> -
> -#include "cmtp.h"
> -
> -static struct bt_sock_list cmtp_sk_list = {
> - .lock = __RW_LOCK_UNLOCKED(cmtp_sk_list.lock)
> -};
> -
> -static int cmtp_sock_release(struct socket *sock)
> -{
> - struct sock *sk = sock->sk;
> -
> - BT_DBG("sock %p sk %p", sock, sk);
> -
> - if (!sk)
> - return 0;
> -
> - bt_sock_unlink(&cmtp_sk_list, sk);
> -
> - sock_orphan(sk);
> - sock_put(sk);
> -
> - return 0;
> -}
> -
> -static int do_cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, void __user *argp)
> -{
> - struct cmtp_connadd_req ca;
> - struct cmtp_conndel_req cd;
> - struct cmtp_connlist_req cl;
> - struct cmtp_conninfo ci;
> - struct socket *nsock;
> - int err;
> -
> - BT_DBG("cmd %x arg %p", cmd, argp);
> -
> - switch (cmd) {
> - case CMTPCONNADD:
> - if (!capable(CAP_NET_ADMIN))
> - return -EPERM;
> -
> - if (copy_from_user(&ca, argp, sizeof(ca)))
> - return -EFAULT;
> -
> - nsock = sockfd_lookup(ca.sock, &err);
> - if (!nsock)
> - return err;
> -
> - if (nsock->sk->sk_state != BT_CONNECTED) {
> - sockfd_put(nsock);
> - return -EBADFD;
> - }
> -
> - err = cmtp_add_connection(&ca, nsock);
> - if (!err) {
> - if (copy_to_user(argp, &ca, sizeof(ca)))
> - err = -EFAULT;
> - } else
> - sockfd_put(nsock);
> -
> - return err;
> -
> - case CMTPCONNDEL:
> - if (!capable(CAP_NET_ADMIN))
> - return -EPERM;
> -
> - if (copy_from_user(&cd, argp, sizeof(cd)))
> - return -EFAULT;
> -
> - return cmtp_del_connection(&cd);
> -
> - case CMTPGETCONNLIST:
> - if (copy_from_user(&cl, argp, sizeof(cl)))
> - return -EFAULT;
> -
> - if (cl.cnum <= 0)
> - return -EINVAL;
> -
> - err = cmtp_get_connlist(&cl);
> - if (!err && copy_to_user(argp, &cl, sizeof(cl)))
> - return -EFAULT;
> -
> - return err;
> -
> - case CMTPGETCONNINFO:
> - if (copy_from_user(&ci, argp, sizeof(ci)))
> - return -EFAULT;
> -
> - err = cmtp_get_conninfo(&ci);
> - if (!err && copy_to_user(argp, &ci, sizeof(ci)))
> - return -EFAULT;
> -
> - return err;
> - }
> -
> - return -EINVAL;
> -}
> -
> -static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
> -{
> - return do_cmtp_sock_ioctl(sock, cmd, (void __user *)arg);
> -}
> -
> -#ifdef CONFIG_COMPAT
> -static int cmtp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
> -{
> - void __user *argp = compat_ptr(arg);
> - if (cmd == CMTPGETCONNLIST) {
> - struct cmtp_connlist_req cl;
> - u32 __user *p = argp;
> - u32 uci;
> - int err;
> -
> - if (get_user(cl.cnum, p) || get_user(uci, p + 1))
> - return -EFAULT;
> -
> - cl.ci = compat_ptr(uci);
> -
> - if (cl.cnum <= 0)
> - return -EINVAL;
> -
> - err = cmtp_get_connlist(&cl);
> -
> - if (!err && put_user(cl.cnum, p))
> - err = -EFAULT;
> -
> - return err;
> - }
> -
> - return do_cmtp_sock_ioctl(sock, cmd, argp);
> -}
> -#endif
> -
> -static const struct proto_ops cmtp_sock_ops = {
> - .family = PF_BLUETOOTH,
> - .owner = THIS_MODULE,
> - .release = cmtp_sock_release,
> - .ioctl = cmtp_sock_ioctl,
> -#ifdef CONFIG_COMPAT
> - .compat_ioctl = cmtp_sock_compat_ioctl,
> -#endif
> - .bind = sock_no_bind,
> - .getname = sock_no_getname,
> - .sendmsg = sock_no_sendmsg,
> - .recvmsg = sock_no_recvmsg,
> - .listen = sock_no_listen,
> - .shutdown = sock_no_shutdown,
> - .connect = sock_no_connect,
> - .socketpair = sock_no_socketpair,
> - .accept = sock_no_accept,
> - .mmap = sock_no_mmap
> -};
> -
> -static struct proto cmtp_proto = {
> - .name = "CMTP",
> - .owner = THIS_MODULE,
> - .obj_size = sizeof(struct bt_sock)
> -};
> -
> -static int cmtp_sock_create(struct net *net, struct socket *sock, int protocol,
> - int kern)
> -{
> - struct sock *sk;
> -
> - BT_DBG("sock %p", sock);
> -
> - if (sock->type != SOCK_RAW)
> - return -ESOCKTNOSUPPORT;
> -
> - sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &cmtp_proto, kern);
> - if (!sk)
> - return -ENOMEM;
> -
> - sock_init_data(sock, sk);
> -
> - sock->ops = &cmtp_sock_ops;
> -
> - sock->state = SS_UNCONNECTED;
> -
> - sock_reset_flag(sk, SOCK_ZAPPED);
> -
> - sk->sk_protocol = protocol;
> - sk->sk_state = BT_OPEN;
> -
> - bt_sock_link(&cmtp_sk_list, sk);
> -
> - return 0;
> -}
> -
> -static const struct net_proto_family cmtp_sock_family_ops = {
> - .family = PF_BLUETOOTH,
> - .owner = THIS_MODULE,
> - .create = cmtp_sock_create
> -};
> -
> -int cmtp_init_sockets(void)
> -{
> - int err;
> -
> - err = proto_register(&cmtp_proto, 0);
> - if (err < 0)
> - return err;
> -
> - err = bt_sock_register(BTPROTO_CMTP, &cmtp_sock_family_ops);
> - if (err < 0) {
> - BT_ERR("Can't register CMTP socket");
> - goto error;
> - }
> -
> - err = bt_procfs_init(&init_net, "cmtp", &cmtp_sk_list, NULL);
> - if (err < 0) {
> - BT_ERR("Failed to create CMTP proc file");
> - bt_sock_unregister(BTPROTO_HIDP);
> - goto error;
> - }
> -
> - BT_INFO("CMTP socket layer initialized");
> -
> - return 0;
> -
> -error:
> - proto_unregister(&cmtp_proto);
> - return err;
> -}
> -
> -void cmtp_cleanup_sockets(void)
> -{
> - bt_procfs_cleanup(&init_net, "cmtp");
> - bt_sock_unregister(BTPROTO_CMTP);
> - proto_unregister(&cmtp_proto);
> -}
> diff --git a/CREDITS b/CREDITS
> index a03b00452a1e..eeeece8ed868 100644
> --- a/CREDITS
> +++ b/CREDITS
> @@ -3649,6 +3649,11 @@ S: Dag Hammerskjolds v. 3E
> S: S-226 64 LUND
> S: Sweden
>
> +N: Tilman Schmidt
> +E: tilman@imap.cc
> +D: Siemens Gigaset ISDN driver author and maintainer
> +D: ISDN CAPI subsystem contributions
> +
> N: Henning P. Schmiedehausen
> E: hps@tanstaafl.de
> D: added PCI support to the serial driver
> --
> 2.53.0
>
Acked-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
--
Luiz Augusto von Dentz
^ permalink raw reply [flat|nested] 5+ messages in thread