aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2019-12-19 12:25:48 +1100
committerStephen Rothwell <sfr@canb.auug.org.au>2019-12-19 12:25:48 +1100
commitb095f75681469e62ac77977689eee5668ad00332 (patch)
treeaf209393a3193393e03e1ea51cb583d21dcc3216
parent3c39cbfddd7048bac4546fce81de5aa803afde0f (diff)
parent92ee2034696cd7fcbfe8539eb93aefb0459bd931 (diff)
Merge remote-tracking branch 'staging/staging-next'
-rw-r--r--Documentation/isdn/avmb1.rst246
-rw-r--r--Documentation/isdn/gigaset.rst465
-rw-r--r--Documentation/isdn/hysdn.rst196
-rw-r--r--Documentation/isdn/index.rst3
-rw-r--r--Documentation/isdn/interface_capi.rst71
-rw-r--r--Documentation/userspace-api/ioctl/ioctl-number.rst1
-rw-r--r--MAINTAINERS3
-rw-r--r--drivers/isdn/Makefile2
-rw-r--r--drivers/isdn/capi/Kconfig32
-rw-r--r--drivers/isdn/capi/Makefile18
-rw-r--r--drivers/isdn/capi/capi.c14
-rw-r--r--drivers/isdn/capi/capilib.c202
-rw-r--r--drivers/isdn/capi/capiutil.c231
-rw-r--r--drivers/isdn/capi/kcapi.c409
-rw-r--r--drivers/isdn/capi/kcapi.h149
-rw-r--r--drivers/isdn/capi/kcapi_proc.c36
-rw-r--r--drivers/staging/Kconfig6
-rw-r--r--drivers/staging/Makefile3
-rw-r--r--drivers/staging/exfat/exfat_super.c4
-rw-r--r--drivers/staging/hp/hp100.c11
-rw-r--r--drivers/staging/isdn/Kconfig12
-rw-r--r--drivers/staging/isdn/Makefile8
-rw-r--r--drivers/staging/isdn/TODO22
-rw-r--r--drivers/staging/isdn/avm/Kconfig65
-rw-r--r--drivers/staging/isdn/avm/Makefile12
-rw-r--r--drivers/staging/isdn/avm/avm_cs.c166
-rw-r--r--drivers/staging/isdn/avm/avmcard.h581
-rw-r--r--drivers/staging/isdn/avm/b1.c819
-rw-r--r--drivers/staging/isdn/avm/b1dma.c981
-rw-r--r--drivers/staging/isdn/avm/b1isa.c243
-rw-r--r--drivers/staging/isdn/avm/b1pci.c416
-rw-r--r--drivers/staging/isdn/avm/b1pcmcia.c224
-rw-r--r--drivers/staging/isdn/avm/c4.c1317
-rw-r--r--drivers/staging/isdn/avm/t1isa.c594
-rw-r--r--drivers/staging/isdn/avm/t1pci.c259
-rw-r--r--drivers/staging/isdn/gigaset/Kconfig62
-rw-r--r--drivers/staging/isdn/gigaset/Makefile17
-rw-r--r--drivers/staging/isdn/gigaset/asyncdata.c606
-rw-r--r--drivers/staging/isdn/gigaset/bas-gigaset.c2672
-rw-r--r--drivers/staging/isdn/gigaset/capi.c2517
-rw-r--r--drivers/staging/isdn/gigaset/common.c1153
-rw-r--r--drivers/staging/isdn/gigaset/dummyll.c74
-rw-r--r--drivers/staging/isdn/gigaset/ev-layer.c1910
-rw-r--r--drivers/staging/isdn/gigaset/gigaset.h827
-rw-r--r--drivers/staging/isdn/gigaset/interface.c613
-rw-r--r--drivers/staging/isdn/gigaset/isocdata.c1006
-rw-r--r--drivers/staging/isdn/gigaset/proc.c77
-rw-r--r--drivers/staging/isdn/gigaset/ser-gigaset.c796
-rw-r--r--drivers/staging/isdn/gigaset/usb-gigaset.c959
-rw-r--r--drivers/staging/isdn/hysdn/Kconfig15
-rw-r--r--drivers/staging/isdn/hysdn/Makefile12
-rw-r--r--drivers/staging/isdn/hysdn/boardergo.c445
-rw-r--r--drivers/staging/isdn/hysdn/boardergo.h100
-rw-r--r--drivers/staging/isdn/hysdn/hycapi.c785
-rw-r--r--drivers/staging/isdn/hysdn/hysdn_boot.c400
-rw-r--r--drivers/staging/isdn/hysdn/hysdn_defs.h282
-rw-r--r--drivers/staging/isdn/hysdn/hysdn_init.c213
-rw-r--r--drivers/staging/isdn/hysdn/hysdn_net.c330
-rw-r--r--drivers/staging/isdn/hysdn/hysdn_pof.h78
-rw-r--r--drivers/staging/isdn/hysdn/hysdn_procconf.c411
-rw-r--r--drivers/staging/isdn/hysdn/hysdn_proclog.c357
-rw-r--r--drivers/staging/isdn/hysdn/hysdn_sched.c197
-rw-r--r--drivers/staging/isdn/hysdn/ince1pc.h134
-rw-r--r--drivers/staging/most/cdev/cdev.c4
-rw-r--r--drivers/staging/most/configfs.c32
-rw-r--r--drivers/staging/most/core.c34
-rw-r--r--drivers/staging/most/dim2/dim2.c2
-rw-r--r--drivers/staging/most/i2c/i2c.c2
-rw-r--r--drivers/staging/most/most.h (renamed from drivers/staging/most/core.h)26
-rw-r--r--drivers/staging/most/net/net.c6
-rw-r--r--drivers/staging/most/sound/sound.c53
-rw-r--r--drivers/staging/most/usb/usb.c2
-rw-r--r--drivers/staging/most/video/video.c6
-rw-r--r--drivers/staging/octeon-usb/Kconfig11
-rw-r--r--drivers/staging/octeon-usb/Makefile2
-rw-r--r--drivers/staging/octeon-usb/TODO8
-rw-r--r--drivers/staging/octeon-usb/octeon-hcd.c3737
-rw-r--r--drivers/staging/octeon-usb/octeon-hcd.h1847
-rw-r--r--drivers/staging/octeon/Kconfig16
-rw-r--r--drivers/staging/octeon/Makefile19
-rw-r--r--drivers/staging/octeon/TODO9
-rw-r--r--drivers/staging/octeon/ethernet-defines.h40
-rw-r--r--drivers/staging/octeon/ethernet-mdio.c178
-rw-r--r--drivers/staging/octeon/ethernet-mdio.h28
-rw-r--r--drivers/staging/octeon/ethernet-mem.c154
-rw-r--r--drivers/staging/octeon/ethernet-mem.h9
-rw-r--r--drivers/staging/octeon/ethernet-rgmii.c158
-rw-r--r--drivers/staging/octeon/ethernet-rx.c538
-rw-r--r--drivers/staging/octeon/ethernet-rx.h31
-rw-r--r--drivers/staging/octeon/ethernet-sgmii.c30
-rw-r--r--drivers/staging/octeon/ethernet-spi.c226
-rw-r--r--drivers/staging/octeon/ethernet-tx.c717
-rw-r--r--drivers/staging/octeon/ethernet-tx.h14
-rw-r--r--drivers/staging/octeon/ethernet-util.h47
-rw-r--r--drivers/staging/octeon/ethernet.c992
-rw-r--r--drivers/staging/octeon/octeon-ethernet.h107
-rw-r--r--drivers/staging/octeon/octeon-stubs.h1433
-rw-r--r--drivers/staging/qlge/qlge.h15
-rw-r--r--drivers/staging/qlge/qlge_dbg.c32
-rw-r--r--drivers/staging/qlge/qlge_ethtool.c39
-rw-r--r--drivers/staging/qlge/qlge_main.c215
-rw-r--r--drivers/staging/qlge/qlge_mpi.c26
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_mlme_ext.c151
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_pwrctrl.c34
-rw-r--r--drivers/staging/rtl8723bs/core/rtw_mlme_ext.c54
-rw-r--r--drivers/staging/rtl8723bs/hal/HalPhyRf_8723B.c12
-rw-r--r--drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c44
-rw-r--r--drivers/staging/rts5208/rtsx.c7
-rw-r--r--drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c19
-rw-r--r--drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c9
-rw-r--r--drivers/staging/wilc1000/netdev.c9
-rw-r--r--drivers/staging/wilc1000/wlan.c23
-rw-r--r--drivers/staging/wilc1000/wlan.h1
-rw-r--r--drivers/staging/wilc1000/wlan_cfg.c8
-rw-r--r--include/linux/b1pcmcia.h21
-rw-r--r--include/linux/isdn/capilli.h18
-rw-r--r--include/linux/isdn/capiutil.h456
-rw-r--r--include/linux/kernelcapi.h75
-rw-r--r--include/uapi/linux/b1lli.h74
-rw-r--r--include/uapi/linux/gigaset_dev.h39
-rw-r--r--include/uapi/linux/hysdn_if.h34
121 files changed, 575 insertions, 36227 deletions
diff --git a/Documentation/isdn/avmb1.rst b/Documentation/isdn/avmb1.rst
deleted file mode 100644
index de3961e67553..000000000000
--- a/Documentation/isdn/avmb1.rst
+++ /dev/null
@@ -1,246 +0,0 @@
-================================
-Driver for active AVM Controller
-================================
-
-The driver provides a kernel capi2.0 Interface (kernelcapi) and
-on top of this a User-Level-CAPI2.0-interface (capi)
-and a driver to connect isdn4linux with CAPI2.0 (capidrv).
-The lowlevel interface can be used to implement a CAPI2.0
-also for passive cards since July 1999.
-
-The author can be reached at calle@calle.in-berlin.de.
-The command avmcapictrl is part of the isdn4k-utils.
-t4-files can be found at ftp://ftp.avm.de/cardware/b1/linux/firmware
-
-Currently supported cards:
-
- - B1 ISA (all versions)
- - B1 PCI
- - T1/T1B (HEMA card)
- - M1
- - M2
- - B1 PCMCIA
-
-Installing
-----------
-
-You need at least /dev/capi20 to load the firmware.
-
-::
-
- mknod /dev/capi20 c 68 0
- mknod /dev/capi20.00 c 68 1
- mknod /dev/capi20.01 c 68 2
- .
- .
- .
- mknod /dev/capi20.19 c 68 20
-
-Running
--------
-
-To use the card you need the t4-files to download the firmware.
-AVM GmbH provides several t4-files for the different D-channel
-protocols (b1.t4 for Euro-ISDN). Install these file in /lib/isdn.
-
-if you configure as modules load the modules this way::
-
- insmod /lib/modules/current/misc/capiutil.o
- insmod /lib/modules/current/misc/b1.o
- insmod /lib/modules/current/misc/kernelcapi.o
- insmod /lib/modules/current/misc/capidrv.o
- insmod /lib/modules/current/misc/capi.o
-
-if you have an B1-PCI card load the module b1pci.o::
-
- insmod /lib/modules/current/misc/b1pci.o
-
-and load the firmware with::
-
- avmcapictrl load /lib/isdn/b1.t4 1
-
-if you have an B1-ISA card load the module b1isa.o
-and add the card by calling::
-
- avmcapictrl add 0x150 15
-
-and load the firmware by calling::
-
- avmcapictrl load /lib/isdn/b1.t4 1
-
-if you have an T1-ISA card load the module t1isa.o
-and add the card by calling::
-
- avmcapictrl add 0x450 15 T1 0
-
-and load the firmware by calling::
-
- avmcapictrl load /lib/isdn/t1.t4 1
-
-if you have an PCMCIA card (B1/M1/M2) load the module b1pcmcia.o
-before you insert the card.
-
-Leased Lines with B1
---------------------
-
-Init card and load firmware.
-
-For an D64S use "FV: 1" as phone number
-
-For an D64S2 use "FV: 1" and "FV: 2" for multilink
-or "FV: 1,2" to use CAPI channel bundling.
-
-/proc-Interface
------------------
-
-/proc/capi::
-
- dr-xr-xr-x 2 root root 0 Jul 1 14:03 .
- dr-xr-xr-x 82 root root 0 Jun 30 19:08 ..
- -r--r--r-- 1 root root 0 Jul 1 14:03 applications
- -r--r--r-- 1 root root 0 Jul 1 14:03 applstats
- -r--r--r-- 1 root root 0 Jul 1 14:03 capi20
- -r--r--r-- 1 root root 0 Jul 1 14:03 capidrv
- -r--r--r-- 1 root root 0 Jul 1 14:03 controller
- -r--r--r-- 1 root root 0 Jul 1 14:03 contrstats
- -r--r--r-- 1 root root 0 Jul 1 14:03 driver
- -r--r--r-- 1 root root 0 Jul 1 14:03 ncci
- -r--r--r-- 1 root root 0 Jul 1 14:03 users
-
-/proc/capi/applications:
- applid level3cnt datablkcnt datablklen ncci-cnt recvqueuelen
- level3cnt:
- capi_register parameter
- datablkcnt:
- capi_register parameter
- ncci-cnt:
- current number of nccis (connections)
- recvqueuelen:
- number of messages on receive queue
-
- for example::
-
- 1 -2 16 2048 1 0
- 2 2 7 2048 1 0
-
-/proc/capi/applstats:
- applid recvctlmsg nrecvdatamsg nsentctlmsg nsentdatamsg
- recvctlmsg:
- capi messages received without DATA_B3_IND
- recvdatamsg:
- capi DATA_B3_IND received
- sentctlmsg:
- capi messages sent without DATA_B3_REQ
- sentdatamsg:
- capi DATA_B3_REQ sent
-
- for example::
-
- 1 2057 1699 1721 1699
-
-/proc/capi/capi20: statistics of capi.o (/dev/capi20)
- minor nopen nrecvdropmsg nrecvctlmsg nrecvdatamsg sentctlmsg sentdatamsg
- minor:
- minor device number of capi device
- nopen:
- number of calls to devices open
- nrecvdropmsg:
- capi messages dropped (messages in recvqueue in close)
- nrecvctlmsg:
- capi messages received without DATA_B3_IND
- nrecvdatamsg:
- capi DATA_B3_IND received
- nsentctlmsg:
- capi messages sent without DATA_B3_REQ
- nsentdatamsg:
- capi DATA_B3_REQ sent
-
- for example::
-
- 1 2 18 0 16 2
-
-/proc/capi/capidrv: statistics of capidrv.o (capi messages)
- nrecvctlmsg nrecvdatamsg sentctlmsg sentdatamsg
- nrecvctlmsg:
- capi messages received without DATA_B3_IND
- nrecvdatamsg:
- capi DATA_B3_IND received
- nsentctlmsg:
- capi messages sent without DATA_B3_REQ
- nsentdatamsg:
- capi DATA_B3_REQ sent
-
- for example:
- 2780 2226 2256 2226
-
-/proc/capi/controller:
- controller drivername state cardname controllerinfo
-
- for example::
-
- 1 b1pci running b1pci-e000 B1 3.07-01 0xe000 19
- 2 t1isa running t1isa-450 B1 3.07-01 0x450 11 0
- 3 b1pcmcia running m2-150 B1 3.07-01 0x150 5
-
-/proc/capi/contrstats:
- controller nrecvctlmsg nrecvdatamsg sentctlmsg sentdatamsg
- nrecvctlmsg:
- capi messages received without DATA_B3_IND
- nrecvdatamsg:
- capi DATA_B3_IND received
- nsentctlmsg:
- capi messages sent without DATA_B3_REQ
- nsentdatamsg:
- capi DATA_B3_REQ sent
-
- for example::
-
- 1 2845 2272 2310 2274
- 2 2 0 2 0
- 3 2 0 2 0
-
-/proc/capi/driver:
- drivername ncontroller
-
- for example::
-
- b1pci 1
- t1isa 1
- b1pcmcia 1
- b1isa 0
-
-/proc/capi/ncci:
- apllid ncci winsize sendwindow
-
- for example::
-
- 1 0x10101 8 0
-
-/proc/capi/users: kernelmodules that use the kernelcapi.
- name
-
- for example::
-
- capidrv
- capi20
-
-Questions
----------
-
-Check out the FAQ (ftp.isdn4linux.de) or subscribe to the
-linux-avmb1@calle.in-berlin.de mailing list by sending
-a mail to majordomo@calle.in-berlin.de with
-subscribe linux-avmb1
-in the body.
-
-German documentation and several scripts can be found at
-ftp://ftp.avm.de/cardware/b1/linux/
-
-Bugs
-----
-
-If you find any please let me know.
-
-Enjoy,
-
-Carsten Paeth (calle@calle.in-berlin.de)
diff --git a/Documentation/isdn/gigaset.rst b/Documentation/isdn/gigaset.rst
deleted file mode 100644
index 98b4ec521c51..000000000000
--- a/Documentation/isdn/gigaset.rst
+++ /dev/null
@@ -1,465 +0,0 @@
-==========================
-GigaSet 307x Device Driver
-==========================
-
-1. Requirements
-=================
-
-1.1. Hardware
--------------
-
- This driver supports the connection of the Gigaset 307x/417x family of
- ISDN DECT bases via Gigaset M101 Data, Gigaset M105 Data or direct USB
- connection. The following devices are reported to be compatible:
-
- Bases:
- - Siemens Gigaset 3070/3075 isdn
- - Siemens Gigaset 4170/4175 isdn
- - Siemens Gigaset SX205/255
- - Siemens Gigaset SX353
- - T-Com Sinus 45 [AB] isdn
- - T-Com Sinus 721X[A] [SE]
- - Vox Chicago 390 ISDN (KPN Telecom)
-
- RS232 data boxes:
- - Siemens Gigaset M101 Data
- - T-Com Sinus 45 Data 1
-
- USB data boxes:
- - Siemens Gigaset M105 Data
- - Siemens Gigaset USB Adapter DECT
- - T-Com Sinus 45 Data 2
- - T-Com Sinus 721 data
- - Chicago 390 USB (KPN)
-
- See also http://www.erbze.info/sinus_gigaset.htm
- (archived at https://web.archive.org/web/20100717020421/http://www.erbze.info:80/sinus_gigaset.htm ) and
- http://gigaset307x.sourceforge.net/
-
- We had also reports from users of Gigaset M105 who could use the drivers
- with SX 100 and CX 100 ISDN bases (only in unimodem mode, see section 2.5.)
- If you have another device that works with our driver, please let us know.
-
- Chances of getting an USB device to work are good if the output of::
-
- lsusb
-
- at the command line contains one of the following::
-
- ID 0681:0001
- ID 0681:0002
- ID 0681:0009
- ID 0681:0021
- ID 0681:0022
-
-1.2. Software
--------------
-
- The driver works with the Kernel CAPI subsystem and can be used with any
- software which is able to use CAPI 2.0 for ISDN connections (voice or data).
-
- There are some user space tools available at
- https://sourceforge.net/projects/gigaset307x/
- which provide access to additional device specific functions like SMS,
- phonebook or call journal.
-
-
-2. How to use the driver
-==========================
-
-2.1. Modules
-------------
-
- For the devices to work, the proper kernel modules have to be loaded.
- This normally happens automatically when the system detects the USB
- device (base, M105) or when the line discipline is attached (M101). It
- can also be triggered manually using the modprobe(8) command, for example
- for troubleshooting or to pass module parameters.
-
- The module ser_gigaset provides a serial line discipline N_GIGASET_M101
- which uses the regular serial port driver to access the device, and must
- therefore be attached to the serial device to which the M101 is connected.
- The ldattach(8) command (included in util-linux-ng release 2.14 or later)
- can be used for that purpose, for example::
-
- ldattach GIGASET_M101 /dev/ttyS1
-
- This will open the device file, attach the line discipline to it, and
- then sleep in the background, keeping the device open so that the line
- discipline remains active. To deactivate it, kill the daemon, for example
- with::
-
- killall ldattach
-
- before disconnecting the device. To have this happen automatically at
- system startup/shutdown on an LSB compatible system, create and activate
- an appropriate LSB startup script /etc/init.d/gigaset. (The init name
- 'gigaset' is officially assigned to this project by LANANA.)
- Alternatively, just add the 'ldattach' command line to /etc/rc.local.
-
- The modules accept the following parameters:
-
- =============== ========== ==========================================
- Module Parameter Meaning
-
- gigaset debug debug level (see section 3.2.)
-
- startmode initial operation mode (see section 2.5.):
- bas_gigaset ) 1=CAPI (default), 0=Unimodem
- ser_gigaset )
- usb_gigaset ) cidmode initial Call-ID mode setting (see section
- 2.5.): 1=on (default), 0=off
-
- =============== ========== ==========================================
-
- Depending on your distribution you may want to create a separate module
- configuration file like /etc/modprobe.d/gigaset.conf for these.
-
-2.2. Device nodes for user space programs
------------------------------------------
-
- The device can be accessed from user space (eg. by the user space tools
- mentioned in 1.2.) through the device nodes:
-
- - /dev/ttyGS0 for M101 (RS232 data boxes)
- - /dev/ttyGU0 for M105 (USB data boxes)
- - /dev/ttyGB0 for the base driver (direct USB connection)
-
- If you connect more than one device of a type, they will get consecutive
- device nodes, eg. /dev/ttyGU1 for a second M105.
-
- You can also set a "default device" for the user space tools to use when
- no device node is given as parameter, by creating a symlink /dev/ttyG to
- one of them, eg.::
-
- ln -s /dev/ttyGB0 /dev/ttyG
-
- The devices accept the following device specific ioctl calls
- (defined in gigaset_dev.h):
-
- ``ioctl(int fd, GIGASET_REDIR, int *cmd);``
-
- If cmd==1, the device is set to be controlled exclusively through the
- character device node; access from the ISDN subsystem is blocked.
-
- If cmd==0, the device is set to be used from the ISDN subsystem and does
- not communicate through the character device node.
-
- ``ioctl(int fd, GIGASET_CONFIG, int *cmd);``
-
- (ser_gigaset and usb_gigaset only)
-
- If cmd==1, the device is set to adapter configuration mode where commands
- are interpreted by the M10x DECT adapter itself instead of being
- forwarded to the base station. In this mode, the device accepts the
- commands described in Siemens document "AT-Kommando Alignment M10x Data"
- for setting the operation mode, associating with a base station and
- querying parameters like field strengh and signal quality.
-
- Note that there is no ioctl command for leaving adapter configuration
- mode and returning to regular operation. In order to leave adapter
- configuration mode, write the command ATO to the device.
-
- ``ioctl(int fd, GIGASET_BRKCHARS, unsigned char brkchars[6]);``
-
- (usb_gigaset only)
-
- Set the break characters on an M105's internal serial adapter to the six
- bytes stored in brkchars[]. Unused bytes should be set to zero.
-
- ioctl(int fd, GIGASET_VERSION, unsigned version[4]);
- Retrieve version information from the driver. version[0] must be set to
- one of:
-
- - GIGVER_DRIVER: retrieve driver version
- - GIGVER_COMPAT: retrieve interface compatibility version
- - GIGVER_FWBASE: retrieve the firmware version of the base
-
- Upon return, version[] is filled with the requested version information.
-
-2.3. CAPI
----------
-
- The devices will show up as CAPI controllers as soon as the
- corresponding driver module is loaded, and can then be used with
- CAPI 2.0 kernel and user space applications. For user space access,
- the module capi.ko must be loaded.
-
- Most distributions handle loading and unloading of the various CAPI
- modules automatically via the command capiinit(1) from the capi4k-utils
- package or a similar mechanism. Note that capiinit(1) cannot unload the
- Gigaset drivers because it doesn't support more than one module per
- driver.
-
-2.5. Unimodem mode
-------------------
-
- In this mode the device works like a modem connected to a serial port
- (the /dev/ttyGU0, ... mentioned above) which understands the commands::
-
- ATZ init, reset
- => OK or ERROR
- ATD
- ATDT dial
- => OK, CONNECT,
- BUSY,
- NO DIAL TONE,
- NO CARRIER,
- NO ANSWER
- <pause>+++<pause> change to command mode when connected
- ATH hangup
-
- You can use some configuration tool of your distribution to configure this
- "modem" or configure pppd/wvdial manually. There are some example ppp
- configuration files and chat scripts in the gigaset-VERSION/ppp directory
- in the driver packages from https://sourceforge.net/projects/gigaset307x/.
- Please note that the USB drivers are not able to change the state of the
- control lines. This means you must use "Stupid Mode" if you are using
- wvdial or you should use the nocrtscts option of pppd.
- You must also assure that the ppp_async module is loaded with the parameter
- flag_time=0. You can do this e.g. by adding a line like::
-
- options ppp_async flag_time=0
-
- to an appropriate module configuration file, like::
-
- /etc/modprobe.d/gigaset.conf.
-
- Unimodem mode is needed for making some devices [e.g. SX100] work which
- do not support the regular Gigaset command set. If debug output (see
- section 3.2.) shows something like this when dialing::
-
- CMD Received: ERROR
- Available Params: 0
- Connection State: 0, Response: -1
- gigaset_process_response: resp_code -1 in ConState 0 !
- Timeout occurred
-
- then switching to unimodem mode may help.
-
- If you have installed the command line tool gigacontr, you can enter
- unimodem mode using::
-
- gigacontr --mode unimodem
-
- You can switch back using::
-
- gigacontr --mode isdn
-
- You can also put the driver directly into Unimodem mode when it's loaded,
- by passing the module parameter startmode=0 to the hardware specific
- module, e.g.::
-
- modprobe usb_gigaset startmode=0
-
- or by adding a line like::
-
- options usb_gigaset startmode=0
-
- to an appropriate module configuration file, like::
-
- /etc/modprobe.d/gigaset.conf
-
-2.6. Call-ID (CID) mode
------------------------
-
- Call-IDs are numbers used to tag commands to, and responses from, the
- Gigaset base in order to support the simultaneous handling of multiple
- ISDN calls. Their use can be enabled ("CID mode") or disabled ("Unimodem
- mode"). Without Call-IDs (in Unimodem mode), only a very limited set of
- functions is available. It allows outgoing data connections only, but
- does not signal incoming calls or other base events.
-
- DECT cordless data devices (M10x) permanently occupy the cordless
- connection to the base while Call-IDs are activated. As the Gigaset
- bases only support one DECT data connection at a time, this prevents
- other DECT cordless data devices from accessing the base.
-
- During active operation, the driver switches to the necessary mode
- automatically. However, for the reasons above, the mode chosen when
- the device is not in use (idle) can be selected by the user.
-
- - If you want to receive incoming calls, you can use the default
- settings (CID mode).
- - If you have several DECT data devices (M10x) which you want to use
- in turn, select Unimodem mode by passing the parameter "cidmode=0" to
- the appropriate driver module (ser_gigaset or usb_gigaset).
-
- If you want both of these at once, you are out of luck.
-
- You can also use the tty class parameter "cidmode" of the device to
- change its CID mode while the driver is loaded, eg.::
-
- echo 0 > /sys/class/tty/ttyGU0/cidmode
-
-2.7. Dialing Numbers
---------------------
-provided by an application for dialing out must
- be a public network number according to the local dialing plan, without
- any dial prefix for getting an outside line.
-
- Internal calls can be made by providing an internal extension number
- prefixed with ``**`` (two asterisks) as the called party number. So to dial
- eg. the first registered DECT handset, give ``**11`` as the called party
- number. Dialing ``***`` (three asterisks) calls all extensions
- simultaneously (global call).
-
- Unimodem mode does not support internal calls.
-
-2.8. Unregistered Wireless Devices (M101/M105)
-----------------------------------------------
-
- The main purpose of the ser_gigaset and usb_gigaset drivers is to allow
- the M101 and M105 wireless devices to be used as ISDN devices for ISDN
- connections through a Gigaset base. Therefore they assume that the device
- is registered to a DECT base.
-
- If the M101/M105 device is not registered to a base, initialization of
- the device fails, and a corresponding error message is logged by the
- driver. In that situation, a restricted set of functions is available
- which includes, in particular, those necessary for registering the device
- to a base or for switching it between Fixed Part and Portable Part
- modes. See the gigacontr(8) manpage for details.
-
-3. Troubleshooting
-====================
-
-3.1. Solutions to frequently reported problems
-----------------------------------------------
-
- Problem:
- You have a slow provider and isdn4linux gives up dialing too early.
- Solution:
- Load the isdn module using the dialtimeout option. You can do this e.g.
- by adding a line like::
-
- options isdn dialtimeout=15
-
- to /etc/modprobe.d/gigaset.conf or a similar file.
-
- Problem:
- The isdnlog program emits error messages or just doesn't work.
- Solution:
- Isdnlog supports only the HiSax driver. Do not attempt to use it with
- other drivers such as Gigaset.
-
- Problem:
- You have two or more DECT data adapters (M101/M105) and only the
- first one you turn on works.
- Solution:
- Select Unimodem mode for all DECT data adapters. (see section 2.5.)
-
- Problem:
- Messages like this::
-
- usb_gigaset 3-2:1.0: Could not initialize the device.
-
- appear in your syslog.
- Solution:
- Check whether your M10x wireless device is correctly registered to the
- Gigaset base. (see section 2.7.)
-
-3.2. Telling the driver to provide more information
----------------------------------------------------
- Building the driver with the "Gigaset debugging" kernel configuration
- option (CONFIG_GIGASET_DEBUG) gives it the ability to produce additional
- information useful for debugging.
-
- You can control the amount of debugging information the driver produces by
- writing an appropriate value to /sys/module/gigaset/parameters/debug,
- e.g.::
-
- echo 0 > /sys/module/gigaset/parameters/debug
-
- switches off debugging output completely,
-
- ::
-
- echo 0x302020 > /sys/module/gigaset/parameters/debug
-
- enables a reasonable set of debugging output messages. These values are
- bit patterns where every bit controls a certain type of debugging output.
- See the constants DEBUG_* in the source file gigaset.h for details.
-
- The initial value can be set using the debug parameter when loading the
- module "gigaset", e.g. by adding a line::
-
- options gigaset debug=0
-
- to your module configuration file, eg. /etc/modprobe.d/gigaset.conf
-
- Generated debugging information can be found
- - as output of the command::
-
- dmesg
-
- - in system log files written by your syslog daemon, usually
- in /var/log/, e.g. /var/log/messages.
-
-3.3. Reporting problems and bugs
---------------------------------
- If you can't solve problems with the driver on your own, feel free to
- use one of the forums, bug trackers, or mailing lists on
-
- https://sourceforge.net/projects/gigaset307x
-
- or write an electronic mail to the maintainers.
-
- Try to provide as much information as possible, such as
-
- - distribution
- - kernel version (uname -r)
- - gcc version (gcc --version)
- - hardware architecture (uname -m, ...)
- - type and firmware version of your device (base and wireless module,
- if any)
- - output of "lsusb -v" (if using an USB device)
- - error messages
- - relevant system log messages (it would help if you activate debug
- output as described in 3.2.)
-
- For help with general configuration problems not specific to our driver,
- such as isdn4linux and network configuration issues, please refer to the
- appropriate forums and newsgroups.
-
-3.4. Reporting problem solutions
---------------------------------
- If you solved a problem with our drivers, wrote startup scripts for your
- distribution, ... feel free to contact us (using one of the places
- mentioned in 3.3.). We'd like to add scripts, hints, documentation
- to the driver and/or the project web page.
-
-
-4. Links, other software
-==========================
-
- - Sourceforge project developing this driver and associated tools
- https://sourceforge.net/projects/gigaset307x
- - Yahoo! Group on the Siemens Gigaset family of devices
- https://de.groups.yahoo.com/group/Siemens-Gigaset
- - Siemens Gigaset/T-Sinus compatibility table
- http://www.erbze.info/sinus_gigaset.htm
- (archived at https://web.archive.org/web/20100717020421/http://www.erbze.info:80/sinus_gigaset.htm )
-
-
-5. Credits
-============
-
- Thanks to
-
- Karsten Keil
- for his help with isdn4linux
- Deti Fliegl
- for his base driver code
- Dennis Dietrich
- for his kernel 2.6 patches
- Andreas Rummel
- for his work and logs to get unimodem mode working
- Andreas Degert
- for his logs and patches to get cx 100 working
- Dietrich Feist
- for his generous donation of one M105 and two M101 cordless adapters
- Christoph Schweers
- for his generous donation of a M34 device
-
- and all the other people who sent logs and other information.
diff --git a/Documentation/isdn/hysdn.rst b/Documentation/isdn/hysdn.rst
deleted file mode 100644
index 0a168d1cbffc..000000000000
--- a/Documentation/isdn/hysdn.rst
+++ /dev/null
@@ -1,196 +0,0 @@
-============
-Hysdn Driver
-============
-
-The hysdn driver has been written by
-Werner Cornelius (werner@isdn4linux.de or werner@titro.de)
-for Hypercope GmbH Aachen Germany. Hypercope agreed to publish this driver
-under the GNU General Public License.
-
-The CAPI 2.0-support was added by Ulrich Albrecht (ualbrecht@hypercope.de)
-for Hypercope GmbH Aachen, Germany.
-
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-.. Table of contents
-
- 1. About the driver
-
- 2. Loading/Unloading the driver
-
- 3. Entries in the /proc filesystem
-
- 4. The /proc/net/hysdn/cardconfX file
-
- 5. The /proc/net/hysdn/cardlogX file
-
- 6. Where to get additional info and help
-
-
-1. About the driver
-===================
-
- The drivers/isdn/hysdn subdir contains a driver for HYPERCOPEs active
- PCI isdn cards Champ, Ergo and Metro. To enable support for this cards
- enable ISDN support in the kernel config and support for HYSDN cards in
- the active cards submenu. The driver may only be compiled and used if
- support for loadable modules and the process filesystem have been enabled.
-
- These cards provide two different interfaces to the kernel. Without the
- optional CAPI 2.0 support, they register as ethernet card. IP-routing
- to a ISDN-destination is performed on the card itself. All necessary
- handlers for various protocols like ppp and others as well as config info
- and firmware may be fetched from Hypercopes WWW-Site www.hypercope.de.
-
- With CAPI 2.0 support enabled, the card can also be used as a CAPI 2.0
- compliant devices with either CAPI 2.0 applications
- (check isdn4k-utils) or -using the capidrv module- as a regular
- isdn4linux device. This is done via the same mechanism as with the
- active AVM cards and in fact uses the same module.
-
-
-2. Loading/Unloading the driver
-===============================
-
- The module has no command line parameters and auto detects up to 10 cards
- in the id-range 0-9.
- If a loaded driver shall be unloaded all open files in the /proc/net/hysdn
- subdir need to be closed and all ethernet interfaces allocated by this
- driver must be shut down. Otherwise the module counter will avoid a module
- unload.
-
- If you are using the CAPI 2.0-interface, make sure to load/modprobe the
- kernelcapi-module first.
-
- If you plan to use the capidrv-link to isdn4linux, make sure to load
- capidrv.o after all modules using this driver (i.e. after hysdn and
- any avm-specific modules).
-
-3. Entries in the /proc filesystem
-==================================
-
- When the module has been loaded it adds the directory hysdn in the
- /proc/net tree. This directory contains exactly 2 file entries for each
- card. One is called cardconfX and the other cardlogX, where X is the
- card id number from 0 to 9.
- The cards are numbered in the order found in the PCI config data.
-
-4. The /proc/net/hysdn/cardconfX file
-=====================================
-
- This file may be read to get by everyone to get info about the cards type,
- actual state, available features and used resources.
- The first 3 entries (id, bus and slot) are PCI info fields, the following
- type field gives the information about the cards type:
-
- - 4 -> Ergo card (server card with 2 b-chans)
- - 5 -> Metro card (server card with 4 or 8 b-chans)
- - 6 -> Champ card (client card with 2 b-chans)
-
- The following 3 fields show the hardware assignments for irq, iobase and the
- dual ported memory (dp-mem).
-
- The fields b-chans and fax-chans announce the available card resources of
- this types for the user.
-
- The state variable indicates the actual drivers state for this card with the
- following assignments.
-
- - 0 -> card has not been booted since driver load
- - 1 -> card booting is actually in progess
- - 2 -> card is in an error state due to a previous boot failure
- - 3 -> card is booted and active
-
- And the last field (device) shows the name of the ethernet device assigned
- to this card. Up to the first successful boot this field only shows a -
- to tell that no net device has been allocated up to now. Once a net device
- has been allocated it remains assigned to this card, even if a card is
- rebooted and an boot error occurs.
-
- Writing to the cardconfX file boots the card or transfers config lines to
- the cards firmware. The type of data is automatically detected when the
- first data is written. Only root has write access to this file.
- The firmware boot files are normally called hyclient.pof for client cards
- and hyserver.pof for server cards.
- After successfully writing the boot file, complete config files or single
- config lines may be copied to this file.
- If an error occurs the return value given to the writing process has the
- following additional codes (decimal):
-
- ==== ============================================
- 1000 Another process is currently bootng the card
- 1001 Invalid firmware header
- 1002 Boards dual-port RAM test failed
- 1003 Internal firmware handler error
- 1004 Boot image size invalid
- 1005 First boot stage (bootstrap loader) failed
- 1006 Second boot stage failure
- 1007 Timeout waiting for card ready during boot
- 1008 Operation only allowed in booted state
- 1009 Config line too long
- 1010 Invalid channel number
- 1011 Timeout sending config data
- ==== ============================================
-
- Additional info about error reasons may be fetched from the log output.
-
-5. The /proc/net/hysdn/cardlogX file
-====================================
-
- The cardlogX file entry may be opened multiple for reading by everyone to
- get the cards and drivers log data. Card messages always start with the
- keyword LOG. All other lines are output from the driver.
- The driver log data may be redirected to the syslog by selecting the
- appropriate bitmask. The cards log messages will always be send to this
- interface but never to the syslog.
-
- A root user may write a decimal or hex (with 0x) value t this file to select
- desired output options. As mentioned above the cards log dat is always
- written to the cardlog file independent of the following options only used
- to check and debug the driver itself:
-
- For example::
-
- echo "0x34560078" > /proc/net/hysdn/cardlog0
-
- to output the hex log mask 34560078 for card 0.
-
- The written value is regarded as an unsigned 32-Bit value, bit ored for
- desired output. The following bits are already assigned:
-
- ========== ============================================================
- 0x80000000 All driver log data is alternatively via syslog
- 0x00000001 Log memory allocation errors
- 0x00000010 Firmware load start and close are logged
- 0x00000020 Log firmware record parser
- 0x00000040 Log every firmware write actions
- 0x00000080 Log all card related boot messages
- 0x00000100 Output all config data sent for debugging purposes
- 0x00000200 Only non comment config lines are shown wth channel
- 0x00000400 Additional conf log output
- 0x00001000 Log the asynchronous scheduler actions (config and log)
- 0x00100000 Log all open and close actions to /proc/net/hysdn/card files
- 0x00200000 Log all actions from /proc file entries
- 0x00010000 Log network interface init and deinit
- ========== ============================================================
-
-6. Where to get additional info and help
-========================================
-
- If you have any problems concerning the driver or configuration contact
- the Hypercope support team (support@hypercope.de) and or the authors
- Werner Cornelius (werner@isdn4linux or cornelius@titro.de) or
- Ulrich Albrecht (ualbrecht@hypercope.de).
diff --git a/Documentation/isdn/index.rst b/Documentation/isdn/index.rst
index 407e74b78372..9622939fa526 100644
--- a/Documentation/isdn/index.rst
+++ b/Documentation/isdn/index.rst
@@ -9,9 +9,6 @@ ISDN
interface_capi
- avmb1
- gigaset
- hysdn
m_isdn
credits
diff --git a/Documentation/isdn/interface_capi.rst b/Documentation/isdn/interface_capi.rst
index 01a4b5ade9a4..fe2421444b76 100644
--- a/Documentation/isdn/interface_capi.rst
+++ b/Documentation/isdn/interface_capi.rst
@@ -26,13 +26,6 @@ This standard is freely available from https://www.capi.org.
2. Driver and Device Registration
=================================
-CAPI drivers optionally register themselves with Kernel CAPI by calling the
-Kernel CAPI function register_capi_driver() with a pointer to a struct
-capi_driver. This structure must be filled with the name and revision of the
-driver, and optionally a pointer to a callback function, add_card(). The
-registration can be revoked by calling the function unregister_capi_driver()
-with a pointer to the same struct capi_driver.
-
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
@@ -89,9 +82,6 @@ register_capi_driver():
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
-``int (*add_card)(struct capi_driver *driver, capicardparams *data)``
- a callback function pointer (may be NULL)
-
4.2 struct capi_ctr
-------------------
@@ -178,12 +168,6 @@ to be set by the driver before calling attach_capi_ctr():
pointer to a callback function returning the entry for the device in
the CAPI controller info table, /proc/capi/controller
-``const struct file_operations *proc_fops``
- pointers to callback functions for the device's proc file
- system entry, /proc/capi/controllers/<n>; pointer to the device's
- capi_ctr structure is available from struct proc_dir_entry::data
- which is available from struct inode.
-
Note:
Callback functions except send_message() are never called in interrupt
context.
@@ -267,25 +251,10 @@ _cmstruct alternative representation for CAPI parameters of type 'struct'
_cmsg structure members.
=========== =================================================================
-Functions capi_cmsg2message() and capi_message2cmsg() are provided to convert
-messages between their transport encoding described in the CAPI 2.0 standard
-and their _cmsg structure representation. Note that capi_cmsg2message() does
-not know or check the size of its destination buffer. The caller must make
-sure it is big enough to accommodate the resulting CAPI message.
-
5. Lower Layer Interface Functions
==================================
-(declared in <linux/isdn/capilli.h>)
-
-::
-
- void register_capi_driver(struct capi_driver *drvr)
- void unregister_capi_driver(struct capi_driver *drvr)
-
-register/unregister a driver with Kernel CAPI
-
::
int attach_capi_ctr(struct capi_ctr *ctrlr)
@@ -302,13 +271,6 @@ signal controller ready/not ready
::
- void capi_ctr_suspend_output(struct capi_ctr *ctrlr)
- void capi_ctr_resume_output(struct capi_ctr *ctrlr)
-
-signal suspend/resume
-
-::
-
void capi_ctr_handle_message(struct capi_ctr * ctrlr, u16 applid,
struct sk_buff *skb)
@@ -319,21 +281,6 @@ for forwarding to the specified application
6. Helper Functions and Macros
==============================
-Library functions (from <linux/isdn/capilli.h>):
-
-::
-
- void capilib_new_ncci(struct list_head *head, u16 applid,
- u32 ncci, u32 winsize)
- void capilib_free_ncci(struct list_head *head, u16 applid, u32 ncci)
- void capilib_release_appl(struct list_head *head, u16 applid)
- void capilib_release(struct list_head *head)
- void capilib_data_b3_conf(struct list_head *head, u16 applid,
- u32 ncci, u16 msgid)
- u16 capilib_data_b3_req(struct list_head *head, u16 applid,
- u32 ncci, u16 msgid)
-
-
Macros to extract/set element values from/in a CAPI message header
(from <linux/isdn/capiutil.h>):
@@ -357,24 +304,6 @@ CAPIMSG_DATALEN(m) CAPIMSG_SETDATALEN(m, len) Data Length (u16)
Library functions for working with _cmsg structures
(from <linux/isdn/capiutil.h>):
-``unsigned capi_cmsg2message(_cmsg *cmsg, u8 *msg)``
- Assembles a CAPI 2.0 message from the parameters in ``*cmsg``,
- storing the result in ``*msg``.
-
-``unsigned capi_message2cmsg(_cmsg *cmsg, u8 *msg)``
- Disassembles the CAPI 2.0 message in ``*msg``, storing the parameters
- in ``*cmsg``.
-
-``unsigned capi_cmsg_header(_cmsg *cmsg, u16 ApplId, u8 Command, u8 Subcommand, u16 Messagenumber, u32 Controller)``
- Fills the header part and address field of the _cmsg structure ``*cmsg``
- with the given values, zeroing the remainder of the structure so only
- parameters with non-default values need to be changed before sending
- the message.
-
-``void capi_cmsg_answer(_cmsg *cmsg)``
- Sets the low bit of the Subcommand field in ``*cmsg``, thereby
- converting ``_REQ`` to ``_CONF`` and ``_IND`` to ``_RESP``.
-
``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
diff --git a/Documentation/userspace-api/ioctl/ioctl-number.rst b/Documentation/userspace-api/ioctl/ioctl-number.rst
index dbdc1ccbe949..cdf8551d70d7 100644
--- a/Documentation/userspace-api/ioctl/ioctl-number.rst
+++ b/Documentation/userspace-api/ioctl/ioctl-number.rst
@@ -132,7 +132,6 @@ Code Seq# Include File Comments
'F' 80-8F linux/arcfb.h conflict!
'F' DD video/sstfb.h conflict!
'G' 00-3F drivers/misc/sgi-gru/grulib.h conflict!
-'G' 00-0F linux/gigaset_dev.h conflict!
'H' 00-7F linux/hiddev.h conflict!
'H' 00-0F linux/hidraw.h conflict!
'H' 01 linux/mei.h conflict!
diff --git a/MAINTAINERS b/MAINTAINERS
index aed1b9f3373b..c4a599c02805 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8828,7 +8828,7 @@ S: Maintained
F: drivers/isdn/mISDN
F: drivers/isdn/hardware
-ISDN/CAPI SUBSYSTEM
+ISDN/CMTP OVER BLUETOOTH
M: Karsten Keil <isdn@linux-pingi.de>
L: isdn4linux@listserv.isdn4linux.de (subscribers-only)
L: netdev@vger.kernel.org
@@ -8836,7 +8836,6 @@ W: http://www.isdn4linux.de
S: Odd Fixes
F: Documentation/isdn/
F: drivers/isdn/capi/
-F: drivers/staging/isdn/
F: net/bluetooth/cmtp/
F: include/linux/isdn/
F: include/uapi/linux/isdn/
diff --git a/drivers/isdn/Makefile b/drivers/isdn/Makefile
index 63baf27a2c79..d14334f4007e 100644
--- a/drivers/isdn/Makefile
+++ b/drivers/isdn/Makefile
@@ -3,6 +3,6 @@
# Object files in subdirectories
-obj-$(CONFIG_ISDN_CAPI) += capi/
+obj-$(CONFIG_BT_CMTP) += capi/
obj-$(CONFIG_MISDN) += mISDN/
obj-$(CONFIG_ISDN) += hardware/
diff --git a/drivers/isdn/capi/Kconfig b/drivers/isdn/capi/Kconfig
index 573fea5500ce..cc408ad9aafb 100644
--- a/drivers/isdn/capi/Kconfig
+++ b/drivers/isdn/capi/Kconfig
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
-menuconfig ISDN_CAPI
- tristate "CAPI 2.0 subsystem"
+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
@@ -15,42 +15,18 @@ menuconfig ISDN_CAPI
See CONFIG_BT_CMTP for the last remaining regular driver
in the kernel that uses the CAPI subsystem.
-if ISDN_CAPI
-
config CAPI_TRACE
- bool "CAPI trace support"
- default y
+ 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).
- This will increase the size of the kernelcapi module by 20 KB.
- If unsure, say Y.
-
-config ISDN_CAPI_CAPI20
- tristate "CAPI2.0 /dev/capi20 support"
- help
- This option will provide the CAPI 2.0 interface to userspace
- applications via /dev/capi20. Applications should use the
- standardized libcapi20 to access this functionality. You should say
- Y/M here.
config ISDN_CAPI_MIDDLEWARE
- bool "CAPI2.0 Middleware support"
- depends on ISDN_CAPI_CAPI20 && TTY
+ 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.
-
-config ISDN_CAPI_CAPIDRV_VERBOSE
- bool "Verbose reason code reporting"
- depends on ISDN_CAPI_CAPIDRV
- help
- If you say Y here, the capidrv interface will give verbose reasons
- for disconnecting. This will increase the size of the kernel by 7 KB.
- If unsure, say N.
-
-endif
diff --git a/drivers/isdn/capi/Makefile b/drivers/isdn/capi/Makefile
index d299f3e75f89..352217ebabd8 100644
--- a/drivers/isdn/capi/Makefile
+++ b/drivers/isdn/capi/Makefile
@@ -1,17 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
-# Makefile for the CAPI subsystem.
+# Makefile for the CAPI subsystem used by BT_CMTP
-# Ordering constraints: kernelcapi.o first
-
-# Each configuration option enables a list of files.
-
-obj-$(CONFIG_ISDN_CAPI) += kernelcapi.o
-obj-$(CONFIG_ISDN_CAPI_CAPI20) += capi.o
-obj-$(CONFIG_ISDN_CAPI_CAPIDRV) += capidrv.o
-
-# Multipart objects.
-
-kernelcapi-y := kcapi.o capiutil.o capilib.o
-kernelcapi-$(CONFIG_PROC_FS) += kcapi_proc.o
-
-ccflags-y += -I$(srctree)/$(src)/../include -I$(srctree)/$(src)/../include/uapi
+obj-$(CONFIG_BT_CMTP) += kernelcapi.o
+kernelcapi-y := kcapi.o capiutil.o capi.o kcapi_proc.o
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index 1675da34239b..85767f52fe3c 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -39,7 +39,9 @@
#include <linux/isdn/capiutil.h>
#include <linux/isdn/capicmd.h>
-MODULE_DESCRIPTION("CAPI4Linux: Userspace /dev/capi20 interface");
+#include "kcapi.h"
+
+MODULE_DESCRIPTION("CAPI4Linux: kernel CAPI layer and /dev/capi20 interface");
MODULE_AUTHOR("Carsten Paeth");
MODULE_LICENSE("GPL");
@@ -1412,15 +1414,22 @@ 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;
}
capi_class = class_create(THIS_MODULE, "capi");
if (IS_ERR(capi_class)) {
unregister_chrdev(capi_major, "capi20");
+ kcapi_exit();
return PTR_ERR(capi_class);
}
@@ -1430,6 +1439,7 @@ static int __init capi_init(void)
device_destroy(capi_class, MKDEV(capi_major, 0));
class_destroy(capi_class);
unregister_chrdev(capi_major, "capi20");
+ kcapi_exit();
return -ENOMEM;
}
@@ -1455,6 +1465,8 @@ static void __exit capi_exit(void)
unregister_chrdev(capi_major, "capi20");
capinc_tty_exit();
+
+ kcapi_exit();
}
module_init(capi_init);
diff --git a/drivers/isdn/capi/capilib.c b/drivers/isdn/capi/capilib.c
deleted file mode 100644
index a39ad3796bba..000000000000
--- a/drivers/isdn/capi/capilib.c
+++ /dev/null
@@ -1,202 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-#include <linux/slab.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/isdn/capilli.h>
-
-#define DBG(format, arg...) do { \
- printk(KERN_DEBUG "%s: " format "\n" , __func__ , ## arg); \
- } while (0)
-
-struct capilib_msgidqueue {
- struct capilib_msgidqueue *next;
- u16 msgid;
-};
-
-struct capilib_ncci {
- struct list_head list;
- u16 applid;
- u32 ncci;
- u32 winsize;
- int nmsg;
- struct capilib_msgidqueue *msgidqueue;
- struct capilib_msgidqueue *msgidlast;
- struct capilib_msgidqueue *msgidfree;
- struct capilib_msgidqueue msgidpool[CAPI_MAXDATAWINDOW];
-};
-
-// ---------------------------------------------------------------------------
-// NCCI Handling
-
-static inline void mq_init(struct capilib_ncci *np)
-{
- u_int i;
- np->msgidqueue = NULL;
- np->msgidlast = NULL;
- np->nmsg = 0;
- memset(np->msgidpool, 0, sizeof(np->msgidpool));
- np->msgidfree = &np->msgidpool[0];
- for (i = 1; i < np->winsize; i++) {
- np->msgidpool[i].next = np->msgidfree;
- np->msgidfree = &np->msgidpool[i];
- }
-}
-
-static inline int mq_enqueue(struct capilib_ncci *np, u16 msgid)
-{
- struct capilib_msgidqueue *mq;
- if ((mq = np->msgidfree) == NULL)
- return 0;
- np->msgidfree = mq->next;
- mq->msgid = msgid;
- mq->next = NULL;
- if (np->msgidlast)
- np->msgidlast->next = mq;
- np->msgidlast = mq;
- if (!np->msgidqueue)
- np->msgidqueue = mq;
- np->nmsg++;
- return 1;
-}
-
-static inline int mq_dequeue(struct capilib_ncci *np, u16 msgid)
-{
- struct capilib_msgidqueue **pp;
- for (pp = &np->msgidqueue; *pp; pp = &(*pp)->next) {
- if ((*pp)->msgid == msgid) {
- struct capilib_msgidqueue *mq = *pp;
- *pp = mq->next;
- if (mq == np->msgidlast)
- np->msgidlast = NULL;
- mq->next = np->msgidfree;
- np->msgidfree = mq;
- np->nmsg--;
- return 1;
- }
- }
- return 0;
-}
-
-void capilib_new_ncci(struct list_head *head, u16 applid, u32 ncci, u32 winsize)
-{
- struct capilib_ncci *np;
-
- np = kmalloc(sizeof(*np), GFP_ATOMIC);
- if (!np) {
- printk(KERN_WARNING "capilib_new_ncci: no memory.\n");
- return;
- }
- if (winsize > CAPI_MAXDATAWINDOW) {
- printk(KERN_ERR "capi_new_ncci: winsize %d too big\n",
- winsize);
- winsize = CAPI_MAXDATAWINDOW;
- }
- np->applid = applid;
- np->ncci = ncci;
- np->winsize = winsize;
- mq_init(np);
- list_add_tail(&np->list, head);
- DBG("kcapi: appl %d ncci 0x%x up", applid, ncci);
-}
-
-EXPORT_SYMBOL(capilib_new_ncci);
-
-void capilib_free_ncci(struct list_head *head, u16 applid, u32 ncci)
-{
- struct list_head *l;
- struct capilib_ncci *np;
-
- list_for_each(l, head) {
- np = list_entry(l, struct capilib_ncci, list);
- if (np->applid != applid)
- continue;
- if (np->ncci != ncci)
- continue;
- printk(KERN_INFO "kcapi: appl %d ncci 0x%x down\n", applid, ncci);
- list_del(&np->list);
- kfree(np);
- return;
- }
- printk(KERN_ERR "capilib_free_ncci: ncci 0x%x not found\n", ncci);
-}
-
-EXPORT_SYMBOL(capilib_free_ncci);
-
-void capilib_release_appl(struct list_head *head, u16 applid)
-{
- struct list_head *l, *n;
- struct capilib_ncci *np;
-
- list_for_each_safe(l, n, head) {
- np = list_entry(l, struct capilib_ncci, list);
- if (np->applid != applid)
- continue;
- printk(KERN_INFO "kcapi: appl %d ncci 0x%x forced down\n", applid, np->ncci);
- list_del(&np->list);
- kfree(np);
- }
-}
-
-EXPORT_SYMBOL(capilib_release_appl);
-
-void capilib_release(struct list_head *head)
-{
- struct list_head *l, *n;
- struct capilib_ncci *np;
-
- list_for_each_safe(l, n, head) {
- np = list_entry(l, struct capilib_ncci, list);
- printk(KERN_INFO "kcapi: appl %d ncci 0x%x forced down\n", np->applid, np->ncci);
- list_del(&np->list);
- kfree(np);
- }
-}
-
-EXPORT_SYMBOL(capilib_release);
-
-u16 capilib_data_b3_req(struct list_head *head, u16 applid, u32 ncci, u16 msgid)
-{
- struct list_head *l;
- struct capilib_ncci *np;
-
- list_for_each(l, head) {
- np = list_entry(l, struct capilib_ncci, list);
- if (np->applid != applid)
- continue;
- if (np->ncci != ncci)
- continue;
-
- if (mq_enqueue(np, msgid) == 0)
- return CAPI_SENDQUEUEFULL;
-
- return CAPI_NOERROR;
- }
- printk(KERN_ERR "capilib_data_b3_req: ncci 0x%x not found\n", ncci);
- return CAPI_NOERROR;
-}
-
-EXPORT_SYMBOL(capilib_data_b3_req);
-
-void capilib_data_b3_conf(struct list_head *head, u16 applid, u32 ncci, u16 msgid)
-{
- struct list_head *l;
- struct capilib_ncci *np;
-
- list_for_each(l, head) {
- np = list_entry(l, struct capilib_ncci, list);
- if (np->applid != applid)
- continue;
- if (np->ncci != ncci)
- continue;
-
- if (mq_dequeue(np, msgid) == 0) {
- printk(KERN_ERR "kcapi: msgid %hu ncci 0x%x not on queue\n",
- msgid, ncci);
- }
- return;
- }
- printk(KERN_ERR "capilib_data_b3_conf: ncci 0x%x not found\n", ncci);
-}
-
-EXPORT_SYMBOL(capilib_data_b3_conf);
diff --git a/drivers/isdn/capi/capiutil.c b/drivers/isdn/capi/capiutil.c
index 9846d82eb097..f26bf3c66d7e 100644
--- a/drivers/isdn/capi/capiutil.c
+++ b/drivers/isdn/capi/capiutil.c
@@ -20,6 +20,8 @@
#include <linux/isdn/capiutil.h>
#include <linux/slab.h>
+#include "kcapi.h"
+
/* from CAPI2.0 DDK AVM Berlin GmbH */
typedef struct {
@@ -245,190 +247,6 @@ static void jumpcstruct(_cmsg *cmsg)
}
}
}
-/*-------------------------------------------------------*/
-static void pars_2_message(_cmsg *cmsg)
-{
-
- for (; TYP != _CEND; cmsg->p++) {
- switch (TYP) {
- case _CBYTE:
- byteTLcpy(cmsg->m + cmsg->l, OFF);
- cmsg->l++;
- break;
- case _CWORD:
- wordTLcpy(cmsg->m + cmsg->l, OFF);
- cmsg->l += 2;
- break;
- case _CDWORD:
- dwordTLcpy(cmsg->m + cmsg->l, OFF);
- cmsg->l += 4;
- break;
- case _CSTRUCT:
- if (*(u8 **) OFF == NULL) {
- *(cmsg->m + cmsg->l) = '\0';
- cmsg->l++;
- } else if (**(_cstruct *) OFF != 0xff) {
- structTLcpy(cmsg->m + cmsg->l, *(_cstruct *) OFF, 1 + **(_cstruct *) OFF);
- cmsg->l += 1 + **(_cstruct *) OFF;
- } else {
- _cstruct s = *(_cstruct *) OFF;
- structTLcpy(cmsg->m + cmsg->l, s, 3 + *(u16 *) (s + 1));
- cmsg->l += 3 + *(u16 *) (s + 1);
- }
- break;
- case _CMSTRUCT:
-/*----- Metastruktur 0 -----*/
- if (*(_cmstruct *) OFF == CAPI_DEFAULT) {
- *(cmsg->m + cmsg->l) = '\0';
- cmsg->l++;
- jumpcstruct(cmsg);
- }
-/*----- Metastruktur wird composed -----*/
- else {
- unsigned _l = cmsg->l;
- unsigned _ls;
- cmsg->l++;
- cmsg->p++;
- pars_2_message(cmsg);
- _ls = cmsg->l - _l - 1;
- if (_ls < 255)
- (cmsg->m + _l)[0] = (u8) _ls;
- else {
- structTLcpyovl(cmsg->m + _l + 3, cmsg->m + _l + 1, _ls);
- (cmsg->m + _l)[0] = 0xff;
- wordTLcpy(cmsg->m + _l + 1, &_ls);
- }
- }
- break;
- }
- }
-}
-
-/**
- * capi_cmsg2message() - assemble CAPI 2.0 message from _cmsg structure
- * @cmsg: _cmsg structure
- * @msg: buffer for assembled message
- *
- * Return value: 0 for success
- */
-
-unsigned capi_cmsg2message(_cmsg *cmsg, u8 *msg)
-{
- cmsg->m = msg;
- cmsg->l = 8;
- cmsg->p = 0;
- cmsg->par = capi_cmd2par(cmsg->Command, cmsg->Subcommand);
- if (!cmsg->par)
- return 1; /* invalid command/subcommand */
-
- pars_2_message(cmsg);
-
- wordTLcpy(msg + 0, &cmsg->l);
- byteTLcpy(cmsg->m + 4, &cmsg->Command);
- byteTLcpy(cmsg->m + 5, &cmsg->Subcommand);
- wordTLcpy(cmsg->m + 2, &cmsg->ApplId);
- wordTLcpy(cmsg->m + 6, &cmsg->Messagenumber);
-
- return 0;
-}
-
-/*-------------------------------------------------------*/
-static void message_2_pars(_cmsg *cmsg)
-{
- for (; TYP != _CEND; cmsg->p++) {
-
- switch (TYP) {
- case _CBYTE:
- byteTRcpy(cmsg->m + cmsg->l, OFF);
- cmsg->l++;
- break;
- case _CWORD:
- wordTRcpy(cmsg->m + cmsg->l, OFF);
- cmsg->l += 2;
- break;
- case _CDWORD:
- dwordTRcpy(cmsg->m + cmsg->l, OFF);
- cmsg->l += 4;
- break;
- case _CSTRUCT:
- *(u8 **) OFF = cmsg->m + cmsg->l;
-
- 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') {
- *(_cmstruct *) OFF = CAPI_DEFAULT;
- cmsg->l++;
- jumpcstruct(cmsg);
- } else {
- unsigned _l = cmsg->l;
- *(_cmstruct *) OFF = CAPI_COMPOSE;
- cmsg->l = (cmsg->m + _l)[0] == 255 ? cmsg->l + 3 : cmsg->l + 1;
- cmsg->p++;
- message_2_pars(cmsg);
- }
- break;
- }
- }
-}
-
-/**
- * capi_message2cmsg() - disassemble CAPI 2.0 message into _cmsg structure
- * @cmsg: _cmsg structure
- * @msg: buffer for assembled message
- *
- * Return value: 0 for success
- */
-
-unsigned capi_message2cmsg(_cmsg *cmsg, u8 *msg)
-{
- memset(cmsg, 0, sizeof(_cmsg));
- 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);
- if (!cmsg->par)
- return 1; /* invalid command/subcommand */
-
- message_2_pars(cmsg);
-
- wordTRcpy(msg + 0, &cmsg->l);
- wordTRcpy(cmsg->m + 2, &cmsg->ApplId);
- wordTRcpy(cmsg->m + 6, &cmsg->Messagenumber);
-
- return 0;
-}
-
-/**
- * capi_cmsg_header() - initialize header part of _cmsg structure
- * @cmsg: _cmsg structure
- * @_ApplId: ApplID field value
- * @_Command: Command field value
- * @_Subcommand: Subcommand field value
- * @_Messagenumber: Message Number field value
- * @_Controller: Controller/PLCI/NCCI field value
- *
- * Return value: 0 for success
- */
-
-unsigned capi_cmsg_header(_cmsg *cmsg, u16 _ApplId,
- u8 _Command, u8 _Subcommand,
- u16 _Messagenumber, u32 _Controller)
-{
- memset(cmsg, 0, sizeof(_cmsg));
- cmsg->ApplId = _ApplId;
- cmsg->Command = _Command;
- cmsg->Subcommand = _Subcommand;
- cmsg->Messagenumber = _Messagenumber;
- cmsg->adr.adrController = _Controller;
- return 0;
-}
/*-------------------------------------------------------*/
@@ -561,8 +379,6 @@ static char *pnames[] =
/*2f */ "Useruserdata"
};
-
-
#include <stdarg.h>
/*-------------------------------------------------------*/
@@ -800,37 +616,6 @@ _cdebbuf *capi_message2str(u8 *msg)
return cdb;
}
-/**
- * capi_cmsg2str() - format _cmsg structure for printing
- * @cmsg: _cmsg structure
- *
- * Allocates a CAPI debug buffer and fills it with a printable representation
- * of the CAPI 2.0 message stored in @cmsg by a previous call to
- * capi_cmsg2message() or capi_message2cmsg().
- * Return value: allocated debug buffer, NULL on error
- * The returned buffer should be freed by a call to cdebbuf_free() after use.
- */
-
-_cdebbuf *capi_cmsg2str(_cmsg *cmsg)
-{
- _cdebbuf *cdb;
-
- if (!cmsg->m)
- return NULL; /* no message */
- cdb = cdebbuf_alloc();
- if (!cdb)
- return NULL;
- cmsg->l = 8;
- cmsg->p = 0;
- cdb = bufprint(cdb, "%s ID=%03d #0x%04x LEN=%04d\n",
- capi_cmd2str(cmsg->Command, cmsg->Subcommand),
- ((u16 *) cmsg->m)[1],
- ((u16 *) cmsg->m)[3],
- ((u16 *) cmsg->m)[0]);
- cdb = protocol_message_2_pars(cdb, cmsg, 1);
- return cdb;
-}
-
int __init cdebug_init(void)
{
g_cmsg = kmalloc(sizeof(_cmsg), GFP_KERNEL);
@@ -854,7 +639,7 @@ int __init cdebug_init(void)
return 0;
}
-void __exit cdebug_exit(void)
+void cdebug_exit(void)
{
if (g_debbuf)
kfree(g_debbuf->buf);
@@ -885,16 +670,8 @@ int __init cdebug_init(void)
return 0;
}
-void __exit cdebug_exit(void)
+void cdebug_exit(void)
{
}
#endif
-
-EXPORT_SYMBOL(cdebbuf_free);
-EXPORT_SYMBOL(capi_cmsg2message);
-EXPORT_SYMBOL(capi_message2cmsg);
-EXPORT_SYMBOL(capi_cmsg_header);
-EXPORT_SYMBOL(capi_cmd2str);
-EXPORT_SYMBOL(capi_cmsg2str);
-EXPORT_SYMBOL(capi_message2str);
diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c
index a4ceb61c5b60..7168778fbbe1 100644
--- a/drivers/isdn/capi/kcapi.c
+++ b/drivers/isdn/capi/kcapi.c
@@ -10,8 +10,6 @@
*
*/
-#define AVMB1_COMPAT
-
#include "kcapi.h"
#include <linux/module.h>
#include <linux/mm.h>
@@ -31,18 +29,12 @@
#include <linux/uaccess.h>
#include <linux/isdn/capicmd.h>
#include <linux/isdn/capiutil.h>
-#ifdef AVMB1_COMPAT
-#include <linux/b1lli.h>
-#endif
#include <linux/mutex.h>
#include <linux/rcupdate.h>
static int showcapimsgs = 0;
static struct workqueue_struct *kcapi_wq;
-MODULE_DESCRIPTION("CAPI4Linux: kernel CAPI layer");
-MODULE_AUTHOR("Carsten Paeth");
-MODULE_LICENSE("GPL");
module_param(showcapimsgs, uint, 0);
/* ------------------------------------------------------------- */
@@ -61,9 +53,6 @@ static char capi_manufakturer[64] = "AVM Berlin";
#define NCCI2CTRL(ncci) (((ncci) >> 24) & 0x7f)
-LIST_HEAD(capi_drivers);
-DEFINE_MUTEX(capi_drivers_lock);
-
struct capi_ctr *capi_controller[CAPI_MAXCONTR];
DEFINE_MUTEX(capi_controller_lock);
@@ -71,8 +60,6 @@ struct capi20_appl *capi_applications[CAPI_MAXAPPL];
static int ncontrollers;
-static BLOCKING_NOTIFIER_HEAD(ctr_notifier_list);
-
/* -------- controller ref counting -------------------------------------- */
static inline struct capi_ctr *
@@ -200,8 +187,6 @@ static void notify_up(u32 contr)
if (ap)
register_appl(ctr, applid, &ap->rparam);
}
-
- wake_up_interruptible_all(&ctr->state_wait_queue);
} else
printk(KERN_WARNING "%s: invalid contr %d\n", __func__, contr);
@@ -229,8 +214,6 @@ static void ctr_down(struct capi_ctr *ctr, int new_state)
if (ap)
capi_ctr_put(ctr);
}
-
- wake_up_interruptible_all(&ctr->state_wait_queue);
}
static void notify_down(u32 contr)
@@ -251,36 +234,23 @@ static void notify_down(u32 contr)
mutex_unlock(&capi_controller_lock);
}
-static int
-notify_handler(struct notifier_block *nb, unsigned long val, void *v)
+static void do_notify_work(struct work_struct *work)
{
- u32 contr = (long)v;
+ struct capictr_event *event =
+ container_of(work, struct capictr_event, work);
- switch (val) {
+ switch (event->type) {
case CAPICTR_UP:
- notify_up(contr);
+ notify_up(event->controller);
break;
case CAPICTR_DOWN:
- notify_down(contr);
+ notify_down(event->controller);
break;
}
- return NOTIFY_OK;
-}
-static void do_notify_work(struct work_struct *work)
-{
- struct capictr_event *event =
- container_of(work, struct capictr_event, work);
-
- blocking_notifier_call_chain(&ctr_notifier_list, event->type,
- (void *)(long)event->controller);
kfree(event);
}
-/*
- * The notifier will result in adding/deleteing of devices. Devices can
- * only removed in user process, not in bh.
- */
static int notify_push(unsigned int event_type, u32 controller)
{
struct capictr_event *event = kmalloc(sizeof(*event), GFP_ATOMIC);
@@ -296,18 +266,6 @@ static int notify_push(unsigned int event_type, u32 controller)
return 0;
}
-int register_capictr_notifier(struct notifier_block *nb)
-{
- return blocking_notifier_chain_register(&ctr_notifier_list, nb);
-}
-EXPORT_SYMBOL_GPL(register_capictr_notifier);
-
-int unregister_capictr_notifier(struct notifier_block *nb)
-{
- return blocking_notifier_chain_unregister(&ctr_notifier_list, nb);
-}
-EXPORT_SYMBOL_GPL(unregister_capictr_notifier);
-
/* -------- Receiver ------------------------------------------ */
static void recv_handler(struct work_struct *work)
@@ -454,48 +412,6 @@ void capi_ctr_down(struct capi_ctr *ctr)
EXPORT_SYMBOL(capi_ctr_down);
-/**
- * capi_ctr_suspend_output() - suspend controller
- * @ctr: controller descriptor structure.
- *
- * Called by hardware driver to stop data flow.
- *
- * Note: The caller is responsible for synchronizing concurrent state changes
- * as well as invocations of capi_ctr_handle_message.
- */
-
-void capi_ctr_suspend_output(struct capi_ctr *ctr)
-{
- if (!ctr->blocked) {
- printk(KERN_DEBUG "kcapi: controller [%03d] suspend\n",
- ctr->cnr);
- ctr->blocked = 1;
- }
-}
-
-EXPORT_SYMBOL(capi_ctr_suspend_output);
-
-/**
- * capi_ctr_resume_output() - resume controller
- * @ctr: controller descriptor structure.
- *
- * Called by hardware driver to resume data flow.
- *
- * Note: The caller is responsible for synchronizing concurrent state changes
- * as well as invocations of capi_ctr_handle_message.
- */
-
-void capi_ctr_resume_output(struct capi_ctr *ctr)
-{
- if (ctr->blocked) {
- printk(KERN_DEBUG "kcapi: controller [%03d] resumed\n",
- ctr->cnr);
- ctr->blocked = 0;
- }
-}
-
-EXPORT_SYMBOL(capi_ctr_resume_output);
-
/* ------------------------------------------------------------- */
/**
@@ -531,7 +447,6 @@ int attach_capi_ctr(struct capi_ctr *ctr)
ctr->state = CAPI_CTR_DETECTED;
ctr->blocked = 0;
ctr->traceflag = showcapimsgs;
- init_waitqueue_head(&ctr->state_wait_queue);
sprintf(ctr->procfn, "capi/controllers/%d", ctr->cnr);
ctr->procent = proc_create_single_data(ctr->procfn, 0, NULL,
@@ -586,38 +501,6 @@ unlock_out:
EXPORT_SYMBOL(detach_capi_ctr);
-/**
- * register_capi_driver() - register CAPI driver
- * @driver: driver descriptor structure.
- *
- * Called by hardware driver to register itself with the CAPI subsystem.
- */
-
-void register_capi_driver(struct capi_driver *driver)
-{
- mutex_lock(&capi_drivers_lock);
- list_add_tail(&driver->list, &capi_drivers);
- mutex_unlock(&capi_drivers_lock);
-}
-
-EXPORT_SYMBOL(register_capi_driver);
-
-/**
- * unregister_capi_driver() - unregister CAPI driver
- * @driver: driver descriptor structure.
- *
- * Called by hardware driver to unregister itself from the CAPI subsystem.
- */
-
-void unregister_capi_driver(struct capi_driver *driver)
-{
- mutex_lock(&capi_drivers_lock);
- list_del(&driver->list);
- mutex_unlock(&capi_drivers_lock);
-}
-
-EXPORT_SYMBOL(unregister_capi_driver);
-
/* ------------------------------------------------------------- */
/* -------- CAPI2.0 Interface ---------------------------------- */
/* ------------------------------------------------------------- */
@@ -648,8 +531,6 @@ u16 capi20_isinstalled(void)
return ret;
}
-EXPORT_SYMBOL(capi20_isinstalled);
-
/**
* capi20_register() - CAPI 2.0 operation CAPI_REGISTER
* @ap: CAPI application descriptor structure.
@@ -711,8 +592,6 @@ u16 capi20_register(struct capi20_appl *ap)
return CAPI_NOERROR;
}
-EXPORT_SYMBOL(capi20_register);
-
/**
* capi20_release() - CAPI 2.0 operation CAPI_RELEASE
* @ap: CAPI application descriptor structure.
@@ -755,8 +634,6 @@ u16 capi20_release(struct capi20_appl *ap)
return CAPI_NOERROR;
}
-EXPORT_SYMBOL(capi20_release);
-
/**
* capi20_put_message() - CAPI 2.0 operation CAPI_PUT_MESSAGE
* @ap: CAPI application descriptor structure.
@@ -834,8 +711,6 @@ u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb)
return ctr->send_message(ctr, skb);
}
-EXPORT_SYMBOL(capi20_put_message);
-
/**
* capi20_get_manufacturer() - CAPI 2.0 operation CAPI_GET_MANUFACTURER
* @contr: controller number.
@@ -869,8 +744,6 @@ u16 capi20_get_manufacturer(u32 contr, u8 *buf)
return ret;
}
-EXPORT_SYMBOL(capi20_get_manufacturer);
-
/**
* capi20_get_version() - CAPI 2.0 operation CAPI_GET_VERSION
* @contr: controller number.
@@ -904,8 +777,6 @@ u16 capi20_get_version(u32 contr, struct capi_version *verp)
return ret;
}
-EXPORT_SYMBOL(capi20_get_version);
-
/**
* capi20_get_serial() - CAPI 2.0 operation CAPI_GET_SERIAL_NUMBER
* @contr: controller number.
@@ -939,8 +810,6 @@ u16 capi20_get_serial(u32 contr, u8 *serial)
return ret;
}
-EXPORT_SYMBOL(capi20_get_serial);
-
/**
* capi20_get_profile() - CAPI 2.0 operation CAPI_GET_PROFILE
* @contr: controller number.
@@ -974,209 +843,6 @@ u16 capi20_get_profile(u32 contr, struct capi_profile *profp)
return ret;
}
-EXPORT_SYMBOL(capi20_get_profile);
-
-/* Must be called with capi_controller_lock held. */
-static int wait_on_ctr_state(struct capi_ctr *ctr, unsigned int state)
-{
- DEFINE_WAIT(wait);
- int retval = 0;
-
- ctr = capi_ctr_get(ctr);
- if (!ctr)
- return -ESRCH;
-
- for (;;) {
- prepare_to_wait(&ctr->state_wait_queue, &wait,
- TASK_INTERRUPTIBLE);
-
- if (ctr->state == state)
- break;
- if (ctr->state == CAPI_CTR_DETACHED) {
- retval = -ESRCH;
- break;
- }
- if (signal_pending(current)) {
- retval = -EINTR;
- break;
- }
-
- mutex_unlock(&capi_controller_lock);
- schedule();
- mutex_lock(&capi_controller_lock);
- }
- finish_wait(&ctr->state_wait_queue, &wait);
-
- capi_ctr_put(ctr);
-
- return retval;
-}
-
-#ifdef AVMB1_COMPAT
-static int old_capi_manufacturer(unsigned int cmd, void __user *data)
-{
- avmb1_loadandconfigdef ldef;
- avmb1_extcarddef cdef;
- avmb1_resetdef rdef;
- capicardparams cparams;
- struct capi_ctr *ctr;
- struct capi_driver *driver = NULL;
- capiloaddata ldata;
- struct list_head *l;
- int retval;
-
- switch (cmd) {
- case AVMB1_ADDCARD:
- case AVMB1_ADDCARD_WITH_TYPE:
- if (cmd == AVMB1_ADDCARD) {
- if ((retval = copy_from_user(&cdef, data,
- sizeof(avmb1_carddef))))
- return -EFAULT;
- cdef.cardtype = AVM_CARDTYPE_B1;
- cdef.cardnr = 0;
- } else {
- if ((retval = copy_from_user(&cdef, data,
- sizeof(avmb1_extcarddef))))
- return -EFAULT;
- }
- cparams.port = cdef.port;
- cparams.irq = cdef.irq;
- cparams.cardnr = cdef.cardnr;
-
- mutex_lock(&capi_drivers_lock);
-
- switch (cdef.cardtype) {
- case AVM_CARDTYPE_B1:
- list_for_each(l, &capi_drivers) {
- driver = list_entry(l, struct capi_driver, list);
- if (strcmp(driver->name, "b1isa") == 0)
- break;
- }
- break;
- case AVM_CARDTYPE_T1:
- list_for_each(l, &capi_drivers) {
- driver = list_entry(l, struct capi_driver, list);
- if (strcmp(driver->name, "t1isa") == 0)
- break;
- }
- break;
- default:
- driver = NULL;
- break;
- }
- if (!driver) {
- printk(KERN_ERR "kcapi: driver not loaded.\n");
- retval = -EIO;
- } else if (!driver->add_card) {
- printk(KERN_ERR "kcapi: driver has no add card function.\n");
- retval = -EIO;
- } else
- retval = driver->add_card(driver, &cparams);
-
- mutex_unlock(&capi_drivers_lock);
- return retval;
-
- case AVMB1_LOAD:
- case AVMB1_LOAD_AND_CONFIG:
-
- if (cmd == AVMB1_LOAD) {
- if (copy_from_user(&ldef, data,
- sizeof(avmb1_loaddef)))
- return -EFAULT;
- ldef.t4config.len = 0;
- ldef.t4config.data = NULL;
- } else {
- if (copy_from_user(&ldef, data,
- sizeof(avmb1_loadandconfigdef)))
- return -EFAULT;
- }
-
- mutex_lock(&capi_controller_lock);
-
- ctr = get_capi_ctr_by_nr(ldef.contr);
- if (!ctr) {
- retval = -EINVAL;
- goto load_unlock_out;
- }
-
- if (ctr->load_firmware == NULL) {
- printk(KERN_DEBUG "kcapi: load: no load function\n");
- retval = -ESRCH;
- goto load_unlock_out;
- }
-
- if (ldef.t4file.len <= 0) {
- printk(KERN_DEBUG "kcapi: load: invalid parameter: length of t4file is %d ?\n", ldef.t4file.len);
- retval = -EINVAL;
- goto load_unlock_out;
- }
- if (ldef.t4file.data == NULL) {
- printk(KERN_DEBUG "kcapi: load: invalid parameter: dataptr is 0\n");
- retval = -EINVAL;
- goto load_unlock_out;
- }
-
- ldata.firmware.user = 1;
- ldata.firmware.data = ldef.t4file.data;
- ldata.firmware.len = ldef.t4file.len;
- ldata.configuration.user = 1;
- ldata.configuration.data = ldef.t4config.data;
- ldata.configuration.len = ldef.t4config.len;
-
- if (ctr->state != CAPI_CTR_DETECTED) {
- printk(KERN_INFO "kcapi: load: contr=%d not in detect state\n", ldef.contr);
- retval = -EBUSY;
- goto load_unlock_out;
- }
- ctr->state = CAPI_CTR_LOADING;
-
- retval = ctr->load_firmware(ctr, &ldata);
- if (retval) {
- ctr->state = CAPI_CTR_DETECTED;
- goto load_unlock_out;
- }
-
- retval = wait_on_ctr_state(ctr, CAPI_CTR_RUNNING);
-
- load_unlock_out:
- mutex_unlock(&capi_controller_lock);
- return retval;
-
- case AVMB1_RESETCARD:
- if (copy_from_user(&rdef, data, sizeof(avmb1_resetdef)))
- return -EFAULT;
-
- retval = 0;
-
- mutex_lock(&capi_controller_lock);
-
- ctr = get_capi_ctr_by_nr(rdef.contr);
- if (!ctr) {
- retval = -ESRCH;
- goto reset_unlock_out;
- }
-
- if (ctr->state == CAPI_CTR_DETECTED)
- goto reset_unlock_out;
-
- if (ctr->reset_ctr == NULL) {
- printk(KERN_DEBUG "kcapi: reset: no reset function\n");
- retval = -ESRCH;
- goto reset_unlock_out;
- }
-
- ctr->reset_ctr(ctr);
-
- retval = wait_on_ctr_state(ctr, CAPI_CTR_DETECTED);
-
- reset_unlock_out:
- mutex_unlock(&capi_controller_lock);
- return retval;
- }
- return -EINVAL;
-}
-#endif
-
/**
* capi20_manufacturer() - CAPI 2.0 operation CAPI_MANUFACTURER
* @cmd: command.
@@ -1192,14 +858,6 @@ int capi20_manufacturer(unsigned long cmd, void __user *data)
int retval;
switch (cmd) {
-#ifdef AVMB1_COMPAT
- case AVMB1_LOAD:
- case AVMB1_LOAD_AND_CONFIG:
- case AVMB1_RESETCARD:
- case AVMB1_GET_CARDINFO:
- case AVMB1_REMOVECARD:
- return old_capi_manufacturer(cmd, data);
-#endif
case KCAPI_CMD_TRACE:
{
kcapi_flagdef fdef;
@@ -1222,43 +880,6 @@ int capi20_manufacturer(unsigned long cmd, void __user *data)
return retval;
}
- case KCAPI_CMD_ADDCARD:
- {
- struct list_head *l;
- struct capi_driver *driver = NULL;
- capicardparams cparams;
- kcapi_carddef cdef;
-
- if ((retval = copy_from_user(&cdef, data, sizeof(cdef))))
- return -EFAULT;
-
- cparams.port = cdef.port;
- cparams.irq = cdef.irq;
- cparams.membase = cdef.membase;
- cparams.cardnr = cdef.cardnr;
- cparams.cardtype = 0;
- cdef.driver[sizeof(cdef.driver) - 1] = 0;
-
- mutex_lock(&capi_drivers_lock);
-
- list_for_each(l, &capi_drivers) {
- driver = list_entry(l, struct capi_driver, list);
- if (strcmp(driver->name, cdef.driver) == 0)
- break;
- }
- if (driver == NULL) {
- printk(KERN_ERR "kcapi: driver \"%s\" not loaded.\n",
- cdef.driver);
- retval = -ESRCH;
- } else if (!driver->add_card) {
- printk(KERN_ERR "kcapi: driver \"%s\" has no add card function.\n", cdef.driver);
- retval = -EIO;
- } else
- retval = driver->add_card(driver, &cparams);
-
- mutex_unlock(&capi_drivers_lock);
- return retval;
- }
default:
printk(KERN_ERR "kcapi: manufacturer command %lu unknown.\n",
@@ -1269,8 +890,6 @@ int capi20_manufacturer(unsigned long cmd, void __user *data)
return -EINVAL;
}
-EXPORT_SYMBOL(capi20_manufacturer);
-
/* ------------------------------------------------------------- */
/* -------- Init & Cleanup ------------------------------------- */
/* ------------------------------------------------------------- */
@@ -1279,12 +898,7 @@ EXPORT_SYMBOL(capi20_manufacturer);
* init / exit functions
*/
-static struct notifier_block capictr_nb = {
- .notifier_call = notify_handler,
- .priority = INT_MAX,
-};
-
-static int __init kcapi_init(void)
+int __init kcapi_init(void)
{
int err;
@@ -1292,11 +906,8 @@ static int __init kcapi_init(void)
if (!kcapi_wq)
return -ENOMEM;
- register_capictr_notifier(&capictr_nb);
-
err = cdebug_init();
if (err) {
- unregister_capictr_notifier(&capictr_nb);
destroy_workqueue(kcapi_wq);
return err;
}
@@ -1305,14 +916,10 @@ static int __init kcapi_init(void)
return 0;
}
-static void __exit kcapi_exit(void)
+void kcapi_exit(void)
{
kcapi_proc_exit();
- unregister_capictr_notifier(&capictr_nb);
cdebug_exit();
destroy_workqueue(kcapi_wq);
}
-
-module_init(kcapi_init);
-module_exit(kcapi_exit);
diff --git a/drivers/isdn/capi/kcapi.h b/drivers/isdn/capi/kcapi.h
index 6d439f9a76b2..479623e1db2a 100644
--- a/drivers/isdn/capi/kcapi.h
+++ b/drivers/isdn/capi/kcapi.h
@@ -30,22 +30,153 @@ enum {
CAPI_CTR_RUNNING = 3,
};
-extern struct list_head capi_drivers;
-extern struct mutex capi_drivers_lock;
-
extern struct capi_ctr *capi_controller[CAPI_MAXCONTR];
extern struct mutex capi_controller_lock;
extern struct capi20_appl *capi_applications[CAPI_MAXAPPL];
-#ifdef CONFIG_PROC_FS
-
void kcapi_proc_init(void);
void kcapi_proc_exit(void);
-#else
+struct capi20_appl {
+ u16 applid;
+ capi_register_params rparam;
+ void (*recv_message)(struct capi20_appl *ap, struct sk_buff *skb);
+ void *private;
-static inline void kcapi_proc_init(void) { };
-static inline void kcapi_proc_exit(void) { };
+ /* 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;
+};
-#endif
+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/capi/kcapi_proc.c b/drivers/isdn/capi/kcapi_proc.c
index c94bd12c0f7c..eadbe59b3753 100644
--- a/drivers/isdn/capi/kcapi_proc.c
+++ b/drivers/isdn/capi/kcapi_proc.c
@@ -192,37 +192,15 @@ static const struct seq_operations seq_applstats_ops = {
// ---------------------------------------------------------------------------
-static void *capi_driver_start(struct seq_file *seq, loff_t *pos)
- __acquires(&capi_drivers_lock)
+/* /proc/capi/drivers is always empty */
+static ssize_t empty_read(struct file *file, char __user *buf,
+ size_t size, loff_t *off)
{
- mutex_lock(&capi_drivers_lock);
- return seq_list_start(&capi_drivers, *pos);
-}
-
-static void *capi_driver_next(struct seq_file *seq, void *v, loff_t *pos)
-{
- return seq_list_next(v, &capi_drivers, pos);
-}
-
-static void capi_driver_stop(struct seq_file *seq, void *v)
- __releases(&capi_drivers_lock)
-{
- mutex_unlock(&capi_drivers_lock);
-}
-
-static int capi_driver_show(struct seq_file *seq, void *v)
-{
- struct capi_driver *drv = list_entry(v, struct capi_driver, list);
-
- seq_printf(seq, "%-32s %s\n", drv->name, drv->revision);
return 0;
}
-static const struct seq_operations seq_capi_driver_ops = {
- .start = capi_driver_start,
- .next = capi_driver_next,
- .stop = capi_driver_stop,
- .show = capi_driver_show,
+static const struct file_operations empty_fops = {
+ .read = empty_read,
};
// ---------------------------------------------------------------------------
@@ -236,10 +214,10 @@ kcapi_proc_init(void)
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_seq("capi/driver", 0, NULL, &seq_capi_driver_ops);
+ proc_create("capi/driver", 0, NULL, &empty_fops);
}
-void __exit
+void
kcapi_proc_exit(void)
{
remove_proc_entry("capi/driver", NULL);
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index eaf753b70ec5..baccd7c883cc 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -42,10 +42,6 @@ source "drivers/staging/rtl8188eu/Kconfig"
source "drivers/staging/rts5208/Kconfig"
-source "drivers/staging/octeon/Kconfig"
-
-source "drivers/staging/octeon-usb/Kconfig"
-
source "drivers/staging/vt6655/Kconfig"
source "drivers/staging/vt6656/Kconfig"
@@ -116,8 +112,6 @@ source "drivers/staging/fieldbus/Kconfig"
source "drivers/staging/kpc2000/Kconfig"
-source "drivers/staging/isdn/Kconfig"
-
source "drivers/staging/wusbcore/Kconfig"
source "drivers/staging/uwb/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 0a4396c9067b..463aef6a18ef 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -12,8 +12,6 @@ obj-$(CONFIG_R8712U) += rtl8712/
obj-$(CONFIG_R8188EU) += rtl8188eu/
obj-$(CONFIG_RTS5208) += rts5208/
obj-$(CONFIG_NETLOGIC_XLR_NET) += netlogic/
-obj-$(CONFIG_OCTEON_ETHERNET) += octeon/
-obj-$(CONFIG_OCTEON_USB) += octeon-usb/
obj-$(CONFIG_VT6655) += vt6655/
obj-$(CONFIG_VT6656) += vt6656/
obj-$(CONFIG_VME_BUS) += vme/
@@ -48,7 +46,6 @@ obj-$(CONFIG_STAGING_GASKET_FRAMEWORK) += gasket/
obj-$(CONFIG_XIL_AXIS_FIFO) += axis-fifo/
obj-$(CONFIG_FIELDBUS_DEV) += fieldbus/
obj-$(CONFIG_KPC2000) += kpc2000/
-obj-$(CONFIG_ISDN_CAPI) += isdn/
obj-$(CONFIG_UWB) += uwb/
obj-$(CONFIG_USB_WUSB) += wusbcore/
obj-$(CONFIG_EXFAT_FS) += exfat/
diff --git a/drivers/staging/exfat/exfat_super.c b/drivers/staging/exfat/exfat_super.c
index 9f91853b189b..744344a2521c 100644
--- a/drivers/staging/exfat/exfat_super.c
+++ b/drivers/staging/exfat/exfat_super.c
@@ -1481,7 +1481,7 @@ static int ffsReadStat(struct inode *inode, struct dir_entry_t *info)
count = count_dos_name_entries(sb, &dir, TYPE_DIR);
if (count < 0) {
- ret = count; /* propogate error upward */
+ ret = count; /* propagate error upward */
goto out;
}
info->NumSubdirs = count;
@@ -1548,7 +1548,7 @@ static int ffsReadStat(struct inode *inode, struct dir_entry_t *info)
count = count_dos_name_entries(sb, &dir, TYPE_DIR);
if (count < 0) {
- ret = count; /* propogate error upward */
+ ret = count; /* propagate error upward */
goto out;
}
info->NumSubdirs += count;
diff --git a/drivers/staging/hp/hp100.c b/drivers/staging/hp/hp100.c
index 6ec78f5c602f..e2f0b58e5dfd 100644
--- a/drivers/staging/hp/hp100.c
+++ b/drivers/staging/hp/hp100.c
@@ -339,14 +339,11 @@ static __init int hp100_isa_probe1(struct net_device *dev, int ioaddr)
if (sig == NULL)
goto err;
- for (i = 0; i < ARRAY_SIZE(hp100_isa_tbl); i++) {
- if (!strcmp(hp100_isa_tbl[i], sig))
- break;
-
- }
+ i = match_string(hp100_isa_tbl, ARRAY_SIZE(hp100_isa_tbl), sig);
+ if (i < 0)
+ goto err;
- if (i < ARRAY_SIZE(hp100_isa_tbl))
- return hp100_probe1(dev, ioaddr, HP100_BUS_ISA, NULL);
+ return hp100_probe1(dev, ioaddr, HP100_BUS_ISA, NULL);
err:
return -ENODEV;
diff --git a/drivers/staging/isdn/Kconfig b/drivers/staging/isdn/Kconfig
deleted file mode 100644
index faaf63887094..000000000000
--- a/drivers/staging/isdn/Kconfig
+++ /dev/null
@@ -1,12 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-menu "ISDN CAPI drivers"
- depends on ISDN_CAPI
-
-source "drivers/staging/isdn/avm/Kconfig"
-
-source "drivers/staging/isdn/gigaset/Kconfig"
-
-source "drivers/staging/isdn/hysdn/Kconfig"
-
-endmenu
-
diff --git a/drivers/staging/isdn/Makefile b/drivers/staging/isdn/Makefile
deleted file mode 100644
index 025504bae5df..000000000000
--- a/drivers/staging/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_CAPI_AVM) += avm/
-obj-$(CONFIG_HYSDN) += hysdn/
-obj-$(CONFIG_ISDN_DRV_GIGASET) += gigaset/
diff --git a/drivers/staging/isdn/TODO b/drivers/staging/isdn/TODO
deleted file mode 100644
index 9210d11eb68b..000000000000
--- a/drivers/staging/isdn/TODO
+++ /dev/null
@@ -1,22 +0,0 @@
-TODO: Remove in late 2019 unless there are users
-
-
-I tried to find any indication of whether the capi drivers are
-still in use, and have not found anything from a long time ago.
-
-With public ISDN networks almost completely shut down over the past 12
-months, there is very little you can actually do with this hardware. The
-main remaining use case would be to connect ISDN voice phones to an
-in-house installation with Asterisk or LCR, but anyone trying this in
-turn seems to be using either the mISDN driver stack, or out-of-tree
-drivers from the hardware vendors.
-
-I may of course have missed something, so I would suggest moving
-these into drivers/staging/ just in case someone still uses one
-of the three remaining in-kernel drivers (avm, hysdn, gigaset).
-
-If nobody complains, we can remove them entirely in six months,
-or otherwise move the core code and any drivers that are still
-needed back into drivers/isdn.
-
- Arnd Bergmann <arnd@arndb.de>
diff --git a/drivers/staging/isdn/avm/Kconfig b/drivers/staging/isdn/avm/Kconfig
deleted file mode 100644
index 81483db067bb..000000000000
--- a/drivers/staging/isdn/avm/Kconfig
+++ /dev/null
@@ -1,65 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# ISDN AVM drivers
-#
-
-menuconfig CAPI_AVM
- bool "Active AVM cards"
- help
- Enable support for AVM active ISDN cards.
-
-if CAPI_AVM
-
-config ISDN_DRV_AVMB1_B1ISA
- tristate "AVM B1 ISA support"
- depends on ISA
- help
- Enable support for the ISA version of the AVM B1 card.
-
-config ISDN_DRV_AVMB1_B1PCI
- tristate "AVM B1 PCI support"
- depends on PCI
- help
- Enable support for the PCI version of the AVM B1 card.
-
-config ISDN_DRV_AVMB1_B1PCIV4
- bool "AVM B1 PCI V4 support"
- depends on ISDN_DRV_AVMB1_B1PCI
- help
- Enable support for the V4 version of AVM B1 PCI card.
-
-config ISDN_DRV_AVMB1_T1ISA
- tristate "AVM T1/T1-B ISA support"
- depends on ISA
- help
- Enable support for the AVM T1 T1B card.
- Note: This is a PRI card and handle 30 B-channels.
-
-config ISDN_DRV_AVMB1_B1PCMCIA
- tristate "AVM B1/M1/M2 PCMCIA support"
- depends on PCMCIA
- help
- Enable support for the PCMCIA version of the AVM B1 card.
-
-config ISDN_DRV_AVMB1_AVM_CS
- tristate "AVM B1/M1/M2 PCMCIA cs module"
- depends on ISDN_DRV_AVMB1_B1PCMCIA
- help
- Enable the PCMCIA client driver for the AVM B1/M1/M2
- PCMCIA cards.
-
-config ISDN_DRV_AVMB1_T1PCI
- tristate "AVM T1/T1-B PCI support"
- depends on PCI
- help
- Enable support for the AVM T1 T1B card.
- Note: This is a PRI card and handle 30 B-channels.
-
-config ISDN_DRV_AVMB1_C4
- tristate "AVM C4/C2 support"
- depends on PCI
- help
- Enable support for the AVM C4/C2 PCI cards.
- These cards handle 4/2 BRI ISDN lines (8/4 channels).
-
-endif # CAPI_AVM
diff --git a/drivers/staging/isdn/avm/Makefile b/drivers/staging/isdn/avm/Makefile
deleted file mode 100644
index 3830a0573fcc..000000000000
--- a/drivers/staging/isdn/avm/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-# Makefile for the AVM ISDN device drivers
-
-# Each configuration option enables a list of files.
-
-obj-$(CONFIG_ISDN_DRV_AVMB1_B1ISA) += b1isa.o b1.o
-obj-$(CONFIG_ISDN_DRV_AVMB1_B1PCI) += b1pci.o b1.o b1dma.o
-obj-$(CONFIG_ISDN_DRV_AVMB1_B1PCMCIA) += b1pcmcia.o b1.o
-obj-$(CONFIG_ISDN_DRV_AVMB1_AVM_CS) += avm_cs.o
-obj-$(CONFIG_ISDN_DRV_AVMB1_T1ISA) += t1isa.o b1.o
-obj-$(CONFIG_ISDN_DRV_AVMB1_T1PCI) += t1pci.o b1.o b1dma.o
-obj-$(CONFIG_ISDN_DRV_AVMB1_C4) += c4.o b1.o
diff --git a/drivers/staging/isdn/avm/avm_cs.c b/drivers/staging/isdn/avm/avm_cs.c
deleted file mode 100644
index 62b8030ee331..000000000000
--- a/drivers/staging/isdn/avm/avm_cs.c
+++ /dev/null
@@ -1,166 +0,0 @@
-/* $Id: avm_cs.c,v 1.4.6.3 2001/09/23 22:24:33 kai Exp $
- *
- * A PCMCIA client driver for AVM B1/M1/M2
- *
- * 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.
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/ptrace.h>
-#include <linux/string.h>
-#include <linux/tty.h>
-#include <linux/serial.h>
-#include <linux/major.h>
-#include <asm/io.h>
-
-#include <pcmcia/cistpl.h>
-#include <pcmcia/ciscode.h>
-#include <pcmcia/ds.h>
-#include <pcmcia/cisreg.h>
-
-#include <linux/skbuff.h>
-#include <linux/capi.h>
-#include <linux/b1lli.h>
-#include <linux/b1pcmcia.h>
-
-/*====================================================================*/
-
-MODULE_DESCRIPTION("CAPI4Linux: PCMCIA client driver for AVM B1/M1/M2");
-MODULE_AUTHOR("Carsten Paeth");
-MODULE_LICENSE("GPL");
-
-/*====================================================================*/
-
-static int avmcs_config(struct pcmcia_device *link);
-static void avmcs_release(struct pcmcia_device *link);
-static void avmcs_detach(struct pcmcia_device *p_dev);
-
-static int avmcs_probe(struct pcmcia_device *p_dev)
-{
- /* General socket configuration */
- p_dev->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
- p_dev->config_index = 1;
- p_dev->config_regs = PRESENT_OPTION;
-
- return avmcs_config(p_dev);
-} /* avmcs_attach */
-
-
-static void avmcs_detach(struct pcmcia_device *link)
-{
- avmcs_release(link);
-} /* avmcs_detach */
-
-static int avmcs_configcheck(struct pcmcia_device *p_dev, void *priv_data)
-{
- p_dev->resource[0]->end = 16;
- p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
- p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
-
- return pcmcia_request_io(p_dev);
-}
-
-static int avmcs_config(struct pcmcia_device *link)
-{
- int i = -1;
- char devname[128];
- int cardtype;
- int (*addcard)(unsigned int port, unsigned irq);
-
- devname[0] = 0;
- if (link->prod_id[1])
- strlcpy(devname, link->prod_id[1], sizeof(devname));
-
- /*
- * find IO port
- */
- if (pcmcia_loop_config(link, avmcs_configcheck, NULL))
- return -ENODEV;
-
- do {
- if (!link->irq) {
- /* undo */
- pcmcia_disable_device(link);
- break;
- }
-
- /*
- * configure the PCMCIA socket
- */
- i = pcmcia_enable_device(link);
- if (i != 0) {
- pcmcia_disable_device(link);
- break;
- }
-
- } while (0);
-
- if (devname[0]) {
- char *s = strrchr(devname, ' ');
- if (!s)
- s = devname;
- else s++;
- if (strcmp("M1", s) == 0) {
- cardtype = AVM_CARDTYPE_M1;
- } else if (strcmp("M2", s) == 0) {
- cardtype = AVM_CARDTYPE_M2;
- } else {
- cardtype = AVM_CARDTYPE_B1;
- }
- } else
- cardtype = AVM_CARDTYPE_B1;
-
- /* If any step failed, release any partially configured state */
- if (i != 0) {
- avmcs_release(link);
- return -ENODEV;
- }
-
-
- switch (cardtype) {
- case AVM_CARDTYPE_M1: addcard = b1pcmcia_addcard_m1; break;
- case AVM_CARDTYPE_M2: addcard = b1pcmcia_addcard_m2; break;
- default:
- case AVM_CARDTYPE_B1: addcard = b1pcmcia_addcard_b1; break;
- }
- if ((i = (*addcard)(link->resource[0]->start, link->irq)) < 0) {
- dev_err(&link->dev,
- "avm_cs: failed to add AVM-Controller at i/o %#x, irq %d\n",
- (unsigned int) link->resource[0]->start, link->irq);
- avmcs_release(link);
- return -ENODEV;
- }
- return 0;
-
-} /* avmcs_config */
-
-
-static void avmcs_release(struct pcmcia_device *link)
-{
- b1pcmcia_delcard(link->resource[0]->start, link->irq);
- pcmcia_disable_device(link);
-} /* avmcs_release */
-
-
-static const struct pcmcia_device_id avmcs_ids[] = {
- PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN-Controller B1", 0x95d42008, 0x845dc335),
- PCMCIA_DEVICE_PROD_ID12("AVM", "Mobile ISDN-Controller M1", 0x95d42008, 0x81e10430),
- PCMCIA_DEVICE_PROD_ID12("AVM", "Mobile ISDN-Controller M2", 0x95d42008, 0x18e8558a),
- PCMCIA_DEVICE_NULL
-};
-MODULE_DEVICE_TABLE(pcmcia, avmcs_ids);
-
-static struct pcmcia_driver avmcs_driver = {
- .owner = THIS_MODULE,
- .name = "avm_cs",
- .probe = avmcs_probe,
- .remove = avmcs_detach,
- .id_table = avmcs_ids,
-};
-module_pcmcia_driver(avmcs_driver);
diff --git a/drivers/staging/isdn/avm/avmcard.h b/drivers/staging/isdn/avm/avmcard.h
deleted file mode 100644
index cdfa89c71997..000000000000
--- a/drivers/staging/isdn/avm/avmcard.h
+++ /dev/null
@@ -1,581 +0,0 @@
-/* $Id: avmcard.h,v 1.1.4.1.2.1 2001/12/21 15:00:17 kai Exp $
- *
- * 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 _AVMCARD_H_
-#define _AVMCARD_H_
-
-#include <linux/spinlock.h>
-#include <linux/list.h>
-#include <linux/interrupt.h>
-
-#define AVMB1_PORTLEN 0x1f
-#define AVM_MAXVERSION 8
-#define AVM_NCCI_PER_CHANNEL 4
-
-/*
- * Versions
- */
-
-#define VER_DRIVER 0
-#define VER_CARDTYPE 1
-#define VER_HWID 2
-#define VER_SERIAL 3
-#define VER_OPTION 4
-#define VER_PROTO 5
-#define VER_PROFILE 6
-#define VER_CAPI 7
-
-enum avmcardtype {
- avm_b1isa,
- avm_b1pci,
- avm_b1pcmcia,
- avm_m1,
- avm_m2,
- avm_t1isa,
- avm_t1pci,
- avm_c4,
- avm_c2
-};
-
-typedef struct avmcard_dmabuf {
- long size;
- u8 *dmabuf;
- dma_addr_t dmaaddr;
-} avmcard_dmabuf;
-
-typedef struct avmcard_dmainfo {
- u32 recvlen;
- avmcard_dmabuf recvbuf;
-
- avmcard_dmabuf sendbuf;
- struct sk_buff_head send_queue;
-
- struct pci_dev *pcidev;
-} avmcard_dmainfo;
-
-typedef struct avmctrl_info {
- char cardname[32];
-
- int versionlen;
- char versionbuf[1024];
- char *version[AVM_MAXVERSION];
-
- char infobuf[128]; /* for function procinfo */
-
- struct avmcard *card;
- struct capi_ctr capi_ctrl;
-
- struct list_head ncci_head;
-} avmctrl_info;
-
-typedef struct avmcard {
- char name[32];
-
- spinlock_t lock;
- unsigned int port;
- unsigned irq;
- unsigned long membase;
- enum avmcardtype cardtype;
- unsigned char revision;
- unsigned char class;
- int cardnr; /* for t1isa */
-
- char msgbuf[128]; /* capimsg msg part */
- char databuf[2048]; /* capimsg data part */
-
- void __iomem *mbase;
- volatile u32 csr;
- avmcard_dmainfo *dma;
-
- struct avmctrl_info *ctrlinfo;
-
- u_int nr_controllers;
- u_int nlogcontr;
- struct list_head list;
-} avmcard;
-
-extern int b1_irq_table[16];
-
-/*
- * LLI Messages to the ISDN-ControllerISDN Controller
- */
-
-#define SEND_POLL 0x72 /*
- * after load <- RECEIVE_POLL
- */
-#define SEND_INIT 0x11 /*
- * first message <- RECEIVE_INIT
- * int32 NumApplications int32
- * NumNCCIs int32 BoardNumber
- */
-#define SEND_REGISTER 0x12 /*
- * register an application int32
- * ApplIDId int32 NumMessages
- * int32 NumB3Connections int32
- * NumB3Blocks int32 B3Size
- *
- * AnzB3Connection != 0 &&
- * AnzB3Blocks >= 1 && B3Size >= 1
- */
-#define SEND_RELEASE 0x14 /*
- * deregister an application int32
- * ApplID
- */
-#define SEND_MESSAGE 0x15 /*
- * send capi-message int32 length
- * capi-data ...
- */
-#define SEND_DATA_B3_REQ 0x13 /*
- * send capi-data-message int32
- * MsgLength capi-data ... int32
- * B3Length data ....
- */
-
-#define SEND_CONFIG 0x21 /*
- */
-
-#define SEND_POLLACK 0x73 /* T1 Watchdog */
-
-/*
- * LLI Messages from the ISDN-ControllerISDN Controller
- */
-
-#define RECEIVE_POLL 0x32 /*
- * <- after SEND_POLL
- */
-#define RECEIVE_INIT 0x27 /*
- * <- after SEND_INIT int32 length
- * byte total length b1struct board
- * driver revision b1struct card
- * type b1struct reserved b1struct
- * serial number b1struct driver
- * capability b1struct d-channel
- * protocol b1struct CAPI-2.0
- * profile b1struct capi version
- */
-#define RECEIVE_MESSAGE 0x21 /*
- * <- after SEND_MESSAGE int32
- * AppllID int32 Length capi-data
- * ....
- */
-#define RECEIVE_DATA_B3_IND 0x22 /*
- * received data int32 AppllID
- * int32 Length capi-data ...
- * int32 B3Length data ...
- */
-#define RECEIVE_START 0x23 /*
- * Handshake
- */
-#define RECEIVE_STOP 0x24 /*
- * Handshake
- */
-#define RECEIVE_NEW_NCCI 0x25 /*
- * int32 AppllID int32 NCCI int32
- * WindowSize
- */
-#define RECEIVE_FREE_NCCI 0x26 /*
- * int32 AppllID int32 NCCI
- */
-#define RECEIVE_RELEASE 0x26 /*
- * int32 AppllID int32 0xffffffff
- */
-#define RECEIVE_TASK_READY 0x31 /*
- * int32 tasknr
- * int32 Length Taskname ...
- */
-#define RECEIVE_DEBUGMSG 0x71 /*
- * int32 Length message
- *
- */
-#define RECEIVE_POLLDWORD 0x75 /* t1pci in dword mode */
-
-#define WRITE_REGISTER 0x00
-#define READ_REGISTER 0x01
-
-/*
- * port offsets
- */
-
-#define B1_READ 0x00
-#define B1_WRITE 0x01
-#define B1_INSTAT 0x02
-#define B1_OUTSTAT 0x03
-#define B1_ANALYSE 0x04
-#define B1_REVISION 0x05
-#define B1_RESET 0x10
-
-
-#define B1_STAT0(cardtype) ((cardtype) == avm_m1 ? 0x81200000l : 0x80A00000l)
-#define B1_STAT1(cardtype) (0x80E00000l)
-
-/* ---------------------------------------------------------------- */
-
-static inline unsigned char b1outp(unsigned int base,
- unsigned short offset,
- unsigned char value)
-{
- outb(value, base + offset);
- return inb(base + B1_ANALYSE);
-}
-
-
-static inline int b1_rx_full(unsigned int base)
-{
- return inb(base + B1_INSTAT) & 0x1;
-}
-
-static inline unsigned char b1_get_byte(unsigned int base)
-{
- unsigned long stop = jiffies + 1 * HZ; /* maximum wait time 1 sec */
- while (!b1_rx_full(base) && time_before(jiffies, stop));
- if (b1_rx_full(base))
- return inb(base + B1_READ);
- printk(KERN_CRIT "b1lli(0x%x): rx not full after 1 second\n", base);
- return 0;
-}
-
-static inline unsigned int b1_get_word(unsigned int base)
-{
- unsigned int val = 0;
- val |= b1_get_byte(base);
- val |= (b1_get_byte(base) << 8);
- val |= (b1_get_byte(base) << 16);
- val |= (b1_get_byte(base) << 24);
- return val;
-}
-
-static inline int b1_tx_empty(unsigned int base)
-{
- return inb(base + B1_OUTSTAT) & 0x1;
-}
-
-static inline void b1_put_byte(unsigned int base, unsigned char val)
-{
- while (!b1_tx_empty(base));
- b1outp(base, B1_WRITE, val);
-}
-
-static inline int b1_save_put_byte(unsigned int base, unsigned char val)
-{
- unsigned long stop = jiffies + 2 * HZ;
- while (!b1_tx_empty(base) && time_before(jiffies, stop));
- if (!b1_tx_empty(base)) return -1;
- b1outp(base, B1_WRITE, val);
- return 0;
-}
-
-static inline void b1_put_word(unsigned int base, unsigned int val)
-{
- b1_put_byte(base, val & 0xff);
- b1_put_byte(base, (val >> 8) & 0xff);
- b1_put_byte(base, (val >> 16) & 0xff);
- b1_put_byte(base, (val >> 24) & 0xff);
-}
-
-static inline unsigned int b1_get_slice(unsigned int base,
- unsigned char *dp)
-{
- unsigned int len, i;
-
- len = i = b1_get_word(base);
- while (i-- > 0) *dp++ = b1_get_byte(base);
- return len;
-}
-
-static inline void b1_put_slice(unsigned int base,
- unsigned char *dp, unsigned int len)
-{
- unsigned i = len;
- b1_put_word(base, i);
- while (i-- > 0)
- b1_put_byte(base, *dp++);
-}
-
-static void b1_wr_reg(unsigned int base,
- unsigned int reg,
- unsigned int value)
-{
- b1_put_byte(base, WRITE_REGISTER);
- b1_put_word(base, reg);
- b1_put_word(base, value);
-}
-
-static inline unsigned int b1_rd_reg(unsigned int base,
- unsigned int reg)
-{
- b1_put_byte(base, READ_REGISTER);
- b1_put_word(base, reg);
- return b1_get_word(base);
-
-}
-
-static inline void b1_reset(unsigned int base)
-{
- b1outp(base, B1_RESET, 0);
- mdelay(55 * 2); /* 2 TIC's */
-
- b1outp(base, B1_RESET, 1);
- mdelay(55 * 2); /* 2 TIC's */
-
- b1outp(base, B1_RESET, 0);
- mdelay(55 * 2); /* 2 TIC's */
-}
-
-static inline unsigned char b1_disable_irq(unsigned int base)
-{
- return b1outp(base, B1_INSTAT, 0x00);
-}
-
-/* ---------------------------------------------------------------- */
-
-static inline void b1_set_test_bit(unsigned int base,
- enum avmcardtype cardtype,
- int onoff)
-{
- b1_wr_reg(base, B1_STAT0(cardtype), onoff ? 0x21 : 0x20);
-}
-
-static inline int b1_get_test_bit(unsigned int base,
- enum avmcardtype cardtype)
-{
- return (b1_rd_reg(base, B1_STAT0(cardtype)) & 0x01) != 0;
-}
-
-/* ---------------------------------------------------------------- */
-
-#define T1_FASTLINK 0x00
-#define T1_SLOWLINK 0x08
-
-#define T1_READ B1_READ
-#define T1_WRITE B1_WRITE
-#define T1_INSTAT B1_INSTAT
-#define T1_OUTSTAT B1_OUTSTAT
-#define T1_IRQENABLE 0x05
-#define T1_FIFOSTAT 0x06
-#define T1_RESETLINK 0x10
-#define T1_ANALYSE 0x11
-#define T1_IRQMASTER 0x12
-#define T1_IDENT 0x17
-#define T1_RESETBOARD 0x1f
-
-#define T1F_IREADY 0x01
-#define T1F_IHALF 0x02
-#define T1F_IFULL 0x04
-#define T1F_IEMPTY 0x08
-#define T1F_IFLAGS 0xF0
-
-#define T1F_OREADY 0x10
-#define T1F_OHALF 0x20
-#define T1F_OEMPTY 0x40
-#define T1F_OFULL 0x80
-#define T1F_OFLAGS 0xF0
-
-/* there are HEMA cards with 1k and 4k FIFO out */
-#define FIFO_OUTBSIZE 256
-#define FIFO_INPBSIZE 512
-
-#define HEMA_VERSION_ID 0
-#define HEMA_PAL_ID 0
-
-static inline void t1outp(unsigned int base,
- unsigned short offset,
- unsigned char value)
-{
- outb(value, base + offset);
-}
-
-static inline unsigned char t1inp(unsigned int base,
- unsigned short offset)
-{
- return inb(base + offset);
-}
-
-static inline int t1_isfastlink(unsigned int base)
-{
- return (inb(base + T1_IDENT) & ~0x82) == 1;
-}
-
-static inline unsigned char t1_fifostatus(unsigned int base)
-{
- return inb(base + T1_FIFOSTAT);
-}
-
-static inline unsigned int t1_get_slice(unsigned int base,
- unsigned char *dp)
-{
- unsigned int len, i;
-#ifdef FASTLINK_DEBUG
- unsigned wcnt = 0, bcnt = 0;
-#endif
-
- len = i = b1_get_word(base);
- if (t1_isfastlink(base)) {
- int status;
- while (i > 0) {
- status = t1_fifostatus(base) & (T1F_IREADY | T1F_IHALF);
- if (i >= FIFO_INPBSIZE) status |= T1F_IFULL;
-
- switch (status) {
- case T1F_IREADY | T1F_IHALF | T1F_IFULL:
- insb(base + B1_READ, dp, FIFO_INPBSIZE);
- dp += FIFO_INPBSIZE;
- i -= FIFO_INPBSIZE;
-#ifdef FASTLINK_DEBUG
- wcnt += FIFO_INPBSIZE;
-#endif
- break;
- case T1F_IREADY | T1F_IHALF:
- insb(base + B1_READ, dp, i);
-#ifdef FASTLINK_DEBUG
- wcnt += i;
-#endif
- dp += i;
- i = 0;
- break;
- default:
- *dp++ = b1_get_byte(base);
- i--;
-#ifdef FASTLINK_DEBUG
- bcnt++;
-#endif
- break;
- }
- }
-#ifdef FASTLINK_DEBUG
- if (wcnt)
- printk(KERN_DEBUG "b1lli(0x%x): get_slice l=%d w=%d b=%d\n",
- base, len, wcnt, bcnt);
-#endif
- } else {
- while (i-- > 0)
- *dp++ = b1_get_byte(base);
- }
- return len;
-}
-
-static inline void t1_put_slice(unsigned int base,
- unsigned char *dp, unsigned int len)
-{
- unsigned i = len;
- b1_put_word(base, i);
- if (t1_isfastlink(base)) {
- int status;
- while (i > 0) {
- status = t1_fifostatus(base) & (T1F_OREADY | T1F_OHALF);
- if (i >= FIFO_OUTBSIZE) status |= T1F_OEMPTY;
- switch (status) {
- case T1F_OREADY | T1F_OHALF | T1F_OEMPTY:
- outsb(base + B1_WRITE, dp, FIFO_OUTBSIZE);
- dp += FIFO_OUTBSIZE;
- i -= FIFO_OUTBSIZE;
- break;
- case T1F_OREADY | T1F_OHALF:
- outsb(base + B1_WRITE, dp, i);
- dp += i;
- i = 0;
- break;
- default:
- b1_put_byte(base, *dp++);
- i--;
- break;
- }
- }
- } else {
- while (i-- > 0)
- b1_put_byte(base, *dp++);
- }
-}
-
-static inline void t1_disable_irq(unsigned int base)
-{
- t1outp(base, T1_IRQMASTER, 0x00);
-}
-
-static inline void t1_reset(unsigned int base)
-{
- /* reset T1 Controller */
- b1_reset(base);
- /* disable irq on HEMA */
- t1outp(base, B1_INSTAT, 0x00);
- t1outp(base, B1_OUTSTAT, 0x00);
- t1outp(base, T1_IRQMASTER, 0x00);
- /* reset HEMA board configuration */
- t1outp(base, T1_RESETBOARD, 0xf);
-}
-
-static inline void b1_setinterrupt(unsigned int base, unsigned irq,
- enum avmcardtype cardtype)
-{
- switch (cardtype) {
- case avm_t1isa:
- t1outp(base, B1_INSTAT, 0x00);
- t1outp(base, B1_INSTAT, 0x02);
- t1outp(base, T1_IRQMASTER, 0x08);
- break;
- case avm_b1isa:
- b1outp(base, B1_INSTAT, 0x00);
- b1outp(base, B1_RESET, b1_irq_table[irq]);
- b1outp(base, B1_INSTAT, 0x02);
- break;
- default:
- case avm_m1:
- case avm_m2:
- case avm_b1pci:
- b1outp(base, B1_INSTAT, 0x00);
- b1outp(base, B1_RESET, 0xf0);
- b1outp(base, B1_INSTAT, 0x02);
- break;
- case avm_c4:
- case avm_t1pci:
- b1outp(base, B1_RESET, 0xf0);
- break;
- }
-}
-
-/* b1.c */
-avmcard *b1_alloc_card(int nr_controllers);
-void b1_free_card(avmcard *card);
-int b1_detect(unsigned int base, enum avmcardtype cardtype);
-void b1_getrevision(avmcard *card);
-int b1_load_t4file(avmcard *card, capiloaddatapart *t4file);
-int b1_load_config(avmcard *card, capiloaddatapart *config);
-int b1_loaded(avmcard *card);
-
-int b1_load_firmware(struct capi_ctr *ctrl, capiloaddata *data);
-void b1_reset_ctr(struct capi_ctr *ctrl);
-void b1_register_appl(struct capi_ctr *ctrl, u16 appl,
- capi_register_params *rp);
-void b1_release_appl(struct capi_ctr *ctrl, u16 appl);
-u16 b1_send_message(struct capi_ctr *ctrl, struct sk_buff *skb);
-void b1_parse_version(avmctrl_info *card);
-irqreturn_t b1_interrupt(int interrupt, void *devptr);
-
-int b1_proc_show(struct seq_file *m, void *v);
-
-avmcard_dmainfo *avmcard_dma_alloc(char *name, struct pci_dev *,
- long rsize, long ssize);
-void avmcard_dma_free(avmcard_dmainfo *);
-
-/* b1dma.c */
-int b1pciv4_detect(avmcard *card);
-int t1pci_detect(avmcard *card);
-void b1dma_reset(avmcard *card);
-irqreturn_t b1dma_interrupt(int interrupt, void *devptr);
-
-int b1dma_load_firmware(struct capi_ctr *ctrl, capiloaddata *data);
-void b1dma_reset_ctr(struct capi_ctr *ctrl);
-void b1dma_remove_ctr(struct capi_ctr *ctrl);
-void b1dma_register_appl(struct capi_ctr *ctrl,
- u16 appl,
- capi_register_params *rp);
-void b1dma_release_appl(struct capi_ctr *ctrl, u16 appl);
-u16 b1dma_send_message(struct capi_ctr *ctrl, struct sk_buff *skb);
-int b1dma_proc_show(struct seq_file *m, void *v);
-
-#endif /* _AVMCARD_H_ */
diff --git a/drivers/staging/isdn/avm/b1.c b/drivers/staging/isdn/avm/b1.c
deleted file mode 100644
index 32ec8cf31fd0..000000000000
--- a/drivers/staging/isdn/avm/b1.c
+++ /dev/null
@@ -1,819 +0,0 @@
-/* $Id: b1.c,v 1.1.2.2 2004/01/16 21:09:27 keil Exp $
- *
- * Common module for AVM B1 cards.
- *
- * 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.
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/skbuff.h>
-#include <linux/delay.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/capi.h>
-#include <linux/kernelcapi.h>
-#include <linux/slab.h>
-#include <asm/io.h>
-#include <linux/init.h>
-#include <linux/uaccess.h>
-#include <linux/netdevice.h>
-#include <linux/isdn/capilli.h>
-#include "avmcard.h"
-#include <linux/isdn/capicmd.h>
-#include <linux/isdn/capiutil.h>
-
-static char *revision = "$Revision: 1.1.2.2 $";
-
-/* ------------------------------------------------------------- */
-
-MODULE_DESCRIPTION("CAPI4Linux: Common support for active AVM cards");
-MODULE_AUTHOR("Carsten Paeth");
-MODULE_LICENSE("GPL");
-
-/* ------------------------------------------------------------- */
-
-int b1_irq_table[16] =
-{0,
- 0,
- 0,
- 192, /* irq 3 */
- 32, /* irq 4 */
- 160, /* irq 5 */
- 96, /* irq 6 */
- 224, /* irq 7 */
- 0,
- 64, /* irq 9 */
- 80, /* irq 10 */
- 208, /* irq 11 */
- 48, /* irq 12 */
- 0,
- 0,
- 112, /* irq 15 */
-};
-
-/* ------------------------------------------------------------- */
-
-avmcard *b1_alloc_card(int nr_controllers)
-{
- avmcard *card;
- avmctrl_info *cinfo;
- int i;
-
- card = kzalloc(sizeof(*card), GFP_KERNEL);
- if (!card)
- return NULL;
-
- cinfo = kcalloc(nr_controllers, sizeof(*cinfo), GFP_KERNEL);
- if (!cinfo) {
- kfree(card);
- return NULL;
- }
-
- card->ctrlinfo = cinfo;
- for (i = 0; i < nr_controllers; i++) {
- INIT_LIST_HEAD(&cinfo[i].ncci_head);
- cinfo[i].card = card;
- }
- spin_lock_init(&card->lock);
- card->nr_controllers = nr_controllers;
-
- return card;
-}
-
-/* ------------------------------------------------------------- */
-
-void b1_free_card(avmcard *card)
-{
- kfree(card->ctrlinfo);
- kfree(card);
-}
-
-/* ------------------------------------------------------------- */
-
-int b1_detect(unsigned int base, enum avmcardtype cardtype)
-{
- int onoff, i;
-
- /*
- * Statusregister 0000 00xx
- */
- if ((inb(base + B1_INSTAT) & 0xfc)
- || (inb(base + B1_OUTSTAT) & 0xfc))
- return 1;
- /*
- * Statusregister 0000 001x
- */
- b1outp(base, B1_INSTAT, 0x2); /* enable irq */
- /* b1outp(base, B1_OUTSTAT, 0x2); */
- if ((inb(base + B1_INSTAT) & 0xfe) != 0x2
- /* || (inb(base + B1_OUTSTAT) & 0xfe) != 0x2 */)
- return 2;
- /*
- * Statusregister 0000 000x
- */
- b1outp(base, B1_INSTAT, 0x0); /* disable irq */
- b1outp(base, B1_OUTSTAT, 0x0);
- if ((inb(base + B1_INSTAT) & 0xfe)
- || (inb(base + B1_OUTSTAT) & 0xfe))
- return 3;
-
- for (onoff = !0, i = 0; i < 10; i++) {
- b1_set_test_bit(base, cardtype, onoff);
- if (b1_get_test_bit(base, cardtype) != onoff)
- return 4;
- onoff = !onoff;
- }
-
- if (cardtype == avm_m1)
- return 0;
-
- if ((b1_rd_reg(base, B1_STAT1(cardtype)) & 0x0f) != 0x01)
- return 5;
-
- return 0;
-}
-
-void b1_getrevision(avmcard *card)
-{
- card->class = inb(card->port + B1_ANALYSE);
- card->revision = inb(card->port + B1_REVISION);
-}
-
-#define FWBUF_SIZE 256
-int b1_load_t4file(avmcard *card, capiloaddatapart *t4file)
-{
- unsigned char buf[FWBUF_SIZE];
- unsigned char *dp;
- int i, left;
- unsigned int base = card->port;
-
- dp = t4file->data;
- left = t4file->len;
- while (left > FWBUF_SIZE) {
- if (t4file->user) {
- if (copy_from_user(buf, dp, FWBUF_SIZE))
- return -EFAULT;
- } else {
- memcpy(buf, dp, FWBUF_SIZE);
- }
- for (i = 0; i < FWBUF_SIZE; i++)
- if (b1_save_put_byte(base, buf[i]) < 0) {
- printk(KERN_ERR "%s: corrupted firmware file ?\n",
- card->name);
- return -EIO;
- }
- left -= FWBUF_SIZE;
- dp += FWBUF_SIZE;
- }
- if (left) {
- if (t4file->user) {
- if (copy_from_user(buf, dp, left))
- return -EFAULT;
- } else {
- memcpy(buf, dp, left);
- }
- for (i = 0; i < left; i++)
- if (b1_save_put_byte(base, buf[i]) < 0) {
- printk(KERN_ERR "%s: corrupted firmware file ?\n",
- card->name);
- return -EIO;
- }
- }
- return 0;
-}
-
-int b1_load_config(avmcard *card, capiloaddatapart *config)
-{
- unsigned char buf[FWBUF_SIZE];
- unsigned char *dp;
- unsigned int base = card->port;
- int i, j, left;
-
- dp = config->data;
- left = config->len;
- if (left) {
- b1_put_byte(base, SEND_CONFIG);
- b1_put_word(base, 1);
- b1_put_byte(base, SEND_CONFIG);
- b1_put_word(base, left);
- }
- while (left > FWBUF_SIZE) {
- if (config->user) {
- if (copy_from_user(buf, dp, FWBUF_SIZE))
- return -EFAULT;
- } else {
- memcpy(buf, dp, FWBUF_SIZE);
- }
- for (i = 0; i < FWBUF_SIZE; ) {
- b1_put_byte(base, SEND_CONFIG);
- for (j = 0; j < 4; j++) {
- b1_put_byte(base, buf[i++]);
- }
- }
- left -= FWBUF_SIZE;
- dp += FWBUF_SIZE;
- }
- if (left) {
- if (config->user) {
- if (copy_from_user(buf, dp, left))
- return -EFAULT;
- } else {
- memcpy(buf, dp, left);
- }
- for (i = 0; i < left; ) {
- b1_put_byte(base, SEND_CONFIG);
- for (j = 0; j < 4; j++) {
- if (i < left)
- b1_put_byte(base, buf[i++]);
- else
- b1_put_byte(base, 0);
- }
- }
- }
- return 0;
-}
-
-int b1_loaded(avmcard *card)
-{
- unsigned int base = card->port;
- unsigned long stop;
- unsigned char ans;
- unsigned long tout = 2;
-
- for (stop = jiffies + tout * HZ; time_before(jiffies, stop);) {
- if (b1_tx_empty(base))
- break;
- }
- if (!b1_tx_empty(base)) {
- printk(KERN_ERR "%s: b1_loaded: tx err, corrupted t4 file ?\n",
- card->name);
- return 0;
- }
- b1_put_byte(base, SEND_POLL);
- for (stop = jiffies + tout * HZ; time_before(jiffies, stop);) {
- if (b1_rx_full(base)) {
- ans = b1_get_byte(base);
- if (ans == RECEIVE_POLL)
- return 1;
-
- printk(KERN_ERR "%s: b1_loaded: got 0x%x, firmware not running\n",
- card->name, ans);
- return 0;
- }
- }
- printk(KERN_ERR "%s: b1_loaded: firmware not running\n", card->name);
- return 0;
-}
-
-/* ------------------------------------------------------------- */
-
-int b1_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
-{
- avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
- avmcard *card = cinfo->card;
- unsigned int port = card->port;
- unsigned long flags;
- int retval;
-
- b1_reset(port);
- retval = b1_load_t4file(card, &data->firmware);
-
- if (retval) {
- b1_reset(port);
- printk(KERN_ERR "%s: failed to load t4file!!\n",
- card->name);
- return retval;
- }
-
- b1_disable_irq(port);
-
- if (data->configuration.len > 0 && data->configuration.data) {
- retval = b1_load_config(card, &data->configuration);
- if (retval) {
- b1_reset(port);
- printk(KERN_ERR "%s: failed to load config!!\n",
- card->name);
- return retval;
- }
- }
-
- if (!b1_loaded(card)) {
- printk(KERN_ERR "%s: failed to load t4file.\n", card->name);
- return -EIO;
- }
-
- spin_lock_irqsave(&card->lock, flags);
- b1_setinterrupt(port, card->irq, card->cardtype);
- b1_put_byte(port, SEND_INIT);
- b1_put_word(port, CAPI_MAXAPPL);
- b1_put_word(port, AVM_NCCI_PER_CHANNEL * 2);
- b1_put_word(port, ctrl->cnr - 1);
- spin_unlock_irqrestore(&card->lock, flags);
-
- return 0;
-}
-
-void b1_reset_ctr(struct capi_ctr *ctrl)
-{
- avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
- avmcard *card = cinfo->card;
- unsigned int port = card->port;
- unsigned long flags;
-
- b1_reset(port);
- b1_reset(port);
-
- memset(cinfo->version, 0, sizeof(cinfo->version));
- spin_lock_irqsave(&card->lock, flags);
- capilib_release(&cinfo->ncci_head);
- spin_unlock_irqrestore(&card->lock, flags);
- capi_ctr_down(ctrl);
-}
-
-void b1_register_appl(struct capi_ctr *ctrl,
- u16 appl,
- capi_register_params *rp)
-{
- avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
- avmcard *card = cinfo->card;
- unsigned int port = card->port;
- unsigned long flags;
- int nconn, want = rp->level3cnt;
-
- if (want > 0) nconn = want;
- else nconn = ctrl->profile.nbchannel * -want;
- if (nconn == 0) nconn = ctrl->profile.nbchannel;
-
- spin_lock_irqsave(&card->lock, flags);
- b1_put_byte(port, SEND_REGISTER);
- b1_put_word(port, appl);
- b1_put_word(port, 1024 * (nconn + 1));
- b1_put_word(port, nconn);
- b1_put_word(port, rp->datablkcnt);
- b1_put_word(port, rp->datablklen);
- spin_unlock_irqrestore(&card->lock, flags);
-}
-
-void b1_release_appl(struct capi_ctr *ctrl, u16 appl)
-{
- avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
- avmcard *card = cinfo->card;
- unsigned int port = card->port;
- unsigned long flags;
-
- spin_lock_irqsave(&card->lock, flags);
- capilib_release_appl(&cinfo->ncci_head, appl);
- b1_put_byte(port, SEND_RELEASE);
- b1_put_word(port, appl);
- spin_unlock_irqrestore(&card->lock, flags);
-}
-
-u16 b1_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
-{
- avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
- avmcard *card = cinfo->card;
- unsigned int port = card->port;
- unsigned long flags;
- u16 len = CAPIMSG_LEN(skb->data);
- u8 cmd = CAPIMSG_COMMAND(skb->data);
- u8 subcmd = CAPIMSG_SUBCOMMAND(skb->data);
- u16 dlen, retval;
-
- spin_lock_irqsave(&card->lock, flags);
- if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) {
- retval = capilib_data_b3_req(&cinfo->ncci_head,
- CAPIMSG_APPID(skb->data),
- CAPIMSG_NCCI(skb->data),
- CAPIMSG_MSGID(skb->data));
- if (retval != CAPI_NOERROR) {
- spin_unlock_irqrestore(&card->lock, flags);
- return retval;
- }
-
- dlen = CAPIMSG_DATALEN(skb->data);
-
- b1_put_byte(port, SEND_DATA_B3_REQ);
- b1_put_slice(port, skb->data, len);
- b1_put_slice(port, skb->data + len, dlen);
- } else {
- b1_put_byte(port, SEND_MESSAGE);
- b1_put_slice(port, skb->data, len);
- }
- spin_unlock_irqrestore(&card->lock, flags);
-
- dev_kfree_skb_any(skb);
- return CAPI_NOERROR;
-}
-
-/* ------------------------------------------------------------- */
-
-void b1_parse_version(avmctrl_info *cinfo)
-{
- struct capi_ctr *ctrl = &cinfo->capi_ctrl;
- avmcard *card = cinfo->card;
- capi_profile *profp;
- u8 *dversion;
- u8 flag;
- int i, j;
-
- for (j = 0; j < AVM_MAXVERSION; j++)
- cinfo->version[j] = "";
- for (i = 0, j = 0;
- j < AVM_MAXVERSION && i < cinfo->versionlen;
- j++, i += cinfo->versionbuf[i] + 1)
- cinfo->version[j] = &cinfo->versionbuf[i + 1];
-
- strlcpy(ctrl->serial, cinfo->version[VER_SERIAL], sizeof(ctrl->serial));
- memcpy(&ctrl->profile, cinfo->version[VER_PROFILE], sizeof(capi_profile));
- strlcpy(ctrl->manu, "AVM GmbH", sizeof(ctrl->manu));
- dversion = cinfo->version[VER_DRIVER];
- ctrl->version.majorversion = 2;
- ctrl->version.minorversion = 0;
- ctrl->version.majormanuversion = (((dversion[0] - '0') & 0xf) << 4);
- ctrl->version.majormanuversion |= ((dversion[2] - '0') & 0xf);
- ctrl->version.minormanuversion = (dversion[3] - '0') << 4;
- ctrl->version.minormanuversion |=
- (dversion[5] - '0') * 10 + ((dversion[6] - '0') & 0xf);
-
- profp = &ctrl->profile;
-
- flag = ((u8 *)(profp->manu))[1];
- switch (flag) {
- case 0: if (cinfo->version[VER_CARDTYPE])
- strcpy(cinfo->cardname, cinfo->version[VER_CARDTYPE]);
- else strcpy(cinfo->cardname, "B1");
- break;
- case 3: strcpy(cinfo->cardname, "PCMCIA B"); break;
- case 4: strcpy(cinfo->cardname, "PCMCIA M1"); break;
- case 5: strcpy(cinfo->cardname, "PCMCIA M2"); break;
- case 6: strcpy(cinfo->cardname, "B1 V3.0"); break;
- case 7: strcpy(cinfo->cardname, "B1 PCI"); break;
- default: sprintf(cinfo->cardname, "AVM?%u", (unsigned int)flag); break;
- }
- printk(KERN_NOTICE "%s: card %d \"%s\" ready.\n",
- card->name, ctrl->cnr, cinfo->cardname);
-
- flag = ((u8 *)(profp->manu))[3];
- if (flag)
- printk(KERN_NOTICE "%s: card %d Protocol:%s%s%s%s%s%s%s\n",
- card->name,
- ctrl->cnr,
- (flag & 0x01) ? " DSS1" : "",
- (flag & 0x02) ? " CT1" : "",
- (flag & 0x04) ? " VN3" : "",
- (flag & 0x08) ? " NI1" : "",
- (flag & 0x10) ? " AUSTEL" : "",
- (flag & 0x20) ? " ESS" : "",
- (flag & 0x40) ? " 1TR6" : ""
- );
-
- flag = ((u8 *)(profp->manu))[5];
- if (flag)
- printk(KERN_NOTICE "%s: card %d Linetype:%s%s%s%s\n",
- card->name,
- ctrl->cnr,
- (flag & 0x01) ? " point to point" : "",
- (flag & 0x02) ? " point to multipoint" : "",
- (flag & 0x08) ? " leased line without D-channel" : "",
- (flag & 0x04) ? " leased line with D-channel" : ""
- );
-}
-
-/* ------------------------------------------------------------- */
-
-irqreturn_t b1_interrupt(int interrupt, void *devptr)
-{
- avmcard *card = devptr;
- avmctrl_info *cinfo = &card->ctrlinfo[0];
- struct capi_ctr *ctrl = &cinfo->capi_ctrl;
- unsigned char b1cmd;
- struct sk_buff *skb;
-
- unsigned ApplId;
- unsigned MsgLen;
- unsigned DataB3Len;
- unsigned NCCI;
- unsigned WindowSize;
- unsigned long flags;
-
- spin_lock_irqsave(&card->lock, flags);
-
- if (!b1_rx_full(card->port)) {
- spin_unlock_irqrestore(&card->lock, flags);
- return IRQ_NONE;
- }
-
- b1cmd = b1_get_byte(card->port);
-
- switch (b1cmd) {
-
- case RECEIVE_DATA_B3_IND:
-
- ApplId = (unsigned) b1_get_word(card->port);
- MsgLen = b1_get_slice(card->port, card->msgbuf);
- DataB3Len = b1_get_slice(card->port, card->databuf);
- spin_unlock_irqrestore(&card->lock, flags);
-
- if (MsgLen < 30) { /* not CAPI 64Bit */
- memset(card->msgbuf + MsgLen, 0, 30-MsgLen);
- MsgLen = 30;
- CAPIMSG_SETLEN(card->msgbuf, 30);
- }
-
- skb = alloc_skb(DataB3Len + MsgLen, GFP_ATOMIC);
- if (!skb) {
- printk(KERN_ERR "%s: incoming packet dropped\n",
- card->name);
- } else {
- skb_put_data(skb, card->msgbuf, MsgLen);
- skb_put_data(skb, card->databuf, DataB3Len);
- capi_ctr_handle_message(ctrl, ApplId, skb);
- }
- break;
-
- case RECEIVE_MESSAGE:
-
- ApplId = (unsigned) b1_get_word(card->port);
- MsgLen = b1_get_slice(card->port, card->msgbuf);
- skb = alloc_skb(MsgLen, GFP_ATOMIC);
-
- if (!skb) {
- printk(KERN_ERR "%s: incoming packet dropped\n",
- card->name);
- spin_unlock_irqrestore(&card->lock, flags);
- } else {
- skb_put_data(skb, card->msgbuf, MsgLen);
- if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_CONF)
- capilib_data_b3_conf(&cinfo->ncci_head, ApplId,
- CAPIMSG_NCCI(skb->data),
- CAPIMSG_MSGID(skb->data));
- spin_unlock_irqrestore(&card->lock, flags);
- capi_ctr_handle_message(ctrl, ApplId, skb);
- }
- break;
-
- case RECEIVE_NEW_NCCI:
-
- ApplId = b1_get_word(card->port);
- NCCI = b1_get_word(card->port);
- WindowSize = b1_get_word(card->port);
- capilib_new_ncci(&cinfo->ncci_head, ApplId, NCCI, WindowSize);
- spin_unlock_irqrestore(&card->lock, flags);
- break;
-
- case RECEIVE_FREE_NCCI:
-
- ApplId = b1_get_word(card->port);
- NCCI = b1_get_word(card->port);
- if (NCCI != 0xffffffff)
- capilib_free_ncci(&cinfo->ncci_head, ApplId, NCCI);
- spin_unlock_irqrestore(&card->lock, flags);
- break;
-
- case RECEIVE_START:
- /* b1_put_byte(card->port, SEND_POLLACK); */
- spin_unlock_irqrestore(&card->lock, flags);
- capi_ctr_resume_output(ctrl);
- break;
-
- case RECEIVE_STOP:
- spin_unlock_irqrestore(&card->lock, flags);
- capi_ctr_suspend_output(ctrl);
- break;
-
- case RECEIVE_INIT:
-
- cinfo->versionlen = b1_get_slice(card->port, cinfo->versionbuf);
- spin_unlock_irqrestore(&card->lock, flags);
- b1_parse_version(cinfo);
- printk(KERN_INFO "%s: %s-card (%s) now active\n",
- card->name,
- cinfo->version[VER_CARDTYPE],
- cinfo->version[VER_DRIVER]);
- capi_ctr_ready(ctrl);
- break;
-
- case RECEIVE_TASK_READY:
- ApplId = (unsigned) b1_get_word(card->port);
- MsgLen = b1_get_slice(card->port, card->msgbuf);
- spin_unlock_irqrestore(&card->lock, flags);
- card->msgbuf[MsgLen] = 0;
- while (MsgLen > 0
- && (card->msgbuf[MsgLen - 1] == '\n'
- || card->msgbuf[MsgLen - 1] == '\r')) {
- card->msgbuf[MsgLen - 1] = 0;
- MsgLen--;
- }
- printk(KERN_INFO "%s: task %d \"%s\" ready.\n",
- card->name, ApplId, card->msgbuf);
- break;
-
- case RECEIVE_DEBUGMSG:
- MsgLen = b1_get_slice(card->port, card->msgbuf);
- spin_unlock_irqrestore(&card->lock, flags);
- card->msgbuf[MsgLen] = 0;
- while (MsgLen > 0
- && (card->msgbuf[MsgLen - 1] == '\n'
- || card->msgbuf[MsgLen - 1] == '\r')) {
- card->msgbuf[MsgLen - 1] = 0;
- MsgLen--;
- }
- printk(KERN_INFO "%s: DEBUG: %s\n", card->name, card->msgbuf);
- break;
-
- case 0xff:
- spin_unlock_irqrestore(&card->lock, flags);
- printk(KERN_ERR "%s: card removed ?\n", card->name);
- return IRQ_NONE;
- default:
- spin_unlock_irqrestore(&card->lock, flags);
- printk(KERN_ERR "%s: b1_interrupt: 0x%x ???\n",
- card->name, b1cmd);
- return IRQ_HANDLED;
- }
- return IRQ_HANDLED;
-}
-
-/* ------------------------------------------------------------- */
-int b1_proc_show(struct seq_file *m, void *v)
-{
- struct capi_ctr *ctrl = m->private;
- avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
- avmcard *card = cinfo->card;
- u8 flag;
- char *s;
-
- seq_printf(m, "%-16s %s\n", "name", card->name);
- seq_printf(m, "%-16s 0x%x\n", "io", card->port);
- seq_printf(m, "%-16s %d\n", "irq", card->irq);
- switch (card->cardtype) {
- case avm_b1isa: s = "B1 ISA"; break;
- case avm_b1pci: s = "B1 PCI"; break;
- case avm_b1pcmcia: s = "B1 PCMCIA"; break;
- case avm_m1: s = "M1"; break;
- case avm_m2: s = "M2"; break;
- case avm_t1isa: s = "T1 ISA (HEMA)"; break;
- case avm_t1pci: s = "T1 PCI"; break;
- case avm_c4: s = "C4"; break;
- case avm_c2: s = "C2"; break;
- default: s = "???"; break;
- }
- seq_printf(m, "%-16s %s\n", "type", s);
- if (card->cardtype == avm_t1isa)
- seq_printf(m, "%-16s %d\n", "cardnr", card->cardnr);
-
- s = cinfo->version[VER_DRIVER];
- if (s)
- seq_printf(m, "%-16s %s\n", "ver_driver", s);
-
- s = cinfo->version[VER_CARDTYPE];
- if (s)
- seq_printf(m, "%-16s %s\n", "ver_cardtype", s);
-
- s = cinfo->version[VER_SERIAL];
- if (s)
- seq_printf(m, "%-16s %s\n", "ver_serial", s);
-
- if (card->cardtype != avm_m1) {
- flag = ((u8 *)(ctrl->profile.manu))[3];
- if (flag)
- seq_printf(m, "%-16s%s%s%s%s%s%s%s\n",
- "protocol",
- (flag & 0x01) ? " DSS1" : "",
- (flag & 0x02) ? " CT1" : "",
- (flag & 0x04) ? " VN3" : "",
- (flag & 0x08) ? " NI1" : "",
- (flag & 0x10) ? " AUSTEL" : "",
- (flag & 0x20) ? " ESS" : "",
- (flag & 0x40) ? " 1TR6" : ""
- );
- }
- if (card->cardtype != avm_m1) {
- flag = ((u8 *)(ctrl->profile.manu))[5];
- if (flag)
- seq_printf(m, "%-16s%s%s%s%s\n",
- "linetype",
- (flag & 0x01) ? " point to point" : "",
- (flag & 0x02) ? " point to multipoint" : "",
- (flag & 0x08) ? " leased line without D-channel" : "",
- (flag & 0x04) ? " leased line with D-channel" : ""
- );
- }
- seq_printf(m, "%-16s %s\n", "cardname", cinfo->cardname);
-
- return 0;
-}
-EXPORT_SYMBOL(b1_proc_show);
-
-/* ------------------------------------------------------------- */
-
-#ifdef CONFIG_PCI
-
-avmcard_dmainfo *
-avmcard_dma_alloc(char *name, struct pci_dev *pdev, long rsize, long ssize)
-{
- avmcard_dmainfo *p;
- void *buf;
-
- p = kzalloc(sizeof(avmcard_dmainfo), GFP_KERNEL);
- if (!p) {
- printk(KERN_WARNING "%s: no memory.\n", name);
- goto err;
- }
-
- p->recvbuf.size = rsize;
- buf = pci_alloc_consistent(pdev, rsize, &p->recvbuf.dmaaddr);
- if (!buf) {
- printk(KERN_WARNING "%s: allocation of receive dma buffer failed.\n", name);
- goto err_kfree;
- }
- p->recvbuf.dmabuf = buf;
-
- p->sendbuf.size = ssize;
- buf = pci_alloc_consistent(pdev, ssize, &p->sendbuf.dmaaddr);
- if (!buf) {
- printk(KERN_WARNING "%s: allocation of send dma buffer failed.\n", name);
- goto err_free_consistent;
- }
-
- p->sendbuf.dmabuf = buf;
- skb_queue_head_init(&p->send_queue);
-
- return p;
-
-err_free_consistent:
- pci_free_consistent(p->pcidev, p->recvbuf.size,
- p->recvbuf.dmabuf, p->recvbuf.dmaaddr);
-err_kfree:
- kfree(p);
-err:
- return NULL;
-}
-
-void avmcard_dma_free(avmcard_dmainfo *p)
-{
- pci_free_consistent(p->pcidev, p->recvbuf.size,
- p->recvbuf.dmabuf, p->recvbuf.dmaaddr);
- pci_free_consistent(p->pcidev, p->sendbuf.size,
- p->sendbuf.dmabuf, p->sendbuf.dmaaddr);
- skb_queue_purge(&p->send_queue);
- kfree(p);
-}
-
-EXPORT_SYMBOL(avmcard_dma_alloc);
-EXPORT_SYMBOL(avmcard_dma_free);
-
-#endif
-
-EXPORT_SYMBOL(b1_irq_table);
-
-EXPORT_SYMBOL(b1_alloc_card);
-EXPORT_SYMBOL(b1_free_card);
-EXPORT_SYMBOL(b1_detect);
-EXPORT_SYMBOL(b1_getrevision);
-EXPORT_SYMBOL(b1_load_t4file);
-EXPORT_SYMBOL(b1_load_config);
-EXPORT_SYMBOL(b1_loaded);
-EXPORT_SYMBOL(b1_load_firmware);
-EXPORT_SYMBOL(b1_reset_ctr);
-EXPORT_SYMBOL(b1_register_appl);
-EXPORT_SYMBOL(b1_release_appl);
-EXPORT_SYMBOL(b1_send_message);
-
-EXPORT_SYMBOL(b1_parse_version);
-EXPORT_SYMBOL(b1_interrupt);
-
-static int __init b1_init(void)
-{
- char *p;
- char rev[32];
-
- p = strchr(revision, ':');
- if (p && p[1]) {
- strlcpy(rev, p + 2, 32);
- p = strchr(rev, '$');
- if (p && p > rev)
- *(p - 1) = 0;
- } else {
- strcpy(rev, "1.0");
- }
- printk(KERN_INFO "b1: revision %s\n", rev);
-
- return 0;
-}
-
-static void __exit b1_exit(void)
-{
-}
-
-module_init(b1_init);
-module_exit(b1_exit);
diff --git a/drivers/staging/isdn/avm/b1dma.c b/drivers/staging/isdn/avm/b1dma.c
deleted file mode 100644
index 6a3dc9937ce5..000000000000
--- a/drivers/staging/isdn/avm/b1dma.c
+++ /dev/null
@@ -1,981 +0,0 @@
-/* $Id: b1dma.c,v 1.1.2.3 2004/02/10 01:07:12 keil Exp $
- *
- * Common module for AVM B1 cards that support dma with AMCC
- *
- * Copyright 2000 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/kernel.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/skbuff.h>
-#include <linux/delay.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/capi.h>
-#include <linux/kernelcapi.h>
-#include <linux/gfp.h>
-#include <asm/io.h>
-#include <linux/init.h>
-#include <linux/uaccess.h>
-#include <linux/netdevice.h>
-#include <linux/isdn/capilli.h>
-#include "avmcard.h"
-#include <linux/isdn/capicmd.h>
-#include <linux/isdn/capiutil.h>
-
-static char *revision = "$Revision: 1.1.2.3 $";
-
-#undef AVM_B1DMA_DEBUG
-
-/* ------------------------------------------------------------- */
-
-MODULE_DESCRIPTION("CAPI4Linux: DMA support for active AVM cards");
-MODULE_AUTHOR("Carsten Paeth");
-MODULE_LICENSE("GPL");
-
-static bool suppress_pollack = 0;
-module_param(suppress_pollack, bool, 0);
-
-/* ------------------------------------------------------------- */
-
-static void b1dma_dispatch_tx(avmcard *card);
-
-/* ------------------------------------------------------------- */
-
-/* S5933 */
-
-#define AMCC_RXPTR 0x24
-#define AMCC_RXLEN 0x28
-#define AMCC_TXPTR 0x2c
-#define AMCC_TXLEN 0x30
-
-#define AMCC_INTCSR 0x38
-# define EN_READ_TC_INT 0x00008000L
-# define EN_WRITE_TC_INT 0x00004000L
-# define EN_TX_TC_INT EN_READ_TC_INT
-# define EN_RX_TC_INT EN_WRITE_TC_INT
-# define AVM_FLAG 0x30000000L
-
-# define ANY_S5933_INT 0x00800000L
-# define READ_TC_INT 0x00080000L
-# define WRITE_TC_INT 0x00040000L
-# define TX_TC_INT READ_TC_INT
-# define RX_TC_INT WRITE_TC_INT
-# define MASTER_ABORT_INT 0x00100000L
-# define TARGET_ABORT_INT 0x00200000L
-# define BUS_MASTER_INT 0x00200000L
-# define ALL_INT 0x000C0000L
-
-#define AMCC_MCSR 0x3c
-# define A2P_HI_PRIORITY 0x00000100L
-# define EN_A2P_TRANSFERS 0x00000400L
-# define P2A_HI_PRIORITY 0x00001000L
-# define EN_P2A_TRANSFERS 0x00004000L
-# define RESET_A2P_FLAGS 0x04000000L
-# define RESET_P2A_FLAGS 0x02000000L
-
-/* ------------------------------------------------------------- */
-
-static inline void b1dma_writel(avmcard *card, u32 value, int off)
-{
- writel(value, card->mbase + off);
-}
-
-static inline u32 b1dma_readl(avmcard *card, int off)
-{
- return readl(card->mbase + off);
-}
-
-/* ------------------------------------------------------------- */
-
-static inline int b1dma_tx_empty(unsigned int port)
-{
- return inb(port + 0x03) & 0x1;
-}
-
-static inline int b1dma_rx_full(unsigned int port)
-{
- return inb(port + 0x02) & 0x1;
-}
-
-static int b1dma_tolink(avmcard *card, void *buf, unsigned int len)
-{
- unsigned long stop = jiffies + 1 * HZ; /* maximum wait time 1 sec */
- unsigned char *s = (unsigned char *)buf;
- while (len--) {
- while (!b1dma_tx_empty(card->port)
- && time_before(jiffies, stop));
- if (!b1dma_tx_empty(card->port))
- return -1;
- t1outp(card->port, 0x01, *s++);
- }
- return 0;
-}
-
-static int b1dma_fromlink(avmcard *card, void *buf, unsigned int len)
-{
- unsigned long stop = jiffies + 1 * HZ; /* maximum wait time 1 sec */
- unsigned char *s = (unsigned char *)buf;
- while (len--) {
- while (!b1dma_rx_full(card->port)
- && time_before(jiffies, stop));
- if (!b1dma_rx_full(card->port))
- return -1;
- *s++ = t1inp(card->port, 0x00);
- }
- return 0;
-}
-
-static int WriteReg(avmcard *card, u32 reg, u8 val)
-{
- u8 cmd = 0x00;
- if (b1dma_tolink(card, &cmd, 1) == 0
- && b1dma_tolink(card, &reg, 4) == 0) {
- u32 tmp = val;
- return b1dma_tolink(card, &tmp, 4);
- }
- return -1;
-}
-
-static u8 ReadReg(avmcard *card, u32 reg)
-{
- u8 cmd = 0x01;
- if (b1dma_tolink(card, &cmd, 1) == 0
- && b1dma_tolink(card, &reg, 4) == 0) {
- u32 tmp;
- if (b1dma_fromlink(card, &tmp, 4) == 0)
- return (u8)tmp;
- }
- return 0xff;
-}
-
-/* ------------------------------------------------------------- */
-
-static inline void _put_byte(void **pp, u8 val)
-{
- u8 *s = *pp;
- *s++ = val;
- *pp = s;
-}
-
-static inline void _put_word(void **pp, u32 val)
-{
- u8 *s = *pp;
- *s++ = val & 0xff;
- *s++ = (val >> 8) & 0xff;
- *s++ = (val >> 16) & 0xff;
- *s++ = (val >> 24) & 0xff;
- *pp = s;
-}
-
-static inline void _put_slice(void **pp, unsigned char *dp, unsigned int len)
-{
- unsigned i = len;
- _put_word(pp, i);
- while (i-- > 0)
- _put_byte(pp, *dp++);
-}
-
-static inline u8 _get_byte(void **pp)
-{
- u8 *s = *pp;
- u8 val;
- val = *s++;
- *pp = s;
- return val;
-}
-
-static inline u32 _get_word(void **pp)
-{
- u8 *s = *pp;
- u32 val;
- val = *s++;
- val |= (*s++ << 8);
- val |= (*s++ << 16);
- val |= (*s++ << 24);
- *pp = s;
- return val;
-}
-
-static inline u32 _get_slice(void **pp, unsigned char *dp)
-{
- unsigned int len, i;
-
- len = i = _get_word(pp);
- while (i-- > 0) *dp++ = _get_byte(pp);
- return len;
-}
-
-/* ------------------------------------------------------------- */
-
-void b1dma_reset(avmcard *card)
-{
- card->csr = 0x0;
- b1dma_writel(card, card->csr, AMCC_INTCSR);
- b1dma_writel(card, 0, AMCC_MCSR);
- b1dma_writel(card, 0, AMCC_RXLEN);
- b1dma_writel(card, 0, AMCC_TXLEN);
-
- t1outp(card->port, 0x10, 0x00);
- t1outp(card->port, 0x07, 0x00);
-
- b1dma_writel(card, 0, AMCC_MCSR);
- mdelay(10);
- b1dma_writel(card, 0x0f000000, AMCC_MCSR); /* reset all */
- mdelay(10);
- b1dma_writel(card, 0, AMCC_MCSR);
- if (card->cardtype == avm_t1pci)
- mdelay(42);
- else
- mdelay(10);
-}
-
-/* ------------------------------------------------------------- */
-
-static int b1dma_detect(avmcard *card)
-{
- b1dma_writel(card, 0, AMCC_MCSR);
- mdelay(10);
- b1dma_writel(card, 0x0f000000, AMCC_MCSR); /* reset all */
- mdelay(10);
- b1dma_writel(card, 0, AMCC_MCSR);
- mdelay(42);
-
- b1dma_writel(card, 0, AMCC_RXLEN);
- b1dma_writel(card, 0, AMCC_TXLEN);
- card->csr = 0x0;
- b1dma_writel(card, card->csr, AMCC_INTCSR);
-
- if (b1dma_readl(card, AMCC_MCSR) != 0x000000E6)
- return 1;
-
- b1dma_writel(card, 0xffffffff, AMCC_RXPTR);
- b1dma_writel(card, 0xffffffff, AMCC_TXPTR);
- if (b1dma_readl(card, AMCC_RXPTR) != 0xfffffffc
- || b1dma_readl(card, AMCC_TXPTR) != 0xfffffffc)
- return 2;
-
- b1dma_writel(card, 0x0, AMCC_RXPTR);
- b1dma_writel(card, 0x0, AMCC_TXPTR);
- if (b1dma_readl(card, AMCC_RXPTR) != 0x0
- || b1dma_readl(card, AMCC_TXPTR) != 0x0)
- return 3;
-
- t1outp(card->port, 0x10, 0x00);
- t1outp(card->port, 0x07, 0x00);
-
- t1outp(card->port, 0x02, 0x02);
- t1outp(card->port, 0x03, 0x02);
-
- if ((t1inp(card->port, 0x02) & 0xFE) != 0x02
- || t1inp(card->port, 0x3) != 0x03)
- return 4;
-
- t1outp(card->port, 0x02, 0x00);
- t1outp(card->port, 0x03, 0x00);
-
- if ((t1inp(card->port, 0x02) & 0xFE) != 0x00
- || t1inp(card->port, 0x3) != 0x01)
- return 5;
-
- return 0;
-}
-
-int t1pci_detect(avmcard *card)
-{
- int ret;
-
- if ((ret = b1dma_detect(card)) != 0)
- return ret;
-
- /* Transputer test */
-
- if (WriteReg(card, 0x80001000, 0x11) != 0
- || WriteReg(card, 0x80101000, 0x22) != 0
- || WriteReg(card, 0x80201000, 0x33) != 0
- || WriteReg(card, 0x80301000, 0x44) != 0)
- return 6;
-
- if (ReadReg(card, 0x80001000) != 0x11
- || ReadReg(card, 0x80101000) != 0x22
- || ReadReg(card, 0x80201000) != 0x33
- || ReadReg(card, 0x80301000) != 0x44)
- return 7;
-
- if (WriteReg(card, 0x80001000, 0x55) != 0
- || WriteReg(card, 0x80101000, 0x66) != 0
- || WriteReg(card, 0x80201000, 0x77) != 0
- || WriteReg(card, 0x80301000, 0x88) != 0)
- return 8;
-
- if (ReadReg(card, 0x80001000) != 0x55
- || ReadReg(card, 0x80101000) != 0x66
- || ReadReg(card, 0x80201000) != 0x77
- || ReadReg(card, 0x80301000) != 0x88)
- return 9;
-
- return 0;
-}
-
-int b1pciv4_detect(avmcard *card)
-{
- int ret, i;
-
- if ((ret = b1dma_detect(card)) != 0)
- return ret;
-
- for (i = 0; i < 5; i++) {
- if (WriteReg(card, 0x80A00000, 0x21) != 0)
- return 6;
- if ((ReadReg(card, 0x80A00000) & 0x01) != 0x01)
- return 7;
- }
- for (i = 0; i < 5; i++) {
- if (WriteReg(card, 0x80A00000, 0x20) != 0)
- return 8;
- if ((ReadReg(card, 0x80A00000) & 0x01) != 0x00)
- return 9;
- }
-
- return 0;
-}
-
-static void b1dma_queue_tx(avmcard *card, struct sk_buff *skb)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&card->lock, flags);
-
- skb_queue_tail(&card->dma->send_queue, skb);
-
- if (!(card->csr & EN_TX_TC_INT)) {
- b1dma_dispatch_tx(card);
- b1dma_writel(card, card->csr, AMCC_INTCSR);
- }
-
- spin_unlock_irqrestore(&card->lock, flags);
-}
-
-/* ------------------------------------------------------------- */
-
-static void b1dma_dispatch_tx(avmcard *card)
-{
- avmcard_dmainfo *dma = card->dma;
- struct sk_buff *skb;
- u8 cmd, subcmd;
- u16 len;
- u32 txlen;
- void *p;
-
- skb = skb_dequeue(&dma->send_queue);
-
- len = CAPIMSG_LEN(skb->data);
-
- if (len) {
- cmd = CAPIMSG_COMMAND(skb->data);
- subcmd = CAPIMSG_SUBCOMMAND(skb->data);
-
- p = dma->sendbuf.dmabuf;
-
- if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) {
- u16 dlen = CAPIMSG_DATALEN(skb->data);
- _put_byte(&p, SEND_DATA_B3_REQ);
- _put_slice(&p, skb->data, len);
- _put_slice(&p, skb->data + len, dlen);
- } else {
- _put_byte(&p, SEND_MESSAGE);
- _put_slice(&p, skb->data, len);
- }
- txlen = (u8 *)p - (u8 *)dma->sendbuf.dmabuf;
-#ifdef AVM_B1DMA_DEBUG
- printk(KERN_DEBUG "tx: put msg len=%d\n", txlen);
-#endif
- } else {
- txlen = skb->len - 2;
-#ifdef AVM_B1DMA_POLLDEBUG
- if (skb->data[2] == SEND_POLLACK)
- printk(KERN_INFO "%s: send ack\n", card->name);
-#endif
-#ifdef AVM_B1DMA_DEBUG
- printk(KERN_DEBUG "tx: put 0x%x len=%d\n",
- skb->data[2], txlen);
-#endif
- skb_copy_from_linear_data_offset(skb, 2, dma->sendbuf.dmabuf,
- skb->len - 2);
- }
- txlen = (txlen + 3) & ~3;
-
- b1dma_writel(card, dma->sendbuf.dmaaddr, AMCC_TXPTR);
- b1dma_writel(card, txlen, AMCC_TXLEN);
-
- card->csr |= EN_TX_TC_INT;
-
- dev_kfree_skb_any(skb);
-}
-
-/* ------------------------------------------------------------- */
-
-static void queue_pollack(avmcard *card)
-{
- struct sk_buff *skb;
- void *p;
-
- skb = alloc_skb(3, GFP_ATOMIC);
- if (!skb) {
- printk(KERN_CRIT "%s: no memory, lost poll ack\n",
- card->name);
- return;
- }
- p = skb->data;
- _put_byte(&p, 0);
- _put_byte(&p, 0);
- _put_byte(&p, SEND_POLLACK);
- skb_put(skb, (u8 *)p - (u8 *)skb->data);
-
- b1dma_queue_tx(card, skb);
-}
-
-/* ------------------------------------------------------------- */
-
-static void b1dma_handle_rx(avmcard *card)
-{
- avmctrl_info *cinfo = &card->ctrlinfo[0];
- avmcard_dmainfo *dma = card->dma;
- struct capi_ctr *ctrl = &cinfo->capi_ctrl;
- struct sk_buff *skb;
- void *p = dma->recvbuf.dmabuf + 4;
- u32 ApplId, MsgLen, DataB3Len, NCCI, WindowSize;
- u8 b1cmd = _get_byte(&p);
-
-#ifdef AVM_B1DMA_DEBUG
- printk(KERN_DEBUG "rx: 0x%x %lu\n", b1cmd, (unsigned long)dma->recvlen);
-#endif
-
- switch (b1cmd) {
- case RECEIVE_DATA_B3_IND:
-
- ApplId = (unsigned) _get_word(&p);
- MsgLen = _get_slice(&p, card->msgbuf);
- DataB3Len = _get_slice(&p, card->databuf);
-
- if (MsgLen < 30) { /* not CAPI 64Bit */
- memset(card->msgbuf + MsgLen, 0, 30 - MsgLen);
- MsgLen = 30;
- CAPIMSG_SETLEN(card->msgbuf, 30);
- }
- if (!(skb = alloc_skb(DataB3Len + MsgLen, GFP_ATOMIC))) {
- printk(KERN_ERR "%s: incoming packet dropped\n",
- card->name);
- } else {
- skb_put_data(skb, card->msgbuf, MsgLen);
- skb_put_data(skb, card->databuf, DataB3Len);
- capi_ctr_handle_message(ctrl, ApplId, skb);
- }
- break;
-
- case RECEIVE_MESSAGE:
-
- ApplId = (unsigned) _get_word(&p);
- MsgLen = _get_slice(&p, card->msgbuf);
- if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) {
- printk(KERN_ERR "%s: incoming packet dropped\n",
- card->name);
- } else {
- skb_put_data(skb, card->msgbuf, MsgLen);
- if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_CONF) {
- spin_lock(&card->lock);
- capilib_data_b3_conf(&cinfo->ncci_head, ApplId,
- CAPIMSG_NCCI(skb->data),
- CAPIMSG_MSGID(skb->data));
- spin_unlock(&card->lock);
- }
- capi_ctr_handle_message(ctrl, ApplId, skb);
- }
- break;
-
- case RECEIVE_NEW_NCCI:
-
- ApplId = _get_word(&p);
- NCCI = _get_word(&p);
- WindowSize = _get_word(&p);
- spin_lock(&card->lock);
- capilib_new_ncci(&cinfo->ncci_head, ApplId, NCCI, WindowSize);
- spin_unlock(&card->lock);
- break;
-
- case RECEIVE_FREE_NCCI:
-
- ApplId = _get_word(&p);
- NCCI = _get_word(&p);
-
- if (NCCI != 0xffffffff) {
- spin_lock(&card->lock);
- capilib_free_ncci(&cinfo->ncci_head, ApplId, NCCI);
- spin_unlock(&card->lock);
- }
- break;
-
- case RECEIVE_START:
-#ifdef AVM_B1DMA_POLLDEBUG
- printk(KERN_INFO "%s: receive poll\n", card->name);
-#endif
- if (!suppress_pollack)
- queue_pollack(card);
- capi_ctr_resume_output(ctrl);
- break;
-
- case RECEIVE_STOP:
- capi_ctr_suspend_output(ctrl);
- break;
-
- case RECEIVE_INIT:
-
- cinfo->versionlen = _get_slice(&p, cinfo->versionbuf);
- b1_parse_version(cinfo);
- printk(KERN_INFO "%s: %s-card (%s) now active\n",
- card->name,
- cinfo->version[VER_CARDTYPE],
- cinfo->version[VER_DRIVER]);
- capi_ctr_ready(ctrl);
- break;
-
- case RECEIVE_TASK_READY:
- ApplId = (unsigned) _get_word(&p);
- MsgLen = _get_slice(&p, card->msgbuf);
- card->msgbuf[MsgLen] = 0;
- while (MsgLen > 0
- && (card->msgbuf[MsgLen - 1] == '\n'
- || card->msgbuf[MsgLen - 1] == '\r')) {
- card->msgbuf[MsgLen - 1] = 0;
- MsgLen--;
- }
- printk(KERN_INFO "%s: task %d \"%s\" ready.\n",
- card->name, ApplId, card->msgbuf);
- break;
-
- case RECEIVE_DEBUGMSG:
- MsgLen = _get_slice(&p, card->msgbuf);
- card->msgbuf[MsgLen] = 0;
- while (MsgLen > 0
- && (card->msgbuf[MsgLen - 1] == '\n'
- || card->msgbuf[MsgLen - 1] == '\r')) {
- card->msgbuf[MsgLen - 1] = 0;
- MsgLen--;
- }
- printk(KERN_INFO "%s: DEBUG: %s\n", card->name, card->msgbuf);
- break;
-
- default:
- printk(KERN_ERR "%s: b1dma_interrupt: 0x%x ???\n",
- card->name, b1cmd);
- return;
- }
-}
-
-/* ------------------------------------------------------------- */
-
-static void b1dma_handle_interrupt(avmcard *card)
-{
- u32 status;
- u32 newcsr;
-
- spin_lock(&card->lock);
-
- status = b1dma_readl(card, AMCC_INTCSR);
- if ((status & ANY_S5933_INT) == 0) {
- spin_unlock(&card->lock);
- return;
- }
-
- newcsr = card->csr | (status & ALL_INT);
- if (status & TX_TC_INT) newcsr &= ~EN_TX_TC_INT;
- if (status & RX_TC_INT) newcsr &= ~EN_RX_TC_INT;
- b1dma_writel(card, newcsr, AMCC_INTCSR);
-
- if ((status & RX_TC_INT) != 0) {
- struct avmcard_dmainfo *dma = card->dma;
- u32 rxlen;
- if (card->dma->recvlen == 0) {
- rxlen = b1dma_readl(card, AMCC_RXLEN);
- if (rxlen == 0) {
- dma->recvlen = *((u32 *)dma->recvbuf.dmabuf);
- rxlen = (dma->recvlen + 3) & ~3;
- b1dma_writel(card, dma->recvbuf.dmaaddr + 4, AMCC_RXPTR);
- b1dma_writel(card, rxlen, AMCC_RXLEN);
-#ifdef AVM_B1DMA_DEBUG
- } else {
- printk(KERN_ERR "%s: rx not complete (%d).\n",
- card->name, rxlen);
-#endif
- }
- } else {
- spin_unlock(&card->lock);
- b1dma_handle_rx(card);
- dma->recvlen = 0;
- spin_lock(&card->lock);
- b1dma_writel(card, dma->recvbuf.dmaaddr, AMCC_RXPTR);
- b1dma_writel(card, 4, AMCC_RXLEN);
- }
- }
-
- if ((status & TX_TC_INT) != 0) {
- if (skb_queue_empty(&card->dma->send_queue))
- card->csr &= ~EN_TX_TC_INT;
- else
- b1dma_dispatch_tx(card);
- }
- b1dma_writel(card, card->csr, AMCC_INTCSR);
-
- spin_unlock(&card->lock);
-}
-
-irqreturn_t b1dma_interrupt(int interrupt, void *devptr)
-{
- avmcard *card = devptr;
-
- b1dma_handle_interrupt(card);
- return IRQ_HANDLED;
-}
-
-/* ------------------------------------------------------------- */
-
-static int b1dma_loaded(avmcard *card)
-{
- unsigned long stop;
- unsigned char ans;
- unsigned long tout = 2;
- unsigned int base = card->port;
-
- for (stop = jiffies + tout * HZ; time_before(jiffies, stop);) {
- if (b1_tx_empty(base))
- break;
- }
- if (!b1_tx_empty(base)) {
- printk(KERN_ERR "%s: b1dma_loaded: tx err, corrupted t4 file ?\n",
- card->name);
- return 0;
- }
- b1_put_byte(base, SEND_POLLACK);
- for (stop = jiffies + tout * HZ; time_before(jiffies, stop);) {
- if (b1_rx_full(base)) {
- if ((ans = b1_get_byte(base)) == RECEIVE_POLLDWORD) {
- return 1;
- }
- printk(KERN_ERR "%s: b1dma_loaded: got 0x%x, firmware not running in dword mode\n", card->name, ans);
- return 0;
- }
- }
- printk(KERN_ERR "%s: b1dma_loaded: firmware not running\n", card->name);
- return 0;
-}
-
-/* ------------------------------------------------------------- */
-
-static void b1dma_send_init(avmcard *card)
-{
- struct sk_buff *skb;
- void *p;
-
- skb = alloc_skb(15, GFP_ATOMIC);
- if (!skb) {
- printk(KERN_CRIT "%s: no memory, lost register appl.\n",
- card->name);
- return;
- }
- p = skb->data;
- _put_byte(&p, 0);
- _put_byte(&p, 0);
- _put_byte(&p, SEND_INIT);
- _put_word(&p, CAPI_MAXAPPL);
- _put_word(&p, AVM_NCCI_PER_CHANNEL * 30);
- _put_word(&p, card->cardnr - 1);
- skb_put(skb, (u8 *)p - (u8 *)skb->data);
-
- b1dma_queue_tx(card, skb);
-}
-
-int b1dma_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
-{
- avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
- avmcard *card = cinfo->card;
- int retval;
-
- b1dma_reset(card);
-
- if ((retval = b1_load_t4file(card, &data->firmware))) {
- b1dma_reset(card);
- printk(KERN_ERR "%s: failed to load t4file!!\n",
- card->name);
- return retval;
- }
-
- if (data->configuration.len > 0 && data->configuration.data) {
- if ((retval = b1_load_config(card, &data->configuration))) {
- b1dma_reset(card);
- printk(KERN_ERR "%s: failed to load config!!\n",
- card->name);
- return retval;
- }
- }
-
- if (!b1dma_loaded(card)) {
- b1dma_reset(card);
- printk(KERN_ERR "%s: failed to load t4file.\n", card->name);
- return -EIO;
- }
-
- card->csr = AVM_FLAG;
- b1dma_writel(card, card->csr, AMCC_INTCSR);
- b1dma_writel(card, EN_A2P_TRANSFERS | EN_P2A_TRANSFERS | A2P_HI_PRIORITY |
- P2A_HI_PRIORITY | RESET_A2P_FLAGS | RESET_P2A_FLAGS,
- AMCC_MCSR);
- t1outp(card->port, 0x07, 0x30);
- t1outp(card->port, 0x10, 0xF0);
-
- card->dma->recvlen = 0;
- b1dma_writel(card, card->dma->recvbuf.dmaaddr, AMCC_RXPTR);
- b1dma_writel(card, 4, AMCC_RXLEN);
- card->csr |= EN_RX_TC_INT;
- b1dma_writel(card, card->csr, AMCC_INTCSR);
-
- b1dma_send_init(card);
-
- return 0;
-}
-
-void b1dma_reset_ctr(struct capi_ctr *ctrl)
-{
- avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
- avmcard *card = cinfo->card;
- unsigned long flags;
-
- spin_lock_irqsave(&card->lock, flags);
- b1dma_reset(card);
-
- memset(cinfo->version, 0, sizeof(cinfo->version));
- capilib_release(&cinfo->ncci_head);
- spin_unlock_irqrestore(&card->lock, flags);
- capi_ctr_down(ctrl);
-}
-
-/* ------------------------------------------------------------- */
-
-void b1dma_register_appl(struct capi_ctr *ctrl,
- u16 appl,
- capi_register_params *rp)
-{
- avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
- avmcard *card = cinfo->card;
- struct sk_buff *skb;
- int want = rp->level3cnt;
- int nconn;
- void *p;
-
- if (want > 0) nconn = want;
- else nconn = ctrl->profile.nbchannel * -want;
- if (nconn == 0) nconn = ctrl->profile.nbchannel;
-
- skb = alloc_skb(23, GFP_ATOMIC);
- if (!skb) {
- printk(KERN_CRIT "%s: no memory, lost register appl.\n",
- card->name);
- return;
- }
- p = skb->data;
- _put_byte(&p, 0);
- _put_byte(&p, 0);
- _put_byte(&p, SEND_REGISTER);
- _put_word(&p, appl);
- _put_word(&p, 1024 * (nconn + 1));
- _put_word(&p, nconn);
- _put_word(&p, rp->datablkcnt);
- _put_word(&p, rp->datablklen);
- skb_put(skb, (u8 *)p - (u8 *)skb->data);
-
- b1dma_queue_tx(card, skb);
-}
-
-/* ------------------------------------------------------------- */
-
-void b1dma_release_appl(struct capi_ctr *ctrl, u16 appl)
-{
- avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
- avmcard *card = cinfo->card;
- struct sk_buff *skb;
- void *p;
- unsigned long flags;
-
- spin_lock_irqsave(&card->lock, flags);
- capilib_release_appl(&cinfo->ncci_head, appl);
- spin_unlock_irqrestore(&card->lock, flags);
-
- skb = alloc_skb(7, GFP_ATOMIC);
- if (!skb) {
- printk(KERN_CRIT "%s: no memory, lost release appl.\n",
- card->name);
- return;
- }
- p = skb->data;
- _put_byte(&p, 0);
- _put_byte(&p, 0);
- _put_byte(&p, SEND_RELEASE);
- _put_word(&p, appl);
-
- skb_put(skb, (u8 *)p - (u8 *)skb->data);
-
- b1dma_queue_tx(card, skb);
-}
-
-/* ------------------------------------------------------------- */
-
-u16 b1dma_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
-{
- avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
- avmcard *card = cinfo->card;
- u16 retval = CAPI_NOERROR;
-
- if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) {
- unsigned long flags;
- spin_lock_irqsave(&card->lock, flags);
- retval = capilib_data_b3_req(&cinfo->ncci_head,
- CAPIMSG_APPID(skb->data),
- CAPIMSG_NCCI(skb->data),
- CAPIMSG_MSGID(skb->data));
- spin_unlock_irqrestore(&card->lock, flags);
- }
- if (retval == CAPI_NOERROR)
- b1dma_queue_tx(card, skb);
-
- return retval;
-}
-
-/* ------------------------------------------------------------- */
-
-int b1dma_proc_show(struct seq_file *m, void *v)
-{
- struct capi_ctr *ctrl = m->private;
- avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
- avmcard *card = cinfo->card;
- u8 flag;
- char *s;
- u32 txoff, txlen, rxoff, rxlen, csr;
- unsigned long flags;
-
- seq_printf(m, "%-16s %s\n", "name", card->name);
- seq_printf(m, "%-16s 0x%x\n", "io", card->port);
- seq_printf(m, "%-16s %d\n", "irq", card->irq);
- seq_printf(m, "%-16s 0x%lx\n", "membase", card->membase);
- switch (card->cardtype) {
- case avm_b1isa: s = "B1 ISA"; break;
- case avm_b1pci: s = "B1 PCI"; break;
- case avm_b1pcmcia: s = "B1 PCMCIA"; break;
- case avm_m1: s = "M1"; break;
- case avm_m2: s = "M2"; break;
- case avm_t1isa: s = "T1 ISA (HEMA)"; break;
- case avm_t1pci: s = "T1 PCI"; break;
- case avm_c4: s = "C4"; break;
- case avm_c2: s = "C2"; break;
- default: s = "???"; break;
- }
- seq_printf(m, "%-16s %s\n", "type", s);
- if ((s = cinfo->version[VER_DRIVER]) != NULL)
- seq_printf(m, "%-16s %s\n", "ver_driver", s);
- if ((s = cinfo->version[VER_CARDTYPE]) != NULL)
- seq_printf(m, "%-16s %s\n", "ver_cardtype", s);
- if ((s = cinfo->version[VER_SERIAL]) != NULL)
- seq_printf(m, "%-16s %s\n", "ver_serial", s);
-
- if (card->cardtype != avm_m1) {
- flag = ((u8 *)(ctrl->profile.manu))[3];
- if (flag)
- seq_printf(m, "%-16s%s%s%s%s%s%s%s\n",
- "protocol",
- (flag & 0x01) ? " DSS1" : "",
- (flag & 0x02) ? " CT1" : "",
- (flag & 0x04) ? " VN3" : "",
- (flag & 0x08) ? " NI1" : "",
- (flag & 0x10) ? " AUSTEL" : "",
- (flag & 0x20) ? " ESS" : "",
- (flag & 0x40) ? " 1TR6" : ""
- );
- }
- if (card->cardtype != avm_m1) {
- flag = ((u8 *)(ctrl->profile.manu))[5];
- if (flag)
- seq_printf(m, "%-16s%s%s%s%s\n",
- "linetype",
- (flag & 0x01) ? " point to point" : "",
- (flag & 0x02) ? " point to multipoint" : "",
- (flag & 0x08) ? " leased line without D-channel" : "",
- (flag & 0x04) ? " leased line with D-channel" : ""
- );
- }
- seq_printf(m, "%-16s %s\n", "cardname", cinfo->cardname);
-
-
- spin_lock_irqsave(&card->lock, flags);
-
- txoff = (dma_addr_t)b1dma_readl(card, AMCC_TXPTR)-card->dma->sendbuf.dmaaddr;
- txlen = b1dma_readl(card, AMCC_TXLEN);
-
- rxoff = (dma_addr_t)b1dma_readl(card, AMCC_RXPTR)-card->dma->recvbuf.dmaaddr;
- rxlen = b1dma_readl(card, AMCC_RXLEN);
-
- csr = b1dma_readl(card, AMCC_INTCSR);
-
- spin_unlock_irqrestore(&card->lock, flags);
-
- seq_printf(m, "%-16s 0x%lx\n", "csr (cached)", (unsigned long)card->csr);
- seq_printf(m, "%-16s 0x%lx\n", "csr", (unsigned long)csr);
- seq_printf(m, "%-16s %lu\n", "txoff", (unsigned long)txoff);
- seq_printf(m, "%-16s %lu\n", "txlen", (unsigned long)txlen);
- seq_printf(m, "%-16s %lu\n", "rxoff", (unsigned long)rxoff);
- seq_printf(m, "%-16s %lu\n", "rxlen", (unsigned long)rxlen);
-
- return 0;
-}
-EXPORT_SYMBOL(b1dma_proc_show);
-
-/* ------------------------------------------------------------- */
-
-EXPORT_SYMBOL(b1dma_reset);
-EXPORT_SYMBOL(t1pci_detect);
-EXPORT_SYMBOL(b1pciv4_detect);
-EXPORT_SYMBOL(b1dma_interrupt);
-
-EXPORT_SYMBOL(b1dma_load_firmware);
-EXPORT_SYMBOL(b1dma_reset_ctr);
-EXPORT_SYMBOL(b1dma_register_appl);
-EXPORT_SYMBOL(b1dma_release_appl);
-EXPORT_SYMBOL(b1dma_send_message);
-
-static int __init b1dma_init(void)
-{
- char *p;
- char rev[32];
-
- if ((p = strchr(revision, ':')) != NULL && p[1]) {
- strlcpy(rev, p + 2, sizeof(rev));
- if ((p = strchr(rev, '$')) != NULL && p > rev)
- *(p - 1) = 0;
- } else
- strcpy(rev, "1.0");
-
- printk(KERN_INFO "b1dma: revision %s\n", rev);
-
- return 0;
-}
-
-static void __exit b1dma_exit(void)
-{
-}
-
-module_init(b1dma_init);
-module_exit(b1dma_exit);
diff --git a/drivers/staging/isdn/avm/b1isa.c b/drivers/staging/isdn/avm/b1isa.c
deleted file mode 100644
index cdfea72e0ef6..000000000000
--- a/drivers/staging/isdn/avm/b1isa.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/* $Id: b1isa.c,v 1.1.2.3 2004/02/10 01:07:12 keil Exp $
- *
- * Module for AVM B1 ISA-card.
- *
- * 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.
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/skbuff.h>
-#include <linux/delay.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/capi.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <asm/io.h>
-#include <linux/isdn/capicmd.h>
-#include <linux/isdn/capiutil.h>
-#include <linux/isdn/capilli.h>
-#include "avmcard.h"
-
-/* ------------------------------------------------------------- */
-
-static char *revision = "$Revision: 1.1.2.3 $";
-
-/* ------------------------------------------------------------- */
-
-MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM B1 ISA card");
-MODULE_AUTHOR("Carsten Paeth");
-MODULE_LICENSE("GPL");
-
-/* ------------------------------------------------------------- */
-
-static void b1isa_remove(struct pci_dev *pdev)
-{
- avmctrl_info *cinfo = pci_get_drvdata(pdev);
- avmcard *card;
-
- if (!cinfo)
- return;
-
- card = cinfo->card;
-
- b1_reset(card->port);
- b1_reset(card->port);
-
- detach_capi_ctr(&cinfo->capi_ctrl);
- free_irq(card->irq, card);
- release_region(card->port, AVMB1_PORTLEN);
- b1_free_card(card);
-}
-
-/* ------------------------------------------------------------- */
-
-static char *b1isa_procinfo(struct capi_ctr *ctrl);
-
-static int b1isa_probe(struct pci_dev *pdev)
-{
- avmctrl_info *cinfo;
- avmcard *card;
- int retval;
-
- card = b1_alloc_card(1);
- if (!card) {
- printk(KERN_WARNING "b1isa: no memory.\n");
- retval = -ENOMEM;
- goto err;
- }
-
- cinfo = card->ctrlinfo;
-
- card->port = pci_resource_start(pdev, 0);
- card->irq = pdev->irq;
- card->cardtype = avm_b1isa;
- sprintf(card->name, "b1isa-%x", card->port);
-
- if (card->port != 0x150 && card->port != 0x250
- && card->port != 0x300 && card->port != 0x340) {
- printk(KERN_WARNING "b1isa: invalid port 0x%x.\n", card->port);
- retval = -EINVAL;
- goto err_free;
- }
- if (b1_irq_table[card->irq & 0xf] == 0) {
- printk(KERN_WARNING "b1isa: irq %d not valid.\n", card->irq);
- retval = -EINVAL;
- goto err_free;
- }
- if (!request_region(card->port, AVMB1_PORTLEN, card->name)) {
- printk(KERN_WARNING "b1isa: ports 0x%03x-0x%03x in use.\n",
- card->port, card->port + AVMB1_PORTLEN);
- retval = -EBUSY;
- goto err_free;
- }
- retval = request_irq(card->irq, b1_interrupt, 0, card->name, card);
- if (retval) {
- printk(KERN_ERR "b1isa: unable to get IRQ %d.\n", card->irq);
- goto err_release_region;
- }
- b1_reset(card->port);
- if ((retval = b1_detect(card->port, card->cardtype)) != 0) {
- printk(KERN_NOTICE "b1isa: NO card at 0x%x (%d)\n",
- card->port, retval);
- retval = -ENODEV;
- goto err_free_irq;
- }
- b1_reset(card->port);
- b1_getrevision(card);
-
- cinfo->capi_ctrl.owner = THIS_MODULE;
- cinfo->capi_ctrl.driver_name = "b1isa";
- cinfo->capi_ctrl.driverdata = cinfo;
- cinfo->capi_ctrl.register_appl = b1_register_appl;
- cinfo->capi_ctrl.release_appl = b1_release_appl;
- cinfo->capi_ctrl.send_message = b1_send_message;
- cinfo->capi_ctrl.load_firmware = b1_load_firmware;
- cinfo->capi_ctrl.reset_ctr = b1_reset_ctr;
- cinfo->capi_ctrl.procinfo = b1isa_procinfo;
- cinfo->capi_ctrl.proc_show = b1_proc_show;
- strcpy(cinfo->capi_ctrl.name, card->name);
-
- retval = attach_capi_ctr(&cinfo->capi_ctrl);
- if (retval) {
- printk(KERN_ERR "b1isa: attach controller failed.\n");
- goto err_free_irq;
- }
-
- printk(KERN_INFO "b1isa: AVM B1 ISA at i/o %#x, irq %d, revision %d\n",
- card->port, card->irq, card->revision);
-
- pci_set_drvdata(pdev, cinfo);
- return 0;
-
-err_free_irq:
- free_irq(card->irq, card);
-err_release_region:
- release_region(card->port, AVMB1_PORTLEN);
-err_free:
- b1_free_card(card);
-err:
- return retval;
-}
-
-static char *b1isa_procinfo(struct capi_ctr *ctrl)
-{
- avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
-
- if (!cinfo)
- return "";
- sprintf(cinfo->infobuf, "%s %s 0x%x %d r%d",
- cinfo->cardname[0] ? cinfo->cardname : "-",
- cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-",
- cinfo->card ? cinfo->card->port : 0x0,
- cinfo->card ? cinfo->card->irq : 0,
- cinfo->card ? cinfo->card->revision : 0
- );
- return cinfo->infobuf;
-}
-
-/* ------------------------------------------------------------- */
-
-#define MAX_CARDS 4
-static struct pci_dev isa_dev[MAX_CARDS];
-static int io[MAX_CARDS];
-static int irq[MAX_CARDS];
-
-module_param_hw_array(io, int, ioport, NULL, 0);
-module_param_hw_array(irq, int, irq, NULL, 0);
-MODULE_PARM_DESC(io, "I/O base address(es)");
-MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)");
-
-static int b1isa_add_card(struct capi_driver *driver, capicardparams *data)
-{
- int i;
-
- for (i = 0; i < MAX_CARDS; i++) {
- if (isa_dev[i].resource[0].start)
- continue;
-
- isa_dev[i].resource[0].start = data->port;
- isa_dev[i].irq = data->irq;
-
- if (b1isa_probe(&isa_dev[i]) == 0)
- return 0;
- }
- return -ENODEV;
-}
-
-static struct capi_driver capi_driver_b1isa = {
- .name = "b1isa",
- .revision = "1.0",
- .add_card = b1isa_add_card,
-};
-
-static int __init b1isa_init(void)
-{
- char *p;
- char rev[32];
- int i;
-
- if ((p = strchr(revision, ':')) != NULL && p[1]) {
- strlcpy(rev, p + 2, 32);
- if ((p = strchr(rev, '$')) != NULL && p > rev)
- *(p - 1) = 0;
- } else
- strcpy(rev, "1.0");
-
- for (i = 0; i < MAX_CARDS; i++) {
- if (!io[i])
- break;
-
- isa_dev[i].resource[0].start = io[i];
- isa_dev[i].irq = irq[i];
-
- if (b1isa_probe(&isa_dev[i]) != 0)
- return -ENODEV;
- }
-
- strlcpy(capi_driver_b1isa.revision, rev, 32);
- register_capi_driver(&capi_driver_b1isa);
- printk(KERN_INFO "b1isa: revision %s\n", rev);
-
- return 0;
-}
-
-static void __exit b1isa_exit(void)
-{
- int i;
-
- for (i = 0; i < MAX_CARDS; i++) {
- if (isa_dev[i].resource[0].start)
- b1isa_remove(&isa_dev[i]);
- }
- unregister_capi_driver(&capi_driver_b1isa);
-}
-
-module_init(b1isa_init);
-module_exit(b1isa_exit);
diff --git a/drivers/staging/isdn/avm/b1pci.c b/drivers/staging/isdn/avm/b1pci.c
deleted file mode 100644
index b76b57a82c02..000000000000
--- a/drivers/staging/isdn/avm/b1pci.c
+++ /dev/null
@@ -1,416 +0,0 @@
-/* $Id: b1pci.c,v 1.1.2.2 2004/01/16 21:09:27 keil Exp $
- *
- * Module for AVM B1 PCI-card.
- *
- * 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.
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/skbuff.h>
-#include <linux/delay.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/pci.h>
-#include <linux/capi.h>
-#include <asm/io.h>
-#include <linux/init.h>
-#include <linux/isdn/capicmd.h>
-#include <linux/isdn/capiutil.h>
-#include <linux/isdn/capilli.h>
-#include "avmcard.h"
-
-/* ------------------------------------------------------------- */
-
-static char *revision = "$Revision: 1.1.2.2 $";
-
-/* ------------------------------------------------------------- */
-
-static struct pci_device_id b1pci_pci_tbl[] = {
- { PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_B1, PCI_ANY_ID, PCI_ANY_ID },
- { } /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(pci, b1pci_pci_tbl);
-MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM B1 PCI card");
-MODULE_AUTHOR("Carsten Paeth");
-MODULE_LICENSE("GPL");
-
-/* ------------------------------------------------------------- */
-
-static char *b1pci_procinfo(struct capi_ctr *ctrl)
-{
- avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
-
- if (!cinfo)
- return "";
- sprintf(cinfo->infobuf, "%s %s 0x%x %d r%d",
- cinfo->cardname[0] ? cinfo->cardname : "-",
- cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-",
- cinfo->card ? cinfo->card->port : 0x0,
- cinfo->card ? cinfo->card->irq : 0,
- cinfo->card ? cinfo->card->revision : 0
- );
- return cinfo->infobuf;
-}
-
-/* ------------------------------------------------------------- */
-
-static int b1pci_probe(struct capicardparams *p, struct pci_dev *pdev)
-{
- avmcard *card;
- avmctrl_info *cinfo;
- int retval;
-
- card = b1_alloc_card(1);
- if (!card) {
- printk(KERN_WARNING "b1pci: no memory.\n");
- retval = -ENOMEM;
- goto err;
- }
-
- cinfo = card->ctrlinfo;
- sprintf(card->name, "b1pci-%x", p->port);
- card->port = p->port;
- card->irq = p->irq;
- card->cardtype = avm_b1pci;
-
- if (!request_region(card->port, AVMB1_PORTLEN, card->name)) {
- printk(KERN_WARNING "b1pci: ports 0x%03x-0x%03x in use.\n",
- card->port, card->port + AVMB1_PORTLEN);
- retval = -EBUSY;
- goto err_free;
- }
- b1_reset(card->port);
- retval = b1_detect(card->port, card->cardtype);
- if (retval) {
- printk(KERN_NOTICE "b1pci: NO card at 0x%x (%d)\n",
- card->port, retval);
- retval = -ENODEV;
- goto err_release_region;
- }
- b1_reset(card->port);
- b1_getrevision(card);
-
- retval = request_irq(card->irq, b1_interrupt, IRQF_SHARED, card->name, card);
- if (retval) {
- printk(KERN_ERR "b1pci: unable to get IRQ %d.\n", card->irq);
- retval = -EBUSY;
- goto err_release_region;
- }
-
- cinfo->capi_ctrl.driver_name = "b1pci";
- cinfo->capi_ctrl.driverdata = cinfo;
- cinfo->capi_ctrl.register_appl = b1_register_appl;
- cinfo->capi_ctrl.release_appl = b1_release_appl;
- cinfo->capi_ctrl.send_message = b1_send_message;
- cinfo->capi_ctrl.load_firmware = b1_load_firmware;
- cinfo->capi_ctrl.reset_ctr = b1_reset_ctr;
- cinfo->capi_ctrl.procinfo = b1pci_procinfo;
- cinfo->capi_ctrl.proc_show = b1_proc_show;
- strcpy(cinfo->capi_ctrl.name, card->name);
- cinfo->capi_ctrl.owner = THIS_MODULE;
-
- retval = attach_capi_ctr(&cinfo->capi_ctrl);
- if (retval) {
- printk(KERN_ERR "b1pci: attach controller failed.\n");
- goto err_free_irq;
- }
-
- if (card->revision >= 4) {
- printk(KERN_INFO "b1pci: AVM B1 PCI V4 at i/o %#x, irq %d, revision %d (no dma)\n",
- card->port, card->irq, card->revision);
- } else {
- printk(KERN_INFO "b1pci: AVM B1 PCI at i/o %#x, irq %d, revision %d\n",
- card->port, card->irq, card->revision);
- }
-
- pci_set_drvdata(pdev, card);
- return 0;
-
-err_free_irq:
- free_irq(card->irq, card);
-err_release_region:
- release_region(card->port, AVMB1_PORTLEN);
-err_free:
- b1_free_card(card);
-err:
- return retval;
-}
-
-static void b1pci_remove(struct pci_dev *pdev)
-{
- avmcard *card = pci_get_drvdata(pdev);
- avmctrl_info *cinfo = card->ctrlinfo;
- unsigned int port = card->port;
-
- b1_reset(port);
- b1_reset(port);
-
- detach_capi_ctr(&cinfo->capi_ctrl);
- free_irq(card->irq, card);
- release_region(card->port, AVMB1_PORTLEN);
- b1_free_card(card);
-}
-
-#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
-/* ------------------------------------------------------------- */
-
-static char *b1pciv4_procinfo(struct capi_ctr *ctrl)
-{
- avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
-
- if (!cinfo)
- return "";
- sprintf(cinfo->infobuf, "%s %s 0x%x %d 0x%lx r%d",
- cinfo->cardname[0] ? cinfo->cardname : "-",
- cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-",
- cinfo->card ? cinfo->card->port : 0x0,
- cinfo->card ? cinfo->card->irq : 0,
- cinfo->card ? cinfo->card->membase : 0,
- cinfo->card ? cinfo->card->revision : 0
- );
- return cinfo->infobuf;
-}
-
-/* ------------------------------------------------------------- */
-
-static int b1pciv4_probe(struct capicardparams *p, struct pci_dev *pdev)
-{
- avmcard *card;
- avmctrl_info *cinfo;
- int retval;
-
- card = b1_alloc_card(1);
- if (!card) {
- printk(KERN_WARNING "b1pci: no memory.\n");
- retval = -ENOMEM;
- goto err;
- }
-
- card->dma = avmcard_dma_alloc("b1pci", pdev, 2048 + 128, 2048 + 128);
- if (!card->dma) {
- printk(KERN_WARNING "b1pci: dma alloc.\n");
- retval = -ENOMEM;
- goto err_free;
- }
-
- cinfo = card->ctrlinfo;
- sprintf(card->name, "b1pciv4-%x", p->port);
- card->port = p->port;
- card->irq = p->irq;
- card->membase = p->membase;
- card->cardtype = avm_b1pci;
-
- if (!request_region(card->port, AVMB1_PORTLEN, card->name)) {
- printk(KERN_WARNING "b1pci: ports 0x%03x-0x%03x in use.\n",
- card->port, card->port + AVMB1_PORTLEN);
- retval = -EBUSY;
- goto err_free_dma;
- }
-
- card->mbase = ioremap(card->membase, 64);
- if (!card->mbase) {
- printk(KERN_NOTICE "b1pci: can't remap memory at 0x%lx\n",
- card->membase);
- retval = -ENOMEM;
- goto err_release_region;
- }
-
- b1dma_reset(card);
-
- retval = b1pciv4_detect(card);
- if (retval) {
- printk(KERN_NOTICE "b1pci: NO card at 0x%x (%d)\n",
- card->port, retval);
- retval = -ENODEV;
- goto err_unmap;
- }
- b1dma_reset(card);
- b1_getrevision(card);
-
- retval = request_irq(card->irq, b1dma_interrupt, IRQF_SHARED, card->name, card);
- if (retval) {
- printk(KERN_ERR "b1pci: unable to get IRQ %d.\n",
- card->irq);
- retval = -EBUSY;
- goto err_unmap;
- }
-
- cinfo->capi_ctrl.owner = THIS_MODULE;
- cinfo->capi_ctrl.driver_name = "b1pciv4";
- cinfo->capi_ctrl.driverdata = cinfo;
- cinfo->capi_ctrl.register_appl = b1dma_register_appl;
- cinfo->capi_ctrl.release_appl = b1dma_release_appl;
- cinfo->capi_ctrl.send_message = b1dma_send_message;
- cinfo->capi_ctrl.load_firmware = b1dma_load_firmware;
- cinfo->capi_ctrl.reset_ctr = b1dma_reset_ctr;
- cinfo->capi_ctrl.procinfo = b1pciv4_procinfo;
- cinfo->capi_ctrl.proc_show = b1dma_proc_show;
- strcpy(cinfo->capi_ctrl.name, card->name);
-
- retval = attach_capi_ctr(&cinfo->capi_ctrl);
- if (retval) {
- printk(KERN_ERR "b1pci: attach controller failed.\n");
- goto err_free_irq;
- }
- card->cardnr = cinfo->capi_ctrl.cnr;
-
- printk(KERN_INFO "b1pci: AVM B1 PCI V4 at i/o %#x, irq %d, mem %#lx, revision %d (dma)\n",
- card->port, card->irq, card->membase, card->revision);
-
- pci_set_drvdata(pdev, card);
- return 0;
-
-err_free_irq:
- free_irq(card->irq, card);
-err_unmap:
- iounmap(card->mbase);
-err_release_region:
- release_region(card->port, AVMB1_PORTLEN);
-err_free_dma:
- avmcard_dma_free(card->dma);
-err_free:
- b1_free_card(card);
-err:
- return retval;
-
-}
-
-static void b1pciv4_remove(struct pci_dev *pdev)
-{
- avmcard *card = pci_get_drvdata(pdev);
- avmctrl_info *cinfo = card->ctrlinfo;
-
- b1dma_reset(card);
-
- detach_capi_ctr(&cinfo->capi_ctrl);
- free_irq(card->irq, card);
- iounmap(card->mbase);
- release_region(card->port, AVMB1_PORTLEN);
- avmcard_dma_free(card->dma);
- b1_free_card(card);
-}
-
-#endif /* CONFIG_ISDN_DRV_AVMB1_B1PCIV4 */
-
-static int b1pci_pci_probe(struct pci_dev *pdev,
- const struct pci_device_id *ent)
-{
- struct capicardparams param;
- int retval;
-
- if (pci_enable_device(pdev) < 0) {
- printk(KERN_ERR "b1pci: failed to enable AVM-B1\n");
- return -ENODEV;
- }
- param.irq = pdev->irq;
-
- if (pci_resource_start(pdev, 2)) { /* B1 PCI V4 */
-#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
- pci_set_master(pdev);
-#endif
- param.membase = pci_resource_start(pdev, 0);
- param.port = pci_resource_start(pdev, 2);
-
- printk(KERN_INFO "b1pci: PCI BIOS reports AVM-B1 V4 at i/o %#x, irq %d, mem %#x\n",
- param.port, param.irq, param.membase);
-#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
- retval = b1pciv4_probe(&param, pdev);
-#else
- retval = b1pci_probe(&param, pdev);
-#endif
- if (retval != 0) {
- printk(KERN_ERR "b1pci: no AVM-B1 V4 at i/o %#x, irq %d, mem %#x detected\n",
- param.port, param.irq, param.membase);
- }
- } else {
- param.membase = 0;
- param.port = pci_resource_start(pdev, 1);
-
- printk(KERN_INFO "b1pci: PCI BIOS reports AVM-B1 at i/o %#x, irq %d\n",
- param.port, param.irq);
- retval = b1pci_probe(&param, pdev);
- if (retval != 0) {
- printk(KERN_ERR "b1pci: no AVM-B1 at i/o %#x, irq %d detected\n",
- param.port, param.irq);
- }
- }
- return retval;
-}
-
-static void b1pci_pci_remove(struct pci_dev *pdev)
-{
-#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
- avmcard *card = pci_get_drvdata(pdev);
-
- if (card->dma)
- b1pciv4_remove(pdev);
- else
- b1pci_remove(pdev);
-#else
- b1pci_remove(pdev);
-#endif
-}
-
-static struct pci_driver b1pci_pci_driver = {
- .name = "b1pci",
- .id_table = b1pci_pci_tbl,
- .probe = b1pci_pci_probe,
- .remove = b1pci_pci_remove,
-};
-
-static struct capi_driver capi_driver_b1pci = {
- .name = "b1pci",
- .revision = "1.0",
-};
-#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
-static struct capi_driver capi_driver_b1pciv4 = {
- .name = "b1pciv4",
- .revision = "1.0",
-};
-#endif
-
-static int __init b1pci_init(void)
-{
- char *p;
- char rev[32];
- int err;
-
- if ((p = strchr(revision, ':')) != NULL && p[1]) {
- strlcpy(rev, p + 2, 32);
- if ((p = strchr(rev, '$')) != NULL && p > rev)
- *(p - 1) = 0;
- } else
- strcpy(rev, "1.0");
-
-
- err = pci_register_driver(&b1pci_pci_driver);
- if (!err) {
- strlcpy(capi_driver_b1pci.revision, rev, 32);
- register_capi_driver(&capi_driver_b1pci);
-#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
- strlcpy(capi_driver_b1pciv4.revision, rev, 32);
- register_capi_driver(&capi_driver_b1pciv4);
-#endif
- printk(KERN_INFO "b1pci: revision %s\n", rev);
- }
- return err;
-}
-
-static void __exit b1pci_exit(void)
-{
- unregister_capi_driver(&capi_driver_b1pci);
-#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
- unregister_capi_driver(&capi_driver_b1pciv4);
-#endif
- pci_unregister_driver(&b1pci_pci_driver);
-}
-
-module_init(b1pci_init);
-module_exit(b1pci_exit);
diff --git a/drivers/staging/isdn/avm/b1pcmcia.c b/drivers/staging/isdn/avm/b1pcmcia.c
deleted file mode 100644
index 3aca16e62902..000000000000
--- a/drivers/staging/isdn/avm/b1pcmcia.c
+++ /dev/null
@@ -1,224 +0,0 @@
-/* $Id: b1pcmcia.c,v 1.1.2.2 2004/01/16 21:09:27 keil Exp $
- *
- * Module for AVM B1/M1/M2 PCMCIA-card.
- *
- * 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.
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/skbuff.h>
-#include <linux/delay.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <asm/io.h>
-#include <linux/capi.h>
-#include <linux/b1pcmcia.h>
-#include <linux/isdn/capicmd.h>
-#include <linux/isdn/capiutil.h>
-#include <linux/isdn/capilli.h>
-#include "avmcard.h"
-
-/* ------------------------------------------------------------- */
-
-static char *revision = "$Revision: 1.1.2.2 $";
-
-/* ------------------------------------------------------------- */
-
-MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM PCMCIA cards");
-MODULE_AUTHOR("Carsten Paeth");
-MODULE_LICENSE("GPL");
-
-/* ------------------------------------------------------------- */
-
-static void b1pcmcia_remove_ctr(struct capi_ctr *ctrl)
-{
- avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
- avmcard *card = cinfo->card;
- unsigned int port = card->port;
-
- b1_reset(port);
- b1_reset(port);
-
- detach_capi_ctr(ctrl);
- free_irq(card->irq, card);
- b1_free_card(card);
-}
-
-/* ------------------------------------------------------------- */
-
-static LIST_HEAD(cards);
-
-static char *b1pcmcia_procinfo(struct capi_ctr *ctrl);
-
-static int b1pcmcia_add_card(unsigned int port, unsigned irq,
- enum avmcardtype cardtype)
-{
- avmctrl_info *cinfo;
- avmcard *card;
- char *cardname;
- int retval;
-
- card = b1_alloc_card(1);
- if (!card) {
- printk(KERN_WARNING "b1pcmcia: no memory.\n");
- retval = -ENOMEM;
- goto err;
- }
- cinfo = card->ctrlinfo;
-
- switch (cardtype) {
- case avm_m1: sprintf(card->name, "m1-%x", port); break;
- case avm_m2: sprintf(card->name, "m2-%x", port); break;
- default: sprintf(card->name, "b1pcmcia-%x", port); break;
- }
- card->port = port;
- card->irq = irq;
- card->cardtype = cardtype;
-
- retval = request_irq(card->irq, b1_interrupt, IRQF_SHARED, card->name, card);
- if (retval) {
- printk(KERN_ERR "b1pcmcia: unable to get IRQ %d.\n",
- card->irq);
- retval = -EBUSY;
- goto err_free;
- }
- b1_reset(card->port);
- if ((retval = b1_detect(card->port, card->cardtype)) != 0) {
- printk(KERN_NOTICE "b1pcmcia: NO card at 0x%x (%d)\n",
- card->port, retval);
- retval = -ENODEV;
- goto err_free_irq;
- }
- b1_reset(card->port);
- b1_getrevision(card);
-
- cinfo->capi_ctrl.owner = THIS_MODULE;
- cinfo->capi_ctrl.driver_name = "b1pcmcia";
- cinfo->capi_ctrl.driverdata = cinfo;
- cinfo->capi_ctrl.register_appl = b1_register_appl;
- cinfo->capi_ctrl.release_appl = b1_release_appl;
- cinfo->capi_ctrl.send_message = b1_send_message;
- cinfo->capi_ctrl.load_firmware = b1_load_firmware;
- cinfo->capi_ctrl.reset_ctr = b1_reset_ctr;
- cinfo->capi_ctrl.procinfo = b1pcmcia_procinfo;
- cinfo->capi_ctrl.proc_show = b1_proc_show;
- strcpy(cinfo->capi_ctrl.name, card->name);
-
- retval = attach_capi_ctr(&cinfo->capi_ctrl);
- if (retval) {
- printk(KERN_ERR "b1pcmcia: attach controller failed.\n");
- goto err_free_irq;
- }
- switch (cardtype) {
- case avm_m1: cardname = "M1"; break;
- case avm_m2: cardname = "M2"; break;
- default: cardname = "B1 PCMCIA"; break;
- }
-
- printk(KERN_INFO "b1pcmcia: AVM %s at i/o %#x, irq %d, revision %d\n",
- cardname, card->port, card->irq, card->revision);
-
- list_add(&card->list, &cards);
- return cinfo->capi_ctrl.cnr;
-
-err_free_irq:
- free_irq(card->irq, card);
-err_free:
- b1_free_card(card);
-err:
- return retval;
-}
-
-/* ------------------------------------------------------------- */
-
-static char *b1pcmcia_procinfo(struct capi_ctr *ctrl)
-{
- avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
-
- if (!cinfo)
- return "";
- sprintf(cinfo->infobuf, "%s %s 0x%x %d r%d",
- cinfo->cardname[0] ? cinfo->cardname : "-",
- cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-",
- cinfo->card ? cinfo->card->port : 0x0,
- cinfo->card ? cinfo->card->irq : 0,
- cinfo->card ? cinfo->card->revision : 0
- );
- return cinfo->infobuf;
-}
-
-/* ------------------------------------------------------------- */
-
-int b1pcmcia_addcard_b1(unsigned int port, unsigned irq)
-{
- return b1pcmcia_add_card(port, irq, avm_b1pcmcia);
-}
-
-int b1pcmcia_addcard_m1(unsigned int port, unsigned irq)
-{
- return b1pcmcia_add_card(port, irq, avm_m1);
-}
-
-int b1pcmcia_addcard_m2(unsigned int port, unsigned irq)
-{
- return b1pcmcia_add_card(port, irq, avm_m2);
-}
-
-int b1pcmcia_delcard(unsigned int port, unsigned irq)
-{
- struct list_head *l;
- avmcard *card;
-
- list_for_each(l, &cards) {
- card = list_entry(l, avmcard, list);
- if (card->port == port && card->irq == irq) {
- b1pcmcia_remove_ctr(&card->ctrlinfo[0].capi_ctrl);
- return 0;
- }
- }
- return -ESRCH;
-}
-
-EXPORT_SYMBOL(b1pcmcia_addcard_b1);
-EXPORT_SYMBOL(b1pcmcia_addcard_m1);
-EXPORT_SYMBOL(b1pcmcia_addcard_m2);
-EXPORT_SYMBOL(b1pcmcia_delcard);
-
-static struct capi_driver capi_driver_b1pcmcia = {
- .name = "b1pcmcia",
- .revision = "1.0",
-};
-
-static int __init b1pcmcia_init(void)
-{
- char *p;
- char rev[32];
-
- if ((p = strchr(revision, ':')) != NULL && p[1]) {
- strlcpy(rev, p + 2, 32);
- if ((p = strchr(rev, '$')) != NULL && p > rev)
- *(p - 1) = 0;
- } else
- strcpy(rev, "1.0");
-
- strlcpy(capi_driver_b1pcmcia.revision, rev, 32);
- register_capi_driver(&capi_driver_b1pcmcia);
- printk(KERN_INFO "b1pci: revision %s\n", rev);
-
- return 0;
-}
-
-static void __exit b1pcmcia_exit(void)
-{
- unregister_capi_driver(&capi_driver_b1pcmcia);
-}
-
-module_init(b1pcmcia_init);
-module_exit(b1pcmcia_exit);
diff --git a/drivers/staging/isdn/avm/c4.c b/drivers/staging/isdn/avm/c4.c
deleted file mode 100644
index ac72cd204c4d..000000000000
--- a/drivers/staging/isdn/avm/c4.c
+++ /dev/null
@@ -1,1317 +0,0 @@
-/* $Id: c4.c,v 1.1.2.2 2004/01/16 21:09:27 keil Exp $
- *
- * Module for AVM C4 & C2 card.
- *
- * 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.
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/skbuff.h>
-#include <linux/delay.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/pci.h>
-#include <linux/capi.h>
-#include <linux/kernelcapi.h>
-#include <linux/init.h>
-#include <linux/gfp.h>
-#include <asm/io.h>
-#include <linux/uaccess.h>
-#include <linux/netdevice.h>
-#include <linux/isdn/capicmd.h>
-#include <linux/isdn/capiutil.h>
-#include <linux/isdn/capilli.h>
-#include "avmcard.h"
-
-#undef AVM_C4_DEBUG
-#undef AVM_C4_POLLDEBUG
-
-/* ------------------------------------------------------------- */
-
-static char *revision = "$Revision: 1.1.2.2 $";
-
-/* ------------------------------------------------------------- */
-
-static bool suppress_pollack;
-
-static const struct pci_device_id c4_pci_tbl[] = {
- { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285, PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_C4, 0, 0, (unsigned long)4 },
- { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285, PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_C2, 0, 0, (unsigned long)2 },
- { } /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(pci, c4_pci_tbl);
-MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM C2/C4 cards");
-MODULE_AUTHOR("Carsten Paeth");
-MODULE_LICENSE("GPL");
-module_param(suppress_pollack, bool, 0);
-
-/* ------------------------------------------------------------- */
-
-static void c4_dispatch_tx(avmcard *card);
-
-/* ------------------------------------------------------------- */
-
-#define DC21285_DRAM_A0MR 0x40000000
-#define DC21285_DRAM_A1MR 0x40004000
-#define DC21285_DRAM_A2MR 0x40008000
-#define DC21285_DRAM_A3MR 0x4000C000
-
-#define CAS_OFFSET 0x88
-
-#define DC21285_ARMCSR_BASE 0x42000000
-
-#define PCI_OUT_INT_STATUS 0x30
-#define PCI_OUT_INT_MASK 0x34
-#define MAILBOX_0 0x50
-#define MAILBOX_1 0x54
-#define MAILBOX_2 0x58
-#define MAILBOX_3 0x5C
-#define DOORBELL 0x60
-#define DOORBELL_SETUP 0x64
-
-#define CHAN_1_CONTROL 0x90
-#define CHAN_2_CONTROL 0xB0
-#define DRAM_TIMING 0x10C
-#define DRAM_ADDR_SIZE_0 0x110
-#define DRAM_ADDR_SIZE_1 0x114
-#define DRAM_ADDR_SIZE_2 0x118
-#define DRAM_ADDR_SIZE_3 0x11C
-#define SA_CONTROL 0x13C
-#define XBUS_CYCLE 0x148
-#define XBUS_STROBE 0x14C
-#define DBELL_PCI_MASK 0x150
-#define DBELL_SA_MASK 0x154
-
-#define SDRAM_SIZE 0x1000000
-
-/* ------------------------------------------------------------- */
-
-#define MBOX_PEEK_POKE MAILBOX_0
-
-#define DBELL_ADDR 0x01
-#define DBELL_DATA 0x02
-#define DBELL_RNWR 0x40
-#define DBELL_INIT 0x80
-
-/* ------------------------------------------------------------- */
-
-#define MBOX_UP_ADDR MAILBOX_0
-#define MBOX_UP_LEN MAILBOX_1
-#define MBOX_DOWN_ADDR MAILBOX_2
-#define MBOX_DOWN_LEN MAILBOX_3
-
-#define DBELL_UP_HOST 0x00000100
-#define DBELL_UP_ARM 0x00000200
-#define DBELL_DOWN_HOST 0x00000400
-#define DBELL_DOWN_ARM 0x00000800
-#define DBELL_RESET_HOST 0x40000000
-#define DBELL_RESET_ARM 0x80000000
-
-/* ------------------------------------------------------------- */
-
-#define DRAM_TIMING_DEF 0x001A01A5
-#define DRAM_AD_SZ_DEF0 0x00000045
-#define DRAM_AD_SZ_NULL 0x00000000
-
-#define SA_CTL_ALLRIGHT 0x64AA0271
-
-#define INIT_XBUS_CYCLE 0x100016DB
-#define INIT_XBUS_STROBE 0xF1F1F1F1
-
-/* ------------------------------------------------------------- */
-
-#define RESET_TIMEOUT (15 * HZ) /* 15 sec */
-#define PEEK_POKE_TIMEOUT (HZ / 10) /* 0.1 sec */
-
-/* ------------------------------------------------------------- */
-
-#define c4outmeml(addr, value) writel(value, addr)
-#define c4inmeml(addr) readl(addr)
-#define c4outmemw(addr, value) writew(value, addr)
-#define c4inmemw(addr) readw(addr)
-#define c4outmemb(addr, value) writeb(value, addr)
-#define c4inmemb(addr) readb(addr)
-
-/* ------------------------------------------------------------- */
-
-static inline int wait_for_doorbell(avmcard *card, unsigned long t)
-{
- unsigned long stop;
-
- stop = jiffies + t;
- while (c4inmeml(card->mbase + DOORBELL) != 0xffffffff) {
- if (!time_before(jiffies, stop))
- return -1;
- mb();
- }
- return 0;
-}
-
-static int c4_poke(avmcard *card, unsigned long off, unsigned long value)
-{
-
- if (wait_for_doorbell(card, HZ / 10) < 0)
- return -1;
-
- c4outmeml(card->mbase + MBOX_PEEK_POKE, off);
- c4outmeml(card->mbase + DOORBELL, DBELL_ADDR);
-
- if (wait_for_doorbell(card, HZ / 10) < 0)
- return -1;
-
- c4outmeml(card->mbase + MBOX_PEEK_POKE, value);
- c4outmeml(card->mbase + DOORBELL, DBELL_DATA | DBELL_ADDR);
-
- return 0;
-}
-
-static int c4_peek(avmcard *card, unsigned long off, unsigned long *valuep)
-{
- if (wait_for_doorbell(card, HZ / 10) < 0)
- return -1;
-
- c4outmeml(card->mbase + MBOX_PEEK_POKE, off);
- c4outmeml(card->mbase + DOORBELL, DBELL_RNWR | DBELL_ADDR);
-
- if (wait_for_doorbell(card, HZ / 10) < 0)
- return -1;
-
- *valuep = c4inmeml(card->mbase + MBOX_PEEK_POKE);
-
- return 0;
-}
-
-/* ------------------------------------------------------------- */
-
-static int c4_load_t4file(avmcard *card, capiloaddatapart *t4file)
-{
- u32 val;
- unsigned char *dp;
- u_int left;
- u32 loadoff = 0;
-
- dp = t4file->data;
- left = t4file->len;
- while (left >= sizeof(u32)) {
- if (t4file->user) {
- if (copy_from_user(&val, dp, sizeof(val)))
- return -EFAULT;
- } else {
- memcpy(&val, dp, sizeof(val));
- }
- if (c4_poke(card, loadoff, val)) {
- printk(KERN_ERR "%s: corrupted firmware file ?\n",
- card->name);
- return -EIO;
- }
- left -= sizeof(u32);
- dp += sizeof(u32);
- loadoff += sizeof(u32);
- }
- if (left) {
- val = 0;
- if (t4file->user) {
- if (copy_from_user(&val, dp, left))
- return -EFAULT;
- } else {
- memcpy(&val, dp, left);
- }
- if (c4_poke(card, loadoff, val)) {
- printk(KERN_ERR "%s: corrupted firmware file ?\n",
- card->name);
- return -EIO;
- }
- }
- return 0;
-}
-
-/* ------------------------------------------------------------- */
-
-static inline void _put_byte(void **pp, u8 val)
-{
- u8 *s = *pp;
- *s++ = val;
- *pp = s;
-}
-
-static inline void _put_word(void **pp, u32 val)
-{
- u8 *s = *pp;
- *s++ = val & 0xff;
- *s++ = (val >> 8) & 0xff;
- *s++ = (val >> 16) & 0xff;
- *s++ = (val >> 24) & 0xff;
- *pp = s;
-}
-
-static inline void _put_slice(void **pp, unsigned char *dp, unsigned int len)
-{
- unsigned i = len;
- _put_word(pp, i);
- while (i-- > 0)
- _put_byte(pp, *dp++);
-}
-
-static inline u8 _get_byte(void **pp)
-{
- u8 *s = *pp;
- u8 val;
- val = *s++;
- *pp = s;
- return val;
-}
-
-static inline u32 _get_word(void **pp)
-{
- u8 *s = *pp;
- u32 val;
- val = *s++;
- val |= (*s++ << 8);
- val |= (*s++ << 16);
- val |= (*s++ << 24);
- *pp = s;
- return val;
-}
-
-static inline u32 _get_slice(void **pp, unsigned char *dp)
-{
- unsigned int len, i;
-
- len = i = _get_word(pp);
- while (i-- > 0) *dp++ = _get_byte(pp);
- return len;
-}
-
-/* ------------------------------------------------------------- */
-
-static void c4_reset(avmcard *card)
-{
- unsigned long stop;
-
- c4outmeml(card->mbase + DOORBELL, DBELL_RESET_ARM);
-
- stop = jiffies + HZ * 10;
- while (c4inmeml(card->mbase + DOORBELL) != 0xffffffff) {
- if (!time_before(jiffies, stop))
- return;
- c4outmeml(card->mbase + DOORBELL, DBELL_ADDR);
- mb();
- }
-
- c4_poke(card, DC21285_ARMCSR_BASE + CHAN_1_CONTROL, 0);
- c4_poke(card, DC21285_ARMCSR_BASE + CHAN_2_CONTROL, 0);
-}
-
-/* ------------------------------------------------------------- */
-
-static int c4_detect(avmcard *card)
-{
- unsigned long stop, dummy;
-
- c4outmeml(card->mbase + PCI_OUT_INT_MASK, 0x0c);
- if (c4inmeml(card->mbase + PCI_OUT_INT_MASK) != 0x0c)
- return 1;
-
- c4outmeml(card->mbase + DOORBELL, DBELL_RESET_ARM);
-
- stop = jiffies + HZ * 10;
- while (c4inmeml(card->mbase + DOORBELL) != 0xffffffff) {
- if (!time_before(jiffies, stop))
- return 2;
- c4outmeml(card->mbase + DOORBELL, DBELL_ADDR);
- mb();
- }
-
- c4_poke(card, DC21285_ARMCSR_BASE + CHAN_1_CONTROL, 0);
- c4_poke(card, DC21285_ARMCSR_BASE + CHAN_2_CONTROL, 0);
-
- c4outmeml(card->mbase + MAILBOX_0, 0x55aa55aa);
- if (c4inmeml(card->mbase + MAILBOX_0) != 0x55aa55aa) return 3;
-
- c4outmeml(card->mbase + MAILBOX_0, 0xaa55aa55);
- if (c4inmeml(card->mbase + MAILBOX_0) != 0xaa55aa55) return 4;
-
- if (c4_poke(card, DC21285_ARMCSR_BASE + DBELL_SA_MASK, 0)) return 5;
- if (c4_poke(card, DC21285_ARMCSR_BASE + DBELL_PCI_MASK, 0)) return 6;
- if (c4_poke(card, DC21285_ARMCSR_BASE + SA_CONTROL, SA_CTL_ALLRIGHT))
- return 7;
- if (c4_poke(card, DC21285_ARMCSR_BASE + XBUS_CYCLE, INIT_XBUS_CYCLE))
- return 8;
- if (c4_poke(card, DC21285_ARMCSR_BASE + XBUS_STROBE, INIT_XBUS_STROBE))
- return 8;
- if (c4_poke(card, DC21285_ARMCSR_BASE + DRAM_TIMING, 0)) return 9;
-
- mdelay(1);
-
- if (c4_peek(card, DC21285_DRAM_A0MR, &dummy)) return 10;
- if (c4_peek(card, DC21285_DRAM_A1MR, &dummy)) return 11;
- if (c4_peek(card, DC21285_DRAM_A2MR, &dummy)) return 12;
- if (c4_peek(card, DC21285_DRAM_A3MR, &dummy)) return 13;
-
- if (c4_poke(card, DC21285_DRAM_A0MR + CAS_OFFSET, 0)) return 14;
- if (c4_poke(card, DC21285_DRAM_A1MR + CAS_OFFSET, 0)) return 15;
- if (c4_poke(card, DC21285_DRAM_A2MR + CAS_OFFSET, 0)) return 16;
- if (c4_poke(card, DC21285_DRAM_A3MR + CAS_OFFSET, 0)) return 17;
-
- mdelay(1);
-
- if (c4_poke(card, DC21285_ARMCSR_BASE + DRAM_TIMING, DRAM_TIMING_DEF))
- return 18;
-
- if (c4_poke(card, DC21285_ARMCSR_BASE + DRAM_ADDR_SIZE_0, DRAM_AD_SZ_DEF0))
- return 19;
- if (c4_poke(card, DC21285_ARMCSR_BASE + DRAM_ADDR_SIZE_1, DRAM_AD_SZ_NULL))
- return 20;
- if (c4_poke(card, DC21285_ARMCSR_BASE + DRAM_ADDR_SIZE_2, DRAM_AD_SZ_NULL))
- return 21;
- if (c4_poke(card, DC21285_ARMCSR_BASE + DRAM_ADDR_SIZE_3, DRAM_AD_SZ_NULL))
- return 22;
-
- /* Transputer test */
-
- if (c4_poke(card, 0x000000, 0x11111111)
- || c4_poke(card, 0x400000, 0x22222222)
- || c4_poke(card, 0x800000, 0x33333333)
- || c4_poke(card, 0xC00000, 0x44444444))
- return 23;
-
- if (c4_peek(card, 0x000000, &dummy) || dummy != 0x11111111
- || c4_peek(card, 0x400000, &dummy) || dummy != 0x22222222
- || c4_peek(card, 0x800000, &dummy) || dummy != 0x33333333
- || c4_peek(card, 0xC00000, &dummy) || dummy != 0x44444444)
- return 24;
-
- if (c4_poke(card, 0x000000, 0x55555555)
- || c4_poke(card, 0x400000, 0x66666666)
- || c4_poke(card, 0x800000, 0x77777777)
- || c4_poke(card, 0xC00000, 0x88888888))
- return 25;
-
- if (c4_peek(card, 0x000000, &dummy) || dummy != 0x55555555
- || c4_peek(card, 0x400000, &dummy) || dummy != 0x66666666
- || c4_peek(card, 0x800000, &dummy) || dummy != 0x77777777
- || c4_peek(card, 0xC00000, &dummy) || dummy != 0x88888888)
- return 26;
-
- return 0;
-}
-
-/* ------------------------------------------------------------- */
-
-static void c4_dispatch_tx(avmcard *card)
-{
- avmcard_dmainfo *dma = card->dma;
- struct sk_buff *skb;
- u8 cmd, subcmd;
- u16 len;
- u32 txlen;
- void *p;
-
-
- if (card->csr & DBELL_DOWN_ARM) { /* tx busy */
- return;
- }
-
- skb = skb_dequeue(&dma->send_queue);
- if (!skb) {
-#ifdef AVM_C4_DEBUG
- printk(KERN_DEBUG "%s: tx underrun\n", card->name);
-#endif
- return;
- }
-
- len = CAPIMSG_LEN(skb->data);
-
- if (len) {
- cmd = CAPIMSG_COMMAND(skb->data);
- subcmd = CAPIMSG_SUBCOMMAND(skb->data);
-
- p = dma->sendbuf.dmabuf;
-
- if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) {
- u16 dlen = CAPIMSG_DATALEN(skb->data);
- _put_byte(&p, SEND_DATA_B3_REQ);
- _put_slice(&p, skb->data, len);
- _put_slice(&p, skb->data + len, dlen);
- } else {
- _put_byte(&p, SEND_MESSAGE);
- _put_slice(&p, skb->data, len);
- }
- txlen = (u8 *)p - (u8 *)dma->sendbuf.dmabuf;
-#ifdef AVM_C4_DEBUG
- printk(KERN_DEBUG "%s: tx put msg len=%d\n", card->name, txlen);
-#endif
- } else {
- txlen = skb->len - 2;
-#ifdef AVM_C4_POLLDEBUG
- if (skb->data[2] == SEND_POLLACK)
- printk(KERN_INFO "%s: ack to c4\n", card->name);
-#endif
-#ifdef AVM_C4_DEBUG
- printk(KERN_DEBUG "%s: tx put 0x%x len=%d\n",
- card->name, skb->data[2], txlen);
-#endif
- skb_copy_from_linear_data_offset(skb, 2, dma->sendbuf.dmabuf,
- skb->len - 2);
- }
- txlen = (txlen + 3) & ~3;
-
- c4outmeml(card->mbase + MBOX_DOWN_ADDR, dma->sendbuf.dmaaddr);
- c4outmeml(card->mbase + MBOX_DOWN_LEN, txlen);
-
- card->csr |= DBELL_DOWN_ARM;
-
- c4outmeml(card->mbase + DOORBELL, DBELL_DOWN_ARM);
-
- dev_kfree_skb_any(skb);
-}
-
-/* ------------------------------------------------------------- */
-
-static void queue_pollack(avmcard *card)
-{
- struct sk_buff *skb;
- void *p;
-
- skb = alloc_skb(3, GFP_ATOMIC);
- if (!skb) {
- printk(KERN_CRIT "%s: no memory, lost poll ack\n",
- card->name);
- return;
- }
- p = skb->data;
- _put_byte(&p, 0);
- _put_byte(&p, 0);
- _put_byte(&p, SEND_POLLACK);
- skb_put(skb, (u8 *)p - (u8 *)skb->data);
-
- skb_queue_tail(&card->dma->send_queue, skb);
- c4_dispatch_tx(card);
-}
-
-/* ------------------------------------------------------------- */
-
-static void c4_handle_rx(avmcard *card)
-{
- avmcard_dmainfo *dma = card->dma;
- struct capi_ctr *ctrl;
- avmctrl_info *cinfo;
- struct sk_buff *skb;
- void *p = dma->recvbuf.dmabuf;
- u32 ApplId, MsgLen, DataB3Len, NCCI, WindowSize;
- u8 b1cmd = _get_byte(&p);
- u32 cidx;
-
-
-#ifdef AVM_C4_DEBUG
- printk(KERN_DEBUG "%s: rx 0x%x len=%lu\n", card->name,
- b1cmd, (unsigned long)dma->recvlen);
-#endif
-
- switch (b1cmd) {
- case RECEIVE_DATA_B3_IND:
-
- ApplId = (unsigned) _get_word(&p);
- MsgLen = _get_slice(&p, card->msgbuf);
- DataB3Len = _get_slice(&p, card->databuf);
- cidx = CAPIMSG_CONTROLLER(card->msgbuf)-card->cardnr;
- if (cidx >= card->nlogcontr) cidx = 0;
- ctrl = &card->ctrlinfo[cidx].capi_ctrl;
-
- if (MsgLen < 30) { /* not CAPI 64Bit */
- memset(card->msgbuf + MsgLen, 0, 30 - MsgLen);
- MsgLen = 30;
- CAPIMSG_SETLEN(card->msgbuf, 30);
- }
- if (!(skb = alloc_skb(DataB3Len + MsgLen, GFP_ATOMIC))) {
- printk(KERN_ERR "%s: incoming packet dropped\n",
- card->name);
- } else {
- skb_put_data(skb, card->msgbuf, MsgLen);
- skb_put_data(skb, card->databuf, DataB3Len);
- capi_ctr_handle_message(ctrl, ApplId, skb);
- }
- break;
-
- case RECEIVE_MESSAGE:
-
- ApplId = (unsigned) _get_word(&p);
- MsgLen = _get_slice(&p, card->msgbuf);
- cidx = CAPIMSG_CONTROLLER(card->msgbuf)-card->cardnr;
- if (cidx >= card->nlogcontr) cidx = 0;
- cinfo = &card->ctrlinfo[cidx];
- ctrl = &card->ctrlinfo[cidx].capi_ctrl;
-
- if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) {
- printk(KERN_ERR "%s: incoming packet dropped\n",
- card->name);
- } else {
- skb_put_data(skb, card->msgbuf, MsgLen);
- if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_CONF)
- capilib_data_b3_conf(&cinfo->ncci_head, ApplId,
- CAPIMSG_NCCI(skb->data),
- CAPIMSG_MSGID(skb->data));
-
- capi_ctr_handle_message(ctrl, ApplId, skb);
- }
- break;
-
- case RECEIVE_NEW_NCCI:
-
- ApplId = _get_word(&p);
- NCCI = _get_word(&p);
- WindowSize = _get_word(&p);
- cidx = (NCCI & 0x7f) - card->cardnr;
- if (cidx >= card->nlogcontr) cidx = 0;
-
- capilib_new_ncci(&card->ctrlinfo[cidx].ncci_head, ApplId, NCCI, WindowSize);
-
- break;
-
- case RECEIVE_FREE_NCCI:
-
- ApplId = _get_word(&p);
- NCCI = _get_word(&p);
-
- if (NCCI != 0xffffffff) {
- cidx = (NCCI & 0x7f) - card->cardnr;
- if (cidx >= card->nlogcontr) cidx = 0;
- capilib_free_ncci(&card->ctrlinfo[cidx].ncci_head, ApplId, NCCI);
- }
- break;
-
- case RECEIVE_START:
-#ifdef AVM_C4_POLLDEBUG
- printk(KERN_INFO "%s: poll from c4\n", card->name);
-#endif
- if (!suppress_pollack)
- queue_pollack(card);
- for (cidx = 0; cidx < card->nr_controllers; cidx++) {
- ctrl = &card->ctrlinfo[cidx].capi_ctrl;
- capi_ctr_resume_output(ctrl);
- }
- break;
-
- case RECEIVE_STOP:
- for (cidx = 0; cidx < card->nr_controllers; cidx++) {
- ctrl = &card->ctrlinfo[cidx].capi_ctrl;
- capi_ctr_suspend_output(ctrl);
- }
- break;
-
- case RECEIVE_INIT:
-
- cidx = card->nlogcontr;
- if (cidx >= card->nr_controllers) {
- printk(KERN_ERR "%s: card with %d controllers ??\n",
- card->name, cidx + 1);
- break;
- }
- card->nlogcontr++;
- cinfo = &card->ctrlinfo[cidx];
- ctrl = &cinfo->capi_ctrl;
- cinfo->versionlen = _get_slice(&p, cinfo->versionbuf);
- b1_parse_version(cinfo);
- printk(KERN_INFO "%s: %s-card (%s) now active\n",
- card->name,
- cinfo->version[VER_CARDTYPE],
- cinfo->version[VER_DRIVER]);
- capi_ctr_ready(&cinfo->capi_ctrl);
- break;
-
- case RECEIVE_TASK_READY:
- ApplId = (unsigned) _get_word(&p);
- MsgLen = _get_slice(&p, card->msgbuf);
- card->msgbuf[MsgLen] = 0;
- while (MsgLen > 0
- && (card->msgbuf[MsgLen - 1] == '\n'
- || card->msgbuf[MsgLen - 1] == '\r')) {
- card->msgbuf[MsgLen - 1] = 0;
- MsgLen--;
- }
- printk(KERN_INFO "%s: task %d \"%s\" ready.\n",
- card->name, ApplId, card->msgbuf);
- break;
-
- case RECEIVE_DEBUGMSG:
- MsgLen = _get_slice(&p, card->msgbuf);
- card->msgbuf[MsgLen] = 0;
- while (MsgLen > 0
- && (card->msgbuf[MsgLen - 1] == '\n'
- || card->msgbuf[MsgLen - 1] == '\r')) {
- card->msgbuf[MsgLen - 1] = 0;
- MsgLen--;
- }
- printk(KERN_INFO "%s: DEBUG: %s\n", card->name, card->msgbuf);
- break;
-
- default:
- printk(KERN_ERR "%s: c4_interrupt: 0x%x ???\n",
- card->name, b1cmd);
- return;
- }
-}
-
-/* ------------------------------------------------------------- */
-
-static irqreturn_t c4_handle_interrupt(avmcard *card)
-{
- unsigned long flags;
- u32 status;
-
- spin_lock_irqsave(&card->lock, flags);
- status = c4inmeml(card->mbase + DOORBELL);
-
- if (status & DBELL_RESET_HOST) {
- u_int i;
- c4outmeml(card->mbase + PCI_OUT_INT_MASK, 0x0c);
- spin_unlock_irqrestore(&card->lock, flags);
- if (card->nlogcontr == 0)
- return IRQ_HANDLED;
- printk(KERN_ERR "%s: unexpected reset\n", card->name);
- for (i = 0; i < card->nr_controllers; i++) {
- avmctrl_info *cinfo = &card->ctrlinfo[i];
- memset(cinfo->version, 0, sizeof(cinfo->version));
- spin_lock_irqsave(&card->lock, flags);
- capilib_release(&cinfo->ncci_head);
- spin_unlock_irqrestore(&card->lock, flags);
- capi_ctr_down(&cinfo->capi_ctrl);
- }
- card->nlogcontr = 0;
- return IRQ_HANDLED;
- }
-
- status &= (DBELL_UP_HOST | DBELL_DOWN_HOST);
- if (!status) {
- spin_unlock_irqrestore(&card->lock, flags);
- return IRQ_HANDLED;
- }
- c4outmeml(card->mbase + DOORBELL, status);
-
- if ((status & DBELL_UP_HOST) != 0) {
- card->dma->recvlen = c4inmeml(card->mbase + MBOX_UP_LEN);
- c4outmeml(card->mbase + MBOX_UP_LEN, 0);
- c4_handle_rx(card);
- card->dma->recvlen = 0;
- c4outmeml(card->mbase + MBOX_UP_LEN, card->dma->recvbuf.size);
- c4outmeml(card->mbase + DOORBELL, DBELL_UP_ARM);
- }
-
- if ((status & DBELL_DOWN_HOST) != 0) {
- card->csr &= ~DBELL_DOWN_ARM;
- c4_dispatch_tx(card);
- } else if (card->csr & DBELL_DOWN_HOST) {
- if (c4inmeml(card->mbase + MBOX_DOWN_LEN) == 0) {
- card->csr &= ~DBELL_DOWN_ARM;
- c4_dispatch_tx(card);
- }
- }
- spin_unlock_irqrestore(&card->lock, flags);
- return IRQ_HANDLED;
-}
-
-static irqreturn_t c4_interrupt(int interrupt, void *devptr)
-{
- avmcard *card = devptr;
-
- return c4_handle_interrupt(card);
-}
-
-/* ------------------------------------------------------------- */
-
-static void c4_send_init(avmcard *card)
-{
- struct sk_buff *skb;
- void *p;
- unsigned long flags;
-
- skb = alloc_skb(15, GFP_ATOMIC);
- if (!skb) {
- printk(KERN_CRIT "%s: no memory, lost register appl.\n",
- card->name);
- return;
- }
- p = skb->data;
- _put_byte(&p, 0);
- _put_byte(&p, 0);
- _put_byte(&p, SEND_INIT);
- _put_word(&p, CAPI_MAXAPPL);
- _put_word(&p, AVM_NCCI_PER_CHANNEL * 30);
- _put_word(&p, card->cardnr - 1);
- skb_put(skb, (u8 *)p - (u8 *)skb->data);
-
- skb_queue_tail(&card->dma->send_queue, skb);
- spin_lock_irqsave(&card->lock, flags);
- c4_dispatch_tx(card);
- spin_unlock_irqrestore(&card->lock, flags);
-}
-
-static int queue_sendconfigword(avmcard *card, u32 val)
-{
- struct sk_buff *skb;
- unsigned long flags;
- void *p;
-
- skb = alloc_skb(3 + 4, GFP_ATOMIC);
- if (!skb) {
- printk(KERN_CRIT "%s: no memory, send config\n",
- card->name);
- return -ENOMEM;
- }
- p = skb->data;
- _put_byte(&p, 0);
- _put_byte(&p, 0);
- _put_byte(&p, SEND_CONFIG);
- _put_word(&p, val);
- skb_put(skb, (u8 *)p - (u8 *)skb->data);
-
- skb_queue_tail(&card->dma->send_queue, skb);
- spin_lock_irqsave(&card->lock, flags);
- c4_dispatch_tx(card);
- spin_unlock_irqrestore(&card->lock, flags);
- return 0;
-}
-
-static int queue_sendconfig(avmcard *card, char cval[4])
-{
- struct sk_buff *skb;
- unsigned long flags;
- void *p;
-
- skb = alloc_skb(3 + 4, GFP_ATOMIC);
- if (!skb) {
- printk(KERN_CRIT "%s: no memory, send config\n",
- card->name);
- return -ENOMEM;
- }
- p = skb->data;
- _put_byte(&p, 0);
- _put_byte(&p, 0);
- _put_byte(&p, SEND_CONFIG);
- _put_byte(&p, cval[0]);
- _put_byte(&p, cval[1]);
- _put_byte(&p, cval[2]);
- _put_byte(&p, cval[3]);
- skb_put(skb, (u8 *)p - (u8 *)skb->data);
-
- skb_queue_tail(&card->dma->send_queue, skb);
-
- spin_lock_irqsave(&card->lock, flags);
- c4_dispatch_tx(card);
- spin_unlock_irqrestore(&card->lock, flags);
- return 0;
-}
-
-static int c4_send_config(avmcard *card, capiloaddatapart *config)
-{
- u8 val[4];
- unsigned char *dp;
- u_int left;
- int retval;
-
- if ((retval = queue_sendconfigword(card, 1)) != 0)
- return retval;
- if ((retval = queue_sendconfigword(card, config->len)) != 0)
- return retval;
-
- dp = config->data;
- left = config->len;
- while (left >= sizeof(u32)) {
- if (config->user) {
- if (copy_from_user(val, dp, sizeof(val)))
- return -EFAULT;
- } else {
- memcpy(val, dp, sizeof(val));
- }
- if ((retval = queue_sendconfig(card, val)) != 0)
- return retval;
- left -= sizeof(val);
- dp += sizeof(val);
- }
- if (left) {
- memset(val, 0, sizeof(val));
- if (config->user) {
- if (copy_from_user(&val, dp, left))
- return -EFAULT;
- } else {
- memcpy(&val, dp, left);
- }
- if ((retval = queue_sendconfig(card, val)) != 0)
- return retval;
- }
-
- return 0;
-}
-
-static int c4_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
-{
- avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
- avmcard *card = cinfo->card;
- int retval;
-
- if ((retval = c4_load_t4file(card, &data->firmware))) {
- printk(KERN_ERR "%s: failed to load t4file!!\n",
- card->name);
- c4_reset(card);
- return retval;
- }
-
- card->csr = 0;
- c4outmeml(card->mbase + MBOX_UP_LEN, 0);
- c4outmeml(card->mbase + MBOX_DOWN_LEN, 0);
- c4outmeml(card->mbase + DOORBELL, DBELL_INIT);
- mdelay(1);
- c4outmeml(card->mbase + DOORBELL,
- DBELL_UP_HOST | DBELL_DOWN_HOST | DBELL_RESET_HOST);
-
- c4outmeml(card->mbase + PCI_OUT_INT_MASK, 0x08);
-
- card->dma->recvlen = 0;
- c4outmeml(card->mbase + MBOX_UP_ADDR, card->dma->recvbuf.dmaaddr);
- c4outmeml(card->mbase + MBOX_UP_LEN, card->dma->recvbuf.size);
- c4outmeml(card->mbase + DOORBELL, DBELL_UP_ARM);
-
- if (data->configuration.len > 0 && data->configuration.data) {
- retval = c4_send_config(card, &data->configuration);
- if (retval) {
- printk(KERN_ERR "%s: failed to set config!!\n",
- card->name);
- c4_reset(card);
- return retval;
- }
- }
-
- c4_send_init(card);
-
- return 0;
-}
-
-
-static void c4_reset_ctr(struct capi_ctr *ctrl)
-{
- avmcard *card = ((avmctrl_info *)(ctrl->driverdata))->card;
- avmctrl_info *cinfo;
- u_int i;
- unsigned long flags;
-
- spin_lock_irqsave(&card->lock, flags);
-
- c4_reset(card);
-
- spin_unlock_irqrestore(&card->lock, flags);
-
- for (i = 0; i < card->nr_controllers; i++) {
- cinfo = &card->ctrlinfo[i];
- memset(cinfo->version, 0, sizeof(cinfo->version));
- capi_ctr_down(&cinfo->capi_ctrl);
- }
- card->nlogcontr = 0;
-}
-
-static void c4_remove(struct pci_dev *pdev)
-{
- avmcard *card = pci_get_drvdata(pdev);
- avmctrl_info *cinfo;
- u_int i;
-
- if (!card)
- return;
-
- c4_reset(card);
-
- for (i = 0; i < card->nr_controllers; i++) {
- cinfo = &card->ctrlinfo[i];
- detach_capi_ctr(&cinfo->capi_ctrl);
- }
-
- free_irq(card->irq, card);
- iounmap(card->mbase);
- release_region(card->port, AVMB1_PORTLEN);
- avmcard_dma_free(card->dma);
- pci_set_drvdata(pdev, NULL);
- b1_free_card(card);
-}
-
-/* ------------------------------------------------------------- */
-
-
-static void c4_register_appl(struct capi_ctr *ctrl,
- u16 appl,
- capi_register_params *rp)
-{
- avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
- avmcard *card = cinfo->card;
- struct sk_buff *skb;
- int want = rp->level3cnt;
- unsigned long flags;
- int nconn;
- void *p;
-
- if (ctrl->cnr == card->cardnr) {
-
- if (want > 0) nconn = want;
- else nconn = ctrl->profile.nbchannel * 4 * -want;
- if (nconn == 0) nconn = ctrl->profile.nbchannel * 4;
-
- skb = alloc_skb(23, GFP_ATOMIC);
- if (!skb) {
- printk(KERN_CRIT "%s: no memory, lost register appl.\n",
- card->name);
- return;
- }
- p = skb->data;
- _put_byte(&p, 0);
- _put_byte(&p, 0);
- _put_byte(&p, SEND_REGISTER);
- _put_word(&p, appl);
- _put_word(&p, 1024 * (nconn + 1));
- _put_word(&p, nconn);
- _put_word(&p, rp->datablkcnt);
- _put_word(&p, rp->datablklen);
- skb_put(skb, (u8 *)p - (u8 *)skb->data);
-
- skb_queue_tail(&card->dma->send_queue, skb);
-
- spin_lock_irqsave(&card->lock, flags);
- c4_dispatch_tx(card);
- spin_unlock_irqrestore(&card->lock, flags);
- }
-}
-
-/* ------------------------------------------------------------- */
-
-static void c4_release_appl(struct capi_ctr *ctrl, u16 appl)
-{
- avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
- avmcard *card = cinfo->card;
- unsigned long flags;
- struct sk_buff *skb;
- void *p;
-
- spin_lock_irqsave(&card->lock, flags);
- capilib_release_appl(&cinfo->ncci_head, appl);
- spin_unlock_irqrestore(&card->lock, flags);
-
- if (ctrl->cnr == card->cardnr) {
- skb = alloc_skb(7, GFP_ATOMIC);
- if (!skb) {
- printk(KERN_CRIT "%s: no memory, lost release appl.\n",
- card->name);
- return;
- }
- p = skb->data;
- _put_byte(&p, 0);
- _put_byte(&p, 0);
- _put_byte(&p, SEND_RELEASE);
- _put_word(&p, appl);
-
- skb_put(skb, (u8 *)p - (u8 *)skb->data);
- skb_queue_tail(&card->dma->send_queue, skb);
- spin_lock_irqsave(&card->lock, flags);
- c4_dispatch_tx(card);
- spin_unlock_irqrestore(&card->lock, flags);
- }
-}
-
-/* ------------------------------------------------------------- */
-
-
-static u16 c4_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
-{
- avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
- avmcard *card = cinfo->card;
- u16 retval = CAPI_NOERROR;
- unsigned long flags;
-
- spin_lock_irqsave(&card->lock, flags);
- if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) {
- retval = capilib_data_b3_req(&cinfo->ncci_head,
- CAPIMSG_APPID(skb->data),
- CAPIMSG_NCCI(skb->data),
- CAPIMSG_MSGID(skb->data));
- }
- if (retval == CAPI_NOERROR) {
- skb_queue_tail(&card->dma->send_queue, skb);
- c4_dispatch_tx(card);
- }
- spin_unlock_irqrestore(&card->lock, flags);
- return retval;
-}
-
-/* ------------------------------------------------------------- */
-
-static char *c4_procinfo(struct capi_ctr *ctrl)
-{
- avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
-
- if (!cinfo)
- return "";
- sprintf(cinfo->infobuf, "%s %s 0x%x %d 0x%lx",
- cinfo->cardname[0] ? cinfo->cardname : "-",
- cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-",
- cinfo->card ? cinfo->card->port : 0x0,
- cinfo->card ? cinfo->card->irq : 0,
- cinfo->card ? cinfo->card->membase : 0
- );
- return cinfo->infobuf;
-}
-
-static int c4_proc_show(struct seq_file *m, void *v)
-{
- struct capi_ctr *ctrl = m->private;
- avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
- avmcard *card = cinfo->card;
- u8 flag;
- char *s;
-
- seq_printf(m, "%-16s %s\n", "name", card->name);
- seq_printf(m, "%-16s 0x%x\n", "io", card->port);
- seq_printf(m, "%-16s %d\n", "irq", card->irq);
- seq_printf(m, "%-16s 0x%lx\n", "membase", card->membase);
- switch (card->cardtype) {
- case avm_b1isa: s = "B1 ISA"; break;
- case avm_b1pci: s = "B1 PCI"; break;
- case avm_b1pcmcia: s = "B1 PCMCIA"; break;
- case avm_m1: s = "M1"; break;
- case avm_m2: s = "M2"; break;
- case avm_t1isa: s = "T1 ISA (HEMA)"; break;
- case avm_t1pci: s = "T1 PCI"; break;
- case avm_c4: s = "C4"; break;
- case avm_c2: s = "C2"; break;
- default: s = "???"; break;
- }
- seq_printf(m, "%-16s %s\n", "type", s);
- if ((s = cinfo->version[VER_DRIVER]) != NULL)
- seq_printf(m, "%-16s %s\n", "ver_driver", s);
- if ((s = cinfo->version[VER_CARDTYPE]) != NULL)
- seq_printf(m, "%-16s %s\n", "ver_cardtype", s);
- if ((s = cinfo->version[VER_SERIAL]) != NULL)
- seq_printf(m, "%-16s %s\n", "ver_serial", s);
-
- if (card->cardtype != avm_m1) {
- flag = ((u8 *)(ctrl->profile.manu))[3];
- if (flag)
- seq_printf(m, "%-16s%s%s%s%s%s%s%s\n",
- "protocol",
- (flag & 0x01) ? " DSS1" : "",
- (flag & 0x02) ? " CT1" : "",
- (flag & 0x04) ? " VN3" : "",
- (flag & 0x08) ? " NI1" : "",
- (flag & 0x10) ? " AUSTEL" : "",
- (flag & 0x20) ? " ESS" : "",
- (flag & 0x40) ? " 1TR6" : ""
- );
- }
- if (card->cardtype != avm_m1) {
- flag = ((u8 *)(ctrl->profile.manu))[5];
- if (flag)
- seq_printf(m, "%-16s%s%s%s%s\n",
- "linetype",
- (flag & 0x01) ? " point to point" : "",
- (flag & 0x02) ? " point to multipoint" : "",
- (flag & 0x08) ? " leased line without D-channel" : "",
- (flag & 0x04) ? " leased line with D-channel" : ""
- );
- }
- seq_printf(m, "%-16s %s\n", "cardname", cinfo->cardname);
-
- return 0;
-}
-
-/* ------------------------------------------------------------- */
-
-static int c4_add_card(struct capicardparams *p, struct pci_dev *dev,
- int nr_controllers)
-{
- avmcard *card;
- avmctrl_info *cinfo;
- int retval;
- int i;
-
- card = b1_alloc_card(nr_controllers);
- if (!card) {
- printk(KERN_WARNING "c4: no memory.\n");
- retval = -ENOMEM;
- goto err;
- }
- card->dma = avmcard_dma_alloc("c4", dev, 2048 + 128, 2048 + 128);
- if (!card->dma) {
- printk(KERN_WARNING "c4: no memory.\n");
- retval = -ENOMEM;
- goto err_free;
- }
-
- sprintf(card->name, "c%d-%x", nr_controllers, p->port);
- card->port = p->port;
- card->irq = p->irq;
- card->membase = p->membase;
- card->cardtype = (nr_controllers == 4) ? avm_c4 : avm_c2;
-
- if (!request_region(card->port, AVMB1_PORTLEN, card->name)) {
- printk(KERN_WARNING "c4: ports 0x%03x-0x%03x in use.\n",
- card->port, card->port + AVMB1_PORTLEN);
- retval = -EBUSY;
- goto err_free_dma;
- }
-
- card->mbase = ioremap(card->membase, 128);
- if (card->mbase == NULL) {
- printk(KERN_NOTICE "c4: can't remap memory at 0x%lx\n",
- card->membase);
- retval = -EIO;
- goto err_release_region;
- }
-
- retval = c4_detect(card);
- if (retval != 0) {
- printk(KERN_NOTICE "c4: NO card at 0x%x error(%d)\n",
- card->port, retval);
- retval = -EIO;
- goto err_unmap;
- }
- c4_reset(card);
-
- retval = request_irq(card->irq, c4_interrupt, IRQF_SHARED, card->name, card);
- if (retval) {
- printk(KERN_ERR "c4: unable to get IRQ %d.\n", card->irq);
- retval = -EBUSY;
- goto err_unmap;
- }
-
- for (i = 0; i < nr_controllers; i++) {
- cinfo = &card->ctrlinfo[i];
- cinfo->capi_ctrl.owner = THIS_MODULE;
- cinfo->capi_ctrl.driver_name = "c4";
- cinfo->capi_ctrl.driverdata = cinfo;
- cinfo->capi_ctrl.register_appl = c4_register_appl;
- cinfo->capi_ctrl.release_appl = c4_release_appl;
- cinfo->capi_ctrl.send_message = c4_send_message;
- cinfo->capi_ctrl.load_firmware = c4_load_firmware;
- cinfo->capi_ctrl.reset_ctr = c4_reset_ctr;
- cinfo->capi_ctrl.procinfo = c4_procinfo;
- cinfo->capi_ctrl.proc_show = c4_proc_show;
- strcpy(cinfo->capi_ctrl.name, card->name);
-
- retval = attach_capi_ctr(&cinfo->capi_ctrl);
- if (retval) {
- printk(KERN_ERR "c4: attach controller failed (%d).\n", i);
- for (i--; i >= 0; i--) {
- cinfo = &card->ctrlinfo[i];
- detach_capi_ctr(&cinfo->capi_ctrl);
- }
- goto err_free_irq;
- }
- if (i == 0)
- card->cardnr = cinfo->capi_ctrl.cnr;
- }
-
- printk(KERN_INFO "c4: AVM C%d at i/o %#x, irq %d, mem %#lx\n",
- nr_controllers, card->port, card->irq,
- card->membase);
- pci_set_drvdata(dev, card);
- return 0;
-
-err_free_irq:
- free_irq(card->irq, card);
-err_unmap:
- iounmap(card->mbase);
-err_release_region:
- release_region(card->port, AVMB1_PORTLEN);
-err_free_dma:
- avmcard_dma_free(card->dma);
-err_free:
- b1_free_card(card);
-err:
- return retval;
-}
-
-/* ------------------------------------------------------------- */
-
-static int c4_probe(struct pci_dev *dev, const struct pci_device_id *ent)
-{
- int nr = ent->driver_data;
- int retval = 0;
- struct capicardparams param;
-
- if (pci_enable_device(dev) < 0) {
- printk(KERN_ERR "c4: failed to enable AVM-C%d\n", nr);
- return -ENODEV;
- }
- pci_set_master(dev);
-
- param.port = pci_resource_start(dev, 1);
- param.irq = dev->irq;
- param.membase = pci_resource_start(dev, 0);
-
- printk(KERN_INFO "c4: PCI BIOS reports AVM-C%d at i/o %#x, irq %d, mem %#x\n",
- nr, param.port, param.irq, param.membase);
-
- retval = c4_add_card(&param, dev, nr);
- if (retval != 0) {
- printk(KERN_ERR "c4: no AVM-C%d at i/o %#x, irq %d detected, mem %#x\n",
- nr, param.port, param.irq, param.membase);
- pci_disable_device(dev);
- return -ENODEV;
- }
- return 0;
-}
-
-static struct pci_driver c4_pci_driver = {
- .name = "c4",
- .id_table = c4_pci_tbl,
- .probe = c4_probe,
- .remove = c4_remove,
-};
-
-static struct capi_driver capi_driver_c2 = {
- .name = "c2",
- .revision = "1.0",
-};
-
-static struct capi_driver capi_driver_c4 = {
- .name = "c4",
- .revision = "1.0",
-};
-
-static int __init c4_init(void)
-{
- char *p;
- char rev[32];
- int err;
-
- if ((p = strchr(revision, ':')) != NULL && p[1]) {
- strlcpy(rev, p + 2, 32);
- if ((p = strchr(rev, '$')) != NULL && p > rev)
- *(p - 1) = 0;
- } else
- strcpy(rev, "1.0");
-
- err = pci_register_driver(&c4_pci_driver);
- if (!err) {
- strlcpy(capi_driver_c2.revision, rev, 32);
- register_capi_driver(&capi_driver_c2);
- strlcpy(capi_driver_c4.revision, rev, 32);
- register_capi_driver(&capi_driver_c4);
- printk(KERN_INFO "c4: revision %s\n", rev);
- }
- return err;
-}
-
-static void __exit c4_exit(void)
-{
- unregister_capi_driver(&capi_driver_c2);
- unregister_capi_driver(&capi_driver_c4);
- pci_unregister_driver(&c4_pci_driver);
-}
-
-module_init(c4_init);
-module_exit(c4_exit);
diff --git a/drivers/staging/isdn/avm/t1isa.c b/drivers/staging/isdn/avm/t1isa.c
deleted file mode 100644
index 2153619c5b31..000000000000
--- a/drivers/staging/isdn/avm/t1isa.c
+++ /dev/null
@@ -1,594 +0,0 @@
-/* $Id: t1isa.c,v 1.1.2.3 2004/02/10 01:07:12 keil Exp $
- *
- * Module for AVM T1 HEMA-card.
- *
- * 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.
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/skbuff.h>
-#include <linux/delay.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/capi.h>
-#include <linux/netdevice.h>
-#include <linux/kernelcapi.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/gfp.h>
-#include <asm/io.h>
-#include <linux/isdn/capicmd.h>
-#include <linux/isdn/capiutil.h>
-#include <linux/isdn/capilli.h>
-#include "avmcard.h"
-
-/* ------------------------------------------------------------- */
-
-static char *revision = "$Revision: 1.1.2.3 $";
-
-/* ------------------------------------------------------------- */
-
-MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM T1 HEMA ISA card");
-MODULE_AUTHOR("Carsten Paeth");
-MODULE_LICENSE("GPL");
-
-/* ------------------------------------------------------------- */
-
-static int hema_irq_table[16] =
-{0,
- 0,
- 0,
- 0x80, /* irq 3 */
- 0,
- 0x90, /* irq 5 */
- 0,
- 0xA0, /* irq 7 */
- 0,
- 0xB0, /* irq 9 */
- 0xC0, /* irq 10 */
- 0xD0, /* irq 11 */
- 0xE0, /* irq 12 */
- 0,
- 0,
- 0xF0, /* irq 15 */
-};
-
-static int t1_detectandinit(unsigned int base, unsigned irq, int cardnr)
-{
- unsigned char cregs[8];
- unsigned char reverse_cardnr;
- unsigned char dummy;
- int i;
-
- reverse_cardnr = ((cardnr & 0x01) << 3) | ((cardnr & 0x02) << 1)
- | ((cardnr & 0x04) >> 1) | ((cardnr & 0x08) >> 3);
- cregs[0] = (HEMA_VERSION_ID << 4) | (reverse_cardnr & 0xf);
- cregs[1] = 0x00; /* fast & slow link connected to CON1 */
- cregs[2] = 0x05; /* fast link 20MBit, slow link 20 MBit */
- cregs[3] = 0;
- cregs[4] = 0x11; /* zero wait state */
- cregs[5] = hema_irq_table[irq & 0xf];
- cregs[6] = 0;
- cregs[7] = 0;
-
- /*
- * no one else should use the ISA bus in this moment,
- * but no function there to prevent this :-(
- * save_flags(flags); cli();
- */
-
- /* board reset */
- t1outp(base, T1_RESETBOARD, 0xf);
- mdelay(100);
- dummy = t1inp(base, T1_FASTLINK + T1_OUTSTAT); /* first read */
-
- /* write config */
- dummy = (base >> 4) & 0xff;
- for (i = 1; i <= 0xf; i++) t1outp(base, i, dummy);
- t1outp(base, HEMA_PAL_ID & 0xf, dummy);
- t1outp(base, HEMA_PAL_ID >> 4, cregs[0]);
- for (i = 1; i < 7; i++) t1outp(base, 0, cregs[i]);
- t1outp(base, ((base >> 4)) & 0x3, cregs[7]);
- /* restore_flags(flags); */
-
- mdelay(100);
- t1outp(base, T1_FASTLINK + T1_RESETLINK, 0);
- t1outp(base, T1_SLOWLINK + T1_RESETLINK, 0);
- mdelay(10);
- t1outp(base, T1_FASTLINK + T1_RESETLINK, 1);
- t1outp(base, T1_SLOWLINK + T1_RESETLINK, 1);
- mdelay(100);
- t1outp(base, T1_FASTLINK + T1_RESETLINK, 0);
- t1outp(base, T1_SLOWLINK + T1_RESETLINK, 0);
- mdelay(10);
- t1outp(base, T1_FASTLINK + T1_ANALYSE, 0);
- mdelay(5);
- t1outp(base, T1_SLOWLINK + T1_ANALYSE, 0);
-
- if (t1inp(base, T1_FASTLINK + T1_OUTSTAT) != 0x1) /* tx empty */
- return 1;
- if (t1inp(base, T1_FASTLINK + T1_INSTAT) != 0x0) /* rx empty */
- return 2;
- if (t1inp(base, T1_FASTLINK + T1_IRQENABLE) != 0x0)
- return 3;
- if ((t1inp(base, T1_FASTLINK + T1_FIFOSTAT) & 0xf0) != 0x70)
- return 4;
- if ((t1inp(base, T1_FASTLINK + T1_IRQMASTER) & 0x0e) != 0)
- return 5;
- if ((t1inp(base, T1_FASTLINK + T1_IDENT) & 0x7d) != 1)
- return 6;
- if (t1inp(base, T1_SLOWLINK + T1_OUTSTAT) != 0x1) /* tx empty */
- return 7;
- if ((t1inp(base, T1_SLOWLINK + T1_IRQMASTER) & 0x0e) != 0)
- return 8;
- if ((t1inp(base, T1_SLOWLINK + T1_IDENT) & 0x7d) != 0)
- return 9;
- return 0;
-}
-
-static irqreturn_t t1isa_interrupt(int interrupt, void *devptr)
-{
- avmcard *card = devptr;
- avmctrl_info *cinfo = &card->ctrlinfo[0];
- struct capi_ctr *ctrl = &cinfo->capi_ctrl;
- unsigned char b1cmd;
- struct sk_buff *skb;
-
- unsigned ApplId;
- unsigned MsgLen;
- unsigned DataB3Len;
- unsigned NCCI;
- unsigned WindowSize;
- unsigned long flags;
-
- spin_lock_irqsave(&card->lock, flags);
-
- while (b1_rx_full(card->port)) {
-
- b1cmd = b1_get_byte(card->port);
-
- switch (b1cmd) {
-
- case RECEIVE_DATA_B3_IND:
-
- ApplId = (unsigned) b1_get_word(card->port);
- MsgLen = t1_get_slice(card->port, card->msgbuf);
- DataB3Len = t1_get_slice(card->port, card->databuf);
- spin_unlock_irqrestore(&card->lock, flags);
-
- if (MsgLen < 30) { /* not CAPI 64Bit */
- memset(card->msgbuf + MsgLen, 0, 30 - MsgLen);
- MsgLen = 30;
- CAPIMSG_SETLEN(card->msgbuf, 30);
- }
- if (!(skb = alloc_skb(DataB3Len + MsgLen, GFP_ATOMIC))) {
- printk(KERN_ERR "%s: incoming packet dropped\n",
- card->name);
- } else {
- skb_put_data(skb, card->msgbuf, MsgLen);
- skb_put_data(skb, card->databuf, DataB3Len);
- capi_ctr_handle_message(ctrl, ApplId, skb);
- }
- break;
-
- case RECEIVE_MESSAGE:
-
- ApplId = (unsigned) b1_get_word(card->port);
- MsgLen = t1_get_slice(card->port, card->msgbuf);
- if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) {
- spin_unlock_irqrestore(&card->lock, flags);
- printk(KERN_ERR "%s: incoming packet dropped\n",
- card->name);
- } else {
- skb_put_data(skb, card->msgbuf, MsgLen);
- if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3)
- capilib_data_b3_conf(&cinfo->ncci_head, ApplId,
- CAPIMSG_NCCI(skb->data),
- CAPIMSG_MSGID(skb->data));
- spin_unlock_irqrestore(&card->lock, flags);
- capi_ctr_handle_message(ctrl, ApplId, skb);
- }
- break;
-
- case RECEIVE_NEW_NCCI:
-
- ApplId = b1_get_word(card->port);
- NCCI = b1_get_word(card->port);
- WindowSize = b1_get_word(card->port);
- capilib_new_ncci(&cinfo->ncci_head, ApplId, NCCI, WindowSize);
- spin_unlock_irqrestore(&card->lock, flags);
- break;
-
- case RECEIVE_FREE_NCCI:
-
- ApplId = b1_get_word(card->port);
- NCCI = b1_get_word(card->port);
- if (NCCI != 0xffffffff)
- capilib_free_ncci(&cinfo->ncci_head, ApplId, NCCI);
- spin_unlock_irqrestore(&card->lock, flags);
- break;
-
- case RECEIVE_START:
- b1_put_byte(card->port, SEND_POLLACK);
- spin_unlock_irqrestore(&card->lock, flags);
- capi_ctr_resume_output(ctrl);
- break;
-
- case RECEIVE_STOP:
- spin_unlock_irqrestore(&card->lock, flags);
- capi_ctr_suspend_output(ctrl);
- break;
-
- case RECEIVE_INIT:
-
- cinfo->versionlen = t1_get_slice(card->port, cinfo->versionbuf);
- spin_unlock_irqrestore(&card->lock, flags);
- b1_parse_version(cinfo);
- printk(KERN_INFO "%s: %s-card (%s) now active\n",
- card->name,
- cinfo->version[VER_CARDTYPE],
- cinfo->version[VER_DRIVER]);
- capi_ctr_ready(ctrl);
- break;
-
- case RECEIVE_TASK_READY:
- ApplId = (unsigned) b1_get_word(card->port);
- MsgLen = t1_get_slice(card->port, card->msgbuf);
- spin_unlock_irqrestore(&card->lock, flags);
- card->msgbuf[MsgLen] = 0;
- while (MsgLen > 0
- && (card->msgbuf[MsgLen - 1] == '\n'
- || card->msgbuf[MsgLen - 1] == '\r')) {
- card->msgbuf[MsgLen - 1] = 0;
- MsgLen--;
- }
- printk(KERN_INFO "%s: task %d \"%s\" ready.\n",
- card->name, ApplId, card->msgbuf);
- break;
-
- case RECEIVE_DEBUGMSG:
- MsgLen = t1_get_slice(card->port, card->msgbuf);
- spin_unlock_irqrestore(&card->lock, flags);
- card->msgbuf[MsgLen] = 0;
- while (MsgLen > 0
- && (card->msgbuf[MsgLen - 1] == '\n'
- || card->msgbuf[MsgLen - 1] == '\r')) {
- card->msgbuf[MsgLen - 1] = 0;
- MsgLen--;
- }
- printk(KERN_INFO "%s: DEBUG: %s\n", card->name, card->msgbuf);
- break;
-
-
- case 0xff:
- spin_unlock_irqrestore(&card->lock, flags);
- printk(KERN_ERR "%s: card reseted ?\n", card->name);
- return IRQ_HANDLED;
- default:
- spin_unlock_irqrestore(&card->lock, flags);
- printk(KERN_ERR "%s: b1_interrupt: 0x%x ???\n",
- card->name, b1cmd);
- return IRQ_NONE;
- }
- }
- return IRQ_HANDLED;
-}
-
-/* ------------------------------------------------------------- */
-
-static int t1isa_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
-{
- avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
- avmcard *card = cinfo->card;
- unsigned int port = card->port;
- unsigned long flags;
- int retval;
-
- t1_disable_irq(port);
- b1_reset(port);
-
- if ((retval = b1_load_t4file(card, &data->firmware))) {
- b1_reset(port);
- printk(KERN_ERR "%s: failed to load t4file!!\n",
- card->name);
- return retval;
- }
-
- if (data->configuration.len > 0 && data->configuration.data) {
- if ((retval = b1_load_config(card, &data->configuration))) {
- b1_reset(port);
- printk(KERN_ERR "%s: failed to load config!!\n",
- card->name);
- return retval;
- }
- }
-
- if (!b1_loaded(card)) {
- printk(KERN_ERR "%s: failed to load t4file.\n", card->name);
- return -EIO;
- }
-
- spin_lock_irqsave(&card->lock, flags);
- b1_setinterrupt(port, card->irq, card->cardtype);
- b1_put_byte(port, SEND_INIT);
- b1_put_word(port, CAPI_MAXAPPL);
- b1_put_word(port, AVM_NCCI_PER_CHANNEL * 30);
- b1_put_word(port, ctrl->cnr - 1);
- spin_unlock_irqrestore(&card->lock, flags);
-
- return 0;
-}
-
-static void t1isa_reset_ctr(struct capi_ctr *ctrl)
-{
- avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
- avmcard *card = cinfo->card;
- unsigned int port = card->port;
- unsigned long flags;
-
- t1_disable_irq(port);
- b1_reset(port);
- b1_reset(port);
-
- memset(cinfo->version, 0, sizeof(cinfo->version));
- spin_lock_irqsave(&card->lock, flags);
- capilib_release(&cinfo->ncci_head);
- spin_unlock_irqrestore(&card->lock, flags);
- capi_ctr_down(ctrl);
-}
-
-static void t1isa_remove(struct pci_dev *pdev)
-{
- avmctrl_info *cinfo = pci_get_drvdata(pdev);
- avmcard *card;
-
- if (!cinfo)
- return;
-
- card = cinfo->card;
-
- t1_disable_irq(card->port);
- b1_reset(card->port);
- b1_reset(card->port);
- t1_reset(card->port);
-
- detach_capi_ctr(&cinfo->capi_ctrl);
- free_irq(card->irq, card);
- release_region(card->port, AVMB1_PORTLEN);
- b1_free_card(card);
-}
-
-/* ------------------------------------------------------------- */
-
-static u16 t1isa_send_message(struct capi_ctr *ctrl, struct sk_buff *skb);
-static char *t1isa_procinfo(struct capi_ctr *ctrl);
-
-static int t1isa_probe(struct pci_dev *pdev, int cardnr)
-{
- avmctrl_info *cinfo;
- avmcard *card;
- int retval;
-
- card = b1_alloc_card(1);
- if (!card) {
- printk(KERN_WARNING "t1isa: no memory.\n");
- retval = -ENOMEM;
- goto err;
- }
-
- cinfo = card->ctrlinfo;
- card->port = pci_resource_start(pdev, 0);
- card->irq = pdev->irq;
- card->cardtype = avm_t1isa;
- card->cardnr = cardnr;
- sprintf(card->name, "t1isa-%x", card->port);
-
- if (!(((card->port & 0x7) == 0) && ((card->port & 0x30) != 0x30))) {
- printk(KERN_WARNING "t1isa: invalid port 0x%x.\n", card->port);
- retval = -EINVAL;
- goto err_free;
- }
- if (hema_irq_table[card->irq & 0xf] == 0) {
- printk(KERN_WARNING "t1isa: irq %d not valid.\n", card->irq);
- retval = -EINVAL;
- goto err_free;
- }
- if (!request_region(card->port, AVMB1_PORTLEN, card->name)) {
- printk(KERN_INFO "t1isa: ports 0x%03x-0x%03x in use.\n",
- card->port, card->port + AVMB1_PORTLEN);
- retval = -EBUSY;
- goto err_free;
- }
- retval = request_irq(card->irq, t1isa_interrupt, 0, card->name, card);
- if (retval) {
- printk(KERN_INFO "t1isa: unable to get IRQ %d.\n", card->irq);
- retval = -EBUSY;
- goto err_release_region;
- }
-
- if ((retval = t1_detectandinit(card->port, card->irq, card->cardnr)) != 0) {
- printk(KERN_INFO "t1isa: NO card at 0x%x (%d)\n",
- card->port, retval);
- retval = -ENODEV;
- goto err_free_irq;
- }
- t1_disable_irq(card->port);
- b1_reset(card->port);
-
- cinfo->capi_ctrl.owner = THIS_MODULE;
- cinfo->capi_ctrl.driver_name = "t1isa";
- cinfo->capi_ctrl.driverdata = cinfo;
- cinfo->capi_ctrl.register_appl = b1_register_appl;
- cinfo->capi_ctrl.release_appl = b1_release_appl;
- cinfo->capi_ctrl.send_message = t1isa_send_message;
- cinfo->capi_ctrl.load_firmware = t1isa_load_firmware;
- cinfo->capi_ctrl.reset_ctr = t1isa_reset_ctr;
- cinfo->capi_ctrl.procinfo = t1isa_procinfo;
- cinfo->capi_ctrl.proc_show = b1_proc_show;
- strcpy(cinfo->capi_ctrl.name, card->name);
-
- retval = attach_capi_ctr(&cinfo->capi_ctrl);
- if (retval) {
- printk(KERN_INFO "t1isa: attach controller failed.\n");
- goto err_free_irq;
- }
-
- printk(KERN_INFO "t1isa: AVM T1 ISA at i/o %#x, irq %d, card %d\n",
- card->port, card->irq, card->cardnr);
-
- pci_set_drvdata(pdev, cinfo);
- return 0;
-
-err_free_irq:
- free_irq(card->irq, card);
-err_release_region:
- release_region(card->port, AVMB1_PORTLEN);
-err_free:
- b1_free_card(card);
-err:
- return retval;
-}
-
-static u16 t1isa_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
-{
- avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
- avmcard *card = cinfo->card;
- unsigned int port = card->port;
- unsigned long flags;
- u16 len = CAPIMSG_LEN(skb->data);
- u8 cmd = CAPIMSG_COMMAND(skb->data);
- u8 subcmd = CAPIMSG_SUBCOMMAND(skb->data);
- u16 dlen, retval;
-
- spin_lock_irqsave(&card->lock, flags);
- if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) {
- retval = capilib_data_b3_req(&cinfo->ncci_head,
- CAPIMSG_APPID(skb->data),
- CAPIMSG_NCCI(skb->data),
- CAPIMSG_MSGID(skb->data));
- if (retval != CAPI_NOERROR) {
- spin_unlock_irqrestore(&card->lock, flags);
- return retval;
- }
- dlen = CAPIMSG_DATALEN(skb->data);
-
- b1_put_byte(port, SEND_DATA_B3_REQ);
- t1_put_slice(port, skb->data, len);
- t1_put_slice(port, skb->data + len, dlen);
- } else {
- b1_put_byte(port, SEND_MESSAGE);
- t1_put_slice(port, skb->data, len);
- }
- spin_unlock_irqrestore(&card->lock, flags);
- dev_kfree_skb_any(skb);
- return CAPI_NOERROR;
-}
-/* ------------------------------------------------------------- */
-
-static char *t1isa_procinfo(struct capi_ctr *ctrl)
-{
- avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
-
- if (!cinfo)
- return "";
- sprintf(cinfo->infobuf, "%s %s 0x%x %d %d",
- cinfo->cardname[0] ? cinfo->cardname : "-",
- cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-",
- cinfo->card ? cinfo->card->port : 0x0,
- cinfo->card ? cinfo->card->irq : 0,
- cinfo->card ? cinfo->card->cardnr : 0
- );
- return cinfo->infobuf;
-}
-
-
-/* ------------------------------------------------------------- */
-
-#define MAX_CARDS 4
-static struct pci_dev isa_dev[MAX_CARDS];
-static int io[MAX_CARDS];
-static int irq[MAX_CARDS];
-static int cardnr[MAX_CARDS];
-
-module_param_hw_array(io, int, ioport, NULL, 0);
-module_param_hw_array(irq, int, irq, NULL, 0);
-module_param_array(cardnr, int, NULL, 0);
-MODULE_PARM_DESC(io, "I/O base address(es)");
-MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)");
-MODULE_PARM_DESC(cardnr, "Card number(s) (as jumpered)");
-
-static int t1isa_add_card(struct capi_driver *driver, capicardparams *data)
-{
- int i;
-
- for (i = 0; i < MAX_CARDS; i++) {
- if (isa_dev[i].resource[0].start)
- continue;
-
- isa_dev[i].resource[0].start = data->port;
- isa_dev[i].irq = data->irq;
-
- if (t1isa_probe(&isa_dev[i], data->cardnr) == 0)
- return 0;
- }
- return -ENODEV;
-}
-
-static struct capi_driver capi_driver_t1isa = {
- .name = "t1isa",
- .revision = "1.0",
- .add_card = t1isa_add_card,
-};
-
-static int __init t1isa_init(void)
-{
- char rev[32];
- char *p;
- int i;
-
- if ((p = strchr(revision, ':')) != NULL && p[1]) {
- strlcpy(rev, p + 2, 32);
- if ((p = strchr(rev, '$')) != NULL && p > rev)
- *(p - 1) = 0;
- } else
- strcpy(rev, "1.0");
-
- for (i = 0; i < MAX_CARDS; i++) {
- if (!io[i])
- break;
-
- isa_dev[i].resource[0].start = io[i];
- isa_dev[i].irq = irq[i];
-
- if (t1isa_probe(&isa_dev[i], cardnr[i]) != 0)
- return -ENODEV;
- }
-
- strlcpy(capi_driver_t1isa.revision, rev, 32);
- register_capi_driver(&capi_driver_t1isa);
- printk(KERN_INFO "t1isa: revision %s\n", rev);
-
- return 0;
-}
-
-static void __exit t1isa_exit(void)
-{
- int i;
-
- unregister_capi_driver(&capi_driver_t1isa);
- for (i = 0; i < MAX_CARDS; i++) {
- if (!io[i])
- break;
-
- t1isa_remove(&isa_dev[i]);
- }
-}
-
-module_init(t1isa_init);
-module_exit(t1isa_exit);
diff --git a/drivers/staging/isdn/avm/t1pci.c b/drivers/staging/isdn/avm/t1pci.c
deleted file mode 100644
index f5ed1d5004c9..000000000000
--- a/drivers/staging/isdn/avm/t1pci.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/* $Id: t1pci.c,v 1.1.2.2 2004/01/16 21:09:27 keil Exp $
- *
- * Module for AVM T1 PCI-card.
- *
- * 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.
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/skbuff.h>
-#include <linux/delay.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/pci.h>
-#include <linux/capi.h>
-#include <linux/init.h>
-#include <asm/io.h>
-#include <linux/isdn/capicmd.h>
-#include <linux/isdn/capiutil.h>
-#include <linux/isdn/capilli.h>
-#include "avmcard.h"
-
-#undef CONFIG_T1PCI_DEBUG
-#undef CONFIG_T1PCI_POLLDEBUG
-
-/* ------------------------------------------------------------- */
-static char *revision = "$Revision: 1.1.2.2 $";
-/* ------------------------------------------------------------- */
-
-static struct pci_device_id t1pci_pci_tbl[] = {
- { PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_T1, PCI_ANY_ID, PCI_ANY_ID },
- { } /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(pci, t1pci_pci_tbl);
-MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM T1 PCI card");
-MODULE_AUTHOR("Carsten Paeth");
-MODULE_LICENSE("GPL");
-
-/* ------------------------------------------------------------- */
-
-static char *t1pci_procinfo(struct capi_ctr *ctrl);
-
-static int t1pci_add_card(struct capicardparams *p, struct pci_dev *pdev)
-{
- avmcard *card;
- avmctrl_info *cinfo;
- int retval;
-
- card = b1_alloc_card(1);
- if (!card) {
- printk(KERN_WARNING "t1pci: no memory.\n");
- retval = -ENOMEM;
- goto err;
- }
-
- card->dma = avmcard_dma_alloc("t1pci", pdev, 2048 + 128, 2048 + 128);
- if (!card->dma) {
- printk(KERN_WARNING "t1pci: no memory.\n");
- retval = -ENOMEM;
- goto err_free;
- }
-
- cinfo = card->ctrlinfo;
- sprintf(card->name, "t1pci-%x", p->port);
- card->port = p->port;
- card->irq = p->irq;
- card->membase = p->membase;
- card->cardtype = avm_t1pci;
-
- if (!request_region(card->port, AVMB1_PORTLEN, card->name)) {
- printk(KERN_WARNING "t1pci: ports 0x%03x-0x%03x in use.\n",
- card->port, card->port + AVMB1_PORTLEN);
- retval = -EBUSY;
- goto err_free_dma;
- }
-
- card->mbase = ioremap(card->membase, 64);
- if (!card->mbase) {
- printk(KERN_NOTICE "t1pci: can't remap memory at 0x%lx\n",
- card->membase);
- retval = -EIO;
- goto err_release_region;
- }
-
- b1dma_reset(card);
-
- retval = t1pci_detect(card);
- if (retval != 0) {
- if (retval < 6)
- printk(KERN_NOTICE "t1pci: NO card at 0x%x (%d)\n",
- card->port, retval);
- else
- printk(KERN_NOTICE "t1pci: card at 0x%x, but cable not connected or T1 has no power (%d)\n",
- card->port, retval);
- retval = -EIO;
- goto err_unmap;
- }
- b1dma_reset(card);
-
- retval = request_irq(card->irq, b1dma_interrupt, IRQF_SHARED, card->name, card);
- if (retval) {
- printk(KERN_ERR "t1pci: unable to get IRQ %d.\n", card->irq);
- retval = -EBUSY;
- goto err_unmap;
- }
-
- cinfo->capi_ctrl.owner = THIS_MODULE;
- cinfo->capi_ctrl.driver_name = "t1pci";
- cinfo->capi_ctrl.driverdata = cinfo;
- cinfo->capi_ctrl.register_appl = b1dma_register_appl;
- cinfo->capi_ctrl.release_appl = b1dma_release_appl;
- cinfo->capi_ctrl.send_message = b1dma_send_message;
- cinfo->capi_ctrl.load_firmware = b1dma_load_firmware;
- cinfo->capi_ctrl.reset_ctr = b1dma_reset_ctr;
- cinfo->capi_ctrl.procinfo = t1pci_procinfo;
- cinfo->capi_ctrl.proc_show = b1dma_proc_show;
- strcpy(cinfo->capi_ctrl.name, card->name);
-
- retval = attach_capi_ctr(&cinfo->capi_ctrl);
- if (retval) {
- printk(KERN_ERR "t1pci: attach controller failed.\n");
- retval = -EBUSY;
- goto err_free_irq;
- }
- card->cardnr = cinfo->capi_ctrl.cnr;
-
- printk(KERN_INFO "t1pci: AVM T1 PCI at i/o %#x, irq %d, mem %#lx\n",
- card->port, card->irq, card->membase);
-
- pci_set_drvdata(pdev, card);
- return 0;
-
-err_free_irq:
- free_irq(card->irq, card);
-err_unmap:
- iounmap(card->mbase);
-err_release_region:
- release_region(card->port, AVMB1_PORTLEN);
-err_free_dma:
- avmcard_dma_free(card->dma);
-err_free:
- b1_free_card(card);
-err:
- return retval;
-}
-
-/* ------------------------------------------------------------- */
-
-static void t1pci_remove(struct pci_dev *pdev)
-{
- avmcard *card = pci_get_drvdata(pdev);
- avmctrl_info *cinfo = card->ctrlinfo;
-
- b1dma_reset(card);
-
- detach_capi_ctr(&cinfo->capi_ctrl);
- free_irq(card->irq, card);
- iounmap(card->mbase);
- release_region(card->port, AVMB1_PORTLEN);
- avmcard_dma_free(card->dma);
- b1_free_card(card);
-}
-
-/* ------------------------------------------------------------- */
-
-static char *t1pci_procinfo(struct capi_ctr *ctrl)
-{
- avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
-
- if (!cinfo)
- return "";
- sprintf(cinfo->infobuf, "%s %s 0x%x %d 0x%lx",
- cinfo->cardname[0] ? cinfo->cardname : "-",
- cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-",
- cinfo->card ? cinfo->card->port : 0x0,
- cinfo->card ? cinfo->card->irq : 0,
- cinfo->card ? cinfo->card->membase : 0
- );
- return cinfo->infobuf;
-}
-
-/* ------------------------------------------------------------- */
-
-static int t1pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
-{
- struct capicardparams param;
- int retval;
-
- if (pci_enable_device(dev) < 0) {
- printk(KERN_ERR "t1pci: failed to enable AVM-T1-PCI\n");
- return -ENODEV;
- }
- pci_set_master(dev);
-
- param.port = pci_resource_start(dev, 1);
- param.irq = dev->irq;
- param.membase = pci_resource_start(dev, 0);
-
- printk(KERN_INFO "t1pci: PCI BIOS reports AVM-T1-PCI at i/o %#x, irq %d, mem %#x\n",
- param.port, param.irq, param.membase);
-
- retval = t1pci_add_card(&param, dev);
- if (retval != 0) {
- printk(KERN_ERR "t1pci: no AVM-T1-PCI at i/o %#x, irq %d detected, mem %#x\n",
- param.port, param.irq, param.membase);
- pci_disable_device(dev);
- return -ENODEV;
- }
- return 0;
-}
-
-static struct pci_driver t1pci_pci_driver = {
- .name = "t1pci",
- .id_table = t1pci_pci_tbl,
- .probe = t1pci_probe,
- .remove = t1pci_remove,
-};
-
-static struct capi_driver capi_driver_t1pci = {
- .name = "t1pci",
- .revision = "1.0",
-};
-
-static int __init t1pci_init(void)
-{
- char *p;
- char rev[32];
- int err;
-
- if ((p = strchr(revision, ':')) != NULL && p[1]) {
- strlcpy(rev, p + 2, 32);
- if ((p = strchr(rev, '$')) != NULL && p > rev)
- *(p - 1) = 0;
- } else
- strcpy(rev, "1.0");
-
- err = pci_register_driver(&t1pci_pci_driver);
- if (!err) {
- strlcpy(capi_driver_t1pci.revision, rev, 32);
- register_capi_driver(&capi_driver_t1pci);
- printk(KERN_INFO "t1pci: revision %s\n", rev);
- }
- return err;
-}
-
-static void __exit t1pci_exit(void)
-{
- unregister_capi_driver(&capi_driver_t1pci);
- pci_unregister_driver(&t1pci_pci_driver);
-}
-
-module_init(t1pci_init);
-module_exit(t1pci_exit);
diff --git a/drivers/staging/isdn/gigaset/Kconfig b/drivers/staging/isdn/gigaset/Kconfig
deleted file mode 100644
index c593105b3600..000000000000
--- a/drivers/staging/isdn/gigaset/Kconfig
+++ /dev/null
@@ -1,62 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-menuconfig ISDN_DRV_GIGASET
- tristate "Siemens Gigaset support"
- depends on TTY
- select CRC_CCITT
- select BITREVERSE
- help
- This driver supports the Siemens Gigaset SX205/255 family of
- ISDN DECT bases, including the predecessors Gigaset 3070/3075
- and 4170/4175 and their T-Com versions Sinus 45isdn and Sinus
- 721X.
- If you have one of these devices, say M here and for at least
- one of the connection specific parts that follow.
- This will build a module called "gigaset".
- Note: If you build your ISDN subsystem (ISDN_CAPI or ISDN_I4L)
- as a module, you have to build this driver as a module too,
- otherwise the Gigaset device won't show up as an ISDN device.
-
-if ISDN_DRV_GIGASET
-
-config GIGASET_CAPI
- bool "Gigaset CAPI support"
- depends on ISDN_CAPI='y'||(ISDN_CAPI='m'&&ISDN_DRV_GIGASET='m')
- default 'y'
- help
- Build the Gigaset driver as a CAPI 2.0 driver interfacing with
- the Kernel CAPI subsystem. To use it with the old ISDN4Linux
- subsystem you'll have to enable the capidrv glue driver.
- (select ISDN_CAPI_CAPIDRV.)
- Say N to build the old native ISDN4Linux variant.
- If unsure, say Y.
-
-config GIGASET_BASE
- tristate "Gigaset base station support"
- depends on USB
- help
- Say M here if you want to use the USB interface of the Gigaset
- base for connection to your system.
- This will build a module called "bas_gigaset".
-
-config GIGASET_M105
- tristate "Gigaset M105 support"
- depends on USB
- help
- Say M here if you want to connect to the Gigaset base via DECT
- using a Gigaset M105 (Sinus 45 Data 2) USB DECT device.
- This will build a module called "usb_gigaset".
-
-config GIGASET_M101
- tristate "Gigaset M101 support"
- help
- Say M here if you want to connect to the Gigaset base via DECT
- using a Gigaset M101 (Sinus 45 Data 1) RS232 DECT device.
- This will build a module called "ser_gigaset".
-
-config GIGASET_DEBUG
- bool "Gigaset debugging"
- help
- This enables debugging code in the Gigaset drivers.
- If in doubt, say yes.
-
-endif # ISDN_DRV_GIGASET
diff --git a/drivers/staging/isdn/gigaset/Makefile b/drivers/staging/isdn/gigaset/Makefile
deleted file mode 100644
index 9c010891dcd7..000000000000
--- a/drivers/staging/isdn/gigaset/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-gigaset-y := common.o interface.o proc.o ev-layer.o asyncdata.o
-
-ifdef CONFIG_GIGASET_CAPI
-gigaset-y += capi.o
-else
-gigaset-y += dummyll.o
-endif
-
-usb_gigaset-y := usb-gigaset.o
-ser_gigaset-y := ser-gigaset.o
-bas_gigaset-y := bas-gigaset.o isocdata.o
-
-obj-$(CONFIG_ISDN_DRV_GIGASET) += gigaset.o
-obj-$(CONFIG_GIGASET_M105) += usb_gigaset.o
-obj-$(CONFIG_GIGASET_BASE) += bas_gigaset.o
-obj-$(CONFIG_GIGASET_M101) += ser_gigaset.o
diff --git a/drivers/staging/isdn/gigaset/asyncdata.c b/drivers/staging/isdn/gigaset/asyncdata.c
deleted file mode 100644
index a34b3c9d8a71..000000000000
--- a/drivers/staging/isdn/gigaset/asyncdata.c
+++ /dev/null
@@ -1,606 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Common data handling layer for ser_gigaset and usb_gigaset
- *
- * Copyright (c) 2005 by Tilman Schmidt <tilman@imap.cc>,
- * Hansjoerg Lipp <hjlipp@web.de>,
- * Stefan Eilers.
- *
- * =====================================================================
- * =====================================================================
- */
-
-#include "gigaset.h"
-#include <linux/crc-ccitt.h>
-#include <linux/bitrev.h>
-#include <linux/export.h>
-
-/* check if byte must be stuffed/escaped
- * I'm not sure which data should be encoded.
- * Therefore I will go the hard way and encode every value
- * less than 0x20, the flag sequence and the control escape char.
- */
-static inline int muststuff(unsigned char c)
-{
- if (c < PPP_TRANS) return 1;
- if (c == PPP_FLAG) return 1;
- if (c == PPP_ESCAPE) return 1;
- /* other possible candidates: */
- /* 0x91: XON with parity set */
- /* 0x93: XOFF with parity set */
- return 0;
-}
-
-/* == data input =========================================================== */
-
-/* process a block of received bytes in command mode
- * (mstate != MS_LOCKED && (inputstate & INS_command))
- * Append received bytes to the command response buffer and forward them
- * line by line to the response handler. Exit whenever a mode/state change
- * might have occurred.
- * Note: Received lines may be terminated by CR, LF, or CR LF, which will be
- * removed before passing the line to the response handler.
- * Return value:
- * number of processed bytes
- */
-static unsigned cmd_loop(unsigned numbytes, struct inbuf_t *inbuf)
-{
- unsigned char *src = inbuf->data + inbuf->head;
- struct cardstate *cs = inbuf->cs;
- unsigned cbytes = cs->cbytes;
- unsigned procbytes = 0;
- unsigned char c;
-
- while (procbytes < numbytes) {
- c = *src++;
- procbytes++;
-
- switch (c) {
- case '\n':
- if (cbytes == 0 && cs->respdata[0] == '\r') {
- /* collapse LF with preceding CR */
- cs->respdata[0] = 0;
- break;
- }
- /* fall through */
- case '\r':
- /* end of message line, pass to response handler */
- if (cbytes >= MAX_RESP_SIZE) {
- dev_warn(cs->dev, "response too large (%d)\n",
- cbytes);
- cbytes = MAX_RESP_SIZE;
- }
- cs->cbytes = cbytes;
- gigaset_dbg_buffer(DEBUG_TRANSCMD, "received response",
- cbytes, cs->respdata);
- gigaset_handle_modem_response(cs);
- cbytes = 0;
-
- /* store EOL byte for CRLF collapsing */
- cs->respdata[0] = c;
-
- /* cs->dle may have changed */
- if (cs->dle && !(inbuf->inputstate & INS_DLE_command))
- inbuf->inputstate &= ~INS_command;
-
- /* return for reevaluating state */
- goto exit;
-
- case DLE_FLAG:
- if (inbuf->inputstate & INS_DLE_char) {
- /* quoted DLE: clear quote flag */
- inbuf->inputstate &= ~INS_DLE_char;
- } else if (cs->dle ||
- (inbuf->inputstate & INS_DLE_command)) {
- /* DLE escape, pass up for handling */
- inbuf->inputstate |= INS_DLE_char;
- goto exit;
- }
- /* quoted or not in DLE mode: treat as regular data */
- /* fall through */
- default:
- /* append to line buffer if possible */
- if (cbytes < MAX_RESP_SIZE)
- cs->respdata[cbytes] = c;
- cbytes++;
- }
- }
-exit:
- cs->cbytes = cbytes;
- return procbytes;
-}
-
-/* process a block of received bytes in lock mode
- * All received bytes are passed unmodified to the tty i/f.
- * Return value:
- * number of processed bytes
- */
-static unsigned lock_loop(unsigned numbytes, struct inbuf_t *inbuf)
-{
- unsigned char *src = inbuf->data + inbuf->head;
-
- gigaset_dbg_buffer(DEBUG_LOCKCMD, "received response", numbytes, src);
- gigaset_if_receive(inbuf->cs, src, numbytes);
- return numbytes;
-}
-
-/* process a block of received bytes in HDLC data mode
- * (mstate != MS_LOCKED && !(inputstate & INS_command) && proto2 == L2_HDLC)
- * Collect HDLC frames, undoing byte stuffing and watching for DLE escapes.
- * When a frame is complete, check the FCS and pass valid frames to the LL.
- * If DLE is encountered, return immediately to let the caller handle it.
- * Return value:
- * number of processed bytes
- */
-static unsigned hdlc_loop(unsigned numbytes, struct inbuf_t *inbuf)
-{
- struct cardstate *cs = inbuf->cs;
- struct bc_state *bcs = cs->bcs;
- int inputstate = bcs->inputstate;
- __u16 fcs = bcs->rx_fcs;
- struct sk_buff *skb = bcs->rx_skb;
- unsigned char *src = inbuf->data + inbuf->head;
- unsigned procbytes = 0;
- unsigned char c;
-
- if (inputstate & INS_byte_stuff) {
- if (!numbytes)
- return 0;
- inputstate &= ~INS_byte_stuff;
- goto byte_stuff;
- }
-
- while (procbytes < numbytes) {
- c = *src++;
- procbytes++;
- if (c == DLE_FLAG) {
- if (inputstate & INS_DLE_char) {
- /* quoted DLE: clear quote flag */
- inputstate &= ~INS_DLE_char;
- } else if (cs->dle || (inputstate & INS_DLE_command)) {
- /* DLE escape, pass up for handling */
- inputstate |= INS_DLE_char;
- break;
- }
- }
-
- if (c == PPP_ESCAPE) {
- /* byte stuffing indicator: pull in next byte */
- if (procbytes >= numbytes) {
- /* end of buffer, save for later processing */
- inputstate |= INS_byte_stuff;
- break;
- }
-byte_stuff:
- c = *src++;
- procbytes++;
- if (c == DLE_FLAG) {
- if (inputstate & INS_DLE_char) {
- /* quoted DLE: clear quote flag */
- inputstate &= ~INS_DLE_char;
- } else if (cs->dle ||
- (inputstate & INS_DLE_command)) {
- /* DLE escape, pass up for handling */
- inputstate |=
- INS_DLE_char | INS_byte_stuff;
- break;
- }
- }
- c ^= PPP_TRANS;
-#ifdef CONFIG_GIGASET_DEBUG
- if (!muststuff(c))
- gig_dbg(DEBUG_HDLC, "byte stuffed: 0x%02x", c);
-#endif
- } else if (c == PPP_FLAG) {
- /* end of frame: process content if any */
- if (inputstate & INS_have_data) {
- gig_dbg(DEBUG_HDLC,
- "7e----------------------------");
-
- /* check and pass received frame */
- if (!skb) {
- /* skipped frame */
- gigaset_isdn_rcv_err(bcs);
- } else if (skb->len < 2) {
- /* frame too short for FCS */
- dev_warn(cs->dev,
- "short frame (%d)\n",
- skb->len);
- gigaset_isdn_rcv_err(bcs);
- dev_kfree_skb_any(skb);
- } else if (fcs != PPP_GOODFCS) {
- /* frame check error */
- dev_err(cs->dev,
- "Checksum failed, %u bytes corrupted!\n",
- skb->len);
- gigaset_isdn_rcv_err(bcs);
- dev_kfree_skb_any(skb);
- } else {
- /* good frame */
- __skb_trim(skb, skb->len - 2);
- gigaset_skb_rcvd(bcs, skb);
- }
-
- /* prepare reception of next frame */
- inputstate &= ~INS_have_data;
- skb = gigaset_new_rx_skb(bcs);
- } else {
- /* empty frame (7E 7E) */
-#ifdef CONFIG_GIGASET_DEBUG
- ++bcs->emptycount;
-#endif
- if (!skb) {
- /* skipped (?) */
- gigaset_isdn_rcv_err(bcs);
- skb = gigaset_new_rx_skb(bcs);
- }
- }
-
- fcs = PPP_INITFCS;
- continue;
-#ifdef CONFIG_GIGASET_DEBUG
- } else if (muststuff(c)) {
- /* Should not happen. Possible after ZDLE=1<CR><LF>. */
- gig_dbg(DEBUG_HDLC, "not byte stuffed: 0x%02x", c);
-#endif
- }
-
- /* regular data byte, append to skb */
-#ifdef CONFIG_GIGASET_DEBUG
- if (!(inputstate & INS_have_data)) {
- gig_dbg(DEBUG_HDLC, "7e (%d x) ================",
- bcs->emptycount);
- bcs->emptycount = 0;
- }
-#endif
- inputstate |= INS_have_data;
- if (skb) {
- if (skb->len >= bcs->rx_bufsize) {
- dev_warn(cs->dev, "received packet too long\n");
- dev_kfree_skb_any(skb);
- /* skip remainder of packet */
- bcs->rx_skb = skb = NULL;
- } else {
- __skb_put_u8(skb, c);
- fcs = crc_ccitt_byte(fcs, c);
- }
- }
- }
-
- bcs->inputstate = inputstate;
- bcs->rx_fcs = fcs;
- return procbytes;
-}
-
-/* process a block of received bytes in transparent data mode
- * (mstate != MS_LOCKED && !(inputstate & INS_command) && proto2 != L2_HDLC)
- * Invert bytes, undoing byte stuffing and watching for DLE escapes.
- * If DLE is encountered, return immediately to let the caller handle it.
- * Return value:
- * number of processed bytes
- */
-static unsigned iraw_loop(unsigned numbytes, struct inbuf_t *inbuf)
-{
- struct cardstate *cs = inbuf->cs;
- struct bc_state *bcs = cs->bcs;
- int inputstate = bcs->inputstate;
- struct sk_buff *skb = bcs->rx_skb;
- unsigned char *src = inbuf->data + inbuf->head;
- unsigned procbytes = 0;
- unsigned char c;
-
- if (!skb) {
- /* skip this block */
- gigaset_new_rx_skb(bcs);
- return numbytes;
- }
-
- while (procbytes < numbytes && skb->len < bcs->rx_bufsize) {
- c = *src++;
- procbytes++;
-
- if (c == DLE_FLAG) {
- if (inputstate & INS_DLE_char) {
- /* quoted DLE: clear quote flag */
- inputstate &= ~INS_DLE_char;
- } else if (cs->dle || (inputstate & INS_DLE_command)) {
- /* DLE escape, pass up for handling */
- inputstate |= INS_DLE_char;
- break;
- }
- }
-
- /* regular data byte: append to current skb */
- inputstate |= INS_have_data;
- __skb_put_u8(skb, bitrev8(c));
- }
-
- /* pass data up */
- if (inputstate & INS_have_data) {
- gigaset_skb_rcvd(bcs, skb);
- inputstate &= ~INS_have_data;
- gigaset_new_rx_skb(bcs);
- }
-
- bcs->inputstate = inputstate;
- return procbytes;
-}
-
-/* process DLE escapes
- * Called whenever a DLE sequence might be encountered in the input stream.
- * Either processes the entire DLE sequence or, if that isn't possible,
- * notes the fact that an initial DLE has been received in the INS_DLE_char
- * inputstate flag and resumes processing of the sequence on the next call.
- */
-static void handle_dle(struct inbuf_t *inbuf)
-{
- struct cardstate *cs = inbuf->cs;
-
- if (cs->mstate == MS_LOCKED)
- return; /* no DLE processing in lock mode */
-
- if (!(inbuf->inputstate & INS_DLE_char)) {
- /* no DLE pending */
- if (inbuf->data[inbuf->head] == DLE_FLAG &&
- (cs->dle || inbuf->inputstate & INS_DLE_command)) {
- /* start of DLE sequence */
- inbuf->head++;
- if (inbuf->head == inbuf->tail ||
- inbuf->head == RBUFSIZE) {
- /* end of buffer, save for later processing */
- inbuf->inputstate |= INS_DLE_char;
- return;
- }
- } else {
- /* regular data byte */
- return;
- }
- }
-
- /* consume pending DLE */
- inbuf->inputstate &= ~INS_DLE_char;
-
- switch (inbuf->data[inbuf->head]) {
- case 'X': /* begin of event message */
- if (inbuf->inputstate & INS_command)
- dev_notice(cs->dev,
- "received <DLE>X in command mode\n");
- inbuf->inputstate |= INS_command | INS_DLE_command;
- inbuf->head++; /* byte consumed */
- break;
- case '.': /* end of event message */
- if (!(inbuf->inputstate & INS_DLE_command))
- dev_notice(cs->dev,
- "received <DLE>. without <DLE>X\n");
- inbuf->inputstate &= ~INS_DLE_command;
- /* return to data mode if in DLE mode */
- if (cs->dle)
- inbuf->inputstate &= ~INS_command;
- inbuf->head++; /* byte consumed */
- break;
- case DLE_FLAG: /* DLE in data stream */
- /* mark as quoted */
- inbuf->inputstate |= INS_DLE_char;
- if (!(cs->dle || inbuf->inputstate & INS_DLE_command))
- dev_notice(cs->dev,
- "received <DLE><DLE> not in DLE mode\n");
- break; /* quoted byte left in buffer */
- default:
- dev_notice(cs->dev, "received <DLE><%02x>\n",
- inbuf->data[inbuf->head]);
- /* quoted byte left in buffer */
- }
-}
-
-/**
- * gigaset_m10x_input() - process a block of data received from the device
- * @inbuf: received data and device descriptor structure.
- *
- * Called by hardware module {ser,usb}_gigaset with a block of received
- * bytes. Separates the bytes received over the serial data channel into
- * user data and command replies (locked/unlocked) according to the
- * current state of the interface.
- */
-void gigaset_m10x_input(struct inbuf_t *inbuf)
-{
- struct cardstate *cs = inbuf->cs;
- unsigned numbytes, procbytes;
-
- gig_dbg(DEBUG_INTR, "buffer state: %u -> %u", inbuf->head, inbuf->tail);
-
- while (inbuf->head != inbuf->tail) {
- /* check for DLE escape */
- handle_dle(inbuf);
-
- /* process a contiguous block of bytes */
- numbytes = (inbuf->head > inbuf->tail ?
- RBUFSIZE : inbuf->tail) - inbuf->head;
- gig_dbg(DEBUG_INTR, "processing %u bytes", numbytes);
- /*
- * numbytes may be 0 if handle_dle() ate the last byte.
- * This does no harm, *_loop() will just return 0 immediately.
- */
-
- if (cs->mstate == MS_LOCKED)
- procbytes = lock_loop(numbytes, inbuf);
- else if (inbuf->inputstate & INS_command)
- procbytes = cmd_loop(numbytes, inbuf);
- else if (cs->bcs->proto2 == L2_HDLC)
- procbytes = hdlc_loop(numbytes, inbuf);
- else
- procbytes = iraw_loop(numbytes, inbuf);
- inbuf->head += procbytes;
-
- /* check for buffer wraparound */
- if (inbuf->head >= RBUFSIZE)
- inbuf->head = 0;
-
- gig_dbg(DEBUG_INTR, "head set to %u", inbuf->head);
- }
-}
-EXPORT_SYMBOL_GPL(gigaset_m10x_input);
-
-
-/* == data output ========================================================== */
-
-/*
- * Encode a data packet into an octet stuffed HDLC frame with FCS,
- * opening and closing flags, preserving headroom data.
- * parameters:
- * skb skb containing original packet (freed upon return)
- * Return value:
- * pointer to newly allocated skb containing the result frame
- * and the original link layer header, NULL on error
- */
-static struct sk_buff *HDLC_Encode(struct sk_buff *skb)
-{
- struct sk_buff *hdlc_skb;
- __u16 fcs;
- unsigned char c;
- unsigned char *cp;
- int len;
- unsigned int stuf_cnt;
-
- stuf_cnt = 0;
- fcs = PPP_INITFCS;
- cp = skb->data;
- len = skb->len;
- while (len--) {
- if (muststuff(*cp))
- stuf_cnt++;
- fcs = crc_ccitt_byte(fcs, *cp++);
- }
- fcs ^= 0xffff; /* complement */
-
- /* size of new buffer: original size + number of stuffing bytes
- * + 2 bytes FCS + 2 stuffing bytes for FCS (if needed) + 2 flag bytes
- * + room for link layer header
- */
- hdlc_skb = dev_alloc_skb(skb->len + stuf_cnt + 6 + skb->mac_len);
- if (!hdlc_skb) {
- dev_kfree_skb_any(skb);
- return NULL;
- }
-
- /* Copy link layer header into new skb */
- skb_reset_mac_header(hdlc_skb);
- skb_reserve(hdlc_skb, skb->mac_len);
- memcpy(skb_mac_header(hdlc_skb), skb_mac_header(skb), skb->mac_len);
- hdlc_skb->mac_len = skb->mac_len;
-
- /* Add flag sequence in front of everything.. */
- skb_put_u8(hdlc_skb, PPP_FLAG);
-
- /* Perform byte stuffing while copying data. */
- while (skb->len--) {
- if (muststuff(*skb->data)) {
- skb_put_u8(hdlc_skb, PPP_ESCAPE);
- skb_put_u8(hdlc_skb, (*skb->data++) ^ PPP_TRANS);
- } else
- skb_put_u8(hdlc_skb, *skb->data++);
- }
-
- /* Finally add FCS (byte stuffed) and flag sequence */
- c = (fcs & 0x00ff); /* least significant byte first */
- if (muststuff(c)) {
- skb_put_u8(hdlc_skb, PPP_ESCAPE);
- c ^= PPP_TRANS;
- }
- skb_put_u8(hdlc_skb, c);
-
- c = ((fcs >> 8) & 0x00ff);
- if (muststuff(c)) {
- skb_put_u8(hdlc_skb, PPP_ESCAPE);
- c ^= PPP_TRANS;
- }
- skb_put_u8(hdlc_skb, c);
-
- skb_put_u8(hdlc_skb, PPP_FLAG);
-
- dev_kfree_skb_any(skb);
- return hdlc_skb;
-}
-
-/*
- * Encode a data packet into an octet stuffed raw bit inverted frame,
- * preserving headroom data.
- * parameters:
- * skb skb containing original packet (freed upon return)
- * Return value:
- * pointer to newly allocated skb containing the result frame
- * and the original link layer header, NULL on error
- */
-static struct sk_buff *iraw_encode(struct sk_buff *skb)
-{
- struct sk_buff *iraw_skb;
- unsigned char c;
- unsigned char *cp;
- int len;
-
- /* size of new buffer (worst case = every byte must be stuffed):
- * 2 * original size + room for link layer header
- */
- iraw_skb = dev_alloc_skb(2 * skb->len + skb->mac_len);
- if (!iraw_skb) {
- dev_kfree_skb_any(skb);
- return NULL;
- }
-
- /* copy link layer header into new skb */
- skb_reset_mac_header(iraw_skb);
- skb_reserve(iraw_skb, skb->mac_len);
- memcpy(skb_mac_header(iraw_skb), skb_mac_header(skb), skb->mac_len);
- iraw_skb->mac_len = skb->mac_len;
-
- /* copy and stuff data */
- cp = skb->data;
- len = skb->len;
- while (len--) {
- c = bitrev8(*cp++);
- if (c == DLE_FLAG)
- skb_put_u8(iraw_skb, c);
- skb_put_u8(iraw_skb, c);
- }
- dev_kfree_skb_any(skb);
- return iraw_skb;
-}
-
-/**
- * gigaset_m10x_send_skb() - queue an skb for sending
- * @bcs: B channel descriptor structure.
- * @skb: data to send.
- *
- * Called by LL to encode and queue an skb for sending, and start
- * transmission if necessary.
- * Once the payload data has been transmitted completely, gigaset_skb_sent()
- * will be called with the skb's link layer header preserved.
- *
- * Return value:
- * number of bytes accepted for sending (skb->len) if ok,
- * error code < 0 (eg. -ENOMEM) on error
- */
-int gigaset_m10x_send_skb(struct bc_state *bcs, struct sk_buff *skb)
-{
- struct cardstate *cs = bcs->cs;
- unsigned len = skb->len;
- unsigned long flags;
-
- if (bcs->proto2 == L2_HDLC)
- skb = HDLC_Encode(skb);
- else
- skb = iraw_encode(skb);
- if (!skb) {
- dev_err(cs->dev,
- "unable to allocate memory for encoding!\n");
- return -ENOMEM;
- }
-
- skb_queue_tail(&bcs->squeue, skb);
- spin_lock_irqsave(&cs->lock, flags);
- if (cs->connected)
- tasklet_schedule(&cs->write_tasklet);
- spin_unlock_irqrestore(&cs->lock, flags);
-
- return len; /* ok so far */
-}
-EXPORT_SYMBOL_GPL(gigaset_m10x_send_skb);
diff --git a/drivers/staging/isdn/gigaset/bas-gigaset.c b/drivers/staging/isdn/gigaset/bas-gigaset.c
deleted file mode 100644
index c334525a5f63..000000000000
--- a/drivers/staging/isdn/gigaset/bas-gigaset.c
+++ /dev/null
@@ -1,2672 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * USB driver for Gigaset 307x base via direct USB connection.
- *
- * Copyright (c) 2001 by Hansjoerg Lipp <hjlipp@web.de>,
- * Tilman Schmidt <tilman@imap.cc>,
- * Stefan Eilers.
- *
- * =====================================================================
- * =====================================================================
- */
-
-#include "gigaset.h"
-#include <linux/usb.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-
-/* Version Information */
-#define DRIVER_AUTHOR "Tilman Schmidt <tilman@imap.cc>, Hansjoerg Lipp <hjlipp@web.de>, Stefan Eilers"
-#define DRIVER_DESC "USB Driver for Gigaset 307x"
-
-
-/* Module parameters */
-
-static int startmode = SM_ISDN;
-static int cidmode = 1;
-
-module_param(startmode, int, S_IRUGO);
-module_param(cidmode, int, S_IRUGO);
-MODULE_PARM_DESC(startmode, "start in isdn4linux mode");
-MODULE_PARM_DESC(cidmode, "Call-ID mode");
-
-#define GIGASET_MINORS 1
-#define GIGASET_MINOR 16
-#define GIGASET_MODULENAME "bas_gigaset"
-#define GIGASET_DEVNAME "ttyGB"
-
-/* length limit according to Siemens 3070usb-protokoll.doc ch. 2.1 */
-#define IF_WRITEBUF 264
-
-/* interrupt pipe message size according to ibid. ch. 2.2 */
-#define IP_MSGSIZE 3
-
-/* Values for the Gigaset 307x */
-#define USB_GIGA_VENDOR_ID 0x0681
-#define USB_3070_PRODUCT_ID 0x0001
-#define USB_3075_PRODUCT_ID 0x0002
-#define USB_SX303_PRODUCT_ID 0x0021
-#define USB_SX353_PRODUCT_ID 0x0022
-
-/* table of devices that work with this driver */
-static const struct usb_device_id gigaset_table[] = {
- { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_3070_PRODUCT_ID) },
- { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_3075_PRODUCT_ID) },
- { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_SX303_PRODUCT_ID) },
- { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_SX353_PRODUCT_ID) },
- { } /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(usb, gigaset_table);
-
-/*======================= local function prototypes ==========================*/
-
-/* function called if a new device belonging to this driver is connected */
-static int gigaset_probe(struct usb_interface *interface,
- const struct usb_device_id *id);
-
-/* Function will be called if the device is unplugged */
-static void gigaset_disconnect(struct usb_interface *interface);
-
-/* functions called before/after suspend */
-static int gigaset_suspend(struct usb_interface *intf, pm_message_t message);
-static int gigaset_resume(struct usb_interface *intf);
-
-/* functions called before/after device reset */
-static int gigaset_pre_reset(struct usb_interface *intf);
-static int gigaset_post_reset(struct usb_interface *intf);
-
-static int atread_submit(struct cardstate *, int);
-static void stopurbs(struct bas_bc_state *);
-static int req_submit(struct bc_state *, int, int, int);
-static int atwrite_submit(struct cardstate *, unsigned char *, int);
-static int start_cbsend(struct cardstate *);
-
-/*============================================================================*/
-
-struct bas_cardstate {
- struct usb_device *udev; /* USB device pointer */
- struct cardstate *cs;
- struct usb_interface *interface; /* interface for this device */
- unsigned char minor; /* starting minor number */
-
- struct urb *urb_ctrl; /* control pipe default URB */
- struct usb_ctrlrequest dr_ctrl;
- struct timer_list timer_ctrl; /* control request timeout */
- int retry_ctrl;
-
- struct timer_list timer_atrdy; /* AT command ready timeout */
- struct urb *urb_cmd_out; /* for sending AT commands */
- struct usb_ctrlrequest dr_cmd_out;
- int retry_cmd_out;
-
- struct urb *urb_cmd_in; /* for receiving AT replies */
- struct usb_ctrlrequest dr_cmd_in;
- struct timer_list timer_cmd_in; /* receive request timeout */
- unsigned char *rcvbuf; /* AT reply receive buffer */
-
- struct urb *urb_int_in; /* URB for interrupt pipe */
- unsigned char *int_in_buf;
- struct work_struct int_in_wq; /* for usb_clear_halt() */
- struct timer_list timer_int_in; /* int read retry delay */
- int retry_int_in;
-
- spinlock_t lock; /* locks all following */
- int basstate; /* bitmap (BS_*) */
- int pending; /* uncompleted base request */
- wait_queue_head_t waitqueue;
- int rcvbuf_size; /* size of AT receive buffer */
- /* 0: no receive in progress */
- int retry_cmd_in; /* receive req retry count */
-};
-
-/* status of direct USB connection to 307x base (bits in basstate) */
-#define BS_ATOPEN 0x001 /* AT channel open */
-#define BS_B1OPEN 0x002 /* B channel 1 open */
-#define BS_B2OPEN 0x004 /* B channel 2 open */
-#define BS_ATREADY 0x008 /* base ready for AT command */
-#define BS_INIT 0x010 /* base has signalled INIT_OK */
-#define BS_ATTIMER 0x020 /* waiting for HD_READY_SEND_ATDATA */
-#define BS_ATRDPEND 0x040 /* urb_cmd_in in use */
-#define BS_ATWRPEND 0x080 /* urb_cmd_out in use */
-#define BS_SUSPEND 0x100 /* USB port suspended */
-#define BS_RESETTING 0x200 /* waiting for HD_RESET_INTERRUPT_PIPE_ACK */
-
-
-static struct gigaset_driver *driver;
-
-/* usb specific object needed to register this driver with the usb subsystem */
-static struct usb_driver gigaset_usb_driver = {
- .name = GIGASET_MODULENAME,
- .probe = gigaset_probe,
- .disconnect = gigaset_disconnect,
- .id_table = gigaset_table,
- .suspend = gigaset_suspend,
- .resume = gigaset_resume,
- .reset_resume = gigaset_post_reset,
- .pre_reset = gigaset_pre_reset,
- .post_reset = gigaset_post_reset,
- .disable_hub_initiated_lpm = 1,
-};
-
-/* get message text for usb_submit_urb return code
- */
-static char *get_usb_rcmsg(int rc)
-{
- static char unkmsg[28];
-
- switch (rc) {
- case 0:
- return "success";
- case -ENOMEM:
- return "out of memory";
- case -ENODEV:
- return "device not present";
- case -ENOENT:
- return "endpoint not present";
- case -ENXIO:
- return "URB type not supported";
- case -EINVAL:
- return "invalid argument";
- case -EAGAIN:
- return "start frame too early or too much scheduled";
- case -EFBIG:
- return "too many isoc frames requested";
- case -EPIPE:
- return "endpoint stalled";
- case -EMSGSIZE:
- return "invalid packet size";
- case -ENOSPC:
- return "would overcommit USB bandwidth";
- case -ESHUTDOWN:
- return "device shut down";
- case -EPERM:
- return "reject flag set";
- case -EHOSTUNREACH:
- return "device suspended";
- default:
- snprintf(unkmsg, sizeof(unkmsg), "unknown error %d", rc);
- return unkmsg;
- }
-}
-
-/* get message text for USB status code
- */
-static char *get_usb_statmsg(int status)
-{
- static char unkmsg[28];
-
- switch (status) {
- case 0:
- return "success";
- case -ENOENT:
- return "unlinked (sync)";
- case -EINPROGRESS:
- return "URB still pending";
- case -EPROTO:
- return "bitstuff error, timeout, or unknown USB error";
- case -EILSEQ:
- return "CRC mismatch, timeout, or unknown USB error";
- case -ETIME:
- return "USB response timeout";
- case -EPIPE:
- return "endpoint stalled";
- case -ECOMM:
- return "IN buffer overrun";
- case -ENOSR:
- return "OUT buffer underrun";
- case -EOVERFLOW:
- return "endpoint babble";
- case -EREMOTEIO:
- return "short packet";
- case -ENODEV:
- return "device removed";
- case -EXDEV:
- return "partial isoc transfer";
- case -EINVAL:
- return "ISO madness";
- case -ECONNRESET:
- return "unlinked (async)";
- case -ESHUTDOWN:
- return "device shut down";
- default:
- snprintf(unkmsg, sizeof(unkmsg), "unknown status %d", status);
- return unkmsg;
- }
-}
-
-/* usb_pipetype_str
- * retrieve string representation of USB pipe type
- */
-static inline char *usb_pipetype_str(int pipe)
-{
- if (usb_pipeisoc(pipe))
- return "Isoc";
- if (usb_pipeint(pipe))
- return "Int";
- if (usb_pipecontrol(pipe))
- return "Ctrl";
- if (usb_pipebulk(pipe))
- return "Bulk";
- return "?";
-}
-
-/* dump_urb
- * write content of URB to syslog for debugging
- */
-static inline void dump_urb(enum debuglevel level, const char *tag,
- struct urb *urb)
-{
-#ifdef CONFIG_GIGASET_DEBUG
- int i;
- gig_dbg(level, "%s urb(0x%08lx)->{", tag, (unsigned long) urb);
- if (urb) {
- gig_dbg(level,
- " dev=0x%08lx, pipe=%s:EP%d/DV%d:%s, "
- "hcpriv=0x%08lx, transfer_flags=0x%x,",
- (unsigned long) urb->dev,
- usb_pipetype_str(urb->pipe),
- usb_pipeendpoint(urb->pipe), usb_pipedevice(urb->pipe),
- usb_pipein(urb->pipe) ? "in" : "out",
- (unsigned long) urb->hcpriv,
- urb->transfer_flags);
- gig_dbg(level,
- " transfer_buffer=0x%08lx[%d], actual_length=%d, "
- "setup_packet=0x%08lx,",
- (unsigned long) urb->transfer_buffer,
- urb->transfer_buffer_length, urb->actual_length,
- (unsigned long) urb->setup_packet);
- gig_dbg(level,
- " start_frame=%d, number_of_packets=%d, interval=%d, "
- "error_count=%d,",
- urb->start_frame, urb->number_of_packets, urb->interval,
- urb->error_count);
- gig_dbg(level,
- " context=0x%08lx, complete=0x%08lx, "
- "iso_frame_desc[]={",
- (unsigned long) urb->context,
- (unsigned long) urb->complete);
- for (i = 0; i < urb->number_of_packets; i++) {
- struct usb_iso_packet_descriptor *pifd
- = &urb->iso_frame_desc[i];
- gig_dbg(level,
- " {offset=%u, length=%u, actual_length=%u, "
- "status=%u}",
- pifd->offset, pifd->length, pifd->actual_length,
- pifd->status);
- }
- }
- gig_dbg(level, "}}");
-#endif
-}
-
-/* read/set modem control bits etc. (m10x only) */
-static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state,
- unsigned new_state)
-{
- return -EINVAL;
-}
-
-static int gigaset_baud_rate(struct cardstate *cs, unsigned cflag)
-{
- return -EINVAL;
-}
-
-static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag)
-{
- return -EINVAL;
-}
-
-/* set/clear bits in base connection state, return previous state
- */
-static inline int update_basstate(struct bas_cardstate *ucs,
- int set, int clear)
-{
- unsigned long flags;
- int state;
-
- spin_lock_irqsave(&ucs->lock, flags);
- state = ucs->basstate;
- ucs->basstate = (state & ~clear) | set;
- spin_unlock_irqrestore(&ucs->lock, flags);
- return state;
-}
-
-/* error_hangup
- * hang up any existing connection because of an unrecoverable error
- * This function may be called from any context and takes care of scheduling
- * the necessary actions for execution outside of interrupt context.
- * cs->lock must not be held.
- * argument:
- * B channel control structure
- */
-static inline void error_hangup(struct bc_state *bcs)
-{
- struct cardstate *cs = bcs->cs;
-
- gigaset_add_event(cs, &bcs->at_state, EV_HUP, NULL, 0, NULL);
- gigaset_schedule_event(cs);
-}
-
-/* error_reset
- * reset Gigaset device because of an unrecoverable error
- * This function may be called from any context, and takes care of
- * scheduling the necessary actions for execution outside of interrupt context.
- * cs->hw.bas->lock must not be held.
- * argument:
- * controller state structure
- */
-static inline void error_reset(struct cardstate *cs)
-{
- /* reset interrupt pipe to recover (ignore errors) */
- update_basstate(cs->hw.bas, BS_RESETTING, 0);
- if (req_submit(cs->bcs, HD_RESET_INTERRUPT_PIPE, 0, BAS_TIMEOUT))
- /* submission failed, escalate to USB port reset */
- usb_queue_reset_device(cs->hw.bas->interface);
-}
-
-/* check_pending
- * check for completion of pending control request
- * parameter:
- * ucs hardware specific controller state structure
- */
-static void check_pending(struct bas_cardstate *ucs)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&ucs->lock, flags);
- switch (ucs->pending) {
- case 0:
- break;
- case HD_OPEN_ATCHANNEL:
- if (ucs->basstate & BS_ATOPEN)
- ucs->pending = 0;
- break;
- case HD_OPEN_B1CHANNEL:
- if (ucs->basstate & BS_B1OPEN)
- ucs->pending = 0;
- break;
- case HD_OPEN_B2CHANNEL:
- if (ucs->basstate & BS_B2OPEN)
- ucs->pending = 0;
- break;
- case HD_CLOSE_ATCHANNEL:
- if (!(ucs->basstate & BS_ATOPEN))
- ucs->pending = 0;
- break;
- case HD_CLOSE_B1CHANNEL:
- if (!(ucs->basstate & BS_B1OPEN))
- ucs->pending = 0;
- break;
- case HD_CLOSE_B2CHANNEL:
- if (!(ucs->basstate & BS_B2OPEN))
- ucs->pending = 0;
- break;
- case HD_DEVICE_INIT_ACK: /* no reply expected */
- ucs->pending = 0;
- break;
- case HD_RESET_INTERRUPT_PIPE:
- if (!(ucs->basstate & BS_RESETTING))
- ucs->pending = 0;
- break;
- /*
- * HD_READ_ATMESSAGE and HD_WRITE_ATMESSAGE are handled separately
- * and should never end up here
- */
- default:
- dev_warn(&ucs->interface->dev,
- "unknown pending request 0x%02x cleared\n",
- ucs->pending);
- ucs->pending = 0;
- }
-
- if (!ucs->pending)
- del_timer(&ucs->timer_ctrl);
-
- spin_unlock_irqrestore(&ucs->lock, flags);
-}
-
-/* cmd_in_timeout
- * timeout routine for command input request
- * argument:
- * controller state structure
- */
-static void cmd_in_timeout(struct timer_list *t)
-{
- struct bas_cardstate *ucs = from_timer(ucs, t, timer_cmd_in);
- struct cardstate *cs = ucs->cs;
- int rc;
-
- if (!ucs->rcvbuf_size) {
- gig_dbg(DEBUG_USBREQ, "%s: no receive in progress", __func__);
- return;
- }
-
- if (ucs->retry_cmd_in++ >= BAS_RETRY) {
- dev_err(cs->dev,
- "control read: timeout, giving up after %d tries\n",
- ucs->retry_cmd_in);
- kfree(ucs->rcvbuf);
- ucs->rcvbuf = NULL;
- ucs->rcvbuf_size = 0;
- error_reset(cs);
- return;
- }
-
- gig_dbg(DEBUG_USBREQ, "%s: timeout, retry %d",
- __func__, ucs->retry_cmd_in);
- rc = atread_submit(cs, BAS_TIMEOUT);
- if (rc < 0) {
- kfree(ucs->rcvbuf);
- ucs->rcvbuf = NULL;
- ucs->rcvbuf_size = 0;
- if (rc != -ENODEV)
- error_reset(cs);
- }
-}
-
-/* read_ctrl_callback
- * USB completion handler for control pipe input
- * called by the USB subsystem in interrupt context
- * parameter:
- * urb USB request block
- * urb->context = inbuf structure for controller state
- */
-static void read_ctrl_callback(struct urb *urb)
-{
- struct inbuf_t *inbuf = urb->context;
- struct cardstate *cs = inbuf->cs;
- struct bas_cardstate *ucs = cs->hw.bas;
- int status = urb->status;
- unsigned numbytes;
- int rc;
-
- update_basstate(ucs, 0, BS_ATRDPEND);
- wake_up(&ucs->waitqueue);
- del_timer(&ucs->timer_cmd_in);
-
- switch (status) {
- case 0: /* normal completion */
- numbytes = urb->actual_length;
- if (unlikely(numbytes != ucs->rcvbuf_size)) {
- dev_warn(cs->dev,
- "control read: received %d chars, expected %d\n",
- numbytes, ucs->rcvbuf_size);
- if (numbytes > ucs->rcvbuf_size)
- numbytes = ucs->rcvbuf_size;
- }
-
- /* copy received bytes to inbuf, notify event layer */
- if (gigaset_fill_inbuf(inbuf, ucs->rcvbuf, numbytes)) {
- gig_dbg(DEBUG_INTR, "%s-->BH", __func__);
- gigaset_schedule_event(cs);
- }
- break;
-
- case -ENOENT: /* cancelled */
- case -ECONNRESET: /* cancelled (async) */
- case -EINPROGRESS: /* pending */
- case -ENODEV: /* device removed */
- case -ESHUTDOWN: /* device shut down */
- /* no further action necessary */
- gig_dbg(DEBUG_USBREQ, "%s: %s",
- __func__, get_usb_statmsg(status));
- break;
-
- default: /* other errors: retry */
- if (ucs->retry_cmd_in++ < BAS_RETRY) {
- gig_dbg(DEBUG_USBREQ, "%s: %s, retry %d", __func__,
- get_usb_statmsg(status), ucs->retry_cmd_in);
- rc = atread_submit(cs, BAS_TIMEOUT);
- if (rc >= 0)
- /* successfully resubmitted, skip freeing */
- return;
- if (rc == -ENODEV)
- /* disconnect, no further action necessary */
- break;
- }
- dev_err(cs->dev, "control read: %s, giving up after %d tries\n",
- get_usb_statmsg(status), ucs->retry_cmd_in);
- error_reset(cs);
- }
-
- /* read finished, free buffer */
- kfree(ucs->rcvbuf);
- ucs->rcvbuf = NULL;
- ucs->rcvbuf_size = 0;
-}
-
-/* atread_submit
- * submit an HD_READ_ATMESSAGE command URB and optionally start a timeout
- * parameters:
- * cs controller state structure
- * timeout timeout in 1/10 sec., 0: none
- * return value:
- * 0 on success
- * -EBUSY if another request is pending
- * any URB submission error code
- */
-static int atread_submit(struct cardstate *cs, int timeout)
-{
- struct bas_cardstate *ucs = cs->hw.bas;
- int basstate;
- int ret;
-
- gig_dbg(DEBUG_USBREQ, "-------> HD_READ_ATMESSAGE (%d)",
- ucs->rcvbuf_size);
-
- basstate = update_basstate(ucs, BS_ATRDPEND, 0);
- if (basstate & BS_ATRDPEND) {
- dev_err(cs->dev,
- "could not submit HD_READ_ATMESSAGE: URB busy\n");
- return -EBUSY;
- }
-
- if (basstate & BS_SUSPEND) {
- dev_notice(cs->dev,
- "HD_READ_ATMESSAGE not submitted, "
- "suspend in progress\n");
- update_basstate(ucs, 0, BS_ATRDPEND);
- /* treat like disconnect */
- return -ENODEV;
- }
-
- ucs->dr_cmd_in.bRequestType = IN_VENDOR_REQ;
- ucs->dr_cmd_in.bRequest = HD_READ_ATMESSAGE;
- ucs->dr_cmd_in.wValue = 0;
- ucs->dr_cmd_in.wIndex = 0;
- ucs->dr_cmd_in.wLength = cpu_to_le16(ucs->rcvbuf_size);
- usb_fill_control_urb(ucs->urb_cmd_in, ucs->udev,
- usb_rcvctrlpipe(ucs->udev, 0),
- (unsigned char *) &ucs->dr_cmd_in,
- ucs->rcvbuf, ucs->rcvbuf_size,
- read_ctrl_callback, cs->inbuf);
-
- ret = usb_submit_urb(ucs->urb_cmd_in, GFP_ATOMIC);
- if (ret != 0) {
- update_basstate(ucs, 0, BS_ATRDPEND);
- dev_err(cs->dev, "could not submit HD_READ_ATMESSAGE: %s\n",
- get_usb_rcmsg(ret));
- return ret;
- }
-
- if (timeout > 0) {
- gig_dbg(DEBUG_USBREQ, "setting timeout of %d/10 secs", timeout);
- mod_timer(&ucs->timer_cmd_in, jiffies + timeout * HZ / 10);
- }
- return 0;
-}
-
-/* int_in_work
- * workqueue routine to clear halt on interrupt in endpoint
- */
-
-static void int_in_work(struct work_struct *work)
-{
- struct bas_cardstate *ucs =
- container_of(work, struct bas_cardstate, int_in_wq);
- struct urb *urb = ucs->urb_int_in;
- struct cardstate *cs = urb->context;
- int rc;
-
- /* clear halt condition */
- rc = usb_clear_halt(ucs->udev, urb->pipe);
- gig_dbg(DEBUG_USBREQ, "clear_halt: %s", get_usb_rcmsg(rc));
- if (rc == 0)
- /* success, resubmit interrupt read URB */
- rc = usb_submit_urb(urb, GFP_ATOMIC);
-
- switch (rc) {
- case 0: /* success */
- case -ENODEV: /* device gone */
- case -EINVAL: /* URB already resubmitted, or terminal badness */
- break;
- default: /* failure: try to recover by resetting the device */
- dev_err(cs->dev, "clear halt failed: %s\n", get_usb_rcmsg(rc));
- rc = usb_lock_device_for_reset(ucs->udev, ucs->interface);
- if (rc == 0) {
- rc = usb_reset_device(ucs->udev);
- usb_unlock_device(ucs->udev);
- }
- }
- ucs->retry_int_in = 0;
-}
-
-/* int_in_resubmit
- * timer routine for interrupt read delayed resubmit
- * argument:
- * controller state structure
- */
-static void int_in_resubmit(struct timer_list *t)
-{
- struct bas_cardstate *ucs = from_timer(ucs, t, timer_int_in);
- struct cardstate *cs = ucs->cs;
- int rc;
-
- if (ucs->retry_int_in++ >= BAS_RETRY) {
- dev_err(cs->dev, "interrupt read: giving up after %d tries\n",
- ucs->retry_int_in);
- usb_queue_reset_device(ucs->interface);
- return;
- }
-
- gig_dbg(DEBUG_USBREQ, "%s: retry %d", __func__, ucs->retry_int_in);
- rc = usb_submit_urb(ucs->urb_int_in, GFP_ATOMIC);
- if (rc != 0 && rc != -ENODEV) {
- dev_err(cs->dev, "could not resubmit interrupt URB: %s\n",
- get_usb_rcmsg(rc));
- usb_queue_reset_device(ucs->interface);
- }
-}
-
-/* read_int_callback
- * USB completion handler for interrupt pipe input
- * called by the USB subsystem in interrupt context
- * parameter:
- * urb USB request block
- * urb->context = controller state structure
- */
-static void read_int_callback(struct urb *urb)
-{
- struct cardstate *cs = urb->context;
- struct bas_cardstate *ucs = cs->hw.bas;
- struct bc_state *bcs;
- int status = urb->status;
- unsigned long flags;
- int rc;
- unsigned l;
- int channel;
-
- switch (status) {
- case 0: /* success */
- ucs->retry_int_in = 0;
- break;
- case -EPIPE: /* endpoint stalled */
- schedule_work(&ucs->int_in_wq);
- /* fall through */
- case -ENOENT: /* cancelled */
- case -ECONNRESET: /* cancelled (async) */
- case -EINPROGRESS: /* pending */
- case -ENODEV: /* device removed */
- case -ESHUTDOWN: /* device shut down */
- /* no further action necessary */
- gig_dbg(DEBUG_USBREQ, "%s: %s",
- __func__, get_usb_statmsg(status));
- return;
- case -EPROTO: /* protocol error or unplug */
- case -EILSEQ:
- case -ETIME:
- /* resubmit after delay */
- gig_dbg(DEBUG_USBREQ, "%s: %s",
- __func__, get_usb_statmsg(status));
- mod_timer(&ucs->timer_int_in, jiffies + HZ / 10);
- return;
- default: /* other errors: just resubmit */
- dev_warn(cs->dev, "interrupt read: %s\n",
- get_usb_statmsg(status));
- goto resubmit;
- }
-
- /* drop incomplete packets even if the missing bytes wouldn't matter */
- if (unlikely(urb->actual_length < IP_MSGSIZE)) {
- dev_warn(cs->dev, "incomplete interrupt packet (%d bytes)\n",
- urb->actual_length);
- goto resubmit;
- }
-
- l = (unsigned) ucs->int_in_buf[1] +
- (((unsigned) ucs->int_in_buf[2]) << 8);
-
- gig_dbg(DEBUG_USBREQ, "<-------%d: 0x%02x (%u [0x%02x 0x%02x])",
- urb->actual_length, (int)ucs->int_in_buf[0], l,
- (int)ucs->int_in_buf[1], (int)ucs->int_in_buf[2]);
-
- channel = 0;
-
- switch (ucs->int_in_buf[0]) {
- case HD_DEVICE_INIT_OK:
- update_basstate(ucs, BS_INIT, 0);
- break;
-
- case HD_READY_SEND_ATDATA:
- del_timer(&ucs->timer_atrdy);
- update_basstate(ucs, BS_ATREADY, BS_ATTIMER);
- start_cbsend(cs);
- break;
-
- case HD_OPEN_B2CHANNEL_ACK:
- ++channel;
- /* fall through */
- case HD_OPEN_B1CHANNEL_ACK:
- bcs = cs->bcs + channel;
- update_basstate(ucs, BS_B1OPEN << channel, 0);
- gigaset_bchannel_up(bcs);
- break;
-
- case HD_OPEN_ATCHANNEL_ACK:
- update_basstate(ucs, BS_ATOPEN, 0);
- start_cbsend(cs);
- break;
-
- case HD_CLOSE_B2CHANNEL_ACK:
- ++channel;
- /* fall through */
- case HD_CLOSE_B1CHANNEL_ACK:
- bcs = cs->bcs + channel;
- update_basstate(ucs, 0, BS_B1OPEN << channel);
- stopurbs(bcs->hw.bas);
- gigaset_bchannel_down(bcs);
- break;
-
- case HD_CLOSE_ATCHANNEL_ACK:
- update_basstate(ucs, 0, BS_ATOPEN);
- break;
-
- case HD_B2_FLOW_CONTROL:
- ++channel;
- /* fall through */
- case HD_B1_FLOW_CONTROL:
- bcs = cs->bcs + channel;
- atomic_add((l - BAS_NORMFRAME) * BAS_CORRFRAMES,
- &bcs->hw.bas->corrbytes);
- gig_dbg(DEBUG_ISO,
- "Flow control (channel %d, sub %d): 0x%02x => %d",
- channel, bcs->hw.bas->numsub, l,
- atomic_read(&bcs->hw.bas->corrbytes));
- break;
-
- case HD_RECEIVEATDATA_ACK: /* AT response ready to be received */
- if (!l) {
- dev_warn(cs->dev,
- "HD_RECEIVEATDATA_ACK with length 0 ignored\n");
- break;
- }
- spin_lock_irqsave(&cs->lock, flags);
- if (ucs->basstate & BS_ATRDPEND) {
- spin_unlock_irqrestore(&cs->lock, flags);
- dev_warn(cs->dev,
- "HD_RECEIVEATDATA_ACK(%d) during HD_READ_ATMESSAGE(%d) ignored\n",
- l, ucs->rcvbuf_size);
- break;
- }
- if (ucs->rcvbuf_size) {
- /* throw away previous buffer - we have no queue */
- dev_err(cs->dev,
- "receive AT data overrun, %d bytes lost\n",
- ucs->rcvbuf_size);
- kfree(ucs->rcvbuf);
- ucs->rcvbuf_size = 0;
- }
- ucs->rcvbuf = kmalloc(l, GFP_ATOMIC);
- if (ucs->rcvbuf == NULL) {
- spin_unlock_irqrestore(&cs->lock, flags);
- dev_err(cs->dev, "out of memory receiving AT data\n");
- break;
- }
- ucs->rcvbuf_size = l;
- ucs->retry_cmd_in = 0;
- rc = atread_submit(cs, BAS_TIMEOUT);
- if (rc < 0) {
- kfree(ucs->rcvbuf);
- ucs->rcvbuf = NULL;
- ucs->rcvbuf_size = 0;
- }
- spin_unlock_irqrestore(&cs->lock, flags);
- if (rc < 0 && rc != -ENODEV)
- error_reset(cs);
- break;
-
- case HD_RESET_INTERRUPT_PIPE_ACK:
- update_basstate(ucs, 0, BS_RESETTING);
- dev_notice(cs->dev, "interrupt pipe reset\n");
- break;
-
- case HD_SUSPEND_END:
- gig_dbg(DEBUG_USBREQ, "HD_SUSPEND_END");
- break;
-
- default:
- dev_warn(cs->dev,
- "unknown Gigaset signal 0x%02x (%u) ignored\n",
- (int) ucs->int_in_buf[0], l);
- }
-
- check_pending(ucs);
- wake_up(&ucs->waitqueue);
-
-resubmit:
- rc = usb_submit_urb(urb, GFP_ATOMIC);
- if (unlikely(rc != 0 && rc != -ENODEV)) {
- dev_err(cs->dev, "could not resubmit interrupt URB: %s\n",
- get_usb_rcmsg(rc));
- error_reset(cs);
- }
-}
-
-/* read_iso_callback
- * USB completion handler for B channel isochronous input
- * called by the USB subsystem in interrupt context
- * parameter:
- * urb USB request block of completed request
- * urb->context = bc_state structure
- */
-static void read_iso_callback(struct urb *urb)
-{
- struct bc_state *bcs;
- struct bas_bc_state *ubc;
- int status = urb->status;
- unsigned long flags;
- int i, rc;
-
- /* status codes not worth bothering the tasklet with */
- if (unlikely(status == -ENOENT ||
- status == -ECONNRESET ||
- status == -EINPROGRESS ||
- status == -ENODEV ||
- status == -ESHUTDOWN)) {
- gig_dbg(DEBUG_ISO, "%s: %s",
- __func__, get_usb_statmsg(status));
- return;
- }
-
- bcs = urb->context;
- ubc = bcs->hw.bas;
-
- spin_lock_irqsave(&ubc->isoinlock, flags);
- if (likely(ubc->isoindone == NULL)) {
- /* pass URB to tasklet */
- ubc->isoindone = urb;
- ubc->isoinstatus = status;
- tasklet_hi_schedule(&ubc->rcvd_tasklet);
- } else {
- /* tasklet still busy, drop data and resubmit URB */
- gig_dbg(DEBUG_ISO, "%s: overrun", __func__);
- ubc->loststatus = status;
- for (i = 0; i < BAS_NUMFRAMES; i++) {
- ubc->isoinlost += urb->iso_frame_desc[i].actual_length;
- if (unlikely(urb->iso_frame_desc[i].status != 0 &&
- urb->iso_frame_desc[i].status != -EINPROGRESS))
- ubc->loststatus = urb->iso_frame_desc[i].status;
- urb->iso_frame_desc[i].status = 0;
- urb->iso_frame_desc[i].actual_length = 0;
- }
- if (likely(ubc->running)) {
- /* urb->dev is clobbered by USB subsystem */
- urb->dev = bcs->cs->hw.bas->udev;
- urb->transfer_flags = URB_ISO_ASAP;
- urb->number_of_packets = BAS_NUMFRAMES;
- rc = usb_submit_urb(urb, GFP_ATOMIC);
- if (unlikely(rc != 0 && rc != -ENODEV)) {
- dev_err(bcs->cs->dev,
- "could not resubmit isoc read URB: %s\n",
- get_usb_rcmsg(rc));
- dump_urb(DEBUG_ISO, "isoc read", urb);
- error_hangup(bcs);
- }
- }
- }
- spin_unlock_irqrestore(&ubc->isoinlock, flags);
-}
-
-/* write_iso_callback
- * USB completion handler for B channel isochronous output
- * called by the USB subsystem in interrupt context
- * parameter:
- * urb USB request block of completed request
- * urb->context = isow_urbctx_t structure
- */
-static void write_iso_callback(struct urb *urb)
-{
- struct isow_urbctx_t *ucx;
- struct bas_bc_state *ubc;
- int status = urb->status;
- unsigned long flags;
-
- /* status codes not worth bothering the tasklet with */
- if (unlikely(status == -ENOENT ||
- status == -ECONNRESET ||
- status == -EINPROGRESS ||
- status == -ENODEV ||
- status == -ESHUTDOWN)) {
- gig_dbg(DEBUG_ISO, "%s: %s",
- __func__, get_usb_statmsg(status));
- return;
- }
-
- /* pass URB context to tasklet */
- ucx = urb->context;
- ubc = ucx->bcs->hw.bas;
- ucx->status = status;
-
- spin_lock_irqsave(&ubc->isooutlock, flags);
- ubc->isooutovfl = ubc->isooutdone;
- ubc->isooutdone = ucx;
- spin_unlock_irqrestore(&ubc->isooutlock, flags);
- tasklet_hi_schedule(&ubc->sent_tasklet);
-}
-
-/* starturbs
- * prepare and submit USB request blocks for isochronous input and output
- * argument:
- * B channel control structure
- * return value:
- * 0 on success
- * < 0 on error (no URBs submitted)
- */
-static int starturbs(struct bc_state *bcs)
-{
- struct usb_device *udev = bcs->cs->hw.bas->udev;
- struct bas_bc_state *ubc = bcs->hw.bas;
- struct urb *urb;
- int j, k;
- int rc;
-
- /* initialize L2 reception */
- if (bcs->proto2 == L2_HDLC)
- bcs->inputstate |= INS_flag_hunt;
-
- /* submit all isochronous input URBs */
- ubc->running = 1;
- for (k = 0; k < BAS_INURBS; k++) {
- urb = ubc->isoinurbs[k];
- if (!urb) {
- rc = -EFAULT;
- goto error;
- }
- usb_fill_int_urb(urb, udev,
- usb_rcvisocpipe(udev, 3 + 2 * bcs->channel),
- ubc->isoinbuf + k * BAS_INBUFSIZE,
- BAS_INBUFSIZE, read_iso_callback, bcs,
- BAS_FRAMETIME);
-
- urb->transfer_flags = URB_ISO_ASAP;
- urb->number_of_packets = BAS_NUMFRAMES;
- for (j = 0; j < BAS_NUMFRAMES; j++) {
- urb->iso_frame_desc[j].offset = j * BAS_MAXFRAME;
- urb->iso_frame_desc[j].length = BAS_MAXFRAME;
- urb->iso_frame_desc[j].status = 0;
- urb->iso_frame_desc[j].actual_length = 0;
- }
-
- dump_urb(DEBUG_ISO, "Initial isoc read", urb);
- rc = usb_submit_urb(urb, GFP_ATOMIC);
- if (rc != 0)
- goto error;
- }
-
- /* initialize L2 transmission */
- gigaset_isowbuf_init(ubc->isooutbuf, PPP_FLAG);
-
- /* set up isochronous output URBs for flag idling */
- for (k = 0; k < BAS_OUTURBS; ++k) {
- urb = ubc->isoouturbs[k].urb;
- if (!urb) {
- rc = -EFAULT;
- goto error;
- }
- usb_fill_int_urb(urb, udev,
- usb_sndisocpipe(udev, 4 + 2 * bcs->channel),
- ubc->isooutbuf->data,
- sizeof(ubc->isooutbuf->data),
- write_iso_callback, &ubc->isoouturbs[k],
- BAS_FRAMETIME);
-
- urb->transfer_flags = URB_ISO_ASAP;
- urb->number_of_packets = BAS_NUMFRAMES;
- for (j = 0; j < BAS_NUMFRAMES; ++j) {
- urb->iso_frame_desc[j].offset = BAS_OUTBUFSIZE;
- urb->iso_frame_desc[j].length = BAS_NORMFRAME;
- urb->iso_frame_desc[j].status = 0;
- urb->iso_frame_desc[j].actual_length = 0;
- }
- ubc->isoouturbs[k].limit = -1;
- }
-
- /* keep one URB free, submit the others */
- for (k = 0; k < BAS_OUTURBS - 1; ++k) {
- dump_urb(DEBUG_ISO, "Initial isoc write", urb);
- rc = usb_submit_urb(ubc->isoouturbs[k].urb, GFP_ATOMIC);
- if (rc != 0)
- goto error;
- }
- dump_urb(DEBUG_ISO, "Initial isoc write (free)", urb);
- ubc->isooutfree = &ubc->isoouturbs[BAS_OUTURBS - 1];
- ubc->isooutdone = ubc->isooutovfl = NULL;
- return 0;
-error:
- stopurbs(ubc);
- return rc;
-}
-
-/* stopurbs
- * cancel the USB request blocks for isochronous input and output
- * errors are silently ignored
- * argument:
- * B channel control structure
- */
-static void stopurbs(struct bas_bc_state *ubc)
-{
- int k, rc;
-
- ubc->running = 0;
-
- for (k = 0; k < BAS_INURBS; ++k) {
- rc = usb_unlink_urb(ubc->isoinurbs[k]);
- gig_dbg(DEBUG_ISO,
- "%s: isoc input URB %d unlinked, result = %s",
- __func__, k, get_usb_rcmsg(rc));
- }
-
- for (k = 0; k < BAS_OUTURBS; ++k) {
- rc = usb_unlink_urb(ubc->isoouturbs[k].urb);
- gig_dbg(DEBUG_ISO,
- "%s: isoc output URB %d unlinked, result = %s",
- __func__, k, get_usb_rcmsg(rc));
- }
-}
-
-/* Isochronous Write - Bottom Half */
-/* =============================== */
-
-/* submit_iso_write_urb
- * fill and submit the next isochronous write URB
- * parameters:
- * ucx context structure containing URB
- * return value:
- * number of frames submitted in URB
- * 0 if URB not submitted because no data available (isooutbuf busy)
- * error code < 0 on error
- */
-static int submit_iso_write_urb(struct isow_urbctx_t *ucx)
-{
- struct urb *urb = ucx->urb;
- struct bas_bc_state *ubc = ucx->bcs->hw.bas;
- struct usb_iso_packet_descriptor *ifd;
- int corrbytes, nframe, rc;
-
- /* urb->dev is clobbered by USB subsystem */
- urb->dev = ucx->bcs->cs->hw.bas->udev;
- urb->transfer_flags = URB_ISO_ASAP;
- urb->transfer_buffer = ubc->isooutbuf->data;
- urb->transfer_buffer_length = sizeof(ubc->isooutbuf->data);
-
- for (nframe = 0; nframe < BAS_NUMFRAMES; nframe++) {
- ifd = &urb->iso_frame_desc[nframe];
-
- /* compute frame length according to flow control */
- ifd->length = BAS_NORMFRAME;
- corrbytes = atomic_read(&ubc->corrbytes);
- if (corrbytes != 0) {
- gig_dbg(DEBUG_ISO, "%s: corrbytes=%d",
- __func__, corrbytes);
- if (corrbytes > BAS_HIGHFRAME - BAS_NORMFRAME)
- corrbytes = BAS_HIGHFRAME - BAS_NORMFRAME;
- else if (corrbytes < BAS_LOWFRAME - BAS_NORMFRAME)
- corrbytes = BAS_LOWFRAME - BAS_NORMFRAME;
- ifd->length += corrbytes;
- atomic_add(-corrbytes, &ubc->corrbytes);
- }
-
- /* retrieve block of data to send */
- rc = gigaset_isowbuf_getbytes(ubc->isooutbuf, ifd->length);
- if (rc < 0) {
- if (rc == -EBUSY) {
- gig_dbg(DEBUG_ISO,
- "%s: buffer busy at frame %d",
- __func__, nframe);
- /* tasklet will be restarted from
- gigaset_isoc_send_skb() */
- } else {
- dev_err(ucx->bcs->cs->dev,
- "%s: buffer error %d at frame %d\n",
- __func__, rc, nframe);
- return rc;
- }
- break;
- }
- ifd->offset = rc;
- ucx->limit = ubc->isooutbuf->nextread;
- ifd->status = 0;
- ifd->actual_length = 0;
- }
- if (unlikely(nframe == 0))
- return 0; /* no data to send */
- urb->number_of_packets = nframe;
-
- rc = usb_submit_urb(urb, GFP_ATOMIC);
- if (unlikely(rc)) {
- if (rc == -ENODEV)
- /* device removed - give up silently */
- gig_dbg(DEBUG_ISO, "%s: disconnected", __func__);
- else
- dev_err(ucx->bcs->cs->dev,
- "could not submit isoc write URB: %s\n",
- get_usb_rcmsg(rc));
- return rc;
- }
- ++ubc->numsub;
- return nframe;
-}
-
-/* write_iso_tasklet
- * tasklet scheduled when an isochronous output URB from the Gigaset device
- * has completed
- * parameter:
- * data B channel state structure
- */
-static void write_iso_tasklet(unsigned long data)
-{
- struct bc_state *bcs = (struct bc_state *) data;
- struct bas_bc_state *ubc = bcs->hw.bas;
- struct cardstate *cs = bcs->cs;
- struct isow_urbctx_t *done, *next, *ovfl;
- struct urb *urb;
- int status;
- struct usb_iso_packet_descriptor *ifd;
- unsigned long flags;
- int i;
- struct sk_buff *skb;
- int len;
- int rc;
-
- /* loop while completed URBs arrive in time */
- for (;;) {
- if (unlikely(!(ubc->running))) {
- gig_dbg(DEBUG_ISO, "%s: not running", __func__);
- return;
- }
-
- /* retrieve completed URBs */
- spin_lock_irqsave(&ubc->isooutlock, flags);
- done = ubc->isooutdone;
- ubc->isooutdone = NULL;
- ovfl = ubc->isooutovfl;
- ubc->isooutovfl = NULL;
- spin_unlock_irqrestore(&ubc->isooutlock, flags);
- if (ovfl) {
- dev_err(cs->dev, "isoc write underrun\n");
- error_hangup(bcs);
- break;
- }
- if (!done)
- break;
-
- /* submit free URB if available */
- spin_lock_irqsave(&ubc->isooutlock, flags);
- next = ubc->isooutfree;
- ubc->isooutfree = NULL;
- spin_unlock_irqrestore(&ubc->isooutlock, flags);
- if (next) {
- rc = submit_iso_write_urb(next);
- if (unlikely(rc <= 0 && rc != -ENODEV)) {
- /* could not submit URB, put it back */
- spin_lock_irqsave(&ubc->isooutlock, flags);
- if (ubc->isooutfree == NULL) {
- ubc->isooutfree = next;
- next = NULL;
- }
- spin_unlock_irqrestore(&ubc->isooutlock, flags);
- if (next) {
- /* couldn't put it back */
- dev_err(cs->dev,
- "losing isoc write URB\n");
- error_hangup(bcs);
- }
- }
- }
-
- /* process completed URB */
- urb = done->urb;
- status = done->status;
- switch (status) {
- case -EXDEV: /* partial completion */
- gig_dbg(DEBUG_ISO, "%s: URB partially completed",
- __func__);
- /* fall through - what's the difference anyway? */
- case 0: /* normal completion */
- /* inspect individual frames
- * assumptions (for lack of documentation):
- * - actual_length bytes of first frame in error are
- * successfully sent
- * - all following frames are not sent at all
- */
- for (i = 0; i < BAS_NUMFRAMES; i++) {
- ifd = &urb->iso_frame_desc[i];
- if (ifd->status ||
- ifd->actual_length != ifd->length) {
- dev_warn(cs->dev,
- "isoc write: frame %d[%d/%d]: %s\n",
- i, ifd->actual_length,
- ifd->length,
- get_usb_statmsg(ifd->status));
- break;
- }
- }
- break;
- case -EPIPE: /* stall - probably underrun */
- dev_err(cs->dev, "isoc write: stalled\n");
- error_hangup(bcs);
- break;
- default: /* other errors */
- dev_warn(cs->dev, "isoc write: %s\n",
- get_usb_statmsg(status));
- }
-
- /* mark the write buffer area covered by this URB as free */
- if (done->limit >= 0)
- ubc->isooutbuf->read = done->limit;
-
- /* mark URB as free */
- spin_lock_irqsave(&ubc->isooutlock, flags);
- next = ubc->isooutfree;
- ubc->isooutfree = done;
- spin_unlock_irqrestore(&ubc->isooutlock, flags);
- if (next) {
- /* only one URB still active - resubmit one */
- rc = submit_iso_write_urb(next);
- if (unlikely(rc <= 0 && rc != -ENODEV)) {
- /* couldn't submit */
- error_hangup(bcs);
- }
- }
- }
-
- /* process queued SKBs */
- while ((skb = skb_dequeue(&bcs->squeue))) {
- /* copy to output buffer, doing L2 encapsulation */
- len = skb->len;
- if (gigaset_isoc_buildframe(bcs, skb->data, len) == -EAGAIN) {
- /* insufficient buffer space, push back onto queue */
- skb_queue_head(&bcs->squeue, skb);
- gig_dbg(DEBUG_ISO, "%s: skb requeued, qlen=%d",
- __func__, skb_queue_len(&bcs->squeue));
- break;
- }
- skb_pull(skb, len);
- gigaset_skb_sent(bcs, skb);
- dev_kfree_skb_any(skb);
- }
-}
-
-/* Isochronous Read - Bottom Half */
-/* ============================== */
-
-/* read_iso_tasklet
- * tasklet scheduled when an isochronous input URB from the Gigaset device
- * has completed
- * parameter:
- * data B channel state structure
- */
-static void read_iso_tasklet(unsigned long data)
-{
- struct bc_state *bcs = (struct bc_state *) data;
- struct bas_bc_state *ubc = bcs->hw.bas;
- struct cardstate *cs = bcs->cs;
- struct urb *urb;
- int status;
- struct usb_iso_packet_descriptor *ifd;
- char *rcvbuf;
- unsigned long flags;
- int totleft, numbytes, offset, frame, rc;
-
- /* loop while more completed URBs arrive in the meantime */
- for (;;) {
- /* retrieve URB */
- spin_lock_irqsave(&ubc->isoinlock, flags);
- urb = ubc->isoindone;
- if (!urb) {
- spin_unlock_irqrestore(&ubc->isoinlock, flags);
- return;
- }
- status = ubc->isoinstatus;
- ubc->isoindone = NULL;
- if (unlikely(ubc->loststatus != -EINPROGRESS)) {
- dev_warn(cs->dev,
- "isoc read overrun, URB dropped (status: %s, %d bytes)\n",
- get_usb_statmsg(ubc->loststatus),
- ubc->isoinlost);
- ubc->loststatus = -EINPROGRESS;
- }
- spin_unlock_irqrestore(&ubc->isoinlock, flags);
-
- if (unlikely(!(ubc->running))) {
- gig_dbg(DEBUG_ISO,
- "%s: channel not running, "
- "dropped URB with status: %s",
- __func__, get_usb_statmsg(status));
- return;
- }
-
- switch (status) {
- case 0: /* normal completion */
- break;
- case -EXDEV: /* inspect individual frames
- (we do that anyway) */
- gig_dbg(DEBUG_ISO, "%s: URB partially completed",
- __func__);
- break;
- case -ENOENT:
- case -ECONNRESET:
- case -EINPROGRESS:
- gig_dbg(DEBUG_ISO, "%s: %s",
- __func__, get_usb_statmsg(status));
- continue; /* -> skip */
- case -EPIPE:
- dev_err(cs->dev, "isoc read: stalled\n");
- error_hangup(bcs);
- continue; /* -> skip */
- default: /* other error */
- dev_warn(cs->dev, "isoc read: %s\n",
- get_usb_statmsg(status));
- goto error;
- }
-
- rcvbuf = urb->transfer_buffer;
- totleft = urb->actual_length;
- for (frame = 0; totleft > 0 && frame < BAS_NUMFRAMES; frame++) {
- ifd = &urb->iso_frame_desc[frame];
- numbytes = ifd->actual_length;
- switch (ifd->status) {
- case 0: /* success */
- break;
- case -EPROTO: /* protocol error or unplug */
- case -EILSEQ:
- case -ETIME:
- /* probably just disconnected, ignore */
- gig_dbg(DEBUG_ISO,
- "isoc read: frame %d[%d]: %s\n",
- frame, numbytes,
- get_usb_statmsg(ifd->status));
- break;
- default: /* other error */
- /* report, assume transferred bytes are ok */
- dev_warn(cs->dev,
- "isoc read: frame %d[%d]: %s\n",
- frame, numbytes,
- get_usb_statmsg(ifd->status));
- }
- if (unlikely(numbytes > BAS_MAXFRAME))
- dev_warn(cs->dev,
- "isoc read: frame %d[%d]: %s\n",
- frame, numbytes,
- "exceeds max frame size");
- if (unlikely(numbytes > totleft)) {
- dev_warn(cs->dev,
- "isoc read: frame %d[%d]: %s\n",
- frame, numbytes,
- "exceeds total transfer length");
- numbytes = totleft;
- }
- offset = ifd->offset;
- if (unlikely(offset + numbytes > BAS_INBUFSIZE)) {
- dev_warn(cs->dev,
- "isoc read: frame %d[%d]: %s\n",
- frame, numbytes,
- "exceeds end of buffer");
- numbytes = BAS_INBUFSIZE - offset;
- }
- gigaset_isoc_receive(rcvbuf + offset, numbytes, bcs);
- totleft -= numbytes;
- }
- if (unlikely(totleft > 0))
- dev_warn(cs->dev, "isoc read: %d data bytes missing\n",
- totleft);
-
-error:
- /* URB processed, resubmit */
- for (frame = 0; frame < BAS_NUMFRAMES; frame++) {
- urb->iso_frame_desc[frame].status = 0;
- urb->iso_frame_desc[frame].actual_length = 0;
- }
- /* urb->dev is clobbered by USB subsystem */
- urb->dev = bcs->cs->hw.bas->udev;
- urb->transfer_flags = URB_ISO_ASAP;
- urb->number_of_packets = BAS_NUMFRAMES;
- rc = usb_submit_urb(urb, GFP_ATOMIC);
- if (unlikely(rc != 0 && rc != -ENODEV)) {
- dev_err(cs->dev,
- "could not resubmit isoc read URB: %s\n",
- get_usb_rcmsg(rc));
- dump_urb(DEBUG_ISO, "resubmit isoc read", urb);
- error_hangup(bcs);
- }
- }
-}
-
-/* Channel Operations */
-/* ================== */
-
-/* req_timeout
- * timeout routine for control output request
- * argument:
- * controller state structure
- */
-static void req_timeout(struct timer_list *t)
-{
- struct bas_cardstate *ucs = from_timer(ucs, t, timer_ctrl);
- struct cardstate *cs = ucs->cs;
- int pending;
- unsigned long flags;
-
- check_pending(ucs);
-
- spin_lock_irqsave(&ucs->lock, flags);
- pending = ucs->pending;
- ucs->pending = 0;
- spin_unlock_irqrestore(&ucs->lock, flags);
-
- switch (pending) {
- case 0: /* no pending request */
- gig_dbg(DEBUG_USBREQ, "%s: no request pending", __func__);
- break;
-
- case HD_OPEN_ATCHANNEL:
- dev_err(cs->dev, "timeout opening AT channel\n");
- error_reset(cs);
- break;
-
- case HD_OPEN_B1CHANNEL:
- dev_err(cs->dev, "timeout opening channel 1\n");
- error_hangup(&cs->bcs[0]);
- break;
-
- case HD_OPEN_B2CHANNEL:
- dev_err(cs->dev, "timeout opening channel 2\n");
- error_hangup(&cs->bcs[1]);
- break;
-
- case HD_CLOSE_ATCHANNEL:
- dev_err(cs->dev, "timeout closing AT channel\n");
- error_reset(cs);
- break;
-
- case HD_CLOSE_B1CHANNEL:
- dev_err(cs->dev, "timeout closing channel 1\n");
- error_reset(cs);
- break;
-
- case HD_CLOSE_B2CHANNEL:
- dev_err(cs->dev, "timeout closing channel 2\n");
- error_reset(cs);
- break;
-
- case HD_RESET_INTERRUPT_PIPE:
- /* error recovery escalation */
- dev_err(cs->dev,
- "reset interrupt pipe timeout, attempting USB reset\n");
- usb_queue_reset_device(ucs->interface);
- break;
-
- default:
- dev_warn(cs->dev, "request 0x%02x timed out, clearing\n",
- pending);
- }
-
- wake_up(&ucs->waitqueue);
-}
-
-/* write_ctrl_callback
- * USB completion handler for control pipe output
- * called by the USB subsystem in interrupt context
- * parameter:
- * urb USB request block of completed request
- * urb->context = hardware specific controller state structure
- */
-static void write_ctrl_callback(struct urb *urb)
-{
- struct bas_cardstate *ucs = urb->context;
- int status = urb->status;
- int rc;
- unsigned long flags;
-
- /* check status */
- switch (status) {
- case 0: /* normal completion */
- spin_lock_irqsave(&ucs->lock, flags);
- switch (ucs->pending) {
- case HD_DEVICE_INIT_ACK: /* no reply expected */
- del_timer(&ucs->timer_ctrl);
- ucs->pending = 0;
- break;
- }
- spin_unlock_irqrestore(&ucs->lock, flags);
- return;
-
- case -ENOENT: /* cancelled */
- case -ECONNRESET: /* cancelled (async) */
- case -EINPROGRESS: /* pending */
- case -ENODEV: /* device removed */
- case -ESHUTDOWN: /* device shut down */
- /* ignore silently */
- gig_dbg(DEBUG_USBREQ, "%s: %s",
- __func__, get_usb_statmsg(status));
- break;
-
- default: /* any failure */
- /* don't retry if suspend requested */
- if (++ucs->retry_ctrl > BAS_RETRY ||
- (ucs->basstate & BS_SUSPEND)) {
- dev_err(&ucs->interface->dev,
- "control request 0x%02x failed: %s\n",
- ucs->dr_ctrl.bRequest,
- get_usb_statmsg(status));
- break; /* give up */
- }
- dev_notice(&ucs->interface->dev,
- "control request 0x%02x: %s, retry %d\n",
- ucs->dr_ctrl.bRequest, get_usb_statmsg(status),
- ucs->retry_ctrl);
- /* urb->dev is clobbered by USB subsystem */
- urb->dev = ucs->udev;
- rc = usb_submit_urb(urb, GFP_ATOMIC);
- if (unlikely(rc)) {
- dev_err(&ucs->interface->dev,
- "could not resubmit request 0x%02x: %s\n",
- ucs->dr_ctrl.bRequest, get_usb_rcmsg(rc));
- break;
- }
- /* resubmitted */
- return;
- }
-
- /* failed, clear pending request */
- spin_lock_irqsave(&ucs->lock, flags);
- del_timer(&ucs->timer_ctrl);
- ucs->pending = 0;
- spin_unlock_irqrestore(&ucs->lock, flags);
- wake_up(&ucs->waitqueue);
-}
-
-/* req_submit
- * submit a control output request without message buffer to the Gigaset base
- * and optionally start a timeout
- * parameters:
- * bcs B channel control structure
- * req control request code (HD_*)
- * val control request parameter value (set to 0 if unused)
- * timeout timeout in seconds (0: no timeout)
- * return value:
- * 0 on success
- * -EBUSY if another request is pending
- * any URB submission error code
- */
-static int req_submit(struct bc_state *bcs, int req, int val, int timeout)
-{
- struct bas_cardstate *ucs = bcs->cs->hw.bas;
- int ret;
- unsigned long flags;
-
- gig_dbg(DEBUG_USBREQ, "-------> 0x%02x (%d)", req, val);
-
- spin_lock_irqsave(&ucs->lock, flags);
- if (ucs->pending) {
- spin_unlock_irqrestore(&ucs->lock, flags);
- dev_err(bcs->cs->dev,
- "submission of request 0x%02x failed: "
- "request 0x%02x still pending\n",
- req, ucs->pending);
- return -EBUSY;
- }
-
- ucs->dr_ctrl.bRequestType = OUT_VENDOR_REQ;
- ucs->dr_ctrl.bRequest = req;
- ucs->dr_ctrl.wValue = cpu_to_le16(val);
- ucs->dr_ctrl.wIndex = 0;
- ucs->dr_ctrl.wLength = 0;
- usb_fill_control_urb(ucs->urb_ctrl, ucs->udev,
- usb_sndctrlpipe(ucs->udev, 0),
- (unsigned char *) &ucs->dr_ctrl, NULL, 0,
- write_ctrl_callback, ucs);
- ucs->retry_ctrl = 0;
- ret = usb_submit_urb(ucs->urb_ctrl, GFP_ATOMIC);
- if (unlikely(ret)) {
- dev_err(bcs->cs->dev, "could not submit request 0x%02x: %s\n",
- req, get_usb_rcmsg(ret));
- spin_unlock_irqrestore(&ucs->lock, flags);
- return ret;
- }
- ucs->pending = req;
-
- if (timeout > 0) {
- gig_dbg(DEBUG_USBREQ, "setting timeout of %d/10 secs", timeout);
- mod_timer(&ucs->timer_ctrl, jiffies + timeout * HZ / 10);
- }
-
- spin_unlock_irqrestore(&ucs->lock, flags);
- return 0;
-}
-
-/* gigaset_init_bchannel
- * called by common.c to connect a B channel
- * initialize isochronous I/O and tell the Gigaset base to open the channel
- * argument:
- * B channel control structure
- * return value:
- * 0 on success, error code < 0 on error
- */
-static int gigaset_init_bchannel(struct bc_state *bcs)
-{
- struct cardstate *cs = bcs->cs;
- int req, ret;
- unsigned long flags;
-
- spin_lock_irqsave(&cs->lock, flags);
- if (unlikely(!cs->connected)) {
- gig_dbg(DEBUG_USBREQ, "%s: not connected", __func__);
- spin_unlock_irqrestore(&cs->lock, flags);
- return -ENODEV;
- }
-
- if (cs->hw.bas->basstate & BS_SUSPEND) {
- dev_notice(cs->dev,
- "not starting isoc I/O, suspend in progress\n");
- spin_unlock_irqrestore(&cs->lock, flags);
- return -EHOSTUNREACH;
- }
-
- ret = starturbs(bcs);
- if (ret < 0) {
- spin_unlock_irqrestore(&cs->lock, flags);
- dev_err(cs->dev,
- "could not start isoc I/O for channel B%d: %s\n",
- bcs->channel + 1,
- ret == -EFAULT ? "null URB" : get_usb_rcmsg(ret));
- if (ret != -ENODEV)
- error_hangup(bcs);
- return ret;
- }
-
- req = bcs->channel ? HD_OPEN_B2CHANNEL : HD_OPEN_B1CHANNEL;
- ret = req_submit(bcs, req, 0, BAS_TIMEOUT);
- if (ret < 0) {
- dev_err(cs->dev, "could not open channel B%d\n",
- bcs->channel + 1);
- stopurbs(bcs->hw.bas);
- }
-
- spin_unlock_irqrestore(&cs->lock, flags);
- if (ret < 0 && ret != -ENODEV)
- error_hangup(bcs);
- return ret;
-}
-
-/* gigaset_close_bchannel
- * called by common.c to disconnect a B channel
- * tell the Gigaset base to close the channel
- * stopping isochronous I/O and LL notification will be done when the
- * acknowledgement for the close arrives
- * argument:
- * B channel control structure
- * return value:
- * 0 on success, error code < 0 on error
- */
-static int gigaset_close_bchannel(struct bc_state *bcs)
-{
- struct cardstate *cs = bcs->cs;
- int req, ret;
- unsigned long flags;
-
- spin_lock_irqsave(&cs->lock, flags);
- if (unlikely(!cs->connected)) {
- spin_unlock_irqrestore(&cs->lock, flags);
- gig_dbg(DEBUG_USBREQ, "%s: not connected", __func__);
- return -ENODEV;
- }
-
- if (!(cs->hw.bas->basstate & (bcs->channel ? BS_B2OPEN : BS_B1OPEN))) {
- /* channel not running: just signal common.c */
- spin_unlock_irqrestore(&cs->lock, flags);
- gigaset_bchannel_down(bcs);
- return 0;
- }
-
- /* channel running: tell device to close it */
- req = bcs->channel ? HD_CLOSE_B2CHANNEL : HD_CLOSE_B1CHANNEL;
- ret = req_submit(bcs, req, 0, BAS_TIMEOUT);
- if (ret < 0)
- dev_err(cs->dev, "closing channel B%d failed\n",
- bcs->channel + 1);
-
- spin_unlock_irqrestore(&cs->lock, flags);
- return ret;
-}
-
-/* Device Operations */
-/* ================= */
-
-/* complete_cb
- * unqueue first command buffer from queue, waking any sleepers
- * must be called with cs->cmdlock held
- * parameter:
- * cs controller state structure
- */
-static void complete_cb(struct cardstate *cs)
-{
- struct cmdbuf_t *cb = cs->cmdbuf;
-
- /* unqueue completed buffer */
- cs->cmdbytes -= cs->curlen;
- gig_dbg(DEBUG_OUTPUT, "write_command: sent %u bytes, %u left",
- cs->curlen, cs->cmdbytes);
- if (cb->next != NULL) {
- cs->cmdbuf = cb->next;
- cs->cmdbuf->prev = NULL;
- cs->curlen = cs->cmdbuf->len;
- } else {
- cs->cmdbuf = NULL;
- cs->lastcmdbuf = NULL;
- cs->curlen = 0;
- }
-
- if (cb->wake_tasklet)
- tasklet_schedule(cb->wake_tasklet);
-
- kfree(cb);
-}
-
-/* write_command_callback
- * USB completion handler for AT command transmission
- * called by the USB subsystem in interrupt context
- * parameter:
- * urb USB request block of completed request
- * urb->context = controller state structure
- */
-static void write_command_callback(struct urb *urb)
-{
- struct cardstate *cs = urb->context;
- struct bas_cardstate *ucs = cs->hw.bas;
- int status = urb->status;
- unsigned long flags;
-
- update_basstate(ucs, 0, BS_ATWRPEND);
- wake_up(&ucs->waitqueue);
-
- /* check status */
- switch (status) {
- case 0: /* normal completion */
- break;
- case -ENOENT: /* cancelled */
- case -ECONNRESET: /* cancelled (async) */
- case -EINPROGRESS: /* pending */
- case -ENODEV: /* device removed */
- case -ESHUTDOWN: /* device shut down */
- /* ignore silently */
- gig_dbg(DEBUG_USBREQ, "%s: %s",
- __func__, get_usb_statmsg(status));
- return;
- default: /* any failure */
- if (++ucs->retry_cmd_out > BAS_RETRY) {
- dev_warn(cs->dev,
- "command write: %s, "
- "giving up after %d retries\n",
- get_usb_statmsg(status),
- ucs->retry_cmd_out);
- break;
- }
- if (ucs->basstate & BS_SUSPEND) {
- dev_warn(cs->dev,
- "command write: %s, "
- "won't retry - suspend requested\n",
- get_usb_statmsg(status));
- break;
- }
- if (cs->cmdbuf == NULL) {
- dev_warn(cs->dev,
- "command write: %s, "
- "cannot retry - cmdbuf gone\n",
- get_usb_statmsg(status));
- break;
- }
- dev_notice(cs->dev, "command write: %s, retry %d\n",
- get_usb_statmsg(status), ucs->retry_cmd_out);
- if (atwrite_submit(cs, cs->cmdbuf->buf, cs->cmdbuf->len) >= 0)
- /* resubmitted - bypass regular exit block */
- return;
- /* command send failed, assume base still waiting */
- update_basstate(ucs, BS_ATREADY, 0);
- }
-
- spin_lock_irqsave(&cs->cmdlock, flags);
- if (cs->cmdbuf != NULL)
- complete_cb(cs);
- spin_unlock_irqrestore(&cs->cmdlock, flags);
-}
-
-/* atrdy_timeout
- * timeout routine for AT command transmission
- * argument:
- * controller state structure
- */
-static void atrdy_timeout(struct timer_list *t)
-{
- struct bas_cardstate *ucs = from_timer(ucs, t, timer_atrdy);
- struct cardstate *cs = ucs->cs;
-
- dev_warn(cs->dev, "timeout waiting for HD_READY_SEND_ATDATA\n");
-
- /* fake the missing signal - what else can I do? */
- update_basstate(ucs, BS_ATREADY, BS_ATTIMER);
- start_cbsend(cs);
-}
-
-/* atwrite_submit
- * submit an HD_WRITE_ATMESSAGE command URB
- * parameters:
- * cs controller state structure
- * buf buffer containing command to send
- * len length of command to send
- * return value:
- * 0 on success
- * -EBUSY if another request is pending
- * any URB submission error code
- */
-static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len)
-{
- struct bas_cardstate *ucs = cs->hw.bas;
- int rc;
-
- gig_dbg(DEBUG_USBREQ, "-------> HD_WRITE_ATMESSAGE (%d)", len);
-
- if (update_basstate(ucs, BS_ATWRPEND, 0) & BS_ATWRPEND) {
- dev_err(cs->dev,
- "could not submit HD_WRITE_ATMESSAGE: URB busy\n");
- return -EBUSY;
- }
-
- ucs->dr_cmd_out.bRequestType = OUT_VENDOR_REQ;
- ucs->dr_cmd_out.bRequest = HD_WRITE_ATMESSAGE;
- ucs->dr_cmd_out.wValue = 0;
- ucs->dr_cmd_out.wIndex = 0;
- ucs->dr_cmd_out.wLength = cpu_to_le16(len);
- usb_fill_control_urb(ucs->urb_cmd_out, ucs->udev,
- usb_sndctrlpipe(ucs->udev, 0),
- (unsigned char *) &ucs->dr_cmd_out, buf, len,
- write_command_callback, cs);
- rc = usb_submit_urb(ucs->urb_cmd_out, GFP_ATOMIC);
- if (unlikely(rc)) {
- update_basstate(ucs, 0, BS_ATWRPEND);
- dev_err(cs->dev, "could not submit HD_WRITE_ATMESSAGE: %s\n",
- get_usb_rcmsg(rc));
- return rc;
- }
-
- /* submitted successfully, start timeout if necessary */
- if (!(update_basstate(ucs, BS_ATTIMER, BS_ATREADY) & BS_ATTIMER)) {
- gig_dbg(DEBUG_OUTPUT, "setting ATREADY timeout of %d/10 secs",
- ATRDY_TIMEOUT);
- mod_timer(&ucs->timer_atrdy, jiffies + ATRDY_TIMEOUT * HZ / 10);
- }
- return 0;
-}
-
-/* start_cbsend
- * start transmission of AT command queue if necessary
- * parameter:
- * cs controller state structure
- * return value:
- * 0 on success
- * error code < 0 on error
- */
-static int start_cbsend(struct cardstate *cs)
-{
- struct cmdbuf_t *cb;
- struct bas_cardstate *ucs = cs->hw.bas;
- unsigned long flags;
- int rc;
- int retval = 0;
-
- /* check if suspend requested */
- if (ucs->basstate & BS_SUSPEND) {
- gig_dbg(DEBUG_OUTPUT, "suspending");
- return -EHOSTUNREACH;
- }
-
- /* check if AT channel is open */
- if (!(ucs->basstate & BS_ATOPEN)) {
- gig_dbg(DEBUG_OUTPUT, "AT channel not open");
- rc = req_submit(cs->bcs, HD_OPEN_ATCHANNEL, 0, BAS_TIMEOUT);
- if (rc < 0) {
- /* flush command queue */
- spin_lock_irqsave(&cs->cmdlock, flags);
- while (cs->cmdbuf != NULL)
- complete_cb(cs);
- spin_unlock_irqrestore(&cs->cmdlock, flags);
- }
- return rc;
- }
-
- /* try to send first command in queue */
- spin_lock_irqsave(&cs->cmdlock, flags);
-
- while ((cb = cs->cmdbuf) != NULL && (ucs->basstate & BS_ATREADY)) {
- ucs->retry_cmd_out = 0;
- rc = atwrite_submit(cs, cb->buf, cb->len);
- if (unlikely(rc)) {
- retval = rc;
- complete_cb(cs);
- }
- }
-
- spin_unlock_irqrestore(&cs->cmdlock, flags);
- return retval;
-}
-
-/* gigaset_write_cmd
- * This function is called by the device independent part of the driver
- * to transmit an AT command string to the Gigaset device.
- * It encapsulates the device specific method for transmission over the
- * direct USB connection to the base.
- * The command string is added to the queue of commands to send, and
- * USB transmission is started if necessary.
- * parameters:
- * cs controller state structure
- * cb command buffer structure
- * return value:
- * number of bytes queued on success
- * error code < 0 on error
- */
-static int gigaset_write_cmd(struct cardstate *cs, struct cmdbuf_t *cb)
-{
- unsigned long flags;
- int rc;
-
- gigaset_dbg_buffer(cs->mstate != MS_LOCKED ?
- DEBUG_TRANSCMD : DEBUG_LOCKCMD,
- "CMD Transmit", cb->len, cb->buf);
-
- /* translate "+++" escape sequence sent as a single separate command
- * into "close AT channel" command for error recovery
- * The next command will reopen the AT channel automatically.
- */
- if (cb->len == 3 && !memcmp(cb->buf, "+++", 3)) {
- /* If an HD_RECEIVEATDATA_ACK message remains unhandled
- * because of an error, the base never sends another one.
- * The response channel is thus effectively blocked.
- * Closing and reopening the AT channel does *not* clear
- * this condition.
- * As a stopgap measure, submit a zero-length AT read
- * before closing the AT channel. This has the undocumented
- * effect of triggering a new HD_RECEIVEATDATA_ACK message
- * from the base if necessary.
- * The subsequent AT channel close then discards any pending
- * messages.
- */
- spin_lock_irqsave(&cs->lock, flags);
- if (!(cs->hw.bas->basstate & BS_ATRDPEND)) {
- kfree(cs->hw.bas->rcvbuf);
- cs->hw.bas->rcvbuf = NULL;
- cs->hw.bas->rcvbuf_size = 0;
- cs->hw.bas->retry_cmd_in = 0;
- atread_submit(cs, 0);
- }
- spin_unlock_irqrestore(&cs->lock, flags);
-
- rc = req_submit(cs->bcs, HD_CLOSE_ATCHANNEL, 0, BAS_TIMEOUT);
- if (cb->wake_tasklet)
- tasklet_schedule(cb->wake_tasklet);
- if (!rc)
- rc = cb->len;
- kfree(cb);
- return rc;
- }
-
- spin_lock_irqsave(&cs->cmdlock, flags);
- cb->prev = cs->lastcmdbuf;
- if (cs->lastcmdbuf)
- cs->lastcmdbuf->next = cb;
- else {
- cs->cmdbuf = cb;
- cs->curlen = cb->len;
- }
- cs->cmdbytes += cb->len;
- cs->lastcmdbuf = cb;
- spin_unlock_irqrestore(&cs->cmdlock, flags);
-
- spin_lock_irqsave(&cs->lock, flags);
- if (unlikely(!cs->connected)) {
- spin_unlock_irqrestore(&cs->lock, flags);
- gig_dbg(DEBUG_USBREQ, "%s: not connected", __func__);
- /* flush command queue */
- spin_lock_irqsave(&cs->cmdlock, flags);
- while (cs->cmdbuf != NULL)
- complete_cb(cs);
- spin_unlock_irqrestore(&cs->cmdlock, flags);
- return -ENODEV;
- }
- rc = start_cbsend(cs);
- spin_unlock_irqrestore(&cs->lock, flags);
- return rc < 0 ? rc : cb->len;
-}
-
-/* gigaset_write_room
- * tty_driver.write_room interface routine
- * return number of characters the driver will accept to be written via
- * gigaset_write_cmd
- * parameter:
- * controller state structure
- * return value:
- * number of characters
- */
-static int gigaset_write_room(struct cardstate *cs)
-{
- return IF_WRITEBUF;
-}
-
-/* gigaset_chars_in_buffer
- * tty_driver.chars_in_buffer interface routine
- * return number of characters waiting to be sent
- * parameter:
- * controller state structure
- * return value:
- * number of characters
- */
-static int gigaset_chars_in_buffer(struct cardstate *cs)
-{
- return cs->cmdbytes;
-}
-
-/* gigaset_brkchars
- * implementation of ioctl(GIGASET_BRKCHARS)
- * parameter:
- * controller state structure
- * return value:
- * -EINVAL (unimplemented function)
- */
-static int gigaset_brkchars(struct cardstate *cs, const unsigned char buf[6])
-{
- return -EINVAL;
-}
-
-
-/* Device Initialization/Shutdown */
-/* ============================== */
-
-/* Free hardware dependent part of the B channel structure
- * parameter:
- * bcs B channel structure
- */
-static void gigaset_freebcshw(struct bc_state *bcs)
-{
- struct bas_bc_state *ubc = bcs->hw.bas;
- int i;
-
- if (!ubc)
- return;
-
- /* kill URBs and tasklets before freeing - better safe than sorry */
- ubc->running = 0;
- gig_dbg(DEBUG_INIT, "%s: killing isoc URBs", __func__);
- for (i = 0; i < BAS_OUTURBS; ++i) {
- usb_kill_urb(ubc->isoouturbs[i].urb);
- usb_free_urb(ubc->isoouturbs[i].urb);
- }
- for (i = 0; i < BAS_INURBS; ++i) {
- usb_kill_urb(ubc->isoinurbs[i]);
- usb_free_urb(ubc->isoinurbs[i]);
- }
- tasklet_kill(&ubc->sent_tasklet);
- tasklet_kill(&ubc->rcvd_tasklet);
- kfree(ubc->isooutbuf);
- kfree(ubc);
- bcs->hw.bas = NULL;
-}
-
-/* Initialize hardware dependent part of the B channel structure
- * parameter:
- * bcs B channel structure
- * return value:
- * 0 on success, error code < 0 on failure
- */
-static int gigaset_initbcshw(struct bc_state *bcs)
-{
- int i;
- struct bas_bc_state *ubc;
-
- bcs->hw.bas = ubc = kmalloc(sizeof(struct bas_bc_state), GFP_KERNEL);
- if (!ubc) {
- pr_err("out of memory\n");
- return -ENOMEM;
- }
-
- ubc->running = 0;
- atomic_set(&ubc->corrbytes, 0);
- spin_lock_init(&ubc->isooutlock);
- for (i = 0; i < BAS_OUTURBS; ++i) {
- ubc->isoouturbs[i].urb = NULL;
- ubc->isoouturbs[i].bcs = bcs;
- }
- ubc->isooutdone = ubc->isooutfree = ubc->isooutovfl = NULL;
- ubc->numsub = 0;
- ubc->isooutbuf = kmalloc(sizeof(struct isowbuf_t), GFP_KERNEL);
- if (!ubc->isooutbuf) {
- pr_err("out of memory\n");
- kfree(ubc);
- bcs->hw.bas = NULL;
- return -ENOMEM;
- }
- tasklet_init(&ubc->sent_tasklet,
- write_iso_tasklet, (unsigned long) bcs);
-
- spin_lock_init(&ubc->isoinlock);
- for (i = 0; i < BAS_INURBS; ++i)
- ubc->isoinurbs[i] = NULL;
- ubc->isoindone = NULL;
- ubc->loststatus = -EINPROGRESS;
- ubc->isoinlost = 0;
- ubc->seqlen = 0;
- ubc->inbyte = 0;
- ubc->inbits = 0;
- ubc->goodbytes = 0;
- ubc->alignerrs = 0;
- ubc->fcserrs = 0;
- ubc->frameerrs = 0;
- ubc->giants = 0;
- ubc->runts = 0;
- ubc->aborts = 0;
- ubc->shared0s = 0;
- ubc->stolen0s = 0;
- tasklet_init(&ubc->rcvd_tasklet,
- read_iso_tasklet, (unsigned long) bcs);
- return 0;
-}
-
-static void gigaset_reinitbcshw(struct bc_state *bcs)
-{
- struct bas_bc_state *ubc = bcs->hw.bas;
-
- bcs->hw.bas->running = 0;
- atomic_set(&bcs->hw.bas->corrbytes, 0);
- bcs->hw.bas->numsub = 0;
- spin_lock_init(&ubc->isooutlock);
- spin_lock_init(&ubc->isoinlock);
- ubc->loststatus = -EINPROGRESS;
-}
-
-static void gigaset_freecshw(struct cardstate *cs)
-{
- /* timers, URBs and rcvbuf are disposed of in disconnect */
- kfree(cs->hw.bas->int_in_buf);
- kfree(cs->hw.bas);
- cs->hw.bas = NULL;
-}
-
-/* Initialize hardware dependent part of the cardstate structure
- * parameter:
- * cs cardstate structure
- * return value:
- * 0 on success, error code < 0 on failure
- */
-static int gigaset_initcshw(struct cardstate *cs)
-{
- struct bas_cardstate *ucs;
-
- cs->hw.bas = ucs = kzalloc(sizeof(*ucs), GFP_KERNEL);
- if (!ucs) {
- pr_err("out of memory\n");
- return -ENOMEM;
- }
- ucs->int_in_buf = kmalloc(IP_MSGSIZE, GFP_KERNEL);
- if (!ucs->int_in_buf) {
- kfree(ucs);
- pr_err("out of memory\n");
- return -ENOMEM;
- }
-
- spin_lock_init(&ucs->lock);
- ucs->cs = cs;
- timer_setup(&ucs->timer_ctrl, req_timeout, 0);
- timer_setup(&ucs->timer_atrdy, atrdy_timeout, 0);
- timer_setup(&ucs->timer_cmd_in, cmd_in_timeout, 0);
- timer_setup(&ucs->timer_int_in, int_in_resubmit, 0);
- init_waitqueue_head(&ucs->waitqueue);
- INIT_WORK(&ucs->int_in_wq, int_in_work);
-
- return 0;
-}
-
-/* freeurbs
- * unlink and deallocate all URBs unconditionally
- * caller must make sure that no commands are still in progress
- * parameter:
- * cs controller state structure
- */
-static void freeurbs(struct cardstate *cs)
-{
- struct bas_cardstate *ucs = cs->hw.bas;
- struct bas_bc_state *ubc;
- int i, j;
-
- gig_dbg(DEBUG_INIT, "%s: killing URBs", __func__);
- for (j = 0; j < BAS_CHANNELS; ++j) {
- ubc = cs->bcs[j].hw.bas;
- for (i = 0; i < BAS_OUTURBS; ++i) {
- usb_kill_urb(ubc->isoouturbs[i].urb);
- usb_free_urb(ubc->isoouturbs[i].urb);
- ubc->isoouturbs[i].urb = NULL;
- }
- for (i = 0; i < BAS_INURBS; ++i) {
- usb_kill_urb(ubc->isoinurbs[i]);
- usb_free_urb(ubc->isoinurbs[i]);
- ubc->isoinurbs[i] = NULL;
- }
- }
- usb_kill_urb(ucs->urb_int_in);
- usb_free_urb(ucs->urb_int_in);
- ucs->urb_int_in = NULL;
- usb_kill_urb(ucs->urb_cmd_out);
- usb_free_urb(ucs->urb_cmd_out);
- ucs->urb_cmd_out = NULL;
- usb_kill_urb(ucs->urb_cmd_in);
- usb_free_urb(ucs->urb_cmd_in);
- ucs->urb_cmd_in = NULL;
- usb_kill_urb(ucs->urb_ctrl);
- usb_free_urb(ucs->urb_ctrl);
- ucs->urb_ctrl = NULL;
-}
-
-/* gigaset_probe
- * This function is called when a new USB device is connected.
- * It checks whether the new device is handled by this driver.
- */
-static int gigaset_probe(struct usb_interface *interface,
- const struct usb_device_id *id)
-{
- struct usb_host_interface *hostif;
- struct usb_device *udev = interface_to_usbdev(interface);
- struct cardstate *cs = NULL;
- struct bas_cardstate *ucs = NULL;
- struct bas_bc_state *ubc;
- struct usb_endpoint_descriptor *endpoint;
- int i, j;
- int rc;
-
- gig_dbg(DEBUG_INIT,
- "%s: Check if device matches .. (Vendor: 0x%x, Product: 0x%x)",
- __func__, le16_to_cpu(udev->descriptor.idVendor),
- le16_to_cpu(udev->descriptor.idProduct));
-
- /* set required alternate setting */
- hostif = interface->cur_altsetting;
- if (hostif->desc.bAlternateSetting != 3) {
- gig_dbg(DEBUG_INIT,
- "%s: wrong alternate setting %d - trying to switch",
- __func__, hostif->desc.bAlternateSetting);
- if (usb_set_interface(udev, hostif->desc.bInterfaceNumber, 3)
- < 0) {
- dev_warn(&udev->dev, "usb_set_interface failed, "
- "device %d interface %d altsetting %d\n",
- udev->devnum, hostif->desc.bInterfaceNumber,
- hostif->desc.bAlternateSetting);
- return -ENODEV;
- }
- hostif = interface->cur_altsetting;
- }
-
- /* Reject application specific interfaces
- */
- if (hostif->desc.bInterfaceClass != 255) {
- dev_warn(&udev->dev, "%s: bInterfaceClass == %d\n",
- __func__, hostif->desc.bInterfaceClass);
- return -ENODEV;
- }
-
- if (hostif->desc.bNumEndpoints < 1)
- return -ENODEV;
-
- dev_info(&udev->dev,
- "%s: Device matched (Vendor: 0x%x, Product: 0x%x)\n",
- __func__, le16_to_cpu(udev->descriptor.idVendor),
- le16_to_cpu(udev->descriptor.idProduct));
-
- /* allocate memory for our device state and initialize it */
- cs = gigaset_initcs(driver, BAS_CHANNELS, 0, 0, cidmode,
- GIGASET_MODULENAME);
- if (!cs)
- return -ENODEV;
- ucs = cs->hw.bas;
-
- /* save off device structure ptrs for later use */
- usb_get_dev(udev);
- ucs->udev = udev;
- ucs->interface = interface;
- cs->dev = &interface->dev;
-
- /* allocate URBs:
- * - one for the interrupt pipe
- * - three for the different uses of the default control pipe
- * - three for each isochronous pipe
- */
- if (!(ucs->urb_int_in = usb_alloc_urb(0, GFP_KERNEL)) ||
- !(ucs->urb_cmd_in = usb_alloc_urb(0, GFP_KERNEL)) ||
- !(ucs->urb_cmd_out = usb_alloc_urb(0, GFP_KERNEL)) ||
- !(ucs->urb_ctrl = usb_alloc_urb(0, GFP_KERNEL)))
- goto allocerr;
-
- for (j = 0; j < BAS_CHANNELS; ++j) {
- ubc = cs->bcs[j].hw.bas;
- for (i = 0; i < BAS_OUTURBS; ++i)
- if (!(ubc->isoouturbs[i].urb =
- usb_alloc_urb(BAS_NUMFRAMES, GFP_KERNEL)))
- goto allocerr;
- for (i = 0; i < BAS_INURBS; ++i)
- if (!(ubc->isoinurbs[i] =
- usb_alloc_urb(BAS_NUMFRAMES, GFP_KERNEL)))
- goto allocerr;
- }
-
- ucs->rcvbuf = NULL;
- ucs->rcvbuf_size = 0;
-
- /* Fill the interrupt urb and send it to the core */
- endpoint = &hostif->endpoint[0].desc;
- usb_fill_int_urb(ucs->urb_int_in, udev,
- usb_rcvintpipe(udev,
- usb_endpoint_num(endpoint)),
- ucs->int_in_buf, IP_MSGSIZE, read_int_callback, cs,
- endpoint->bInterval);
- rc = usb_submit_urb(ucs->urb_int_in, GFP_KERNEL);
- if (rc != 0) {
- dev_err(cs->dev, "could not submit interrupt URB: %s\n",
- get_usb_rcmsg(rc));
- goto error;
- }
- ucs->retry_int_in = 0;
-
- /* tell the device that the driver is ready */
- rc = req_submit(cs->bcs, HD_DEVICE_INIT_ACK, 0, 0);
- if (rc != 0)
- goto error;
-
- /* tell common part that the device is ready */
- if (startmode == SM_LOCKED)
- cs->mstate = MS_LOCKED;
-
- /* save address of controller structure */
- usb_set_intfdata(interface, cs);
-
- rc = gigaset_start(cs);
- if (rc < 0)
- goto error;
-
- return 0;
-
-allocerr:
- dev_err(cs->dev, "could not allocate URBs\n");
- rc = -ENOMEM;
-error:
- freeurbs(cs);
- usb_set_intfdata(interface, NULL);
- usb_put_dev(udev);
- gigaset_freecs(cs);
- return rc;
-}
-
-/* gigaset_disconnect
- * This function is called when the Gigaset base is unplugged.
- */
-static void gigaset_disconnect(struct usb_interface *interface)
-{
- struct cardstate *cs;
- struct bas_cardstate *ucs;
- int j;
-
- cs = usb_get_intfdata(interface);
-
- ucs = cs->hw.bas;
-
- dev_info(cs->dev, "disconnecting Gigaset base\n");
-
- /* mark base as not ready, all channels disconnected */
- ucs->basstate = 0;
-
- /* tell LL all channels are down */
- for (j = 0; j < BAS_CHANNELS; ++j)
- gigaset_bchannel_down(cs->bcs + j);
-
- /* stop driver (common part) */
- gigaset_stop(cs);
-
- /* stop delayed work and URBs, free ressources */
- del_timer_sync(&ucs->timer_ctrl);
- del_timer_sync(&ucs->timer_atrdy);
- del_timer_sync(&ucs->timer_cmd_in);
- del_timer_sync(&ucs->timer_int_in);
- cancel_work_sync(&ucs->int_in_wq);
- freeurbs(cs);
- usb_set_intfdata(interface, NULL);
- kfree(ucs->rcvbuf);
- ucs->rcvbuf = NULL;
- ucs->rcvbuf_size = 0;
- usb_put_dev(ucs->udev);
- ucs->interface = NULL;
- ucs->udev = NULL;
- cs->dev = NULL;
- gigaset_freecs(cs);
-}
-
-/* gigaset_suspend
- * This function is called before the USB connection is suspended
- * or before the USB device is reset.
- * In the latter case, message == PMSG_ON.
- */
-static int gigaset_suspend(struct usb_interface *intf, pm_message_t message)
-{
- struct cardstate *cs = usb_get_intfdata(intf);
- struct bas_cardstate *ucs = cs->hw.bas;
- int rc;
-
- /* set suspend flag; this stops AT command/response traffic */
- if (update_basstate(ucs, BS_SUSPEND, 0) & BS_SUSPEND) {
- gig_dbg(DEBUG_SUSPEND, "already suspended");
- return 0;
- }
-
- /* wait a bit for blocking conditions to go away */
- rc = wait_event_timeout(ucs->waitqueue,
- !(ucs->basstate &
- (BS_B1OPEN | BS_B2OPEN | BS_ATRDPEND | BS_ATWRPEND)),
- BAS_TIMEOUT * HZ / 10);
- gig_dbg(DEBUG_SUSPEND, "wait_event_timeout() -> %d", rc);
-
- /* check for conditions preventing suspend */
- if (ucs->basstate & (BS_B1OPEN | BS_B2OPEN | BS_ATRDPEND | BS_ATWRPEND)) {
- dev_warn(cs->dev, "cannot suspend:\n");
- if (ucs->basstate & BS_B1OPEN)
- dev_warn(cs->dev, " B channel 1 open\n");
- if (ucs->basstate & BS_B2OPEN)
- dev_warn(cs->dev, " B channel 2 open\n");
- if (ucs->basstate & BS_ATRDPEND)
- dev_warn(cs->dev, " receiving AT reply\n");
- if (ucs->basstate & BS_ATWRPEND)
- dev_warn(cs->dev, " sending AT command\n");
- update_basstate(ucs, 0, BS_SUSPEND);
- return -EBUSY;
- }
-
- /* close AT channel if open */
- if (ucs->basstate & BS_ATOPEN) {
- gig_dbg(DEBUG_SUSPEND, "closing AT channel");
- rc = req_submit(cs->bcs, HD_CLOSE_ATCHANNEL, 0, 0);
- if (rc) {
- update_basstate(ucs, 0, BS_SUSPEND);
- return rc;
- }
- wait_event_timeout(ucs->waitqueue, !ucs->pending,
- BAS_TIMEOUT * HZ / 10);
- /* in case of timeout, proceed anyway */
- }
-
- /* kill all URBs and delayed work that might still be pending */
- usb_kill_urb(ucs->urb_ctrl);
- usb_kill_urb(ucs->urb_int_in);
- del_timer_sync(&ucs->timer_ctrl);
- del_timer_sync(&ucs->timer_atrdy);
- del_timer_sync(&ucs->timer_cmd_in);
- del_timer_sync(&ucs->timer_int_in);
-
- /* don't try to cancel int_in_wq from within reset as it
- * might be the one requesting the reset
- */
- if (message.event != PM_EVENT_ON)
- cancel_work_sync(&ucs->int_in_wq);
-
- gig_dbg(DEBUG_SUSPEND, "suspend complete");
- return 0;
-}
-
-/* gigaset_resume
- * This function is called after the USB connection has been resumed.
- */
-static int gigaset_resume(struct usb_interface *intf)
-{
- struct cardstate *cs = usb_get_intfdata(intf);
- struct bas_cardstate *ucs = cs->hw.bas;
- int rc;
-
- /* resubmit interrupt URB for spontaneous messages from base */
- rc = usb_submit_urb(ucs->urb_int_in, GFP_KERNEL);
- if (rc) {
- dev_err(cs->dev, "could not resubmit interrupt URB: %s\n",
- get_usb_rcmsg(rc));
- return rc;
- }
- ucs->retry_int_in = 0;
-
- /* clear suspend flag to reallow activity */
- update_basstate(ucs, 0, BS_SUSPEND);
-
- gig_dbg(DEBUG_SUSPEND, "resume complete");
- return 0;
-}
-
-/* gigaset_pre_reset
- * This function is called before the USB connection is reset.
- */
-static int gigaset_pre_reset(struct usb_interface *intf)
-{
- /* handle just like suspend */
- return gigaset_suspend(intf, PMSG_ON);
-}
-
-/* gigaset_post_reset
- * This function is called after the USB connection has been reset.
- */
-static int gigaset_post_reset(struct usb_interface *intf)
-{
- /* FIXME: send HD_DEVICE_INIT_ACK? */
-
- /* resume operations */
- return gigaset_resume(intf);
-}
-
-
-static const struct gigaset_ops gigops = {
- .write_cmd = gigaset_write_cmd,
- .write_room = gigaset_write_room,
- .chars_in_buffer = gigaset_chars_in_buffer,
- .brkchars = gigaset_brkchars,
- .init_bchannel = gigaset_init_bchannel,
- .close_bchannel = gigaset_close_bchannel,
- .initbcshw = gigaset_initbcshw,
- .freebcshw = gigaset_freebcshw,
- .reinitbcshw = gigaset_reinitbcshw,
- .initcshw = gigaset_initcshw,
- .freecshw = gigaset_freecshw,
- .set_modem_ctrl = gigaset_set_modem_ctrl,
- .baud_rate = gigaset_baud_rate,
- .set_line_ctrl = gigaset_set_line_ctrl,
- .send_skb = gigaset_isoc_send_skb,
- .handle_input = gigaset_isoc_input,
-};
-
-/* bas_gigaset_init
- * This function is called after the kernel module is loaded.
- */
-static int __init bas_gigaset_init(void)
-{
- int result;
-
- /* allocate memory for our driver state and initialize it */
- driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS,
- GIGASET_MODULENAME, GIGASET_DEVNAME,
- &gigops, THIS_MODULE);
- if (driver == NULL)
- goto error;
-
- /* register this driver with the USB subsystem */
- result = usb_register(&gigaset_usb_driver);
- if (result < 0) {
- pr_err("error %d registering USB driver\n", -result);
- goto error;
- }
-
- pr_info(DRIVER_DESC "\n");
- return 0;
-
-error:
- if (driver)
- gigaset_freedriver(driver);
- driver = NULL;
- return -1;
-}
-
-/* bas_gigaset_exit
- * This function is called before the kernel module is unloaded.
- */
-static void __exit bas_gigaset_exit(void)
-{
- struct bas_cardstate *ucs;
- int i;
-
- gigaset_blockdriver(driver); /* => probe will fail
- * => no gigaset_start any more
- */
-
- /* stop all connected devices */
- for (i = 0; i < driver->minors; i++) {
- if (gigaset_shutdown(driver->cs + i) < 0)
- continue; /* no device */
- /* from now on, no isdn callback should be possible */
-
- /* close all still open channels */
- ucs = driver->cs[i].hw.bas;
- if (ucs->basstate & BS_B1OPEN) {
- gig_dbg(DEBUG_INIT, "closing B1 channel");
- usb_control_msg(ucs->udev,
- usb_sndctrlpipe(ucs->udev, 0),
- HD_CLOSE_B1CHANNEL, OUT_VENDOR_REQ,
- 0, 0, NULL, 0, BAS_TIMEOUT);
- }
- if (ucs->basstate & BS_B2OPEN) {
- gig_dbg(DEBUG_INIT, "closing B2 channel");
- usb_control_msg(ucs->udev,
- usb_sndctrlpipe(ucs->udev, 0),
- HD_CLOSE_B2CHANNEL, OUT_VENDOR_REQ,
- 0, 0, NULL, 0, BAS_TIMEOUT);
- }
- if (ucs->basstate & BS_ATOPEN) {
- gig_dbg(DEBUG_INIT, "closing AT channel");
- usb_control_msg(ucs->udev,
- usb_sndctrlpipe(ucs->udev, 0),
- HD_CLOSE_ATCHANNEL, OUT_VENDOR_REQ,
- 0, 0, NULL, 0, BAS_TIMEOUT);
- }
- ucs->basstate = 0;
- }
-
- /* deregister this driver with the USB subsystem */
- usb_deregister(&gigaset_usb_driver);
- /* this will call the disconnect-callback */
- /* from now on, no disconnect/probe callback should be running */
-
- gigaset_freedriver(driver);
- driver = NULL;
-}
-
-
-module_init(bas_gigaset_init);
-module_exit(bas_gigaset_exit);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/isdn/gigaset/capi.c b/drivers/staging/isdn/gigaset/capi.c
deleted file mode 100644
index 83d7dd48c61d..000000000000
--- a/drivers/staging/isdn/gigaset/capi.c
+++ /dev/null
@@ -1,2517 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Kernel CAPI interface for the Gigaset driver
- *
- * Copyright (c) 2009 by Tilman Schmidt <tilman@imap.cc>.
- *
- * =====================================================================
- * =====================================================================
- */
-
-#include "gigaset.h"
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/ratelimit.h>
-#include <linux/isdn/capilli.h>
-#include <linux/isdn/capicmd.h>
-#include <linux/isdn/capiutil.h>
-#include <linux/export.h>
-
-/* missing from kernelcapi.h */
-#define CapiNcpiNotSupportedByProtocol 0x0001
-#define CapiFlagsNotSupportedByProtocol 0x0002
-#define CapiAlertAlreadySent 0x0003
-#define CapiFacilitySpecificFunctionNotSupported 0x3011
-
-/* missing from capicmd.h */
-#define CAPI_CONNECT_IND_BASELEN (CAPI_MSG_BASELEN + 4 + 2 + 8 * 1)
-#define CAPI_CONNECT_ACTIVE_IND_BASELEN (CAPI_MSG_BASELEN + 4 + 3 * 1)
-#define CAPI_CONNECT_B3_IND_BASELEN (CAPI_MSG_BASELEN + 4 + 1)
-#define CAPI_CONNECT_B3_ACTIVE_IND_BASELEN (CAPI_MSG_BASELEN + 4 + 1)
-#define CAPI_DATA_B3_REQ_LEN64 (CAPI_MSG_BASELEN + 4 + 4 + 2 + 2 + 2 + 8)
-#define CAPI_DATA_B3_CONF_LEN (CAPI_MSG_BASELEN + 4 + 2 + 2)
-#define CAPI_DISCONNECT_IND_LEN (CAPI_MSG_BASELEN + 4 + 2)
-#define CAPI_DISCONNECT_B3_IND_BASELEN (CAPI_MSG_BASELEN + 4 + 2 + 1)
-#define CAPI_FACILITY_CONF_BASELEN (CAPI_MSG_BASELEN + 4 + 2 + 2 + 1)
-/* most _CONF messages contain only Controller/PLCI/NCCI and Info parameters */
-#define CAPI_STDCONF_LEN (CAPI_MSG_BASELEN + 4 + 2)
-
-#define CAPI_FACILITY_HANDSET 0x0000
-#define CAPI_FACILITY_DTMF 0x0001
-#define CAPI_FACILITY_V42BIS 0x0002
-#define CAPI_FACILITY_SUPPSVC 0x0003
-#define CAPI_FACILITY_WAKEUP 0x0004
-#define CAPI_FACILITY_LI 0x0005
-
-#define CAPI_SUPPSVC_GETSUPPORTED 0x0000
-#define CAPI_SUPPSVC_LISTEN 0x0001
-
-/* missing from capiutil.h */
-#define CAPIMSG_PLCI_PART(m) CAPIMSG_U8(m, 9)
-#define CAPIMSG_NCCI_PART(m) CAPIMSG_U16(m, 10)
-#define CAPIMSG_HANDLE_REQ(m) CAPIMSG_U16(m, 18) /* DATA_B3_REQ/_IND only! */
-#define CAPIMSG_FLAGS(m) CAPIMSG_U16(m, 20)
-#define CAPIMSG_SETCONTROLLER(m, contr) capimsg_setu8(m, 8, contr)
-#define CAPIMSG_SETPLCI_PART(m, plci) capimsg_setu8(m, 9, plci)
-#define CAPIMSG_SETNCCI_PART(m, ncci) capimsg_setu16(m, 10, ncci)
-#define CAPIMSG_SETFLAGS(m, flags) capimsg_setu16(m, 20, flags)
-
-/* parameters with differing location in DATA_B3_CONF/_RESP: */
-#define CAPIMSG_SETHANDLE_CONF(m, handle) capimsg_setu16(m, 12, handle)
-#define CAPIMSG_SETINFO_CONF(m, info) capimsg_setu16(m, 14, info)
-
-/* Flags (DATA_B3_REQ/_IND) */
-#define CAPI_FLAGS_DELIVERY_CONFIRMATION 0x04
-#define CAPI_FLAGS_RESERVED (~0x1f)
-
-/* buffer sizes */
-#define MAX_BC_OCTETS 11
-#define MAX_HLC_OCTETS 3
-#define MAX_NUMBER_DIGITS 20
-#define MAX_FMT_IE_LEN 20
-
-/* values for bcs->apconnstate */
-#define APCONN_NONE 0 /* inactive/listening */
-#define APCONN_SETUP 1 /* connecting */
-#define APCONN_ACTIVE 2 /* B channel up */
-
-/* registered application data structure */
-struct gigaset_capi_appl {
- struct list_head ctrlist;
- struct gigaset_capi_appl *bcnext;
- u16 id;
- struct capi_register_params rp;
- u16 nextMessageNumber;
- u32 listenInfoMask;
- u32 listenCIPmask;
-};
-
-/* CAPI specific controller data structure */
-struct gigaset_capi_ctr {
- struct capi_ctr ctr;
- struct list_head appls;
- struct sk_buff_head sendqueue;
- atomic_t sendqlen;
- /* two _cmsg structures possibly used concurrently: */
- _cmsg hcmsg; /* for message composition triggered from hardware */
- _cmsg acmsg; /* for dissection of messages sent from application */
- u8 bc_buf[MAX_BC_OCTETS + 1];
- u8 hlc_buf[MAX_HLC_OCTETS + 1];
- u8 cgpty_buf[MAX_NUMBER_DIGITS + 3];
- u8 cdpty_buf[MAX_NUMBER_DIGITS + 2];
-};
-
-/* CIP Value table (from CAPI 2.0 standard, ch. 6.1) */
-static struct {
- u8 *bc;
- u8 *hlc;
-} cip2bchlc[] = {
- [1] = { "8090A3", NULL }, /* Speech (A-law) */
- [2] = { "8890", NULL }, /* Unrestricted digital information */
- [3] = { "8990", NULL }, /* Restricted digital information */
- [4] = { "9090A3", NULL }, /* 3,1 kHz audio (A-law) */
- [5] = { "9190", NULL }, /* 7 kHz audio */
- [6] = { "9890", NULL }, /* Video */
- [7] = { "88C0C6E6", NULL }, /* Packet mode */
- [8] = { "8890218F", NULL }, /* 56 kbit/s rate adaptation */
- [9] = { "9190A5", NULL }, /* Unrestricted digital information
- * with tones/announcements */
- [16] = { "8090A3", "9181" }, /* Telephony */
- [17] = { "9090A3", "9184" }, /* Group 2/3 facsimile */
- [18] = { "8890", "91A1" }, /* Group 4 facsimile Class 1 */
- [19] = { "8890", "91A4" }, /* Teletex service basic and mixed mode
- * and Group 4 facsimile service
- * Classes II and III */
- [20] = { "8890", "91A8" }, /* Teletex service basic and
- * processable mode */
- [21] = { "8890", "91B1" }, /* Teletex service basic mode */
- [22] = { "8890", "91B2" }, /* International interworking for
- * Videotex */
- [23] = { "8890", "91B5" }, /* Telex */
- [24] = { "8890", "91B8" }, /* Message Handling Systems
- * in accordance with X.400 */
- [25] = { "8890", "91C1" }, /* OSI application
- * in accordance with X.200 */
- [26] = { "9190A5", "9181" }, /* 7 kHz telephony */
- [27] = { "9190A5", "916001" }, /* Video telephony, first connection */
- [28] = { "8890", "916002" }, /* Video telephony, second connection */
-};
-
-/*
- * helper functions
- * ================
- */
-
-/*
- * emit unsupported parameter warning
- */
-static inline void ignore_cstruct_param(struct cardstate *cs, _cstruct param,
- char *msgname, char *paramname)
-{
- if (param && *param)
- dev_warn(cs->dev, "%s: ignoring unsupported parameter: %s\n",
- msgname, paramname);
-}
-
-/*
- * convert an IE from Gigaset hex string to ETSI binary representation
- * including length byte
- * return value: result length, -1 on error
- */
-static int encode_ie(char *in, u8 *out, int maxlen)
-{
- int l = 0;
- while (*in) {
- if (!isxdigit(in[0]) || !isxdigit(in[1]) || l >= maxlen)
- return -1;
- out[++l] = (hex_to_bin(in[0]) << 4) + hex_to_bin(in[1]);
- in += 2;
- }
- out[0] = l;
- return l;
-}
-
-/*
- * convert an IE from ETSI binary representation including length byte
- * to Gigaset hex string
- */
-static void decode_ie(u8 *in, char *out)
-{
- int i = *in;
- while (i-- > 0) {
- /* ToDo: conversion to upper case necessary? */
- *out++ = toupper(hex_asc_hi(*++in));
- *out++ = toupper(hex_asc_lo(*in));
- }
-}
-
-/*
- * retrieve application data structure for an application ID
- */
-static inline struct gigaset_capi_appl *
-get_appl(struct gigaset_capi_ctr *iif, u16 appl)
-{
- struct gigaset_capi_appl *ap;
-
- list_for_each_entry(ap, &iif->appls, ctrlist)
- if (ap->id == appl)
- return ap;
- return NULL;
-}
-
-/*
- * dump CAPI message to kernel messages for debugging
- */
-static inline void dump_cmsg(enum debuglevel level, const char *tag, _cmsg *p)
-{
-#ifdef CONFIG_GIGASET_DEBUG
- /* dump at most 20 messages in 20 secs */
- static DEFINE_RATELIMIT_STATE(msg_dump_ratelimit, 20 * HZ, 20);
- _cdebbuf *cdb;
-
- if (!(gigaset_debuglevel & level))
- return;
- if (!___ratelimit(&msg_dump_ratelimit, tag))
- return;
-
- cdb = capi_cmsg2str(p);
- if (cdb) {
- gig_dbg(level, "%s: [%d] %s", tag, p->ApplId, cdb->buf);
- cdebbuf_free(cdb);
- } else {
- gig_dbg(level, "%s: [%d] %s", tag, p->ApplId,
- capi_cmd2str(p->Command, p->Subcommand));
- }
-#endif
-}
-
-static inline void dump_rawmsg(enum debuglevel level, const char *tag,
- unsigned char *data)
-{
-#ifdef CONFIG_GIGASET_DEBUG
- char *dbgline;
- int i, l;
-
- if (!(gigaset_debuglevel & level))
- return;
-
- l = CAPIMSG_LEN(data);
- if (l < 12) {
- gig_dbg(level, "%s: ??? LEN=%04d", tag, l);
- return;
- }
- gig_dbg(level, "%s: 0x%02x:0x%02x: ID=%03d #0x%04x LEN=%04d NCCI=0x%x",
- tag, CAPIMSG_COMMAND(data), CAPIMSG_SUBCOMMAND(data),
- CAPIMSG_APPID(data), CAPIMSG_MSGID(data), l,
- CAPIMSG_CONTROL(data));
- l -= 12;
- if (l <= 0)
- return;
- if (l > 64)
- l = 64; /* arbitrary limit */
- dbgline = kmalloc_array(3, l, GFP_ATOMIC);
- if (!dbgline)
- return;
- for (i = 0; i < l; i++) {
- dbgline[3 * i] = hex_asc_hi(data[12 + i]);
- dbgline[3 * i + 1] = hex_asc_lo(data[12 + i]);
- dbgline[3 * i + 2] = ' ';
- }
- dbgline[3 * l - 1] = '\0';
- gig_dbg(level, " %s", dbgline);
- kfree(dbgline);
- if (CAPIMSG_COMMAND(data) == CAPI_DATA_B3 &&
- (CAPIMSG_SUBCOMMAND(data) == CAPI_REQ ||
- CAPIMSG_SUBCOMMAND(data) == CAPI_IND)) {
- l = CAPIMSG_DATALEN(data);
- gig_dbg(level, " DataLength=%d", l);
- if (l <= 0 || !(gigaset_debuglevel & DEBUG_LLDATA))
- return;
- if (l > 64)
- l = 64; /* arbitrary limit */
- dbgline = kmalloc_array(3, l, GFP_ATOMIC);
- if (!dbgline)
- return;
- data += CAPIMSG_LEN(data);
- for (i = 0; i < l; i++) {
- dbgline[3 * i] = hex_asc_hi(data[i]);
- dbgline[3 * i + 1] = hex_asc_lo(data[i]);
- dbgline[3 * i + 2] = ' ';
- }
- dbgline[3 * l - 1] = '\0';
- gig_dbg(level, " %s", dbgline);
- kfree(dbgline);
- }
-#endif
-}
-
-/*
- * format CAPI IE as string
- */
-
-#ifdef CONFIG_GIGASET_DEBUG
-static const char *format_ie(const char *ie)
-{
- static char result[3 * MAX_FMT_IE_LEN];
- int len, count;
- char *pout = result;
-
- if (!ie)
- return "NULL";
-
- count = len = ie[0];
- if (count > MAX_FMT_IE_LEN)
- count = MAX_FMT_IE_LEN - 1;
- while (count--) {
- *pout++ = hex_asc_hi(*++ie);
- *pout++ = hex_asc_lo(*ie);
- *pout++ = ' ';
- }
- if (len > MAX_FMT_IE_LEN) {
- *pout++ = '.';
- *pout++ = '.';
- *pout++ = '.';
- }
- *--pout = 0;
- return result;
-}
-#endif
-
-/*
- * emit DATA_B3_CONF message
- */
-static void send_data_b3_conf(struct cardstate *cs, struct capi_ctr *ctr,
- u16 appl, u16 msgid, int channel,
- u16 handle, u16 info)
-{
- struct sk_buff *cskb;
- u8 *msg;
-
- cskb = alloc_skb(CAPI_DATA_B3_CONF_LEN, GFP_ATOMIC);
- if (!cskb) {
- dev_err(cs->dev, "%s: out of memory\n", __func__);
- return;
- }
- /* frequent message, avoid _cmsg overhead */
- msg = __skb_put(cskb, CAPI_DATA_B3_CONF_LEN);
- CAPIMSG_SETLEN(msg, CAPI_DATA_B3_CONF_LEN);
- CAPIMSG_SETAPPID(msg, appl);
- CAPIMSG_SETCOMMAND(msg, CAPI_DATA_B3);
- CAPIMSG_SETSUBCOMMAND(msg, CAPI_CONF);
- CAPIMSG_SETMSGID(msg, msgid);
- CAPIMSG_SETCONTROLLER(msg, ctr->cnr);
- CAPIMSG_SETPLCI_PART(msg, channel);
- CAPIMSG_SETNCCI_PART(msg, 1);
- CAPIMSG_SETHANDLE_CONF(msg, handle);
- CAPIMSG_SETINFO_CONF(msg, info);
-
- /* emit message */
- dump_rawmsg(DEBUG_MCMD, __func__, msg);
- capi_ctr_handle_message(ctr, appl, cskb);
-}
-
-
-/*
- * driver interface functions
- * ==========================
- */
-
-/**
- * gigaset_skb_sent() - acknowledge transmission of outgoing skb
- * @bcs: B channel descriptor structure.
- * @skb: sent data.
- *
- * Called by hardware module {bas,ser,usb}_gigaset when the data in a
- * skb has been successfully sent, for signalling completion to the LL.
- */
-void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *dskb)
-{
- struct cardstate *cs = bcs->cs;
- struct gigaset_capi_ctr *iif = cs->iif;
- struct gigaset_capi_appl *ap = bcs->ap;
- unsigned char *req = skb_mac_header(dskb);
- u16 flags;
-
- /* update statistics */
- ++bcs->trans_up;
-
- if (!ap) {
- gig_dbg(DEBUG_MCMD, "%s: application gone", __func__);
- return;
- }
-
- /* don't send further B3 messages if disconnected */
- if (bcs->apconnstate < APCONN_ACTIVE) {
- gig_dbg(DEBUG_MCMD, "%s: disconnected", __func__);
- return;
- }
-
- /*
- * send DATA_B3_CONF if "delivery confirmation" bit was set in request;
- * otherwise it has already been sent by do_data_b3_req()
- */
- flags = CAPIMSG_FLAGS(req);
- if (flags & CAPI_FLAGS_DELIVERY_CONFIRMATION)
- send_data_b3_conf(cs, &iif->ctr, ap->id, CAPIMSG_MSGID(req),
- bcs->channel + 1, CAPIMSG_HANDLE_REQ(req),
- (flags & ~CAPI_FLAGS_DELIVERY_CONFIRMATION) ?
- CapiFlagsNotSupportedByProtocol :
- CAPI_NOERROR);
-}
-EXPORT_SYMBOL_GPL(gigaset_skb_sent);
-
-/**
- * gigaset_skb_rcvd() - pass received skb to LL
- * @bcs: B channel descriptor structure.
- * @skb: received data.
- *
- * Called by hardware module {bas,ser,usb}_gigaset when user data has
- * been successfully received, for passing to the LL.
- * Warning: skb must not be accessed anymore!
- */
-void gigaset_skb_rcvd(struct bc_state *bcs, struct sk_buff *skb)
-{
- struct cardstate *cs = bcs->cs;
- struct gigaset_capi_ctr *iif = cs->iif;
- struct gigaset_capi_appl *ap = bcs->ap;
- int len = skb->len;
-
- /* update statistics */
- bcs->trans_down++;
-
- if (!ap) {
- gig_dbg(DEBUG_MCMD, "%s: application gone", __func__);
- dev_kfree_skb_any(skb);
- return;
- }
-
- /* don't send further B3 messages if disconnected */
- if (bcs->apconnstate < APCONN_ACTIVE) {
- gig_dbg(DEBUG_MCMD, "%s: disconnected", __func__);
- dev_kfree_skb_any(skb);
- return;
- }
-
- /*
- * prepend DATA_B3_IND message to payload
- * Parameters: NCCI = 1, all others 0/unused
- * frequent message, avoid _cmsg overhead
- */
- skb_push(skb, CAPI_DATA_B3_REQ_LEN);
- CAPIMSG_SETLEN(skb->data, CAPI_DATA_B3_REQ_LEN);
- CAPIMSG_SETAPPID(skb->data, ap->id);
- CAPIMSG_SETCOMMAND(skb->data, CAPI_DATA_B3);
- CAPIMSG_SETSUBCOMMAND(skb->data, CAPI_IND);
- CAPIMSG_SETMSGID(skb->data, ap->nextMessageNumber++);
- CAPIMSG_SETCONTROLLER(skb->data, iif->ctr.cnr);
- CAPIMSG_SETPLCI_PART(skb->data, bcs->channel + 1);
- CAPIMSG_SETNCCI_PART(skb->data, 1);
- /* Data parameter not used */
- CAPIMSG_SETDATALEN(skb->data, len);
- /* Data handle parameter not used */
- CAPIMSG_SETFLAGS(skb->data, 0);
- /* Data64 parameter not present */
-
- /* emit message */
- dump_rawmsg(DEBUG_MCMD, __func__, skb->data);
- capi_ctr_handle_message(&iif->ctr, ap->id, skb);
-}
-EXPORT_SYMBOL_GPL(gigaset_skb_rcvd);
-
-/**
- * gigaset_isdn_rcv_err() - signal receive error
- * @bcs: B channel descriptor structure.
- *
- * Called by hardware module {bas,ser,usb}_gigaset when a receive error
- * has occurred, for signalling to the LL.
- */
-void gigaset_isdn_rcv_err(struct bc_state *bcs)
-{
- /* if currently ignoring packets, just count down */
- if (bcs->ignore) {
- bcs->ignore--;
- return;
- }
-
- /* update statistics */
- bcs->corrupted++;
-
- /* ToDo: signal error -> LL */
-}
-EXPORT_SYMBOL_GPL(gigaset_isdn_rcv_err);
-
-/**
- * gigaset_isdn_icall() - signal incoming call
- * @at_state: connection state structure.
- *
- * Called by main module at tasklet level to notify the LL that an incoming
- * call has been received. @at_state contains the parameters of the call.
- *
- * Return value: call disposition (ICALL_*)
- */
-int gigaset_isdn_icall(struct at_state_t *at_state)
-{
- struct cardstate *cs = at_state->cs;
- struct bc_state *bcs = at_state->bcs;
- struct gigaset_capi_ctr *iif = cs->iif;
- struct gigaset_capi_appl *ap;
- u32 actCIPmask;
- struct sk_buff *skb;
- unsigned int msgsize;
- unsigned long flags;
- int i;
-
- /*
- * ToDo: signal calls without a free B channel, too
- * (requires a u8 handle for the at_state structure that can
- * be stored in the PLCI and used in the CONNECT_RESP message
- * handler to retrieve it)
- */
- if (!bcs)
- return ICALL_IGNORE;
-
- /* prepare CONNECT_IND message, using B channel number as PLCI */
- capi_cmsg_header(&iif->hcmsg, 0, CAPI_CONNECT, CAPI_IND, 0,
- iif->ctr.cnr | ((bcs->channel + 1) << 8));
-
- /* minimum size, all structs empty */
- msgsize = CAPI_CONNECT_IND_BASELEN;
-
- /* Bearer Capability (mandatory) */
- if (at_state->str_var[STR_ZBC]) {
- /* pass on BC from Gigaset */
- if (encode_ie(at_state->str_var[STR_ZBC], iif->bc_buf,
- MAX_BC_OCTETS) < 0) {
- dev_warn(cs->dev, "RING ignored - bad BC %s\n",
- at_state->str_var[STR_ZBC]);
- return ICALL_IGNORE;
- }
-
- /* look up corresponding CIP value */
- iif->hcmsg.CIPValue = 0; /* default if nothing found */
- for (i = 0; i < ARRAY_SIZE(cip2bchlc); i++)
- if (cip2bchlc[i].bc != NULL &&
- cip2bchlc[i].hlc == NULL &&
- !strcmp(cip2bchlc[i].bc,
- at_state->str_var[STR_ZBC])) {
- iif->hcmsg.CIPValue = i;
- break;
- }
- } else {
- /* no BC (internal call): assume CIP 1 (speech, A-law) */
- iif->hcmsg.CIPValue = 1;
- encode_ie(cip2bchlc[1].bc, iif->bc_buf, MAX_BC_OCTETS);
- }
- iif->hcmsg.BC = iif->bc_buf;
- msgsize += iif->hcmsg.BC[0];
-
- /* High Layer Compatibility (optional) */
- if (at_state->str_var[STR_ZHLC]) {
- /* pass on HLC from Gigaset */
- if (encode_ie(at_state->str_var[STR_ZHLC], iif->hlc_buf,
- MAX_HLC_OCTETS) < 0) {
- dev_warn(cs->dev, "RING ignored - bad HLC %s\n",
- at_state->str_var[STR_ZHLC]);
- return ICALL_IGNORE;
- }
- iif->hcmsg.HLC = iif->hlc_buf;
- msgsize += iif->hcmsg.HLC[0];
-
- /* look up corresponding CIP value */
- /* keep BC based CIP value if none found */
- if (at_state->str_var[STR_ZBC])
- for (i = 0; i < ARRAY_SIZE(cip2bchlc); i++)
- if (cip2bchlc[i].hlc != NULL &&
- !strcmp(cip2bchlc[i].hlc,
- at_state->str_var[STR_ZHLC]) &&
- !strcmp(cip2bchlc[i].bc,
- at_state->str_var[STR_ZBC])) {
- iif->hcmsg.CIPValue = i;
- break;
- }
- }
-
- /* Called Party Number (optional) */
- if (at_state->str_var[STR_ZCPN]) {
- i = strlen(at_state->str_var[STR_ZCPN]);
- if (i > MAX_NUMBER_DIGITS) {
- dev_warn(cs->dev, "RING ignored - bad number %s\n",
- at_state->str_var[STR_ZBC]);
- return ICALL_IGNORE;
- }
- iif->cdpty_buf[0] = i + 1;
- iif->cdpty_buf[1] = 0x80; /* type / numbering plan unknown */
- memcpy(iif->cdpty_buf + 2, at_state->str_var[STR_ZCPN], i);
- iif->hcmsg.CalledPartyNumber = iif->cdpty_buf;
- msgsize += iif->hcmsg.CalledPartyNumber[0];
- }
-
- /* Calling Party Number (optional) */
- if (at_state->str_var[STR_NMBR]) {
- i = strlen(at_state->str_var[STR_NMBR]);
- if (i > MAX_NUMBER_DIGITS) {
- dev_warn(cs->dev, "RING ignored - bad number %s\n",
- at_state->str_var[STR_ZBC]);
- return ICALL_IGNORE;
- }
- iif->cgpty_buf[0] = i + 2;
- iif->cgpty_buf[1] = 0x00; /* type / numbering plan unknown */
- iif->cgpty_buf[2] = 0x80; /* pres. allowed, not screened */
- memcpy(iif->cgpty_buf + 3, at_state->str_var[STR_NMBR], i);
- iif->hcmsg.CallingPartyNumber = iif->cgpty_buf;
- msgsize += iif->hcmsg.CallingPartyNumber[0];
- }
-
- /* remaining parameters (not supported, always left NULL):
- * - CalledPartySubaddress
- * - CallingPartySubaddress
- * - AdditionalInfo
- * - BChannelinformation
- * - Keypadfacility
- * - Useruserdata
- * - Facilitydataarray
- */
-
- gig_dbg(DEBUG_CMD, "icall: PLCI %x CIP %d BC %s",
- iif->hcmsg.adr.adrPLCI, iif->hcmsg.CIPValue,
- format_ie(iif->hcmsg.BC));
- gig_dbg(DEBUG_CMD, "icall: HLC %s",
- format_ie(iif->hcmsg.HLC));
- gig_dbg(DEBUG_CMD, "icall: CgPty %s",
- format_ie(iif->hcmsg.CallingPartyNumber));
- gig_dbg(DEBUG_CMD, "icall: CdPty %s",
- format_ie(iif->hcmsg.CalledPartyNumber));
-
- /* scan application list for matching listeners */
- spin_lock_irqsave(&bcs->aplock, flags);
- if (bcs->ap != NULL || bcs->apconnstate != APCONN_NONE) {
- dev_warn(cs->dev, "%s: channel not properly cleared (%p/%d)\n",
- __func__, bcs->ap, bcs->apconnstate);
- bcs->ap = NULL;
- bcs->apconnstate = APCONN_NONE;
- }
- spin_unlock_irqrestore(&bcs->aplock, flags);
- actCIPmask = 1 | (1 << iif->hcmsg.CIPValue);
- list_for_each_entry(ap, &iif->appls, ctrlist)
- if (actCIPmask & ap->listenCIPmask) {
- /* build CONNECT_IND message for this application */
- iif->hcmsg.ApplId = ap->id;
- iif->hcmsg.Messagenumber = ap->nextMessageNumber++;
-
- skb = alloc_skb(msgsize, GFP_ATOMIC);
- if (!skb) {
- dev_err(cs->dev, "%s: out of memory\n",
- __func__);
- break;
- }
- if (capi_cmsg2message(&iif->hcmsg,
- __skb_put(skb, msgsize))) {
- dev_err(cs->dev, "%s: message parser failure\n",
- __func__);
- dev_kfree_skb_any(skb);
- break;
- }
- dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
-
- /* add to listeners on this B channel, update state */
- spin_lock_irqsave(&bcs->aplock, flags);
- ap->bcnext = bcs->ap;
- bcs->ap = ap;
- bcs->chstate |= CHS_NOTIFY_LL;
- bcs->apconnstate = APCONN_SETUP;
- spin_unlock_irqrestore(&bcs->aplock, flags);
-
- /* emit message */
- capi_ctr_handle_message(&iif->ctr, ap->id, skb);
- }
-
- /*
- * Return "accept" if any listeners.
- * Gigaset will send ALERTING.
- * There doesn't seem to be a way to avoid this.
- */
- return bcs->ap ? ICALL_ACCEPT : ICALL_IGNORE;
-}
-
-/*
- * send a DISCONNECT_IND message to an application
- * does not sleep, clobbers the controller's hcmsg structure
- */
-static void send_disconnect_ind(struct bc_state *bcs,
- struct gigaset_capi_appl *ap, u16 reason)
-{
- struct cardstate *cs = bcs->cs;
- struct gigaset_capi_ctr *iif = cs->iif;
- struct sk_buff *skb;
-
- if (bcs->apconnstate == APCONN_NONE)
- return;
-
- capi_cmsg_header(&iif->hcmsg, ap->id, CAPI_DISCONNECT, CAPI_IND,
- ap->nextMessageNumber++,
- iif->ctr.cnr | ((bcs->channel + 1) << 8));
- iif->hcmsg.Reason = reason;
- skb = alloc_skb(CAPI_DISCONNECT_IND_LEN, GFP_ATOMIC);
- if (!skb) {
- dev_err(cs->dev, "%s: out of memory\n", __func__);
- return;
- }
- if (capi_cmsg2message(&iif->hcmsg,
- __skb_put(skb, CAPI_DISCONNECT_IND_LEN))) {
- dev_err(cs->dev, "%s: message parser failure\n", __func__);
- dev_kfree_skb_any(skb);
- return;
- }
- dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
- capi_ctr_handle_message(&iif->ctr, ap->id, skb);
-}
-
-/*
- * send a DISCONNECT_B3_IND message to an application
- * Parameters: NCCI = 1, NCPI empty, Reason_B3 = 0
- * does not sleep, clobbers the controller's hcmsg structure
- */
-static void send_disconnect_b3_ind(struct bc_state *bcs,
- struct gigaset_capi_appl *ap)
-{
- struct cardstate *cs = bcs->cs;
- struct gigaset_capi_ctr *iif = cs->iif;
- struct sk_buff *skb;
-
- /* nothing to do if no logical connection active */
- if (bcs->apconnstate < APCONN_ACTIVE)
- return;
- bcs->apconnstate = APCONN_SETUP;
-
- capi_cmsg_header(&iif->hcmsg, ap->id, CAPI_DISCONNECT_B3, CAPI_IND,
- ap->nextMessageNumber++,
- iif->ctr.cnr | ((bcs->channel + 1) << 8) | (1 << 16));
- skb = alloc_skb(CAPI_DISCONNECT_B3_IND_BASELEN, GFP_ATOMIC);
- if (!skb) {
- dev_err(cs->dev, "%s: out of memory\n", __func__);
- return;
- }
- if (capi_cmsg2message(&iif->hcmsg,
- __skb_put(skb, CAPI_DISCONNECT_B3_IND_BASELEN))) {
- dev_err(cs->dev, "%s: message parser failure\n", __func__);
- dev_kfree_skb_any(skb);
- return;
- }
- dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
- capi_ctr_handle_message(&iif->ctr, ap->id, skb);
-}
-
-/**
- * gigaset_isdn_connD() - signal D channel connect
- * @bcs: B channel descriptor structure.
- *
- * Called by main module at tasklet level to notify the LL that the D channel
- * connection has been established.
- */
-void gigaset_isdn_connD(struct bc_state *bcs)
-{
- struct cardstate *cs = bcs->cs;
- struct gigaset_capi_ctr *iif = cs->iif;
- struct gigaset_capi_appl *ap;
- struct sk_buff *skb;
- unsigned int msgsize;
- unsigned long flags;
-
- spin_lock_irqsave(&bcs->aplock, flags);
- ap = bcs->ap;
- if (!ap) {
- spin_unlock_irqrestore(&bcs->aplock, flags);
- gig_dbg(DEBUG_CMD, "%s: application gone", __func__);
- return;
- }
- if (bcs->apconnstate == APCONN_NONE) {
- spin_unlock_irqrestore(&bcs->aplock, flags);
- dev_warn(cs->dev, "%s: application %u not connected\n",
- __func__, ap->id);
- return;
- }
- spin_unlock_irqrestore(&bcs->aplock, flags);
- while (ap->bcnext) {
- /* this should never happen */
- dev_warn(cs->dev, "%s: dropping extra application %u\n",
- __func__, ap->bcnext->id);
- send_disconnect_ind(bcs, ap->bcnext,
- CapiCallGivenToOtherApplication);
- ap->bcnext = ap->bcnext->bcnext;
- }
-
- /* prepare CONNECT_ACTIVE_IND message
- * Note: LLC not supported by device
- */
- capi_cmsg_header(&iif->hcmsg, ap->id, CAPI_CONNECT_ACTIVE, CAPI_IND,
- ap->nextMessageNumber++,
- iif->ctr.cnr | ((bcs->channel + 1) << 8));
-
- /* minimum size, all structs empty */
- msgsize = CAPI_CONNECT_ACTIVE_IND_BASELEN;
-
- /* ToDo: set parameter: Connected number
- * (requires ev-layer state machine extension to collect
- * ZCON device reply)
- */
-
- /* build and emit CONNECT_ACTIVE_IND message */
- skb = alloc_skb(msgsize, GFP_ATOMIC);
- if (!skb) {
- dev_err(cs->dev, "%s: out of memory\n", __func__);
- return;
- }
- if (capi_cmsg2message(&iif->hcmsg, __skb_put(skb, msgsize))) {
- dev_err(cs->dev, "%s: message parser failure\n", __func__);
- dev_kfree_skb_any(skb);
- return;
- }
- dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
- capi_ctr_handle_message(&iif->ctr, ap->id, skb);
-}
-
-/**
- * gigaset_isdn_hupD() - signal D channel hangup
- * @bcs: B channel descriptor structure.
- *
- * Called by main module at tasklet level to notify the LL that the D channel
- * connection has been shut down.
- */
-void gigaset_isdn_hupD(struct bc_state *bcs)
-{
- struct gigaset_capi_appl *ap;
- unsigned long flags;
-
- /*
- * ToDo: pass on reason code reported by device
- * (requires ev-layer state machine extension to collect
- * ZCAU device reply)
- */
- spin_lock_irqsave(&bcs->aplock, flags);
- while (bcs->ap != NULL) {
- ap = bcs->ap;
- bcs->ap = ap->bcnext;
- spin_unlock_irqrestore(&bcs->aplock, flags);
- send_disconnect_b3_ind(bcs, ap);
- send_disconnect_ind(bcs, ap, 0);
- spin_lock_irqsave(&bcs->aplock, flags);
- }
- bcs->apconnstate = APCONN_NONE;
- spin_unlock_irqrestore(&bcs->aplock, flags);
-}
-
-/**
- * gigaset_isdn_connB() - signal B channel connect
- * @bcs: B channel descriptor structure.
- *
- * Called by main module at tasklet level to notify the LL that the B channel
- * connection has been established.
- */
-void gigaset_isdn_connB(struct bc_state *bcs)
-{
- struct cardstate *cs = bcs->cs;
- struct gigaset_capi_ctr *iif = cs->iif;
- struct gigaset_capi_appl *ap;
- struct sk_buff *skb;
- unsigned long flags;
- unsigned int msgsize;
- u8 command;
-
- spin_lock_irqsave(&bcs->aplock, flags);
- ap = bcs->ap;
- if (!ap) {
- spin_unlock_irqrestore(&bcs->aplock, flags);
- gig_dbg(DEBUG_CMD, "%s: application gone", __func__);
- return;
- }
- if (!bcs->apconnstate) {
- spin_unlock_irqrestore(&bcs->aplock, flags);
- dev_warn(cs->dev, "%s: application %u not connected\n",
- __func__, ap->id);
- return;
- }
-
- /*
- * emit CONNECT_B3_ACTIVE_IND if we already got CONNECT_B3_REQ;
- * otherwise we have to emit CONNECT_B3_IND first, and follow up with
- * CONNECT_B3_ACTIVE_IND in reply to CONNECT_B3_RESP
- * Parameters in both cases always: NCCI = 1, NCPI empty
- */
- if (bcs->apconnstate >= APCONN_ACTIVE) {
- command = CAPI_CONNECT_B3_ACTIVE;
- msgsize = CAPI_CONNECT_B3_ACTIVE_IND_BASELEN;
- } else {
- command = CAPI_CONNECT_B3;
- msgsize = CAPI_CONNECT_B3_IND_BASELEN;
- }
- bcs->apconnstate = APCONN_ACTIVE;
-
- spin_unlock_irqrestore(&bcs->aplock, flags);
-
- while (ap->bcnext) {
- /* this should never happen */
- dev_warn(cs->dev, "%s: dropping extra application %u\n",
- __func__, ap->bcnext->id);
- send_disconnect_ind(bcs, ap->bcnext,
- CapiCallGivenToOtherApplication);
- ap->bcnext = ap->bcnext->bcnext;
- }
-
- capi_cmsg_header(&iif->hcmsg, ap->id, command, CAPI_IND,
- ap->nextMessageNumber++,
- iif->ctr.cnr | ((bcs->channel + 1) << 8) | (1 << 16));
- skb = alloc_skb(msgsize, GFP_ATOMIC);
- if (!skb) {
- dev_err(cs->dev, "%s: out of memory\n", __func__);
- return;
- }
- if (capi_cmsg2message(&iif->hcmsg, __skb_put(skb, msgsize))) {
- dev_err(cs->dev, "%s: message parser failure\n", __func__);
- dev_kfree_skb_any(skb);
- return;
- }
- dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
- capi_ctr_handle_message(&iif->ctr, ap->id, skb);
-}
-
-/**
- * gigaset_isdn_hupB() - signal B channel hangup
- * @bcs: B channel descriptor structure.
- *
- * Called by main module to notify the LL that the B channel connection has
- * been shut down.
- */
-void gigaset_isdn_hupB(struct bc_state *bcs)
-{
- struct gigaset_capi_appl *ap = bcs->ap;
-
- /* ToDo: assure order of DISCONNECT_B3_IND and DISCONNECT_IND ? */
-
- if (!ap) {
- gig_dbg(DEBUG_CMD, "%s: application gone", __func__);
- return;
- }
-
- send_disconnect_b3_ind(bcs, ap);
-}
-
-/**
- * gigaset_isdn_start() - signal device availability
- * @cs: device descriptor structure.
- *
- * Called by main module to notify the LL that the device is available for
- * use.
- */
-void gigaset_isdn_start(struct cardstate *cs)
-{
- struct gigaset_capi_ctr *iif = cs->iif;
-
- /* fill profile data: manufacturer name */
- strcpy(iif->ctr.manu, "Siemens");
- /* CAPI and device version */
- iif->ctr.version.majorversion = 2; /* CAPI 2.0 */
- iif->ctr.version.minorversion = 0;
- /* ToDo: check/assert cs->gotfwver? */
- iif->ctr.version.majormanuversion = cs->fwver[0];
- iif->ctr.version.minormanuversion = cs->fwver[1];
- /* number of B channels supported */
- iif->ctr.profile.nbchannel = cs->channels;
- /* global options: internal controller, supplementary services */
- iif->ctr.profile.goptions = 0x11;
- /* B1 protocols: 64 kbit/s HDLC or transparent */
- iif->ctr.profile.support1 = 0x03;
- /* B2 protocols: transparent only */
- /* ToDo: X.75 SLP ? */
- iif->ctr.profile.support2 = 0x02;
- /* B3 protocols: transparent only */
- iif->ctr.profile.support3 = 0x01;
- /* no serial number */
- strcpy(iif->ctr.serial, "0");
- capi_ctr_ready(&iif->ctr);
-}
-
-/**
- * gigaset_isdn_stop() - signal device unavailability
- * @cs: device descriptor structure.
- *
- * Called by main module to notify the LL that the device is no longer
- * available for use.
- */
-void gigaset_isdn_stop(struct cardstate *cs)
-{
- struct gigaset_capi_ctr *iif = cs->iif;
- capi_ctr_down(&iif->ctr);
-}
-
-/*
- * kernel CAPI callback methods
- * ============================
- */
-
-/*
- * register CAPI application
- */
-static void gigaset_register_appl(struct capi_ctr *ctr, u16 appl,
- capi_register_params *rp)
-{
- struct gigaset_capi_ctr *iif
- = container_of(ctr, struct gigaset_capi_ctr, ctr);
- struct cardstate *cs = ctr->driverdata;
- struct gigaset_capi_appl *ap;
-
- gig_dbg(DEBUG_CMD, "%s [%u] l3cnt=%u blkcnt=%u blklen=%u",
- __func__, appl, rp->level3cnt, rp->datablkcnt, rp->datablklen);
-
- list_for_each_entry(ap, &iif->appls, ctrlist)
- if (ap->id == appl) {
- dev_notice(cs->dev,
- "application %u already registered\n", appl);
- return;
- }
-
- ap = kzalloc(sizeof(*ap), GFP_KERNEL);
- if (!ap) {
- dev_err(cs->dev, "%s: out of memory\n", __func__);
- return;
- }
- ap->id = appl;
- ap->rp = *rp;
-
- list_add(&ap->ctrlist, &iif->appls);
- dev_info(cs->dev, "application %u registered\n", ap->id);
-}
-
-/*
- * remove CAPI application from channel
- * helper function to keep indentation levels down and stay in 80 columns
- */
-
-static inline void remove_appl_from_channel(struct bc_state *bcs,
- struct gigaset_capi_appl *ap)
-{
- struct cardstate *cs = bcs->cs;
- struct gigaset_capi_appl *bcap;
- unsigned long flags;
- int prevconnstate;
-
- spin_lock_irqsave(&bcs->aplock, flags);
- bcap = bcs->ap;
- if (bcap == NULL) {
- spin_unlock_irqrestore(&bcs->aplock, flags);
- return;
- }
-
- /* check first application on channel */
- if (bcap == ap) {
- bcs->ap = ap->bcnext;
- if (bcs->ap != NULL) {
- spin_unlock_irqrestore(&bcs->aplock, flags);
- return;
- }
-
- /* none left, clear channel state */
- prevconnstate = bcs->apconnstate;
- bcs->apconnstate = APCONN_NONE;
- spin_unlock_irqrestore(&bcs->aplock, flags);
-
- if (prevconnstate == APCONN_ACTIVE) {
- dev_notice(cs->dev, "%s: hanging up channel %u\n",
- __func__, bcs->channel);
- gigaset_add_event(cs, &bcs->at_state,
- EV_HUP, NULL, 0, NULL);
- gigaset_schedule_event(cs);
- }
- return;
- }
-
- /* check remaining list */
- do {
- if (bcap->bcnext == ap) {
- bcap->bcnext = bcap->bcnext->bcnext;
- spin_unlock_irqrestore(&bcs->aplock, flags);
- return;
- }
- bcap = bcap->bcnext;
- } while (bcap != NULL);
- spin_unlock_irqrestore(&bcs->aplock, flags);
-}
-
-/*
- * release CAPI application
- */
-static void gigaset_release_appl(struct capi_ctr *ctr, u16 appl)
-{
- struct gigaset_capi_ctr *iif
- = container_of(ctr, struct gigaset_capi_ctr, ctr);
- struct cardstate *cs = iif->ctr.driverdata;
- struct gigaset_capi_appl *ap, *tmp;
- unsigned ch;
-
- gig_dbg(DEBUG_CMD, "%s [%u]", __func__, appl);
-
- list_for_each_entry_safe(ap, tmp, &iif->appls, ctrlist)
- if (ap->id == appl) {
- /* remove from any channels */
- for (ch = 0; ch < cs->channels; ch++)
- remove_appl_from_channel(&cs->bcs[ch], ap);
-
- /* remove from registration list */
- list_del(&ap->ctrlist);
- kfree(ap);
- dev_info(cs->dev, "application %u released\n", appl);
- }
-}
-
-/*
- * =====================================================================
- * outgoing CAPI message handler
- * =====================================================================
- */
-
-/*
- * helper function: emit reply message with given Info value
- */
-static void send_conf(struct gigaset_capi_ctr *iif,
- struct gigaset_capi_appl *ap,
- struct sk_buff *skb,
- u16 info)
-{
- struct cardstate *cs = iif->ctr.driverdata;
-
- /*
- * _CONF replies always only have NCCI and Info parameters
- * so they'll fit into the _REQ message skb
- */
- capi_cmsg_answer(&iif->acmsg);
- iif->acmsg.Info = info;
- if (capi_cmsg2message(&iif->acmsg, skb->data)) {
- dev_err(cs->dev, "%s: message parser failure\n", __func__);
- dev_kfree_skb_any(skb);
- return;
- }
- __skb_trim(skb, CAPI_STDCONF_LEN);
- dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
- capi_ctr_handle_message(&iif->ctr, ap->id, skb);
-}
-
-/*
- * process FACILITY_REQ message
- */
-static void do_facility_req(struct gigaset_capi_ctr *iif,
- struct gigaset_capi_appl *ap,
- struct sk_buff *skb)
-{
- struct cardstate *cs = iif->ctr.driverdata;
- _cmsg *cmsg = &iif->acmsg;
- struct sk_buff *cskb;
- u8 *pparam;
- unsigned int msgsize = CAPI_FACILITY_CONF_BASELEN;
- u16 function, info;
- static u8 confparam[10]; /* max. 9 octets + length byte */
-
- /* decode message */
- if (capi_message2cmsg(cmsg, skb->data)) {
- dev_err(cs->dev, "%s: message parser failure\n", __func__);
- dev_kfree_skb_any(skb);
- return;
- }
- dump_cmsg(DEBUG_CMD, __func__, cmsg);
-
- /*
- * Facility Request Parameter is not decoded by capi_message2cmsg()
- * encoding depends on Facility Selector
- */
- switch (cmsg->FacilitySelector) {
- case CAPI_FACILITY_DTMF: /* ToDo */
- info = CapiFacilityNotSupported;
- confparam[0] = 2; /* length */
- /* DTMF information: Unknown DTMF request */
- capimsg_setu16(confparam, 1, 2);
- break;
-
- case CAPI_FACILITY_V42BIS: /* not supported */
- info = CapiFacilityNotSupported;
- confparam[0] = 2; /* length */
- /* V.42 bis information: not available */
- capimsg_setu16(confparam, 1, 1);
- break;
-
- case CAPI_FACILITY_SUPPSVC:
- /* decode Function parameter */
- pparam = cmsg->FacilityRequestParameter;
- if (pparam == NULL || pparam[0] < 2) {
- dev_notice(cs->dev, "%s: %s missing\n", "FACILITY_REQ",
- "Facility Request Parameter");
- send_conf(iif, ap, skb, CapiIllMessageParmCoding);
- return;
- }
- function = CAPIMSG_U16(pparam, 1);
- switch (function) {
- case CAPI_SUPPSVC_GETSUPPORTED:
- info = CapiSuccess;
- /* Supplementary Service specific parameter */
- confparam[3] = 6; /* length */
- /* Supplementary services info: Success */
- capimsg_setu16(confparam, 4, CapiSuccess);
- /* Supported Services: none */
- capimsg_setu32(confparam, 6, 0);
- break;
- case CAPI_SUPPSVC_LISTEN:
- if (pparam[0] < 7 || pparam[3] < 4) {
- dev_notice(cs->dev, "%s: %s missing\n",
- "FACILITY_REQ", "Notification Mask");
- send_conf(iif, ap, skb,
- CapiIllMessageParmCoding);
- return;
- }
- if (CAPIMSG_U32(pparam, 4) != 0) {
- dev_notice(cs->dev,
- "%s: unsupported supplementary service notification mask 0x%x\n",
- "FACILITY_REQ", CAPIMSG_U32(pparam, 4));
- info = CapiFacilitySpecificFunctionNotSupported;
- confparam[3] = 2; /* length */
- capimsg_setu16(confparam, 4,
- CapiSupplementaryServiceNotSupported);
- break;
- }
- info = CapiSuccess;
- confparam[3] = 2; /* length */
- capimsg_setu16(confparam, 4, CapiSuccess);
- break;
-
- /* ToDo: add supported services */
-
- default:
- dev_notice(cs->dev,
- "%s: unsupported supplementary service function 0x%04x\n",
- "FACILITY_REQ", function);
- info = CapiFacilitySpecificFunctionNotSupported;
- /* Supplementary Service specific parameter */
- confparam[3] = 2; /* length */
- /* Supplementary services info: not supported */
- capimsg_setu16(confparam, 4,
- CapiSupplementaryServiceNotSupported);
- }
-
- /* Facility confirmation parameter */
- confparam[0] = confparam[3] + 3; /* total length */
- /* Function: copy from _REQ message */
- capimsg_setu16(confparam, 1, function);
- /* Supplementary Service specific parameter already set above */
- break;
-
- case CAPI_FACILITY_WAKEUP: /* ToDo */
- info = CapiFacilityNotSupported;
- confparam[0] = 2; /* length */
- /* Number of accepted awake request parameters: 0 */
- capimsg_setu16(confparam, 1, 0);
- break;
-
- default:
- info = CapiFacilityNotSupported;
- confparam[0] = 0; /* empty struct */
- }
-
- /* send FACILITY_CONF with given Info and confirmation parameter */
- dev_kfree_skb_any(skb);
- capi_cmsg_answer(cmsg);
- cmsg->Info = info;
- cmsg->FacilityConfirmationParameter = confparam;
- msgsize += confparam[0]; /* length */
- cskb = alloc_skb(msgsize, GFP_ATOMIC);
- if (!cskb) {
- dev_err(cs->dev, "%s: out of memory\n", __func__);
- return;
- }
- if (capi_cmsg2message(cmsg, __skb_put(cskb, msgsize))) {
- dev_err(cs->dev, "%s: message parser failure\n", __func__);
- dev_kfree_skb_any(cskb);
- return;
- }
- dump_cmsg(DEBUG_CMD, __func__, cmsg);
- capi_ctr_handle_message(&iif->ctr, ap->id, cskb);
-}
-
-
-/*
- * process LISTEN_REQ message
- * just store the masks in the application data structure
- */
-static void do_listen_req(struct gigaset_capi_ctr *iif,
- struct gigaset_capi_appl *ap,
- struct sk_buff *skb)
-{
- struct cardstate *cs = iif->ctr.driverdata;
-
- /* decode message */
- if (capi_message2cmsg(&iif->acmsg, skb->data)) {
- dev_err(cs->dev, "%s: message parser failure\n", __func__);
- dev_kfree_skb_any(skb);
- return;
- }
- dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
-
- /* store listening parameters */
- ap->listenInfoMask = iif->acmsg.InfoMask;
- ap->listenCIPmask = iif->acmsg.CIPmask;
- send_conf(iif, ap, skb, CapiSuccess);
-}
-
-/*
- * process ALERT_REQ message
- * nothing to do, Gigaset always alerts anyway
- */
-static void do_alert_req(struct gigaset_capi_ctr *iif,
- struct gigaset_capi_appl *ap,
- struct sk_buff *skb)
-{
- struct cardstate *cs = iif->ctr.driverdata;
-
- /* decode message */
- if (capi_message2cmsg(&iif->acmsg, skb->data)) {
- dev_err(cs->dev, "%s: message parser failure\n", __func__);
- dev_kfree_skb_any(skb);
- return;
- }
- dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
- send_conf(iif, ap, skb, CapiAlertAlreadySent);
-}
-
-/*
- * process CONNECT_REQ message
- * allocate a B channel, prepare dial commands, queue a DIAL event,
- * emit CONNECT_CONF reply
- */
-static void do_connect_req(struct gigaset_capi_ctr *iif,
- struct gigaset_capi_appl *ap,
- struct sk_buff *skb)
-{
- struct cardstate *cs = iif->ctr.driverdata;
- _cmsg *cmsg = &iif->acmsg;
- struct bc_state *bcs;
- char **commands;
- char *s;
- u8 *pp;
- unsigned long flags;
- int i, l, lbc, lhlc;
- u16 info;
-
- /* decode message */
- if (capi_message2cmsg(cmsg, skb->data)) {
- dev_err(cs->dev, "%s: message parser failure\n", __func__);
- dev_kfree_skb_any(skb);
- return;
- }
- dump_cmsg(DEBUG_CMD, __func__, cmsg);
-
- /* get free B channel & construct PLCI */
- bcs = gigaset_get_free_channel(cs);
- if (!bcs) {
- dev_notice(cs->dev, "%s: no B channel available\n",
- "CONNECT_REQ");
- send_conf(iif, ap, skb, CapiNoPlciAvailable);
- return;
- }
- spin_lock_irqsave(&bcs->aplock, flags);
- if (bcs->ap != NULL || bcs->apconnstate != APCONN_NONE)
- dev_warn(cs->dev, "%s: channel not properly cleared (%p/%d)\n",
- __func__, bcs->ap, bcs->apconnstate);
- ap->bcnext = NULL;
- bcs->ap = ap;
- bcs->apconnstate = APCONN_SETUP;
- spin_unlock_irqrestore(&bcs->aplock, flags);
-
- bcs->rx_bufsize = ap->rp.datablklen;
- dev_kfree_skb(bcs->rx_skb);
- gigaset_new_rx_skb(bcs);
- cmsg->adr.adrPLCI |= (bcs->channel + 1) << 8;
-
- /* build command table */
- commands = kcalloc(AT_NUM, sizeof(*commands), GFP_KERNEL);
- if (!commands)
- goto oom;
-
- /* encode parameter: Called party number */
- pp = cmsg->CalledPartyNumber;
- if (pp == NULL || *pp == 0) {
- dev_notice(cs->dev, "%s: %s missing\n",
- "CONNECT_REQ", "Called party number");
- info = CapiIllMessageParmCoding;
- goto error;
- }
- l = *pp++;
- /* check type of number/numbering plan byte */
- switch (*pp) {
- case 0x80: /* unknown type / unknown numbering plan */
- case 0x81: /* unknown type / ISDN/Telephony numbering plan */
- break;
- default: /* others: warn about potential misinterpretation */
- dev_notice(cs->dev, "%s: %s type/plan 0x%02x unsupported\n",
- "CONNECT_REQ", "Called party number", *pp);
- }
- pp++;
- l--;
- /* translate "**" internal call prefix to CTP value */
- if (l >= 2 && pp[0] == '*' && pp[1] == '*') {
- s = "^SCTP=0\r";
- pp += 2;
- l -= 2;
- } else {
- s = "^SCTP=1\r";
- }
- commands[AT_TYPE] = kstrdup(s, GFP_KERNEL);
- if (!commands[AT_TYPE])
- goto oom;
- commands[AT_DIAL] = kmalloc(l + 3, GFP_KERNEL);
- if (!commands[AT_DIAL])
- goto oom;
- snprintf(commands[AT_DIAL], l + 3, "D%.*s\r", l, pp);
-
- /* encode parameter: Calling party number */
- pp = cmsg->CallingPartyNumber;
- if (pp != NULL && *pp > 0) {
- l = *pp++;
-
- /* check type of number/numbering plan byte */
- /* ToDo: allow for/handle Ext=1? */
- switch (*pp) {
- case 0x00: /* unknown type / unknown numbering plan */
- case 0x01: /* unknown type / ISDN/Telephony num. plan */
- break;
- default:
- dev_notice(cs->dev,
- "%s: %s type/plan 0x%02x unsupported\n",
- "CONNECT_REQ", "Calling party number", *pp);
- }
- pp++;
- l--;
-
- /* check presentation indicator */
- if (!l) {
- dev_notice(cs->dev, "%s: %s IE truncated\n",
- "CONNECT_REQ", "Calling party number");
- info = CapiIllMessageParmCoding;
- goto error;
- }
- switch (*pp & 0xfc) { /* ignore Screening indicator */
- case 0x80: /* Presentation allowed */
- s = "^SCLIP=1\r";
- break;
- case 0xa0: /* Presentation restricted */
- s = "^SCLIP=0\r";
- break;
- default:
- dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
- "CONNECT_REQ",
- "Presentation/Screening indicator",
- *pp);
- s = "^SCLIP=1\r";
- }
- commands[AT_CLIP] = kstrdup(s, GFP_KERNEL);
- if (!commands[AT_CLIP])
- goto oom;
- pp++;
- l--;
-
- if (l) {
- /* number */
- commands[AT_MSN] = kmalloc(l + 8, GFP_KERNEL);
- if (!commands[AT_MSN])
- goto oom;
- snprintf(commands[AT_MSN], l + 8, "^SMSN=%*s\r", l, pp);
- }
- }
-
- /* check parameter: CIP Value */
- if (cmsg->CIPValue >= ARRAY_SIZE(cip2bchlc) ||
- (cmsg->CIPValue > 0 && cip2bchlc[cmsg->CIPValue].bc == NULL)) {
- dev_notice(cs->dev, "%s: unknown CIP value %d\n",
- "CONNECT_REQ", cmsg->CIPValue);
- info = CapiCipValueUnknown;
- goto error;
- }
-
- /*
- * check/encode parameters: BC & HLC
- * must be encoded together as device doesn't accept HLC separately
- * explicit parameters override values derived from CIP
- */
-
- /* determine lengths */
- if (cmsg->BC && cmsg->BC[0]) /* BC specified explicitly */
- lbc = 2 * cmsg->BC[0];
- else if (cip2bchlc[cmsg->CIPValue].bc) /* BC derived from CIP */
- lbc = strlen(cip2bchlc[cmsg->CIPValue].bc);
- else /* no BC */
- lbc = 0;
- if (cmsg->HLC && cmsg->HLC[0]) /* HLC specified explicitly */
- lhlc = 2 * cmsg->HLC[0];
- else if (cip2bchlc[cmsg->CIPValue].hlc) /* HLC derived from CIP */
- lhlc = strlen(cip2bchlc[cmsg->CIPValue].hlc);
- else /* no HLC */
- lhlc = 0;
-
- if (lbc) {
- /* have BC: allocate and assemble command string */
- l = lbc + 7; /* "^SBC=" + value + "\r" + null byte */
- if (lhlc)
- l += lhlc + 7; /* ";^SHLC=" + value */
- commands[AT_BC] = kmalloc(l, GFP_KERNEL);
- if (!commands[AT_BC])
- goto oom;
- strcpy(commands[AT_BC], "^SBC=");
- if (cmsg->BC && cmsg->BC[0]) /* BC specified explicitly */
- decode_ie(cmsg->BC, commands[AT_BC] + 5);
- else /* BC derived from CIP */
- strcpy(commands[AT_BC] + 5,
- cip2bchlc[cmsg->CIPValue].bc);
- if (lhlc) {
- strcpy(commands[AT_BC] + lbc + 5, ";^SHLC=");
- if (cmsg->HLC && cmsg->HLC[0])
- /* HLC specified explicitly */
- decode_ie(cmsg->HLC,
- commands[AT_BC] + lbc + 12);
- else /* HLC derived from CIP */
- strcpy(commands[AT_BC] + lbc + 12,
- cip2bchlc[cmsg->CIPValue].hlc);
- }
- strcpy(commands[AT_BC] + l - 2, "\r");
- } else {
- /* no BC */
- if (lhlc) {
- dev_notice(cs->dev, "%s: cannot set HLC without BC\n",
- "CONNECT_REQ");
- info = CapiIllMessageParmCoding; /* ? */
- goto error;
- }
- }
-
- /* check/encode parameter: B Protocol */
- if (cmsg->BProtocol == CAPI_DEFAULT) {
- bcs->proto2 = L2_HDLC;
- dev_warn(cs->dev,
- "B2 Protocol X.75 SLP unsupported, using Transparent\n");
- } else {
- switch (cmsg->B1protocol) {
- case 0:
- bcs->proto2 = L2_HDLC;
- break;
- case 1:
- bcs->proto2 = L2_VOICE;
- break;
- default:
- dev_warn(cs->dev,
- "B1 Protocol %u unsupported, using Transparent\n",
- cmsg->B1protocol);
- bcs->proto2 = L2_VOICE;
- }
- if (cmsg->B2protocol != 1)
- dev_warn(cs->dev,
- "B2 Protocol %u unsupported, using Transparent\n",
- cmsg->B2protocol);
- if (cmsg->B3protocol != 0)
- dev_warn(cs->dev,
- "B3 Protocol %u unsupported, using Transparent\n",
- cmsg->B3protocol);
- ignore_cstruct_param(cs, cmsg->B1configuration,
- "CONNECT_REQ", "B1 Configuration");
- ignore_cstruct_param(cs, cmsg->B2configuration,
- "CONNECT_REQ", "B2 Configuration");
- ignore_cstruct_param(cs, cmsg->B3configuration,
- "CONNECT_REQ", "B3 Configuration");
- }
- commands[AT_PROTO] = kmalloc(9, GFP_KERNEL);
- if (!commands[AT_PROTO])
- goto oom;
- snprintf(commands[AT_PROTO], 9, "^SBPR=%u\r", bcs->proto2);
-
- /* ToDo: check/encode remaining parameters */
- ignore_cstruct_param(cs, cmsg->CalledPartySubaddress,
- "CONNECT_REQ", "Called pty subaddr");
- ignore_cstruct_param(cs, cmsg->CallingPartySubaddress,
- "CONNECT_REQ", "Calling pty subaddr");
- ignore_cstruct_param(cs, cmsg->LLC,
- "CONNECT_REQ", "LLC");
- if (cmsg->AdditionalInfo != CAPI_DEFAULT) {
- ignore_cstruct_param(cs, cmsg->BChannelinformation,
- "CONNECT_REQ", "B Channel Information");
- ignore_cstruct_param(cs, cmsg->Keypadfacility,
- "CONNECT_REQ", "Keypad Facility");
- ignore_cstruct_param(cs, cmsg->Useruserdata,
- "CONNECT_REQ", "User-User Data");
- ignore_cstruct_param(cs, cmsg->Facilitydataarray,
- "CONNECT_REQ", "Facility Data Array");
- }
-
- /* encode parameter: B channel to use */
- commands[AT_ISO] = kmalloc(9, GFP_KERNEL);
- if (!commands[AT_ISO])
- goto oom;
- snprintf(commands[AT_ISO], 9, "^SISO=%u\r",
- (unsigned) bcs->channel + 1);
-
- /* queue & schedule EV_DIAL event */
- if (!gigaset_add_event(cs, &bcs->at_state, EV_DIAL, commands,
- bcs->at_state.seq_index, NULL)) {
- info = CAPI_MSGOSRESOURCEERR;
- goto error;
- }
- gigaset_schedule_event(cs);
- send_conf(iif, ap, skb, CapiSuccess);
- return;
-
-oom:
- dev_err(cs->dev, "%s: out of memory\n", __func__);
- info = CAPI_MSGOSRESOURCEERR;
-error:
- if (commands)
- for (i = 0; i < AT_NUM; i++)
- kfree(commands[i]);
- kfree(commands);
- gigaset_free_channel(bcs);
- send_conf(iif, ap, skb, info);
-}
-
-/*
- * process CONNECT_RESP message
- * checks protocol parameters and queues an ACCEPT or HUP event
- */
-static void do_connect_resp(struct gigaset_capi_ctr *iif,
- struct gigaset_capi_appl *ap,
- struct sk_buff *skb)
-{
- struct cardstate *cs = iif->ctr.driverdata;
- _cmsg *cmsg = &iif->acmsg;
- struct bc_state *bcs;
- struct gigaset_capi_appl *oap;
- unsigned long flags;
- int channel;
-
- /* decode message */
- if (capi_message2cmsg(cmsg, skb->data)) {
- dev_err(cs->dev, "%s: message parser failure\n", __func__);
- dev_kfree_skb_any(skb);
- return;
- }
- dump_cmsg(DEBUG_CMD, __func__, cmsg);
- dev_kfree_skb_any(skb);
-
- /* extract and check channel number from PLCI */
- channel = (cmsg->adr.adrPLCI >> 8) & 0xff;
- if (!channel || channel > cs->channels) {
- dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
- "CONNECT_RESP", "PLCI", cmsg->adr.adrPLCI);
- return;
- }
- bcs = cs->bcs + channel - 1;
-
- switch (cmsg->Reject) {
- case 0: /* Accept */
- /* drop all competing applications, keep only this one */
- spin_lock_irqsave(&bcs->aplock, flags);
- while (bcs->ap != NULL) {
- oap = bcs->ap;
- bcs->ap = oap->bcnext;
- if (oap != ap) {
- spin_unlock_irqrestore(&bcs->aplock, flags);
- send_disconnect_ind(bcs, oap,
- CapiCallGivenToOtherApplication);
- spin_lock_irqsave(&bcs->aplock, flags);
- }
- }
- ap->bcnext = NULL;
- bcs->ap = ap;
- spin_unlock_irqrestore(&bcs->aplock, flags);
-
- bcs->rx_bufsize = ap->rp.datablklen;
- dev_kfree_skb(bcs->rx_skb);
- gigaset_new_rx_skb(bcs);
- bcs->chstate |= CHS_NOTIFY_LL;
-
- /* check/encode B channel protocol */
- if (cmsg->BProtocol == CAPI_DEFAULT) {
- bcs->proto2 = L2_HDLC;
- dev_warn(cs->dev,
- "B2 Protocol X.75 SLP unsupported, using Transparent\n");
- } else {
- switch (cmsg->B1protocol) {
- case 0:
- bcs->proto2 = L2_HDLC;
- break;
- case 1:
- bcs->proto2 = L2_VOICE;
- break;
- default:
- dev_warn(cs->dev,
- "B1 Protocol %u unsupported, using Transparent\n",
- cmsg->B1protocol);
- bcs->proto2 = L2_VOICE;
- }
- if (cmsg->B2protocol != 1)
- dev_warn(cs->dev,
- "B2 Protocol %u unsupported, using Transparent\n",
- cmsg->B2protocol);
- if (cmsg->B3protocol != 0)
- dev_warn(cs->dev,
- "B3 Protocol %u unsupported, using Transparent\n",
- cmsg->B3protocol);
- ignore_cstruct_param(cs, cmsg->B1configuration,
- "CONNECT_RESP", "B1 Configuration");
- ignore_cstruct_param(cs, cmsg->B2configuration,
- "CONNECT_RESP", "B2 Configuration");
- ignore_cstruct_param(cs, cmsg->B3configuration,
- "CONNECT_RESP", "B3 Configuration");
- }
-
- /* ToDo: check/encode remaining parameters */
- ignore_cstruct_param(cs, cmsg->ConnectedNumber,
- "CONNECT_RESP", "Connected Number");
- ignore_cstruct_param(cs, cmsg->ConnectedSubaddress,
- "CONNECT_RESP", "Connected Subaddress");
- ignore_cstruct_param(cs, cmsg->LLC,
- "CONNECT_RESP", "LLC");
- if (cmsg->AdditionalInfo != CAPI_DEFAULT) {
- ignore_cstruct_param(cs, cmsg->BChannelinformation,
- "CONNECT_RESP", "BChannel Information");
- ignore_cstruct_param(cs, cmsg->Keypadfacility,
- "CONNECT_RESP", "Keypad Facility");
- ignore_cstruct_param(cs, cmsg->Useruserdata,
- "CONNECT_RESP", "User-User Data");
- ignore_cstruct_param(cs, cmsg->Facilitydataarray,
- "CONNECT_RESP", "Facility Data Array");
- }
-
- /* Accept call */
- if (!gigaset_add_event(cs, &cs->bcs[channel - 1].at_state,
- EV_ACCEPT, NULL, 0, NULL))
- return;
- gigaset_schedule_event(cs);
- return;
-
- case 1: /* Ignore */
- /* send DISCONNECT_IND to this application */
- send_disconnect_ind(bcs, ap, 0);
-
- /* remove it from the list of listening apps */
- spin_lock_irqsave(&bcs->aplock, flags);
- if (bcs->ap == ap) {
- bcs->ap = ap->bcnext;
- if (bcs->ap == NULL) {
- /* last one: stop ev-layer hupD notifications */
- bcs->apconnstate = APCONN_NONE;
- bcs->chstate &= ~CHS_NOTIFY_LL;
- }
- spin_unlock_irqrestore(&bcs->aplock, flags);
- return;
- }
- for (oap = bcs->ap; oap != NULL; oap = oap->bcnext) {
- if (oap->bcnext == ap) {
- oap->bcnext = oap->bcnext->bcnext;
- spin_unlock_irqrestore(&bcs->aplock, flags);
- return;
- }
- }
- spin_unlock_irqrestore(&bcs->aplock, flags);
- dev_err(cs->dev, "%s: application %u not found\n",
- __func__, ap->id);
- return;
-
- default: /* Reject */
- /* drop all competing applications, keep only this one */
- spin_lock_irqsave(&bcs->aplock, flags);
- while (bcs->ap != NULL) {
- oap = bcs->ap;
- bcs->ap = oap->bcnext;
- if (oap != ap) {
- spin_unlock_irqrestore(&bcs->aplock, flags);
- send_disconnect_ind(bcs, oap,
- CapiCallGivenToOtherApplication);
- spin_lock_irqsave(&bcs->aplock, flags);
- }
- }
- ap->bcnext = NULL;
- bcs->ap = ap;
- spin_unlock_irqrestore(&bcs->aplock, flags);
-
- /* reject call - will trigger DISCONNECT_IND for this app */
- dev_info(cs->dev, "%s: Reject=%x\n",
- "CONNECT_RESP", cmsg->Reject);
- if (!gigaset_add_event(cs, &cs->bcs[channel - 1].at_state,
- EV_HUP, NULL, 0, NULL))
- return;
- gigaset_schedule_event(cs);
- return;
- }
-}
-
-/*
- * process CONNECT_B3_REQ message
- * build NCCI and emit CONNECT_B3_CONF reply
- */
-static void do_connect_b3_req(struct gigaset_capi_ctr *iif,
- struct gigaset_capi_appl *ap,
- struct sk_buff *skb)
-{
- struct cardstate *cs = iif->ctr.driverdata;
- _cmsg *cmsg = &iif->acmsg;
- struct bc_state *bcs;
- int channel;
-
- /* decode message */
- if (capi_message2cmsg(cmsg, skb->data)) {
- dev_err(cs->dev, "%s: message parser failure\n", __func__);
- dev_kfree_skb_any(skb);
- return;
- }
- dump_cmsg(DEBUG_CMD, __func__, cmsg);
-
- /* extract and check channel number from PLCI */
- channel = (cmsg->adr.adrPLCI >> 8) & 0xff;
- if (!channel || channel > cs->channels) {
- dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
- "CONNECT_B3_REQ", "PLCI", cmsg->adr.adrPLCI);
- send_conf(iif, ap, skb, CapiIllContrPlciNcci);
- return;
- }
- bcs = &cs->bcs[channel - 1];
-
- /* mark logical connection active */
- bcs->apconnstate = APCONN_ACTIVE;
-
- /* build NCCI: always 1 (one B3 connection only) */
- cmsg->adr.adrNCCI |= 1 << 16;
-
- /* NCPI parameter: not applicable for B3 Transparent */
- ignore_cstruct_param(cs, cmsg->NCPI, "CONNECT_B3_REQ", "NCPI");
- send_conf(iif, ap, skb,
- (cmsg->NCPI && cmsg->NCPI[0]) ?
- CapiNcpiNotSupportedByProtocol : CapiSuccess);
-}
-
-/*
- * process CONNECT_B3_RESP message
- * Depending on the Reject parameter, either emit CONNECT_B3_ACTIVE_IND
- * or queue EV_HUP and emit DISCONNECT_B3_IND.
- * The emitted message is always shorter than the received one,
- * allowing to reuse the skb.
- */
-static void do_connect_b3_resp(struct gigaset_capi_ctr *iif,
- struct gigaset_capi_appl *ap,
- struct sk_buff *skb)
-{
- struct cardstate *cs = iif->ctr.driverdata;
- _cmsg *cmsg = &iif->acmsg;
- struct bc_state *bcs;
- int channel;
- unsigned int msgsize;
- u8 command;
-
- /* decode message */
- if (capi_message2cmsg(cmsg, skb->data)) {
- dev_err(cs->dev, "%s: message parser failure\n", __func__);
- dev_kfree_skb_any(skb);
- return;
- }
- dump_cmsg(DEBUG_CMD, __func__, cmsg);
-
- /* extract and check channel number and NCCI */
- channel = (cmsg->adr.adrNCCI >> 8) & 0xff;
- if (!channel || channel > cs->channels ||
- ((cmsg->adr.adrNCCI >> 16) & 0xffff) != 1) {
- dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
- "CONNECT_B3_RESP", "NCCI", cmsg->adr.adrNCCI);
- dev_kfree_skb_any(skb);
- return;
- }
- bcs = &cs->bcs[channel - 1];
-
- if (cmsg->Reject) {
- /* Reject: clear B3 connect received flag */
- bcs->apconnstate = APCONN_SETUP;
-
- /* trigger hangup, causing eventual DISCONNECT_IND */
- if (!gigaset_add_event(cs, &bcs->at_state,
- EV_HUP, NULL, 0, NULL)) {
- dev_kfree_skb_any(skb);
- return;
- }
- gigaset_schedule_event(cs);
-
- /* emit DISCONNECT_B3_IND */
- command = CAPI_DISCONNECT_B3;
- msgsize = CAPI_DISCONNECT_B3_IND_BASELEN;
- } else {
- /*
- * Accept: emit CONNECT_B3_ACTIVE_IND immediately, as
- * we only send CONNECT_B3_IND if the B channel is up
- */
- command = CAPI_CONNECT_B3_ACTIVE;
- msgsize = CAPI_CONNECT_B3_ACTIVE_IND_BASELEN;
- }
- capi_cmsg_header(cmsg, ap->id, command, CAPI_IND,
- ap->nextMessageNumber++, cmsg->adr.adrNCCI);
- __skb_trim(skb, msgsize);
- if (capi_cmsg2message(cmsg, skb->data)) {
- dev_err(cs->dev, "%s: message parser failure\n", __func__);
- dev_kfree_skb_any(skb);
- return;
- }
- dump_cmsg(DEBUG_CMD, __func__, cmsg);
- capi_ctr_handle_message(&iif->ctr, ap->id, skb);
-}
-
-/*
- * process DISCONNECT_REQ message
- * schedule EV_HUP and emit DISCONNECT_B3_IND if necessary,
- * emit DISCONNECT_CONF reply
- */
-static void do_disconnect_req(struct gigaset_capi_ctr *iif,
- struct gigaset_capi_appl *ap,
- struct sk_buff *skb)
-{
- struct cardstate *cs = iif->ctr.driverdata;
- _cmsg *cmsg = &iif->acmsg;
- struct bc_state *bcs;
- _cmsg *b3cmsg;
- struct sk_buff *b3skb;
- int channel;
-
- /* decode message */
- if (capi_message2cmsg(cmsg, skb->data)) {
- dev_err(cs->dev, "%s: message parser failure\n", __func__);
- dev_kfree_skb_any(skb);
- return;
- }
- dump_cmsg(DEBUG_CMD, __func__, cmsg);
-
- /* extract and check channel number from PLCI */
- channel = (cmsg->adr.adrPLCI >> 8) & 0xff;
- if (!channel || channel > cs->channels) {
- dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
- "DISCONNECT_REQ", "PLCI", cmsg->adr.adrPLCI);
- send_conf(iif, ap, skb, CapiIllContrPlciNcci);
- return;
- }
- bcs = cs->bcs + channel - 1;
-
- /* ToDo: process parameter: Additional info */
- if (cmsg->AdditionalInfo != CAPI_DEFAULT) {
- ignore_cstruct_param(cs, cmsg->BChannelinformation,
- "DISCONNECT_REQ", "B Channel Information");
- ignore_cstruct_param(cs, cmsg->Keypadfacility,
- "DISCONNECT_REQ", "Keypad Facility");
- ignore_cstruct_param(cs, cmsg->Useruserdata,
- "DISCONNECT_REQ", "User-User Data");
- ignore_cstruct_param(cs, cmsg->Facilitydataarray,
- "DISCONNECT_REQ", "Facility Data Array");
- }
-
- /* skip if DISCONNECT_IND already sent */
- if (!bcs->apconnstate)
- return;
-
- /* check for active logical connection */
- if (bcs->apconnstate >= APCONN_ACTIVE) {
- /* clear it */
- bcs->apconnstate = APCONN_SETUP;
-
- /*
- * emit DISCONNECT_B3_IND with cause 0x3301
- * use separate cmsg structure, as the content of iif->acmsg
- * is still needed for creating the _CONF message
- */
- b3cmsg = kmalloc(sizeof(*b3cmsg), GFP_KERNEL);
- if (!b3cmsg) {
- dev_err(cs->dev, "%s: out of memory\n", __func__);
- send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
- return;
- }
- capi_cmsg_header(b3cmsg, ap->id, CAPI_DISCONNECT_B3, CAPI_IND,
- ap->nextMessageNumber++,
- cmsg->adr.adrPLCI | (1 << 16));
- b3cmsg->Reason_B3 = CapiProtocolErrorLayer1;
- b3skb = alloc_skb(CAPI_DISCONNECT_B3_IND_BASELEN, GFP_KERNEL);
- if (b3skb == NULL) {
- dev_err(cs->dev, "%s: out of memory\n", __func__);
- send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
- kfree(b3cmsg);
- return;
- }
- if (capi_cmsg2message(b3cmsg,
- __skb_put(b3skb, CAPI_DISCONNECT_B3_IND_BASELEN))) {
- dev_err(cs->dev, "%s: message parser failure\n",
- __func__);
- kfree(b3cmsg);
- dev_kfree_skb_any(b3skb);
- return;
- }
- dump_cmsg(DEBUG_CMD, __func__, b3cmsg);
- kfree(b3cmsg);
- capi_ctr_handle_message(&iif->ctr, ap->id, b3skb);
- }
-
- /* trigger hangup, causing eventual DISCONNECT_IND */
- if (!gigaset_add_event(cs, &bcs->at_state, EV_HUP, NULL, 0, NULL)) {
- send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
- return;
- }
- gigaset_schedule_event(cs);
-
- /* emit reply */
- send_conf(iif, ap, skb, CapiSuccess);
-}
-
-/*
- * process DISCONNECT_B3_REQ message
- * schedule EV_HUP and emit DISCONNECT_B3_CONF reply
- */
-static void do_disconnect_b3_req(struct gigaset_capi_ctr *iif,
- struct gigaset_capi_appl *ap,
- struct sk_buff *skb)
-{
- struct cardstate *cs = iif->ctr.driverdata;
- _cmsg *cmsg = &iif->acmsg;
- struct bc_state *bcs;
- int channel;
-
- /* decode message */
- if (capi_message2cmsg(cmsg, skb->data)) {
- dev_err(cs->dev, "%s: message parser failure\n", __func__);
- dev_kfree_skb_any(skb);
- return;
- }
- dump_cmsg(DEBUG_CMD, __func__, cmsg);
-
- /* extract and check channel number and NCCI */
- channel = (cmsg->adr.adrNCCI >> 8) & 0xff;
- if (!channel || channel > cs->channels ||
- ((cmsg->adr.adrNCCI >> 16) & 0xffff) != 1) {
- dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
- "DISCONNECT_B3_REQ", "NCCI", cmsg->adr.adrNCCI);
- send_conf(iif, ap, skb, CapiIllContrPlciNcci);
- return;
- }
- bcs = &cs->bcs[channel - 1];
-
- /* reject if logical connection not active */
- if (bcs->apconnstate < APCONN_ACTIVE) {
- send_conf(iif, ap, skb,
- CapiMessageNotSupportedInCurrentState);
- return;
- }
-
- /* trigger hangup, causing eventual DISCONNECT_B3_IND */
- if (!gigaset_add_event(cs, &bcs->at_state, EV_HUP, NULL, 0, NULL)) {
- send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
- return;
- }
- gigaset_schedule_event(cs);
-
- /* NCPI parameter: not applicable for B3 Transparent */
- ignore_cstruct_param(cs, cmsg->NCPI,
- "DISCONNECT_B3_REQ", "NCPI");
- send_conf(iif, ap, skb,
- (cmsg->NCPI && cmsg->NCPI[0]) ?
- CapiNcpiNotSupportedByProtocol : CapiSuccess);
-}
-
-/*
- * process DATA_B3_REQ message
- */
-static void do_data_b3_req(struct gigaset_capi_ctr *iif,
- struct gigaset_capi_appl *ap,
- struct sk_buff *skb)
-{
- struct cardstate *cs = iif->ctr.driverdata;
- struct bc_state *bcs;
- int channel = CAPIMSG_PLCI_PART(skb->data);
- u16 ncci = CAPIMSG_NCCI_PART(skb->data);
- u16 msglen = CAPIMSG_LEN(skb->data);
- u16 datalen = CAPIMSG_DATALEN(skb->data);
- u16 flags = CAPIMSG_FLAGS(skb->data);
- u16 msgid = CAPIMSG_MSGID(skb->data);
- u16 handle = CAPIMSG_HANDLE_REQ(skb->data);
-
- /* frequent message, avoid _cmsg overhead */
- dump_rawmsg(DEBUG_MCMD, __func__, skb->data);
-
- /* check parameters */
- if (channel == 0 || channel > cs->channels || ncci != 1) {
- dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
- "DATA_B3_REQ", "NCCI", CAPIMSG_NCCI(skb->data));
- send_conf(iif, ap, skb, CapiIllContrPlciNcci);
- return;
- }
- bcs = &cs->bcs[channel - 1];
- if (msglen != CAPI_DATA_B3_REQ_LEN && msglen != CAPI_DATA_B3_REQ_LEN64)
- dev_notice(cs->dev, "%s: unexpected length %d\n",
- "DATA_B3_REQ", msglen);
- if (msglen + datalen != skb->len)
- dev_notice(cs->dev, "%s: length mismatch (%d+%d!=%d)\n",
- "DATA_B3_REQ", msglen, datalen, skb->len);
- if (msglen + datalen > skb->len) {
- /* message too short for announced data length */
- send_conf(iif, ap, skb, CapiIllMessageParmCoding); /* ? */
- return;
- }
- if (flags & CAPI_FLAGS_RESERVED) {
- dev_notice(cs->dev, "%s: reserved flags set (%x)\n",
- "DATA_B3_REQ", flags);
- send_conf(iif, ap, skb, CapiIllMessageParmCoding);
- return;
- }
-
- /* reject if logical connection not active */
- if (bcs->apconnstate < APCONN_ACTIVE) {
- send_conf(iif, ap, skb, CapiMessageNotSupportedInCurrentState);
- return;
- }
-
- /* pull CAPI message into link layer header */
- skb_reset_mac_header(skb);
- skb->mac_len = msglen;
- skb_pull(skb, msglen);
-
- /* pass to device-specific module */
- if (cs->ops->send_skb(bcs, skb) < 0) {
- send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
- return;
- }
-
- /*
- * DATA_B3_CONF will be sent by gigaset_skb_sent() only if "delivery
- * confirmation" bit is set; otherwise we have to send it now
- */
- if (!(flags & CAPI_FLAGS_DELIVERY_CONFIRMATION))
- send_data_b3_conf(cs, &iif->ctr, ap->id, msgid, channel, handle,
- flags ? CapiFlagsNotSupportedByProtocol
- : CAPI_NOERROR);
-}
-
-/*
- * process RESET_B3_REQ message
- * just always reply "not supported by current protocol"
- */
-static void do_reset_b3_req(struct gigaset_capi_ctr *iif,
- struct gigaset_capi_appl *ap,
- struct sk_buff *skb)
-{
- struct cardstate *cs = iif->ctr.driverdata;
-
- /* decode message */
- if (capi_message2cmsg(&iif->acmsg, skb->data)) {
- dev_err(cs->dev, "%s: message parser failure\n", __func__);
- dev_kfree_skb_any(skb);
- return;
- }
- dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
- send_conf(iif, ap, skb,
- CapiResetProcedureNotSupportedByCurrentProtocol);
-}
-
-/*
- * unsupported CAPI message handler
- */
-static void do_unsupported(struct gigaset_capi_ctr *iif,
- struct gigaset_capi_appl *ap,
- struct sk_buff *skb)
-{
- struct cardstate *cs = iif->ctr.driverdata;
-
- /* decode message */
- if (capi_message2cmsg(&iif->acmsg, skb->data)) {
- dev_err(cs->dev, "%s: message parser failure\n", __func__);
- dev_kfree_skb_any(skb);
- return;
- }
- dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
- send_conf(iif, ap, skb, CapiMessageNotSupportedInCurrentState);
-}
-
-/*
- * CAPI message handler: no-op
- */
-static void do_nothing(struct gigaset_capi_ctr *iif,
- struct gigaset_capi_appl *ap,
- struct sk_buff *skb)
-{
- struct cardstate *cs = iif->ctr.driverdata;
-
- /* decode message */
- if (capi_message2cmsg(&iif->acmsg, skb->data)) {
- dev_err(cs->dev, "%s: message parser failure\n", __func__);
- dev_kfree_skb_any(skb);
- return;
- }
- dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
- dev_kfree_skb_any(skb);
-}
-
-static void do_data_b3_resp(struct gigaset_capi_ctr *iif,
- struct gigaset_capi_appl *ap,
- struct sk_buff *skb)
-{
- dump_rawmsg(DEBUG_MCMD, __func__, skb->data);
- dev_kfree_skb_any(skb);
-}
-
-/* table of outgoing CAPI message handlers with lookup function */
-typedef void (*capi_send_handler_t)(struct gigaset_capi_ctr *,
- struct gigaset_capi_appl *,
- struct sk_buff *);
-
-static struct {
- u16 cmd;
- capi_send_handler_t handler;
-} capi_send_handler_table[] = {
- /* most frequent messages first for faster lookup */
- { CAPI_DATA_B3_REQ, do_data_b3_req },
- { CAPI_DATA_B3_RESP, do_data_b3_resp },
-
- { CAPI_ALERT_REQ, do_alert_req },
- { CAPI_CONNECT_ACTIVE_RESP, do_nothing },
- { CAPI_CONNECT_B3_ACTIVE_RESP, do_nothing },
- { CAPI_CONNECT_B3_REQ, do_connect_b3_req },
- { CAPI_CONNECT_B3_RESP, do_connect_b3_resp },
- { CAPI_CONNECT_B3_T90_ACTIVE_RESP, do_nothing },
- { CAPI_CONNECT_REQ, do_connect_req },
- { CAPI_CONNECT_RESP, do_connect_resp },
- { CAPI_DISCONNECT_B3_REQ, do_disconnect_b3_req },
- { CAPI_DISCONNECT_B3_RESP, do_nothing },
- { CAPI_DISCONNECT_REQ, do_disconnect_req },
- { CAPI_DISCONNECT_RESP, do_nothing },
- { CAPI_FACILITY_REQ, do_facility_req },
- { CAPI_FACILITY_RESP, do_nothing },
- { CAPI_LISTEN_REQ, do_listen_req },
- { CAPI_SELECT_B_PROTOCOL_REQ, do_unsupported },
- { CAPI_RESET_B3_REQ, do_reset_b3_req },
- { CAPI_RESET_B3_RESP, do_nothing },
-
- /*
- * ToDo: support overlap sending (requires ev-layer state
- * machine extension to generate additional ATD commands)
- */
- { CAPI_INFO_REQ, do_unsupported },
- { CAPI_INFO_RESP, do_nothing },
-
- /*
- * ToDo: what's the proper response for these?
- */
- { CAPI_MANUFACTURER_REQ, do_nothing },
- { CAPI_MANUFACTURER_RESP, do_nothing },
-};
-
-/* look up handler */
-static inline capi_send_handler_t lookup_capi_send_handler(const u16 cmd)
-{
- size_t i;
-
- for (i = 0; i < ARRAY_SIZE(capi_send_handler_table); i++)
- if (capi_send_handler_table[i].cmd == cmd)
- return capi_send_handler_table[i].handler;
- return NULL;
-}
-
-
-/**
- * gigaset_send_message() - accept a CAPI message from an application
- * @ctr: controller descriptor structure.
- * @skb: CAPI message.
- *
- * Return value: CAPI error code
- * Note: capidrv (and probably others, too) only uses the return value to
- * decide whether it has to free the skb (only if result != CAPI_NOERROR (0))
- */
-static u16 gigaset_send_message(struct capi_ctr *ctr, struct sk_buff *skb)
-{
- struct gigaset_capi_ctr *iif
- = container_of(ctr, struct gigaset_capi_ctr, ctr);
- struct cardstate *cs = ctr->driverdata;
- struct gigaset_capi_appl *ap;
- capi_send_handler_t handler;
-
- /* can only handle linear sk_buffs */
- if (skb_linearize(skb) < 0) {
- dev_warn(cs->dev, "%s: skb_linearize failed\n", __func__);
- return CAPI_MSGOSRESOURCEERR;
- }
-
- /* retrieve application data structure */
- ap = get_appl(iif, CAPIMSG_APPID(skb->data));
- if (!ap) {
- dev_notice(cs->dev, "%s: application %u not registered\n",
- __func__, CAPIMSG_APPID(skb->data));
- return CAPI_ILLAPPNR;
- }
-
- /* look up command */
- handler = lookup_capi_send_handler(CAPIMSG_CMD(skb->data));
- if (!handler) {
- /* unknown/unsupported message type */
- if (printk_ratelimit())
- dev_notice(cs->dev, "%s: unsupported message %u\n",
- __func__, CAPIMSG_CMD(skb->data));
- return CAPI_ILLCMDORSUBCMDORMSGTOSMALL;
- }
-
- /* serialize */
- if (atomic_add_return(1, &iif->sendqlen) > 1) {
- /* queue behind other messages */
- skb_queue_tail(&iif->sendqueue, skb);
- return CAPI_NOERROR;
- }
-
- /* process message */
- handler(iif, ap, skb);
-
- /* process other messages arrived in the meantime */
- while (atomic_sub_return(1, &iif->sendqlen) > 0) {
- skb = skb_dequeue(&iif->sendqueue);
- if (!skb) {
- /* should never happen */
- dev_err(cs->dev, "%s: send queue empty\n", __func__);
- continue;
- }
- ap = get_appl(iif, CAPIMSG_APPID(skb->data));
- if (!ap) {
- /* could that happen? */
- dev_warn(cs->dev, "%s: application %u vanished\n",
- __func__, CAPIMSG_APPID(skb->data));
- continue;
- }
- handler = lookup_capi_send_handler(CAPIMSG_CMD(skb->data));
- if (!handler) {
- /* should never happen */
- dev_err(cs->dev, "%s: handler %x vanished\n",
- __func__, CAPIMSG_CMD(skb->data));
- continue;
- }
- handler(iif, ap, skb);
- }
-
- return CAPI_NOERROR;
-}
-
-/**
- * gigaset_procinfo() - build single line description for controller
- * @ctr: controller descriptor structure.
- *
- * Return value: pointer to generated string (null terminated)
- */
-static char *gigaset_procinfo(struct capi_ctr *ctr)
-{
- return ctr->name; /* ToDo: more? */
-}
-
-static int gigaset_proc_show(struct seq_file *m, void *v)
-{
- struct capi_ctr *ctr = m->private;
- struct cardstate *cs = ctr->driverdata;
- char *s;
- int i;
-
- seq_printf(m, "%-16s %s\n", "name", ctr->name);
- seq_printf(m, "%-16s %s %s\n", "dev",
- dev_driver_string(cs->dev), dev_name(cs->dev));
- seq_printf(m, "%-16s %d\n", "id", cs->myid);
- if (cs->gotfwver)
- seq_printf(m, "%-16s %d.%d.%d.%d\n", "firmware",
- cs->fwver[0], cs->fwver[1], cs->fwver[2], cs->fwver[3]);
- seq_printf(m, "%-16s %d\n", "channels", cs->channels);
- seq_printf(m, "%-16s %s\n", "onechannel", cs->onechannel ? "yes" : "no");
-
- switch (cs->mode) {
- case M_UNKNOWN:
- s = "unknown";
- break;
- case M_CONFIG:
- s = "config";
- break;
- case M_UNIMODEM:
- s = "Unimodem";
- break;
- case M_CID:
- s = "CID";
- break;
- default:
- s = "??";
- }
- seq_printf(m, "%-16s %s\n", "mode", s);
-
- switch (cs->mstate) {
- case MS_UNINITIALIZED:
- s = "uninitialized";
- break;
- case MS_INIT:
- s = "init";
- break;
- case MS_LOCKED:
- s = "locked";
- break;
- case MS_SHUTDOWN:
- s = "shutdown";
- break;
- case MS_RECOVER:
- s = "recover";
- break;
- case MS_READY:
- s = "ready";
- break;
- default:
- s = "??";
- }
- seq_printf(m, "%-16s %s\n", "mstate", s);
-
- seq_printf(m, "%-16s %s\n", "running", cs->running ? "yes" : "no");
- seq_printf(m, "%-16s %s\n", "connected", cs->connected ? "yes" : "no");
- seq_printf(m, "%-16s %s\n", "isdn_up", cs->isdn_up ? "yes" : "no");
- seq_printf(m, "%-16s %s\n", "cidmode", cs->cidmode ? "yes" : "no");
-
- for (i = 0; i < cs->channels; i++) {
- seq_printf(m, "[%d]%-13s %d\n", i, "corrupted",
- cs->bcs[i].corrupted);
- seq_printf(m, "[%d]%-13s %d\n", i, "trans_down",
- cs->bcs[i].trans_down);
- seq_printf(m, "[%d]%-13s %d\n", i, "trans_up",
- cs->bcs[i].trans_up);
- seq_printf(m, "[%d]%-13s %d\n", i, "chstate",
- cs->bcs[i].chstate);
- switch (cs->bcs[i].proto2) {
- case L2_BITSYNC:
- s = "bitsync";
- break;
- case L2_HDLC:
- s = "HDLC";
- break;
- case L2_VOICE:
- s = "voice";
- break;
- default:
- s = "??";
- }
- seq_printf(m, "[%d]%-13s %s\n", i, "proto2", s);
- }
- return 0;
-}
-
-/**
- * gigaset_isdn_regdev() - register device to LL
- * @cs: device descriptor structure.
- * @isdnid: device name.
- *
- * Return value: 0 on success, error code < 0 on failure
- */
-int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid)
-{
- struct gigaset_capi_ctr *iif;
- int rc;
-
- iif = kzalloc(sizeof(*iif), GFP_KERNEL);
- if (!iif) {
- pr_err("%s: out of memory\n", __func__);
- return -ENOMEM;
- }
-
- /* prepare controller structure */
- iif->ctr.owner = THIS_MODULE;
- iif->ctr.driverdata = cs;
- strncpy(iif->ctr.name, isdnid, sizeof(iif->ctr.name) - 1);
- iif->ctr.driver_name = "gigaset";
- iif->ctr.load_firmware = NULL;
- iif->ctr.reset_ctr = NULL;
- iif->ctr.register_appl = gigaset_register_appl;
- iif->ctr.release_appl = gigaset_release_appl;
- iif->ctr.send_message = gigaset_send_message;
- iif->ctr.procinfo = gigaset_procinfo;
- iif->ctr.proc_show = gigaset_proc_show,
- INIT_LIST_HEAD(&iif->appls);
- skb_queue_head_init(&iif->sendqueue);
- atomic_set(&iif->sendqlen, 0);
-
- /* register controller with CAPI */
- rc = attach_capi_ctr(&iif->ctr);
- if (rc) {
- pr_err("attach_capi_ctr failed (%d)\n", rc);
- kfree(iif);
- return rc;
- }
-
- cs->iif = iif;
- cs->hw_hdr_len = CAPI_DATA_B3_REQ_LEN;
- return 0;
-}
-
-/**
- * gigaset_isdn_unregdev() - unregister device from LL
- * @cs: device descriptor structure.
- */
-void gigaset_isdn_unregdev(struct cardstate *cs)
-{
- struct gigaset_capi_ctr *iif = cs->iif;
-
- detach_capi_ctr(&iif->ctr);
- kfree(iif);
- cs->iif = NULL;
-}
-
-static struct capi_driver capi_driver_gigaset = {
- .name = "gigaset",
- .revision = "1.0",
-};
-
-/**
- * gigaset_isdn_regdrv() - register driver to LL
- */
-void gigaset_isdn_regdrv(void)
-{
- pr_info("Kernel CAPI interface\n");
- register_capi_driver(&capi_driver_gigaset);
-}
-
-/**
- * gigaset_isdn_unregdrv() - unregister driver from LL
- */
-void gigaset_isdn_unregdrv(void)
-{
- unregister_capi_driver(&capi_driver_gigaset);
-}
diff --git a/drivers/staging/isdn/gigaset/common.c b/drivers/staging/isdn/gigaset/common.c
deleted file mode 100644
index 3bb8092858ab..000000000000
--- a/drivers/staging/isdn/gigaset/common.c
+++ /dev/null
@@ -1,1153 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Stuff used by all variants of the driver
- *
- * Copyright (c) 2001 by Stefan Eilers,
- * Hansjoerg Lipp <hjlipp@web.de>,
- * Tilman Schmidt <tilman@imap.cc>.
- *
- * =====================================================================
- * =====================================================================
- */
-
-#include "gigaset.h"
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-
-/* Version Information */
-#define DRIVER_AUTHOR "Hansjoerg Lipp <hjlipp@web.de>, Tilman Schmidt <tilman@imap.cc>, Stefan Eilers"
-#define DRIVER_DESC "Driver for Gigaset 307x"
-
-#ifdef CONFIG_GIGASET_DEBUG
-#define DRIVER_DESC_DEBUG " (debug build)"
-#else
-#define DRIVER_DESC_DEBUG ""
-#endif
-
-/* Module parameters */
-int gigaset_debuglevel;
-EXPORT_SYMBOL_GPL(gigaset_debuglevel);
-module_param_named(debug, gigaset_debuglevel, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "debug level");
-
-/* driver state flags */
-#define VALID_MINOR 0x01
-#define VALID_ID 0x02
-
-/**
- * gigaset_dbg_buffer() - dump data in ASCII and hex for debugging
- * @level: debugging level.
- * @msg: message prefix.
- * @len: number of bytes to dump.
- * @buf: data to dump.
- *
- * If the current debugging level includes one of the bits set in @level,
- * @len bytes starting at @buf are logged to dmesg at KERN_DEBUG prio,
- * prefixed by the text @msg.
- */
-void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg,
- size_t len, const unsigned char *buf)
-{
- unsigned char outbuf[80];
- unsigned char c;
- size_t space = sizeof outbuf - 1;
- unsigned char *out = outbuf;
- size_t numin = len;
-
- while (numin--) {
- c = *buf++;
- if (c == '~' || c == '^' || c == '\\') {
- if (!space--)
- break;
- *out++ = '\\';
- }
- if (c & 0x80) {
- if (!space--)
- break;
- *out++ = '~';
- c ^= 0x80;
- }
- if (c < 0x20 || c == 0x7f) {
- if (!space--)
- break;
- *out++ = '^';
- c ^= 0x40;
- }
- if (!space--)
- break;
- *out++ = c;
- }
- *out = 0;
-
- gig_dbg(level, "%s (%u bytes): %s", msg, (unsigned) len, outbuf);
-}
-EXPORT_SYMBOL_GPL(gigaset_dbg_buffer);
-
-static int setflags(struct cardstate *cs, unsigned flags, unsigned delay)
-{
- int r;
-
- r = cs->ops->set_modem_ctrl(cs, cs->control_state, flags);
- cs->control_state = flags;
- if (r < 0)
- return r;
-
- if (delay) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(delay * HZ / 1000);
- }
-
- return 0;
-}
-
-int gigaset_enterconfigmode(struct cardstate *cs)
-{
- int i, r;
-
- cs->control_state = TIOCM_RTS;
-
- r = setflags(cs, TIOCM_DTR, 200);
- if (r < 0)
- goto error;
- r = setflags(cs, 0, 200);
- if (r < 0)
- goto error;
- for (i = 0; i < 5; ++i) {
- r = setflags(cs, TIOCM_RTS, 100);
- if (r < 0)
- goto error;
- r = setflags(cs, 0, 100);
- if (r < 0)
- goto error;
- }
- r = setflags(cs, TIOCM_RTS | TIOCM_DTR, 800);
- if (r < 0)
- goto error;
-
- return 0;
-
-error:
- dev_err(cs->dev, "error %d on setuartbits\n", -r);
- cs->control_state = TIOCM_RTS | TIOCM_DTR;
- cs->ops->set_modem_ctrl(cs, 0, TIOCM_RTS | TIOCM_DTR);
-
- return -1;
-}
-
-static int test_timeout(struct at_state_t *at_state)
-{
- if (!at_state->timer_expires)
- return 0;
-
- if (--at_state->timer_expires) {
- gig_dbg(DEBUG_MCMD, "decreased timer of %p to %lu",
- at_state, at_state->timer_expires);
- return 0;
- }
-
- gigaset_add_event(at_state->cs, at_state, EV_TIMEOUT, NULL,
- at_state->timer_index, NULL);
- return 1;
-}
-
-static void timer_tick(struct timer_list *t)
-{
- struct cardstate *cs = from_timer(cs, t, timer);
- unsigned long flags;
- unsigned channel;
- struct at_state_t *at_state;
- int timeout = 0;
-
- spin_lock_irqsave(&cs->lock, flags);
-
- for (channel = 0; channel < cs->channels; ++channel)
- if (test_timeout(&cs->bcs[channel].at_state))
- timeout = 1;
-
- if (test_timeout(&cs->at_state))
- timeout = 1;
-
- list_for_each_entry(at_state, &cs->temp_at_states, list)
- if (test_timeout(at_state))
- timeout = 1;
-
- if (cs->running) {
- mod_timer(&cs->timer, jiffies + msecs_to_jiffies(GIG_TICK));
- if (timeout) {
- gig_dbg(DEBUG_EVENT, "scheduling timeout");
- tasklet_schedule(&cs->event_tasklet);
- }
- }
-
- spin_unlock_irqrestore(&cs->lock, flags);
-}
-
-int gigaset_get_channel(struct bc_state *bcs)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&bcs->cs->lock, flags);
- if (bcs->use_count || !try_module_get(bcs->cs->driver->owner)) {
- gig_dbg(DEBUG_CHANNEL, "could not allocate channel %d",
- bcs->channel);
- spin_unlock_irqrestore(&bcs->cs->lock, flags);
- return -EBUSY;
- }
- ++bcs->use_count;
- bcs->busy = 1;
- gig_dbg(DEBUG_CHANNEL, "allocated channel %d", bcs->channel);
- spin_unlock_irqrestore(&bcs->cs->lock, flags);
- return 0;
-}
-
-struct bc_state *gigaset_get_free_channel(struct cardstate *cs)
-{
- unsigned long flags;
- int i;
-
- spin_lock_irqsave(&cs->lock, flags);
- if (!try_module_get(cs->driver->owner)) {
- gig_dbg(DEBUG_CHANNEL,
- "could not get module for allocating channel");
- spin_unlock_irqrestore(&cs->lock, flags);
- return NULL;
- }
- for (i = 0; i < cs->channels; ++i)
- if (!cs->bcs[i].use_count) {
- ++cs->bcs[i].use_count;
- cs->bcs[i].busy = 1;
- spin_unlock_irqrestore(&cs->lock, flags);
- gig_dbg(DEBUG_CHANNEL, "allocated channel %d", i);
- return cs->bcs + i;
- }
- module_put(cs->driver->owner);
- spin_unlock_irqrestore(&cs->lock, flags);
- gig_dbg(DEBUG_CHANNEL, "no free channel");
- return NULL;
-}
-
-void gigaset_free_channel(struct bc_state *bcs)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&bcs->cs->lock, flags);
- if (!bcs->busy) {
- gig_dbg(DEBUG_CHANNEL, "could not free channel %d",
- bcs->channel);
- spin_unlock_irqrestore(&bcs->cs->lock, flags);
- return;
- }
- --bcs->use_count;
- bcs->busy = 0;
- module_put(bcs->cs->driver->owner);
- gig_dbg(DEBUG_CHANNEL, "freed channel %d", bcs->channel);
- spin_unlock_irqrestore(&bcs->cs->lock, flags);
-}
-
-int gigaset_get_channels(struct cardstate *cs)
-{
- unsigned long flags;
- int i;
-
- spin_lock_irqsave(&cs->lock, flags);
- for (i = 0; i < cs->channels; ++i)
- if (cs->bcs[i].use_count) {
- spin_unlock_irqrestore(&cs->lock, flags);
- gig_dbg(DEBUG_CHANNEL,
- "could not allocate all channels");
- return -EBUSY;
- }
- for (i = 0; i < cs->channels; ++i)
- ++cs->bcs[i].use_count;
- spin_unlock_irqrestore(&cs->lock, flags);
-
- gig_dbg(DEBUG_CHANNEL, "allocated all channels");
-
- return 0;
-}
-
-void gigaset_free_channels(struct cardstate *cs)
-{
- unsigned long flags;
- int i;
-
- gig_dbg(DEBUG_CHANNEL, "unblocking all channels");
- spin_lock_irqsave(&cs->lock, flags);
- for (i = 0; i < cs->channels; ++i)
- --cs->bcs[i].use_count;
- spin_unlock_irqrestore(&cs->lock, flags);
-}
-
-void gigaset_block_channels(struct cardstate *cs)
-{
- unsigned long flags;
- int i;
-
- gig_dbg(DEBUG_CHANNEL, "blocking all channels");
- spin_lock_irqsave(&cs->lock, flags);
- for (i = 0; i < cs->channels; ++i)
- ++cs->bcs[i].use_count;
- spin_unlock_irqrestore(&cs->lock, flags);
-}
-
-static void clear_events(struct cardstate *cs)
-{
- struct event_t *ev;
- unsigned head, tail;
- unsigned long flags;
-
- spin_lock_irqsave(&cs->ev_lock, flags);
-
- head = cs->ev_head;
- tail = cs->ev_tail;
-
- while (tail != head) {
- ev = cs->events + head;
- kfree(ev->ptr);
- head = (head + 1) % MAX_EVENTS;
- }
-
- cs->ev_head = tail;
-
- spin_unlock_irqrestore(&cs->ev_lock, flags);
-}
-
-/**
- * gigaset_add_event() - add event to device event queue
- * @cs: device descriptor structure.
- * @at_state: connection state structure.
- * @type: event type.
- * @ptr: pointer parameter for event.
- * @parameter: integer parameter for event.
- * @arg: pointer parameter for event.
- *
- * Allocate an event queue entry from the device's event queue, and set it up
- * with the parameters given.
- *
- * Return value: added event
- */
-struct event_t *gigaset_add_event(struct cardstate *cs,
- struct at_state_t *at_state, int type,
- void *ptr, int parameter, void *arg)
-{
- unsigned long flags;
- unsigned next, tail;
- struct event_t *event = NULL;
-
- gig_dbg(DEBUG_EVENT, "queueing event %d", type);
-
- spin_lock_irqsave(&cs->ev_lock, flags);
-
- tail = cs->ev_tail;
- next = (tail + 1) % MAX_EVENTS;
- if (unlikely(next == cs->ev_head))
- dev_err(cs->dev, "event queue full\n");
- else {
- event = cs->events + tail;
- event->type = type;
- event->at_state = at_state;
- event->cid = -1;
- event->ptr = ptr;
- event->arg = arg;
- event->parameter = parameter;
- cs->ev_tail = next;
- }
-
- spin_unlock_irqrestore(&cs->ev_lock, flags);
-
- return event;
-}
-EXPORT_SYMBOL_GPL(gigaset_add_event);
-
-static void clear_at_state(struct at_state_t *at_state)
-{
- int i;
-
- for (i = 0; i < STR_NUM; ++i) {
- kfree(at_state->str_var[i]);
- at_state->str_var[i] = NULL;
- }
-}
-
-static void dealloc_temp_at_states(struct cardstate *cs)
-{
- struct at_state_t *cur, *next;
-
- list_for_each_entry_safe(cur, next, &cs->temp_at_states, list) {
- list_del(&cur->list);
- clear_at_state(cur);
- kfree(cur);
- }
-}
-
-static void gigaset_freebcs(struct bc_state *bcs)
-{
- int i;
-
- gig_dbg(DEBUG_INIT, "freeing bcs[%d]->hw", bcs->channel);
- bcs->cs->ops->freebcshw(bcs);
-
- gig_dbg(DEBUG_INIT, "clearing bcs[%d]->at_state", bcs->channel);
- clear_at_state(&bcs->at_state);
- gig_dbg(DEBUG_INIT, "freeing bcs[%d]->skb", bcs->channel);
- dev_kfree_skb(bcs->rx_skb);
- bcs->rx_skb = NULL;
-
- for (i = 0; i < AT_NUM; ++i) {
- kfree(bcs->commands[i]);
- bcs->commands[i] = NULL;
- }
-}
-
-static struct cardstate *alloc_cs(struct gigaset_driver *drv)
-{
- unsigned long flags;
- unsigned i;
- struct cardstate *cs;
- struct cardstate *ret = NULL;
-
- spin_lock_irqsave(&drv->lock, flags);
- if (drv->blocked)
- goto exit;
- for (i = 0; i < drv->minors; ++i) {
- cs = drv->cs + i;
- if (!(cs->flags & VALID_MINOR)) {
- cs->flags = VALID_MINOR;
- ret = cs;
- break;
- }
- }
-exit:
- spin_unlock_irqrestore(&drv->lock, flags);
- return ret;
-}
-
-static void free_cs(struct cardstate *cs)
-{
- cs->flags = 0;
-}
-
-static void make_valid(struct cardstate *cs, unsigned mask)
-{
- unsigned long flags;
- struct gigaset_driver *drv = cs->driver;
- spin_lock_irqsave(&drv->lock, flags);
- cs->flags |= mask;
- spin_unlock_irqrestore(&drv->lock, flags);
-}
-
-static void make_invalid(struct cardstate *cs, unsigned mask)
-{
- unsigned long flags;
- struct gigaset_driver *drv = cs->driver;
- spin_lock_irqsave(&drv->lock, flags);
- cs->flags &= ~mask;
- spin_unlock_irqrestore(&drv->lock, flags);
-}
-
-/**
- * gigaset_freecs() - free all associated ressources of a device
- * @cs: device descriptor structure.
- *
- * Stops all tasklets and timers, unregisters the device from all
- * subsystems it was registered to, deallocates the device structure
- * @cs and all structures referenced from it.
- * Operations on the device should be stopped before calling this.
- */
-void gigaset_freecs(struct cardstate *cs)
-{
- int i;
- unsigned long flags;
-
- if (!cs)
- return;
-
- mutex_lock(&cs->mutex);
-
- spin_lock_irqsave(&cs->lock, flags);
- cs->running = 0;
- spin_unlock_irqrestore(&cs->lock, flags); /* event handler and timer are
- not rescheduled below */
-
- tasklet_kill(&cs->event_tasklet);
- del_timer_sync(&cs->timer);
-
- switch (cs->cs_init) {
- default:
- /* clear B channel structures */
- for (i = 0; i < cs->channels; ++i) {
- gig_dbg(DEBUG_INIT, "clearing bcs[%d]", i);
- gigaset_freebcs(cs->bcs + i);
- }
-
- /* clear device sysfs */
- gigaset_free_dev_sysfs(cs);
-
- gigaset_if_free(cs);
-
- gig_dbg(DEBUG_INIT, "clearing hw");
- cs->ops->freecshw(cs);
-
- /* fall through */
- case 2: /* error in initcshw */
- /* Deregister from LL */
- make_invalid(cs, VALID_ID);
- gigaset_isdn_unregdev(cs);
-
- /* fall through */
- case 1: /* error when registering to LL */
- gig_dbg(DEBUG_INIT, "clearing at_state");
- clear_at_state(&cs->at_state);
- dealloc_temp_at_states(cs);
- clear_events(cs);
- tty_port_destroy(&cs->port);
-
- /* fall through */
- case 0: /* error in basic setup */
- gig_dbg(DEBUG_INIT, "freeing inbuf");
- kfree(cs->inbuf);
- kfree(cs->bcs);
- }
-
- mutex_unlock(&cs->mutex);
- free_cs(cs);
-}
-EXPORT_SYMBOL_GPL(gigaset_freecs);
-
-void gigaset_at_init(struct at_state_t *at_state, struct bc_state *bcs,
- struct cardstate *cs, int cid)
-{
- int i;
-
- INIT_LIST_HEAD(&at_state->list);
- at_state->waiting = 0;
- at_state->getstring = 0;
- at_state->pending_commands = 0;
- at_state->timer_expires = 0;
- at_state->timer_active = 0;
- at_state->timer_index = 0;
- at_state->seq_index = 0;
- at_state->ConState = 0;
- for (i = 0; i < STR_NUM; ++i)
- at_state->str_var[i] = NULL;
- at_state->int_var[VAR_ZDLE] = 0;
- at_state->int_var[VAR_ZCTP] = -1;
- at_state->int_var[VAR_ZSAU] = ZSAU_NULL;
- at_state->cs = cs;
- at_state->bcs = bcs;
- at_state->cid = cid;
- if (!cid)
- at_state->replystruct = cs->tabnocid;
- else
- at_state->replystruct = cs->tabcid;
-}
-
-
-static void gigaset_inbuf_init(struct inbuf_t *inbuf, struct cardstate *cs)
-/* inbuf->read must be allocated before! */
-{
- inbuf->head = 0;
- inbuf->tail = 0;
- inbuf->cs = cs;
- inbuf->inputstate = INS_command;
-}
-
-/**
- * gigaset_fill_inbuf() - append received data to input buffer
- * @inbuf: buffer structure.
- * @src: received data.
- * @numbytes: number of bytes received.
- *
- * Return value: !=0 if some data was appended
- */
-int gigaset_fill_inbuf(struct inbuf_t *inbuf, const unsigned char *src,
- unsigned numbytes)
-{
- unsigned n, head, tail, bytesleft;
-
- gig_dbg(DEBUG_INTR, "received %u bytes", numbytes);
-
- if (!numbytes)
- return 0;
-
- bytesleft = numbytes;
- tail = inbuf->tail;
- head = inbuf->head;
- gig_dbg(DEBUG_INTR, "buffer state: %u -> %u", head, tail);
-
- while (bytesleft) {
- if (head > tail)
- n = head - 1 - tail;
- else if (head == 0)
- n = (RBUFSIZE - 1) - tail;
- else
- n = RBUFSIZE - tail;
- if (!n) {
- dev_err(inbuf->cs->dev,
- "buffer overflow (%u bytes lost)\n",
- bytesleft);
- break;
- }
- if (n > bytesleft)
- n = bytesleft;
- memcpy(inbuf->data + tail, src, n);
- bytesleft -= n;
- tail = (tail + n) % RBUFSIZE;
- src += n;
- }
- gig_dbg(DEBUG_INTR, "setting tail to %u", tail);
- inbuf->tail = tail;
- return numbytes != bytesleft;
-}
-EXPORT_SYMBOL_GPL(gigaset_fill_inbuf);
-
-/* Initialize the b-channel structure */
-static int gigaset_initbcs(struct bc_state *bcs, struct cardstate *cs,
- int channel)
-{
- int i;
-
- bcs->tx_skb = NULL;
-
- skb_queue_head_init(&bcs->squeue);
-
- bcs->corrupted = 0;
- bcs->trans_down = 0;
- bcs->trans_up = 0;
-
- gig_dbg(DEBUG_INIT, "setting up bcs[%d]->at_state", channel);
- gigaset_at_init(&bcs->at_state, bcs, cs, -1);
-
-#ifdef CONFIG_GIGASET_DEBUG
- bcs->emptycount = 0;
-#endif
-
- bcs->rx_bufsize = 0;
- bcs->rx_skb = NULL;
- bcs->rx_fcs = PPP_INITFCS;
- bcs->inputstate = 0;
- bcs->channel = channel;
- bcs->cs = cs;
-
- bcs->chstate = 0;
- bcs->use_count = 1;
- bcs->busy = 0;
- bcs->ignore = cs->ignoreframes;
-
- for (i = 0; i < AT_NUM; ++i)
- bcs->commands[i] = NULL;
-
- spin_lock_init(&bcs->aplock);
- bcs->ap = NULL;
- bcs->apconnstate = 0;
-
- gig_dbg(DEBUG_INIT, " setting up bcs[%d]->hw", channel);
- return cs->ops->initbcshw(bcs);
-}
-
-/**
- * gigaset_initcs() - initialize device structure
- * @drv: hardware driver the device belongs to
- * @channels: number of B channels supported by device
- * @onechannel: !=0 if B channel data and AT commands share one
- * communication channel (M10x),
- * ==0 if B channels have separate communication channels (base)
- * @ignoreframes: number of frames to ignore after setting up B channel
- * @cidmode: !=0: start in CallID mode
- * @modulename: name of driver module for LL registration
- *
- * Allocate and initialize cardstate structure for Gigaset driver
- * Calls hardware dependent gigaset_initcshw() function
- * Calls B channel initialization function gigaset_initbcs() for each B channel
- *
- * Return value:
- * pointer to cardstate structure
- */
-struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels,
- int onechannel, int ignoreframes,
- int cidmode, const char *modulename)
-{
- struct cardstate *cs;
- unsigned long flags;
- int i;
-
- gig_dbg(DEBUG_INIT, "allocating cs");
- cs = alloc_cs(drv);
- if (!cs) {
- pr_err("maximum number of devices exceeded\n");
- return NULL;
- }
-
- cs->cs_init = 0;
- cs->channels = channels;
- cs->onechannel = onechannel;
- cs->ignoreframes = ignoreframes;
- INIT_LIST_HEAD(&cs->temp_at_states);
- cs->running = 0;
- timer_setup(&cs->timer, timer_tick, 0);
- spin_lock_init(&cs->ev_lock);
- cs->ev_tail = 0;
- cs->ev_head = 0;
-
- tasklet_init(&cs->event_tasklet, gigaset_handle_event,
- (unsigned long) cs);
- tty_port_init(&cs->port);
- cs->commands_pending = 0;
- cs->cur_at_seq = 0;
- cs->gotfwver = -1;
- cs->dev = NULL;
- cs->tty_dev = NULL;
- cs->cidmode = cidmode != 0;
- cs->tabnocid = gigaset_tab_nocid;
- cs->tabcid = gigaset_tab_cid;
-
- init_waitqueue_head(&cs->waitqueue);
- cs->waiting = 0;
-
- cs->mode = M_UNKNOWN;
- cs->mstate = MS_UNINITIALIZED;
-
- cs->bcs = kmalloc_array(channels, sizeof(struct bc_state), GFP_KERNEL);
- cs->inbuf = kmalloc(sizeof(struct inbuf_t), GFP_KERNEL);
- if (!cs->bcs || !cs->inbuf) {
- pr_err("out of memory\n");
- goto error;
- }
- ++cs->cs_init;
-
- gig_dbg(DEBUG_INIT, "setting up at_state");
- spin_lock_init(&cs->lock);
- gigaset_at_init(&cs->at_state, NULL, cs, 0);
- cs->dle = 0;
- cs->cbytes = 0;
-
- gig_dbg(DEBUG_INIT, "setting up inbuf");
- gigaset_inbuf_init(cs->inbuf, cs);
-
- cs->connected = 0;
- cs->isdn_up = 0;
-
- gig_dbg(DEBUG_INIT, "setting up cmdbuf");
- cs->cmdbuf = cs->lastcmdbuf = NULL;
- spin_lock_init(&cs->cmdlock);
- cs->curlen = 0;
- cs->cmdbytes = 0;
-
- gig_dbg(DEBUG_INIT, "setting up iif");
- if (gigaset_isdn_regdev(cs, modulename) < 0) {
- pr_err("error registering ISDN device\n");
- goto error;
- }
-
- make_valid(cs, VALID_ID);
- ++cs->cs_init;
- gig_dbg(DEBUG_INIT, "setting up hw");
- if (cs->ops->initcshw(cs) < 0)
- goto error;
-
- ++cs->cs_init;
-
- /* set up character device */
- gigaset_if_init(cs);
-
- /* set up device sysfs */
- gigaset_init_dev_sysfs(cs);
-
- /* set up channel data structures */
- for (i = 0; i < channels; ++i) {
- gig_dbg(DEBUG_INIT, "setting up bcs[%d]", i);
- if (gigaset_initbcs(cs->bcs + i, cs, i) < 0) {
- pr_err("could not allocate channel %d data\n", i);
- goto error;
- }
- }
-
- spin_lock_irqsave(&cs->lock, flags);
- cs->running = 1;
- spin_unlock_irqrestore(&cs->lock, flags);
- cs->timer.expires = jiffies + msecs_to_jiffies(GIG_TICK);
- add_timer(&cs->timer);
-
- gig_dbg(DEBUG_INIT, "cs initialized");
- return cs;
-
-error:
- gig_dbg(DEBUG_INIT, "failed");
- gigaset_freecs(cs);
- return NULL;
-}
-EXPORT_SYMBOL_GPL(gigaset_initcs);
-
-/* ReInitialize the b-channel structure on hangup */
-void gigaset_bcs_reinit(struct bc_state *bcs)
-{
- struct sk_buff *skb;
- struct cardstate *cs = bcs->cs;
- unsigned long flags;
-
- while ((skb = skb_dequeue(&bcs->squeue)) != NULL)
- dev_kfree_skb(skb);
-
- spin_lock_irqsave(&cs->lock, flags);
- clear_at_state(&bcs->at_state);
- bcs->at_state.ConState = 0;
- bcs->at_state.timer_active = 0;
- bcs->at_state.timer_expires = 0;
- bcs->at_state.cid = -1; /* No CID defined */
- spin_unlock_irqrestore(&cs->lock, flags);
-
- bcs->inputstate = 0;
-
-#ifdef CONFIG_GIGASET_DEBUG
- bcs->emptycount = 0;
-#endif
-
- bcs->rx_fcs = PPP_INITFCS;
- bcs->chstate = 0;
-
- bcs->ignore = cs->ignoreframes;
- dev_kfree_skb(bcs->rx_skb);
- bcs->rx_skb = NULL;
-
- cs->ops->reinitbcshw(bcs);
-}
-
-static void cleanup_cs(struct cardstate *cs)
-{
- struct cmdbuf_t *cb, *tcb;
- int i;
- unsigned long flags;
-
- spin_lock_irqsave(&cs->lock, flags);
-
- cs->mode = M_UNKNOWN;
- cs->mstate = MS_UNINITIALIZED;
-
- clear_at_state(&cs->at_state);
- dealloc_temp_at_states(cs);
- gigaset_at_init(&cs->at_state, NULL, cs, 0);
-
- cs->inbuf->inputstate = INS_command;
- cs->inbuf->head = 0;
- cs->inbuf->tail = 0;
-
- cb = cs->cmdbuf;
- while (cb) {
- tcb = cb;
- cb = cb->next;
- kfree(tcb);
- }
- cs->cmdbuf = cs->lastcmdbuf = NULL;
- cs->curlen = 0;
- cs->cmdbytes = 0;
- cs->gotfwver = -1;
- cs->dle = 0;
- cs->cur_at_seq = 0;
- cs->commands_pending = 0;
- cs->cbytes = 0;
-
- spin_unlock_irqrestore(&cs->lock, flags);
-
- for (i = 0; i < cs->channels; ++i) {
- gigaset_freebcs(cs->bcs + i);
- if (gigaset_initbcs(cs->bcs + i, cs, i) < 0)
- pr_err("could not allocate channel %d data\n", i);
- }
-
- if (cs->waiting) {
- cs->cmd_result = -ENODEV;
- cs->waiting = 0;
- wake_up_interruptible(&cs->waitqueue);
- }
-}
-
-
-/**
- * gigaset_start() - start device operations
- * @cs: device descriptor structure.
- *
- * Prepares the device for use by setting up communication parameters,
- * scheduling an EV_START event to initiate device initialization, and
- * waiting for completion of the initialization.
- *
- * Return value:
- * 0 on success, error code < 0 on failure
- */
-int gigaset_start(struct cardstate *cs)
-{
- unsigned long flags;
-
- if (mutex_lock_interruptible(&cs->mutex))
- return -EBUSY;
-
- spin_lock_irqsave(&cs->lock, flags);
- cs->connected = 1;
- spin_unlock_irqrestore(&cs->lock, flags);
-
- if (cs->mstate != MS_LOCKED) {
- cs->ops->set_modem_ctrl(cs, 0, TIOCM_DTR | TIOCM_RTS);
- cs->ops->baud_rate(cs, B115200);
- cs->ops->set_line_ctrl(cs, CS8);
- cs->control_state = TIOCM_DTR | TIOCM_RTS;
- }
-
- cs->waiting = 1;
-
- if (!gigaset_add_event(cs, &cs->at_state, EV_START, NULL, 0, NULL)) {
- cs->waiting = 0;
- goto error;
- }
- gigaset_schedule_event(cs);
-
- wait_event(cs->waitqueue, !cs->waiting);
-
- mutex_unlock(&cs->mutex);
- return 0;
-
-error:
- mutex_unlock(&cs->mutex);
- return -ENOMEM;
-}
-EXPORT_SYMBOL_GPL(gigaset_start);
-
-/**
- * gigaset_shutdown() - shut down device operations
- * @cs: device descriptor structure.
- *
- * Deactivates the device by scheduling an EV_SHUTDOWN event and
- * waiting for completion of the shutdown.
- *
- * Return value:
- * 0 - success, -ENODEV - error (no device associated)
- */
-int gigaset_shutdown(struct cardstate *cs)
-{
- mutex_lock(&cs->mutex);
-
- if (!(cs->flags & VALID_MINOR)) {
- mutex_unlock(&cs->mutex);
- return -ENODEV;
- }
-
- cs->waiting = 1;
-
- if (!gigaset_add_event(cs, &cs->at_state, EV_SHUTDOWN, NULL, 0, NULL))
- goto exit;
- gigaset_schedule_event(cs);
-
- wait_event(cs->waitqueue, !cs->waiting);
-
- cleanup_cs(cs);
-
-exit:
- mutex_unlock(&cs->mutex);
- return 0;
-}
-EXPORT_SYMBOL_GPL(gigaset_shutdown);
-
-/**
- * gigaset_stop() - stop device operations
- * @cs: device descriptor structure.
- *
- * Stops operations on the device by scheduling an EV_STOP event and
- * waiting for completion of the shutdown.
- */
-void gigaset_stop(struct cardstate *cs)
-{
- mutex_lock(&cs->mutex);
-
- cs->waiting = 1;
-
- if (!gigaset_add_event(cs, &cs->at_state, EV_STOP, NULL, 0, NULL))
- goto exit;
- gigaset_schedule_event(cs);
-
- wait_event(cs->waitqueue, !cs->waiting);
-
- cleanup_cs(cs);
-
-exit:
- mutex_unlock(&cs->mutex);
-}
-EXPORT_SYMBOL_GPL(gigaset_stop);
-
-static LIST_HEAD(drivers);
-static DEFINE_SPINLOCK(driver_lock);
-
-struct cardstate *gigaset_get_cs_by_id(int id)
-{
- unsigned long flags;
- struct cardstate *ret = NULL;
- struct cardstate *cs;
- struct gigaset_driver *drv;
- unsigned i;
-
- spin_lock_irqsave(&driver_lock, flags);
- list_for_each_entry(drv, &drivers, list) {
- spin_lock(&drv->lock);
- for (i = 0; i < drv->minors; ++i) {
- cs = drv->cs + i;
- if ((cs->flags & VALID_ID) && cs->myid == id) {
- ret = cs;
- break;
- }
- }
- spin_unlock(&drv->lock);
- if (ret)
- break;
- }
- spin_unlock_irqrestore(&driver_lock, flags);
- return ret;
-}
-
-static struct cardstate *gigaset_get_cs_by_minor(unsigned minor)
-{
- unsigned long flags;
- struct cardstate *ret = NULL;
- struct gigaset_driver *drv;
- unsigned index;
-
- spin_lock_irqsave(&driver_lock, flags);
- list_for_each_entry(drv, &drivers, list) {
- if (minor < drv->minor || minor >= drv->minor + drv->minors)
- continue;
- index = minor - drv->minor;
- spin_lock(&drv->lock);
- if (drv->cs[index].flags & VALID_MINOR)
- ret = drv->cs + index;
- spin_unlock(&drv->lock);
- if (ret)
- break;
- }
- spin_unlock_irqrestore(&driver_lock, flags);
- return ret;
-}
-
-struct cardstate *gigaset_get_cs_by_tty(struct tty_struct *tty)
-{
- return gigaset_get_cs_by_minor(tty->index + tty->driver->minor_start);
-}
-
-/**
- * gigaset_freedriver() - free all associated ressources of a driver
- * @drv: driver descriptor structure.
- *
- * Unregisters the driver from the system and deallocates the driver
- * structure @drv and all structures referenced from it.
- * All devices should be shut down before calling this.
- */
-void gigaset_freedriver(struct gigaset_driver *drv)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&driver_lock, flags);
- list_del(&drv->list);
- spin_unlock_irqrestore(&driver_lock, flags);
-
- gigaset_if_freedriver(drv);
-
- kfree(drv->cs);
- kfree(drv);
-}
-EXPORT_SYMBOL_GPL(gigaset_freedriver);
-
-/**
- * gigaset_initdriver() - initialize driver structure
- * @minor: First minor number
- * @minors: Number of minors this driver can handle
- * @procname: Name of the driver
- * @devname: Name of the device files (prefix without minor number)
- *
- * Allocate and initialize gigaset_driver structure. Initialize interface.
- *
- * Return value:
- * Pointer to the gigaset_driver structure on success, NULL on failure.
- */
-struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors,
- const char *procname,
- const char *devname,
- const struct gigaset_ops *ops,
- struct module *owner)
-{
- struct gigaset_driver *drv;
- unsigned long flags;
- unsigned i;
-
- drv = kmalloc(sizeof *drv, GFP_KERNEL);
- if (!drv)
- return NULL;
-
- drv->have_tty = 0;
- drv->minor = minor;
- drv->minors = minors;
- spin_lock_init(&drv->lock);
- drv->blocked = 0;
- drv->ops = ops;
- drv->owner = owner;
- INIT_LIST_HEAD(&drv->list);
-
- drv->cs = kmalloc_array(minors, sizeof(*drv->cs), GFP_KERNEL);
- if (!drv->cs)
- goto error;
-
- for (i = 0; i < minors; ++i) {
- drv->cs[i].flags = 0;
- drv->cs[i].driver = drv;
- drv->cs[i].ops = drv->ops;
- drv->cs[i].minor_index = i;
- mutex_init(&drv->cs[i].mutex);
- }
-
- gigaset_if_initdriver(drv, procname, devname);
-
- spin_lock_irqsave(&driver_lock, flags);
- list_add(&drv->list, &drivers);
- spin_unlock_irqrestore(&driver_lock, flags);
-
- return drv;
-
-error:
- kfree(drv);
- return NULL;
-}
-EXPORT_SYMBOL_GPL(gigaset_initdriver);
-
-/**
- * gigaset_blockdriver() - block driver
- * @drv: driver descriptor structure.
- *
- * Prevents the driver from attaching new devices, in preparation for
- * deregistration.
- */
-void gigaset_blockdriver(struct gigaset_driver *drv)
-{
- drv->blocked = 1;
-}
-EXPORT_SYMBOL_GPL(gigaset_blockdriver);
-
-static int __init gigaset_init_module(void)
-{
- /* in accordance with the principle of least astonishment,
- * setting the 'debug' parameter to 1 activates a sensible
- * set of default debug levels
- */
- if (gigaset_debuglevel == 1)
- gigaset_debuglevel = DEBUG_DEFAULT;
-
- pr_info(DRIVER_DESC DRIVER_DESC_DEBUG "\n");
- gigaset_isdn_regdrv();
- return 0;
-}
-
-static void __exit gigaset_exit_module(void)
-{
- gigaset_isdn_unregdrv();
-}
-
-module_init(gigaset_init_module);
-module_exit(gigaset_exit_module);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/isdn/gigaset/dummyll.c b/drivers/staging/isdn/gigaset/dummyll.c
deleted file mode 100644
index 4b9637e5da6e..000000000000
--- a/drivers/staging/isdn/gigaset/dummyll.c
+++ /dev/null
@@ -1,74 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Dummy LL interface for the Gigaset driver
- *
- * Copyright (c) 2009 by Tilman Schmidt <tilman@imap.cc>.
- *
- * =====================================================================
- * =====================================================================
- */
-
-#include <linux/export.h>
-#include "gigaset.h"
-
-void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb)
-{
-}
-EXPORT_SYMBOL_GPL(gigaset_skb_sent);
-
-void gigaset_skb_rcvd(struct bc_state *bcs, struct sk_buff *skb)
-{
-}
-EXPORT_SYMBOL_GPL(gigaset_skb_rcvd);
-
-void gigaset_isdn_rcv_err(struct bc_state *bcs)
-{
-}
-EXPORT_SYMBOL_GPL(gigaset_isdn_rcv_err);
-
-int gigaset_isdn_icall(struct at_state_t *at_state)
-{
- return ICALL_IGNORE;
-}
-
-void gigaset_isdn_connD(struct bc_state *bcs)
-{
-}
-
-void gigaset_isdn_hupD(struct bc_state *bcs)
-{
-}
-
-void gigaset_isdn_connB(struct bc_state *bcs)
-{
-}
-
-void gigaset_isdn_hupB(struct bc_state *bcs)
-{
-}
-
-void gigaset_isdn_start(struct cardstate *cs)
-{
-}
-
-void gigaset_isdn_stop(struct cardstate *cs)
-{
-}
-
-int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid)
-{
- return 0;
-}
-
-void gigaset_isdn_unregdev(struct cardstate *cs)
-{
-}
-
-void gigaset_isdn_regdrv(void)
-{
- pr_info("no ISDN subsystem interface\n");
-}
-
-void gigaset_isdn_unregdrv(void)
-{
-}
diff --git a/drivers/staging/isdn/gigaset/ev-layer.c b/drivers/staging/isdn/gigaset/ev-layer.c
deleted file mode 100644
index f8bb1869c600..000000000000
--- a/drivers/staging/isdn/gigaset/ev-layer.c
+++ /dev/null
@@ -1,1910 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Stuff used by all variants of the driver
- *
- * Copyright (c) 2001 by Stefan Eilers,
- * Hansjoerg Lipp <hjlipp@web.de>,
- * Tilman Schmidt <tilman@imap.cc>.
- *
- * =====================================================================
- * =====================================================================
- */
-
-#include <linux/export.h>
-#include "gigaset.h"
-
-/* ========================================================== */
-/* bit masks for pending commands */
-#define PC_DIAL 0x001
-#define PC_HUP 0x002
-#define PC_INIT 0x004
-#define PC_DLE0 0x008
-#define PC_DLE1 0x010
-#define PC_SHUTDOWN 0x020
-#define PC_ACCEPT 0x040
-#define PC_CID 0x080
-#define PC_NOCID 0x100
-#define PC_CIDMODE 0x200
-#define PC_UMMODE 0x400
-
-/* types of modem responses */
-#define RT_NOTHING 0
-#define RT_ZSAU 1
-#define RT_RING 2
-#define RT_NUMBER 3
-#define RT_STRING 4
-#define RT_ZCAU 6
-
-/* Possible ASCII responses */
-#define RSP_OK 0
-#define RSP_ERROR 1
-#define RSP_ZGCI 3
-#define RSP_RING 4
-#define RSP_ZVLS 5
-#define RSP_ZCAU 6
-
-/* responses with values to store in at_state */
-/* - numeric */
-#define RSP_VAR 100
-#define RSP_ZSAU (RSP_VAR + VAR_ZSAU)
-#define RSP_ZDLE (RSP_VAR + VAR_ZDLE)
-#define RSP_ZCTP (RSP_VAR + VAR_ZCTP)
-/* - string */
-#define RSP_STR (RSP_VAR + VAR_NUM)
-#define RSP_NMBR (RSP_STR + STR_NMBR)
-#define RSP_ZCPN (RSP_STR + STR_ZCPN)
-#define RSP_ZCON (RSP_STR + STR_ZCON)
-#define RSP_ZBC (RSP_STR + STR_ZBC)
-#define RSP_ZHLC (RSP_STR + STR_ZHLC)
-
-#define RSP_WRONG_CID -2 /* unknown cid in cmd */
-#define RSP_INVAL -6 /* invalid response */
-#define RSP_NODEV -9 /* device not connected */
-
-#define RSP_NONE -19
-#define RSP_STRING -20
-#define RSP_NULL -21
-#define RSP_INIT -27
-#define RSP_ANY -26
-#define RSP_LAST -28
-
-/* actions for process_response */
-#define ACT_NOTHING 0
-#define ACT_SETDLE1 1
-#define ACT_SETDLE0 2
-#define ACT_FAILINIT 3
-#define ACT_HUPMODEM 4
-#define ACT_CONFIGMODE 5
-#define ACT_INIT 6
-#define ACT_DLE0 7
-#define ACT_DLE1 8
-#define ACT_FAILDLE0 9
-#define ACT_FAILDLE1 10
-#define ACT_RING 11
-#define ACT_CID 12
-#define ACT_FAILCID 13
-#define ACT_SDOWN 14
-#define ACT_FAILSDOWN 15
-#define ACT_DEBUG 16
-#define ACT_WARN 17
-#define ACT_DIALING 18
-#define ACT_ABORTDIAL 19
-#define ACT_DISCONNECT 20
-#define ACT_CONNECT 21
-#define ACT_REMOTEREJECT 22
-#define ACT_CONNTIMEOUT 23
-#define ACT_REMOTEHUP 24
-#define ACT_ABORTHUP 25
-#define ACT_ICALL 26
-#define ACT_ACCEPTED 27
-#define ACT_ABORTACCEPT 28
-#define ACT_TIMEOUT 29
-#define ACT_GETSTRING 30
-#define ACT_SETVER 31
-#define ACT_FAILVER 32
-#define ACT_GOTVER 33
-#define ACT_TEST 34
-#define ACT_ERROR 35
-#define ACT_ABORTCID 36
-#define ACT_ZCAU 37
-#define ACT_NOTIFY_BC_DOWN 38
-#define ACT_NOTIFY_BC_UP 39
-#define ACT_DIAL 40
-#define ACT_ACCEPT 41
-#define ACT_HUP 43
-#define ACT_IF_LOCK 44
-#define ACT_START 45
-#define ACT_STOP 46
-#define ACT_FAKEDLE0 47
-#define ACT_FAKEHUP 48
-#define ACT_FAKESDOWN 49
-#define ACT_SHUTDOWN 50
-#define ACT_PROC_CIDMODE 51
-#define ACT_UMODESET 52
-#define ACT_FAILUMODE 53
-#define ACT_CMODESET 54
-#define ACT_FAILCMODE 55
-#define ACT_IF_VER 56
-#define ACT_CMD 100
-
-/* at command sequences */
-#define SEQ_NONE 0
-#define SEQ_INIT 100
-#define SEQ_DLE0 200
-#define SEQ_DLE1 250
-#define SEQ_CID 300
-#define SEQ_NOCID 350
-#define SEQ_HUP 400
-#define SEQ_DIAL 600
-#define SEQ_ACCEPT 720
-#define SEQ_SHUTDOWN 500
-#define SEQ_CIDMODE 10
-#define SEQ_UMMODE 11
-
-
-/* 100: init, 200: dle0, 250:dle1, 300: get cid (dial), 350: "hup" (no cid),
- * 400: hup, 500: reset, 600: dial, 700: ring */
-struct reply_t gigaset_tab_nocid[] =
-{
-/* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout,
- * action, command */
-
-/* initialize device, set cid mode if possible */
- {RSP_INIT, -1, -1, SEQ_INIT, 100, 1, {ACT_TIMEOUT} },
-
- {EV_TIMEOUT, 100, 100, -1, 101, 3, {0}, "Z\r"},
- {RSP_OK, 101, 103, -1, 120, 5, {ACT_GETSTRING},
- "+GMR\r"},
-
- {EV_TIMEOUT, 101, 101, -1, 102, 5, {0}, "Z\r"},
- {RSP_ERROR, 101, 101, -1, 102, 5, {0}, "Z\r"},
-
- {EV_TIMEOUT, 102, 102, -1, 108, 5, {ACT_SETDLE1},
- "^SDLE=0\r"},
- {RSP_OK, 108, 108, -1, 104, -1},
- {RSP_ZDLE, 104, 104, 0, 103, 5, {0}, "Z\r"},
- {EV_TIMEOUT, 104, 104, -1, 0, 0, {ACT_FAILINIT} },
- {RSP_ERROR, 108, 108, -1, 0, 0, {ACT_FAILINIT} },
-
- {EV_TIMEOUT, 108, 108, -1, 105, 2, {ACT_SETDLE0,
- ACT_HUPMODEM,
- ACT_TIMEOUT} },
- {EV_TIMEOUT, 105, 105, -1, 103, 5, {0}, "Z\r"},
-
- {RSP_ERROR, 102, 102, -1, 107, 5, {0}, "^GETPRE\r"},
- {RSP_OK, 107, 107, -1, 0, 0, {ACT_CONFIGMODE} },
- {RSP_ERROR, 107, 107, -1, 0, 0, {ACT_FAILINIT} },
- {EV_TIMEOUT, 107, 107, -1, 0, 0, {ACT_FAILINIT} },
-
- {RSP_ERROR, 103, 103, -1, 0, 0, {ACT_FAILINIT} },
- {EV_TIMEOUT, 103, 103, -1, 0, 0, {ACT_FAILINIT} },
-
- {RSP_STRING, 120, 120, -1, 121, -1, {ACT_SETVER} },
-
- {EV_TIMEOUT, 120, 121, -1, 0, 0, {ACT_FAILVER,
- ACT_INIT} },
- {RSP_ERROR, 120, 121, -1, 0, 0, {ACT_FAILVER,
- ACT_INIT} },
- {RSP_OK, 121, 121, -1, 0, 0, {ACT_GOTVER,
- ACT_INIT} },
- {RSP_NONE, 121, 121, -1, 120, 0, {ACT_GETSTRING} },
-
-/* leave dle mode */
- {RSP_INIT, 0, 0, SEQ_DLE0, 201, 5, {0}, "^SDLE=0\r"},
- {RSP_OK, 201, 201, -1, 202, -1},
- {RSP_ZDLE, 202, 202, 0, 0, 0, {ACT_DLE0} },
- {RSP_NODEV, 200, 249, -1, 0, 0, {ACT_FAKEDLE0} },
- {RSP_ERROR, 200, 249, -1, 0, 0, {ACT_FAILDLE0} },
- {EV_TIMEOUT, 200, 249, -1, 0, 0, {ACT_FAILDLE0} },
-
-/* enter dle mode */
- {RSP_INIT, 0, 0, SEQ_DLE1, 251, 5, {0}, "^SDLE=1\r"},
- {RSP_OK, 251, 251, -1, 252, -1},
- {RSP_ZDLE, 252, 252, 1, 0, 0, {ACT_DLE1} },
- {RSP_ERROR, 250, 299, -1, 0, 0, {ACT_FAILDLE1} },
- {EV_TIMEOUT, 250, 299, -1, 0, 0, {ACT_FAILDLE1} },
-
-/* incoming call */
- {RSP_RING, -1, -1, -1, -1, -1, {ACT_RING} },
-
-/* get cid */
- {RSP_INIT, 0, 0, SEQ_CID, 301, 5, {0}, "^SGCI?\r"},
- {RSP_OK, 301, 301, -1, 302, -1},
- {RSP_ZGCI, 302, 302, -1, 0, 0, {ACT_CID} },
- {RSP_ERROR, 301, 349, -1, 0, 0, {ACT_FAILCID} },
- {EV_TIMEOUT, 301, 349, -1, 0, 0, {ACT_FAILCID} },
-
-/* enter cid mode */
- {RSP_INIT, 0, 0, SEQ_CIDMODE, 150, 5, {0}, "^SGCI=1\r"},
- {RSP_OK, 150, 150, -1, 0, 0, {ACT_CMODESET} },
- {RSP_ERROR, 150, 150, -1, 0, 0, {ACT_FAILCMODE} },
- {EV_TIMEOUT, 150, 150, -1, 0, 0, {ACT_FAILCMODE} },
-
-/* leave cid mode */
- {RSP_INIT, 0, 0, SEQ_UMMODE, 160, 5, {0}, "Z\r"},
- {RSP_OK, 160, 160, -1, 0, 0, {ACT_UMODESET} },
- {RSP_ERROR, 160, 160, -1, 0, 0, {ACT_FAILUMODE} },
- {EV_TIMEOUT, 160, 160, -1, 0, 0, {ACT_FAILUMODE} },
-
-/* abort getting cid */
- {RSP_INIT, 0, 0, SEQ_NOCID, 0, 0, {ACT_ABORTCID} },
-
-/* reset */
- {RSP_INIT, 0, 0, SEQ_SHUTDOWN, 504, 5, {0}, "Z\r"},
- {RSP_OK, 504, 504, -1, 0, 0, {ACT_SDOWN} },
- {RSP_ERROR, 501, 599, -1, 0, 0, {ACT_FAILSDOWN} },
- {EV_TIMEOUT, 501, 599, -1, 0, 0, {ACT_FAILSDOWN} },
- {RSP_NODEV, 501, 599, -1, 0, 0, {ACT_FAKESDOWN} },
-
- {EV_PROC_CIDMODE, -1, -1, -1, -1, -1, {ACT_PROC_CIDMODE} },
- {EV_IF_LOCK, -1, -1, -1, -1, -1, {ACT_IF_LOCK} },
- {EV_IF_VER, -1, -1, -1, -1, -1, {ACT_IF_VER} },
- {EV_START, -1, -1, -1, -1, -1, {ACT_START} },
- {EV_STOP, -1, -1, -1, -1, -1, {ACT_STOP} },
- {EV_SHUTDOWN, -1, -1, -1, -1, -1, {ACT_SHUTDOWN} },
-
-/* misc. */
- {RSP_ERROR, -1, -1, -1, -1, -1, {ACT_ERROR} },
- {RSP_ZCAU, -1, -1, -1, -1, -1, {ACT_ZCAU} },
- {RSP_NONE, -1, -1, -1, -1, -1, {ACT_DEBUG} },
- {RSP_ANY, -1, -1, -1, -1, -1, {ACT_WARN} },
- {RSP_LAST}
-};
-
-/* 600: start dialing, 650: dial in progress, 800: connection is up, 700: ring,
- * 400: hup, 750: accepted icall */
-struct reply_t gigaset_tab_cid[] =
-{
-/* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout,
- * action, command */
-
-/* dial */
- {EV_DIAL, -1, -1, -1, -1, -1, {ACT_DIAL} },
- {RSP_INIT, 0, 0, SEQ_DIAL, 601, 5, {ACT_CMD + AT_BC} },
- {RSP_OK, 601, 601, -1, 603, 5, {ACT_CMD + AT_PROTO} },
- {RSP_OK, 603, 603, -1, 604, 5, {ACT_CMD + AT_TYPE} },
- {RSP_OK, 604, 604, -1, 605, 5, {ACT_CMD + AT_MSN} },
- {RSP_NULL, 605, 605, -1, 606, 5, {ACT_CMD + AT_CLIP} },
- {RSP_OK, 605, 605, -1, 606, 5, {ACT_CMD + AT_CLIP} },
- {RSP_NULL, 606, 606, -1, 607, 5, {ACT_CMD + AT_ISO} },
- {RSP_OK, 606, 606, -1, 607, 5, {ACT_CMD + AT_ISO} },
- {RSP_OK, 607, 607, -1, 608, 5, {0}, "+VLS=17\r"},
- {RSP_OK, 608, 608, -1, 609, -1},
- {RSP_ZSAU, 609, 609, ZSAU_PROCEEDING, 610, 5, {ACT_CMD + AT_DIAL} },
- {RSP_OK, 610, 610, -1, 650, 0, {ACT_DIALING} },
-
- {RSP_ERROR, 601, 610, -1, 0, 0, {ACT_ABORTDIAL} },
- {EV_TIMEOUT, 601, 610, -1, 0, 0, {ACT_ABORTDIAL} },
-
-/* optional dialing responses */
- {EV_BC_OPEN, 650, 650, -1, 651, -1},
- {RSP_ZVLS, 609, 651, 17, -1, -1, {ACT_DEBUG} },
- {RSP_ZCTP, 610, 651, -1, -1, -1, {ACT_DEBUG} },
- {RSP_ZCPN, 610, 651, -1, -1, -1, {ACT_DEBUG} },
- {RSP_ZSAU, 650, 651, ZSAU_CALL_DELIVERED, -1, -1, {ACT_DEBUG} },
-
-/* connect */
- {RSP_ZSAU, 650, 650, ZSAU_ACTIVE, 800, -1, {ACT_CONNECT} },
- {RSP_ZSAU, 651, 651, ZSAU_ACTIVE, 800, -1, {ACT_CONNECT,
- ACT_NOTIFY_BC_UP} },
- {RSP_ZSAU, 750, 750, ZSAU_ACTIVE, 800, -1, {ACT_CONNECT} },
- {RSP_ZSAU, 751, 751, ZSAU_ACTIVE, 800, -1, {ACT_CONNECT,
- ACT_NOTIFY_BC_UP} },
- {EV_BC_OPEN, 800, 800, -1, 800, -1, {ACT_NOTIFY_BC_UP} },
-
-/* remote hangup */
- {RSP_ZSAU, 650, 651, ZSAU_DISCONNECT_IND, 0, 0, {ACT_REMOTEREJECT} },
- {RSP_ZSAU, 750, 751, ZSAU_DISCONNECT_IND, 0, 0, {ACT_REMOTEHUP} },
- {RSP_ZSAU, 800, 800, ZSAU_DISCONNECT_IND, 0, 0, {ACT_REMOTEHUP} },
-
-/* hangup */
- {EV_HUP, -1, -1, -1, -1, -1, {ACT_HUP} },
- {RSP_INIT, -1, -1, SEQ_HUP, 401, 5, {0}, "+VLS=0\r"},
- {RSP_OK, 401, 401, -1, 402, 5},
- {RSP_ZVLS, 402, 402, 0, 403, 5},
- {RSP_ZSAU, 403, 403, ZSAU_DISCONNECT_REQ, -1, -1, {ACT_DEBUG} },
- {RSP_ZSAU, 403, 403, ZSAU_NULL, 0, 0, {ACT_DISCONNECT} },
- {RSP_NODEV, 401, 403, -1, 0, 0, {ACT_FAKEHUP} },
- {RSP_ERROR, 401, 401, -1, 0, 0, {ACT_ABORTHUP} },
- {EV_TIMEOUT, 401, 403, -1, 0, 0, {ACT_ABORTHUP} },
-
- {EV_BC_CLOSED, 0, 0, -1, 0, -1, {ACT_NOTIFY_BC_DOWN} },
-
-/* ring */
- {RSP_ZBC, 700, 700, -1, -1, -1, {0} },
- {RSP_ZHLC, 700, 700, -1, -1, -1, {0} },
- {RSP_NMBR, 700, 700, -1, -1, -1, {0} },
- {RSP_ZCPN, 700, 700, -1, -1, -1, {0} },
- {RSP_ZCTP, 700, 700, -1, -1, -1, {0} },
- {EV_TIMEOUT, 700, 700, -1, 720, 720, {ACT_ICALL} },
- {EV_BC_CLOSED, 720, 720, -1, 0, -1, {ACT_NOTIFY_BC_DOWN} },
-
-/*accept icall*/
- {EV_ACCEPT, -1, -1, -1, -1, -1, {ACT_ACCEPT} },
- {RSP_INIT, 720, 720, SEQ_ACCEPT, 721, 5, {ACT_CMD + AT_PROTO} },
- {RSP_OK, 721, 721, -1, 722, 5, {ACT_CMD + AT_ISO} },
- {RSP_OK, 722, 722, -1, 723, 5, {0}, "+VLS=17\r"},
- {RSP_OK, 723, 723, -1, 724, 5, {0} },
- {RSP_ZVLS, 724, 724, 17, 750, 50, {ACT_ACCEPTED} },
- {RSP_ERROR, 721, 729, -1, 0, 0, {ACT_ABORTACCEPT} },
- {EV_TIMEOUT, 721, 729, -1, 0, 0, {ACT_ABORTACCEPT} },
- {RSP_ZSAU, 700, 729, ZSAU_NULL, 0, 0, {ACT_ABORTACCEPT} },
- {RSP_ZSAU, 700, 729, ZSAU_ACTIVE, 0, 0, {ACT_ABORTACCEPT} },
- {RSP_ZSAU, 700, 729, ZSAU_DISCONNECT_IND, 0, 0, {ACT_ABORTACCEPT} },
-
- {EV_BC_OPEN, 750, 750, -1, 751, -1},
- {EV_TIMEOUT, 750, 751, -1, 0, 0, {ACT_CONNTIMEOUT} },
-
-/* B channel closed (general case) */
- {EV_BC_CLOSED, -1, -1, -1, -1, -1, {ACT_NOTIFY_BC_DOWN} },
-
-/* misc. */
- {RSP_ZCON, -1, -1, -1, -1, -1, {ACT_DEBUG} },
- {RSP_ZCAU, -1, -1, -1, -1, -1, {ACT_ZCAU} },
- {RSP_NONE, -1, -1, -1, -1, -1, {ACT_DEBUG} },
- {RSP_ANY, -1, -1, -1, -1, -1, {ACT_WARN} },
- {RSP_LAST}
-};
-
-
-static const struct resp_type_t {
- char *response;
- int resp_code;
- int type;
-}
-resp_type[] =
-{
- {"OK", RSP_OK, RT_NOTHING},
- {"ERROR", RSP_ERROR, RT_NOTHING},
- {"ZSAU", RSP_ZSAU, RT_ZSAU},
- {"ZCAU", RSP_ZCAU, RT_ZCAU},
- {"RING", RSP_RING, RT_RING},
- {"ZGCI", RSP_ZGCI, RT_NUMBER},
- {"ZVLS", RSP_ZVLS, RT_NUMBER},
- {"ZCTP", RSP_ZCTP, RT_NUMBER},
- {"ZDLE", RSP_ZDLE, RT_NUMBER},
- {"ZHLC", RSP_ZHLC, RT_STRING},
- {"ZBC", RSP_ZBC, RT_STRING},
- {"NMBR", RSP_NMBR, RT_STRING},
- {"ZCPN", RSP_ZCPN, RT_STRING},
- {"ZCON", RSP_ZCON, RT_STRING},
- {NULL, 0, 0}
-};
-
-static const struct zsau_resp_t {
- char *str;
- int code;
-}
-zsau_resp[] =
-{
- {"OUTGOING_CALL_PROCEEDING", ZSAU_PROCEEDING},
- {"CALL_DELIVERED", ZSAU_CALL_DELIVERED},
- {"ACTIVE", ZSAU_ACTIVE},
- {"DISCONNECT_IND", ZSAU_DISCONNECT_IND},
- {"NULL", ZSAU_NULL},
- {"DISCONNECT_REQ", ZSAU_DISCONNECT_REQ},
- {NULL, ZSAU_UNKNOWN}
-};
-
-/* check for and remove fixed string prefix
- * If s starts with prefix terminated by a non-alphanumeric character,
- * return pointer to the first character after that, otherwise return NULL.
- */
-static char *skip_prefix(char *s, const char *prefix)
-{
- while (*prefix)
- if (*s++ != *prefix++)
- return NULL;
- if (isalnum(*s))
- return NULL;
- return s;
-}
-
-/* queue event with CID */
-static void add_cid_event(struct cardstate *cs, int cid, int type,
- void *ptr, int parameter)
-{
- unsigned long flags;
- unsigned next, tail;
- struct event_t *event;
-
- gig_dbg(DEBUG_EVENT, "queueing event %d for cid %d", type, cid);
-
- spin_lock_irqsave(&cs->ev_lock, flags);
-
- tail = cs->ev_tail;
- next = (tail + 1) % MAX_EVENTS;
- if (unlikely(next == cs->ev_head)) {
- dev_err(cs->dev, "event queue full\n");
- kfree(ptr);
- } else {
- event = cs->events + tail;
- event->type = type;
- event->cid = cid;
- event->ptr = ptr;
- event->arg = NULL;
- event->parameter = parameter;
- event->at_state = NULL;
- cs->ev_tail = next;
- }
-
- spin_unlock_irqrestore(&cs->ev_lock, flags);
-}
-
-/**
- * gigaset_handle_modem_response() - process received modem response
- * @cs: device descriptor structure.
- *
- * Called by asyncdata/isocdata if a block of data received from the
- * device must be processed as a modem command response. The data is
- * already in the cs structure.
- */
-void gigaset_handle_modem_response(struct cardstate *cs)
-{
- char *eoc, *psep, *ptr;
- const struct resp_type_t *rt;
- const struct zsau_resp_t *zr;
- int cid, parameter;
- u8 type, value;
-
- if (!cs->cbytes) {
- /* ignore additional LFs/CRs (M10x config mode or cx100) */
- gig_dbg(DEBUG_MCMD, "skipped EOL [%02X]", cs->respdata[0]);
- return;
- }
- cs->respdata[cs->cbytes] = 0;
-
- if (cs->at_state.getstring) {
- /* state machine wants next line verbatim */
- cs->at_state.getstring = 0;
- ptr = kstrdup(cs->respdata, GFP_ATOMIC);
- gig_dbg(DEBUG_EVENT, "string==%s", ptr ? ptr : "NULL");
- add_cid_event(cs, 0, RSP_STRING, ptr, 0);
- return;
- }
-
- /* look up response type */
- for (rt = resp_type; rt->response; ++rt) {
- eoc = skip_prefix(cs->respdata, rt->response);
- if (eoc)
- break;
- }
- if (!rt->response) {
- add_cid_event(cs, 0, RSP_NONE, NULL, 0);
- gig_dbg(DEBUG_EVENT, "unknown modem response: '%s'\n",
- cs->respdata);
- return;
- }
-
- /* check for CID */
- psep = strrchr(cs->respdata, ';');
- if (psep &&
- !kstrtoint(psep + 1, 10, &cid) &&
- cid >= 1 && cid <= 65535) {
- /* valid CID: chop it off */
- *psep = 0;
- } else {
- /* no valid CID: leave unchanged */
- cid = 0;
- }
-
- gig_dbg(DEBUG_EVENT, "CMD received: %s", cs->respdata);
- if (cid)
- gig_dbg(DEBUG_EVENT, "CID: %d", cid);
-
- switch (rt->type) {
- case RT_NOTHING:
- /* check parameter separator */
- if (*eoc)
- goto bad_param; /* extra parameter */
-
- add_cid_event(cs, cid, rt->resp_code, NULL, 0);
- break;
-
- case RT_RING:
- /* check parameter separator */
- if (!*eoc)
- eoc = NULL; /* no parameter */
- else if (*eoc++ != ',')
- goto bad_param;
-
- add_cid_event(cs, 0, rt->resp_code, NULL, cid);
-
- /* process parameters as individual responses */
- while (eoc) {
- /* look up parameter type */
- psep = NULL;
- for (rt = resp_type; rt->response; ++rt) {
- psep = skip_prefix(eoc, rt->response);
- if (psep)
- break;
- }
-
- /* all legal parameters are of type RT_STRING */
- if (!psep || rt->type != RT_STRING) {
- dev_warn(cs->dev,
- "illegal RING parameter: '%s'\n",
- eoc);
- return;
- }
-
- /* skip parameter value separator */
- if (*psep++ != '=')
- goto bad_param;
-
- /* look up end of parameter */
- eoc = strchr(psep, ',');
- if (eoc)
- *eoc++ = 0;
-
- /* retrieve parameter value */
- ptr = kstrdup(psep, GFP_ATOMIC);
-
- /* queue event */
- add_cid_event(cs, cid, rt->resp_code, ptr, 0);
- }
- break;
-
- case RT_ZSAU:
- /* check parameter separator */
- if (!*eoc) {
- /* no parameter */
- add_cid_event(cs, cid, rt->resp_code, NULL, ZSAU_NONE);
- break;
- }
- if (*eoc++ != '=')
- goto bad_param;
-
- /* look up parameter value */
- for (zr = zsau_resp; zr->str; ++zr)
- if (!strcmp(eoc, zr->str))
- break;
- if (!zr->str)
- goto bad_param;
-
- add_cid_event(cs, cid, rt->resp_code, NULL, zr->code);
- break;
-
- case RT_STRING:
- /* check parameter separator */
- if (*eoc++ != '=')
- goto bad_param;
-
- /* retrieve parameter value */
- ptr = kstrdup(eoc, GFP_ATOMIC);
-
- /* queue event */
- add_cid_event(cs, cid, rt->resp_code, ptr, 0);
- break;
-
- case RT_ZCAU:
- /* check parameter separators */
- if (*eoc++ != '=')
- goto bad_param;
- psep = strchr(eoc, ',');
- if (!psep)
- goto bad_param;
- *psep++ = 0;
-
- /* decode parameter values */
- if (kstrtou8(eoc, 16, &type) || kstrtou8(psep, 16, &value)) {
- *--psep = ',';
- goto bad_param;
- }
- parameter = (type << 8) | value;
-
- add_cid_event(cs, cid, rt->resp_code, NULL, parameter);
- break;
-
- case RT_NUMBER:
- /* check parameter separator */
- if (*eoc++ != '=')
- goto bad_param;
-
- /* decode parameter value */
- if (kstrtoint(eoc, 10, &parameter))
- goto bad_param;
-
- /* special case ZDLE: set flag before queueing event */
- if (rt->resp_code == RSP_ZDLE)
- cs->dle = parameter;
-
- add_cid_event(cs, cid, rt->resp_code, NULL, parameter);
- break;
-
-bad_param:
- /* parameter unexpected, incomplete or malformed */
- dev_warn(cs->dev, "bad parameter in response '%s'\n",
- cs->respdata);
- add_cid_event(cs, cid, rt->resp_code, NULL, -1);
- break;
-
- default:
- dev_err(cs->dev, "%s: internal error on '%s'\n",
- __func__, cs->respdata);
- }
-}
-EXPORT_SYMBOL_GPL(gigaset_handle_modem_response);
-
-/* disconnect_nobc
- * process closing of connection associated with given AT state structure
- * without B channel
- */
-static void disconnect_nobc(struct at_state_t **at_state_p,
- struct cardstate *cs)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&cs->lock, flags);
- ++(*at_state_p)->seq_index;
-
- /* revert to selected idle mode */
- if (!cs->cidmode) {
- cs->at_state.pending_commands |= PC_UMMODE;
- gig_dbg(DEBUG_EVENT, "Scheduling PC_UMMODE");
- cs->commands_pending = 1;
- }
-
- /* check for and deallocate temporary AT state */
- if (!list_empty(&(*at_state_p)->list)) {
- list_del(&(*at_state_p)->list);
- kfree(*at_state_p);
- *at_state_p = NULL;
- }
-
- spin_unlock_irqrestore(&cs->lock, flags);
-}
-
-/* disconnect_bc
- * process closing of connection associated with given AT state structure
- * and B channel
- */
-static void disconnect_bc(struct at_state_t *at_state,
- struct cardstate *cs, struct bc_state *bcs)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&cs->lock, flags);
- ++at_state->seq_index;
-
- /* revert to selected idle mode */
- if (!cs->cidmode) {
- cs->at_state.pending_commands |= PC_UMMODE;
- gig_dbg(DEBUG_EVENT, "Scheduling PC_UMMODE");
- cs->commands_pending = 1;
- }
- spin_unlock_irqrestore(&cs->lock, flags);
-
- /* invoke hardware specific handler */
- cs->ops->close_bchannel(bcs);
-
- /* notify LL */
- if (bcs->chstate & (CHS_D_UP | CHS_NOTIFY_LL)) {
- bcs->chstate &= ~(CHS_D_UP | CHS_NOTIFY_LL);
- gigaset_isdn_hupD(bcs);
- }
-}
-
-/* get_free_channel
- * get a free AT state structure: either one of those associated with the
- * B channels of the Gigaset device, or if none of those is available,
- * a newly allocated one with bcs=NULL
- * The structure should be freed by calling disconnect_nobc() after use.
- */
-static inline struct at_state_t *get_free_channel(struct cardstate *cs,
- int cid)
-/* cids: >0: siemens-cid
- * 0: without cid
- * -1: no cid assigned yet
- */
-{
- unsigned long flags;
- int i;
- struct at_state_t *ret;
-
- for (i = 0; i < cs->channels; ++i)
- if (gigaset_get_channel(cs->bcs + i) >= 0) {
- ret = &cs->bcs[i].at_state;
- ret->cid = cid;
- return ret;
- }
-
- spin_lock_irqsave(&cs->lock, flags);
- ret = kmalloc(sizeof(struct at_state_t), GFP_ATOMIC);
- if (ret) {
- gigaset_at_init(ret, NULL, cs, cid);
- list_add(&ret->list, &cs->temp_at_states);
- }
- spin_unlock_irqrestore(&cs->lock, flags);
- return ret;
-}
-
-static void init_failed(struct cardstate *cs, int mode)
-{
- int i;
- struct at_state_t *at_state;
-
- cs->at_state.pending_commands &= ~PC_INIT;
- cs->mode = mode;
- cs->mstate = MS_UNINITIALIZED;
- gigaset_free_channels(cs);
- for (i = 0; i < cs->channels; ++i) {
- at_state = &cs->bcs[i].at_state;
- if (at_state->pending_commands & PC_CID) {
- at_state->pending_commands &= ~PC_CID;
- at_state->pending_commands |= PC_NOCID;
- cs->commands_pending = 1;
- }
- }
-}
-
-static void schedule_init(struct cardstate *cs, int state)
-{
- if (cs->at_state.pending_commands & PC_INIT) {
- gig_dbg(DEBUG_EVENT, "not scheduling PC_INIT again");
- return;
- }
- cs->mstate = state;
- cs->mode = M_UNKNOWN;
- gigaset_block_channels(cs);
- cs->at_state.pending_commands |= PC_INIT;
- gig_dbg(DEBUG_EVENT, "Scheduling PC_INIT");
- cs->commands_pending = 1;
-}
-
-/* send an AT command
- * adding the "AT" prefix, cid and DLE encapsulation as appropriate
- */
-static void send_command(struct cardstate *cs, const char *cmd,
- struct at_state_t *at_state)
-{
- int cid = at_state->cid;
- struct cmdbuf_t *cb;
- size_t buflen;
-
- buflen = strlen(cmd) + 12; /* DLE ( A T 1 2 3 4 5 <cmd> DLE ) \0 */
- cb = kmalloc(sizeof(struct cmdbuf_t) + buflen, GFP_ATOMIC);
- if (!cb) {
- dev_err(cs->dev, "%s: out of memory\n", __func__);
- return;
- }
- if (cid > 0 && cid <= 65535)
- cb->len = snprintf(cb->buf, buflen,
- cs->dle ? "\020(AT%d%s\020)" : "AT%d%s",
- cid, cmd);
- else
- cb->len = snprintf(cb->buf, buflen,
- cs->dle ? "\020(AT%s\020)" : "AT%s",
- cmd);
- cb->offset = 0;
- cb->next = NULL;
- cb->wake_tasklet = NULL;
- cs->ops->write_cmd(cs, cb);
-}
-
-static struct at_state_t *at_state_from_cid(struct cardstate *cs, int cid)
-{
- struct at_state_t *at_state;
- int i;
- unsigned long flags;
-
- if (cid == 0)
- return &cs->at_state;
-
- for (i = 0; i < cs->channels; ++i)
- if (cid == cs->bcs[i].at_state.cid)
- return &cs->bcs[i].at_state;
-
- spin_lock_irqsave(&cs->lock, flags);
-
- list_for_each_entry(at_state, &cs->temp_at_states, list)
- if (cid == at_state->cid) {
- spin_unlock_irqrestore(&cs->lock, flags);
- return at_state;
- }
-
- spin_unlock_irqrestore(&cs->lock, flags);
-
- return NULL;
-}
-
-static void bchannel_down(struct bc_state *bcs)
-{
- if (bcs->chstate & CHS_B_UP) {
- bcs->chstate &= ~CHS_B_UP;
- gigaset_isdn_hupB(bcs);
- }
-
- if (bcs->chstate & (CHS_D_UP | CHS_NOTIFY_LL)) {
- bcs->chstate &= ~(CHS_D_UP | CHS_NOTIFY_LL);
- gigaset_isdn_hupD(bcs);
- }
-
- gigaset_free_channel(bcs);
-
- gigaset_bcs_reinit(bcs);
-}
-
-static void bchannel_up(struct bc_state *bcs)
-{
- if (bcs->chstate & CHS_B_UP) {
- dev_notice(bcs->cs->dev, "%s: B channel already up\n",
- __func__);
- return;
- }
-
- bcs->chstate |= CHS_B_UP;
- gigaset_isdn_connB(bcs);
-}
-
-static void start_dial(struct at_state_t *at_state, void *data,
- unsigned seq_index)
-{
- struct bc_state *bcs = at_state->bcs;
- struct cardstate *cs = at_state->cs;
- char **commands = data;
- unsigned long flags;
- int i;
-
- bcs->chstate |= CHS_NOTIFY_LL;
-
- spin_lock_irqsave(&cs->lock, flags);
- if (at_state->seq_index != seq_index) {
- spin_unlock_irqrestore(&cs->lock, flags);
- goto error;
- }
- spin_unlock_irqrestore(&cs->lock, flags);
-
- for (i = 0; i < AT_NUM; ++i) {
- kfree(bcs->commands[i]);
- bcs->commands[i] = commands[i];
- }
-
- at_state->pending_commands |= PC_CID;
- gig_dbg(DEBUG_EVENT, "Scheduling PC_CID");
- cs->commands_pending = 1;
- return;
-
-error:
- for (i = 0; i < AT_NUM; ++i) {
- kfree(commands[i]);
- commands[i] = NULL;
- }
- at_state->pending_commands |= PC_NOCID;
- gig_dbg(DEBUG_EVENT, "Scheduling PC_NOCID");
- cs->commands_pending = 1;
- return;
-}
-
-static void start_accept(struct at_state_t *at_state)
-{
- struct cardstate *cs = at_state->cs;
- struct bc_state *bcs = at_state->bcs;
- int i;
-
- for (i = 0; i < AT_NUM; ++i) {
- kfree(bcs->commands[i]);
- bcs->commands[i] = NULL;
- }
-
- bcs->commands[AT_PROTO] = kmalloc(9, GFP_ATOMIC);
- bcs->commands[AT_ISO] = kmalloc(9, GFP_ATOMIC);
- if (!bcs->commands[AT_PROTO] || !bcs->commands[AT_ISO]) {
- dev_err(at_state->cs->dev, "out of memory\n");
- /* error reset */
- at_state->pending_commands |= PC_HUP;
- gig_dbg(DEBUG_EVENT, "Scheduling PC_HUP");
- cs->commands_pending = 1;
- return;
- }
-
- snprintf(bcs->commands[AT_PROTO], 9, "^SBPR=%u\r", bcs->proto2);
- snprintf(bcs->commands[AT_ISO], 9, "^SISO=%u\r", bcs->channel + 1);
-
- at_state->pending_commands |= PC_ACCEPT;
- gig_dbg(DEBUG_EVENT, "Scheduling PC_ACCEPT");
- cs->commands_pending = 1;
-}
-
-static void do_start(struct cardstate *cs)
-{
- gigaset_free_channels(cs);
-
- if (cs->mstate != MS_LOCKED)
- schedule_init(cs, MS_INIT);
-
- cs->isdn_up = 1;
- gigaset_isdn_start(cs);
-
- cs->waiting = 0;
- wake_up(&cs->waitqueue);
-}
-
-static void finish_shutdown(struct cardstate *cs)
-{
- if (cs->mstate != MS_LOCKED) {
- cs->mstate = MS_UNINITIALIZED;
- cs->mode = M_UNKNOWN;
- }
-
- /* Tell the LL that the device is not available .. */
- if (cs->isdn_up) {
- cs->isdn_up = 0;
- gigaset_isdn_stop(cs);
- }
-
- /* The rest is done by cleanup_cs() in process context. */
-
- cs->cmd_result = -ENODEV;
- cs->waiting = 0;
- wake_up(&cs->waitqueue);
-}
-
-static void do_shutdown(struct cardstate *cs)
-{
- gigaset_block_channels(cs);
-
- if (cs->mstate == MS_READY) {
- cs->mstate = MS_SHUTDOWN;
- cs->at_state.pending_commands |= PC_SHUTDOWN;
- gig_dbg(DEBUG_EVENT, "Scheduling PC_SHUTDOWN");
- cs->commands_pending = 1;
- } else
- finish_shutdown(cs);
-}
-
-static void do_stop(struct cardstate *cs)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&cs->lock, flags);
- cs->connected = 0;
- spin_unlock_irqrestore(&cs->lock, flags);
-
- do_shutdown(cs);
-}
-
-/* Entering cid mode or getting a cid failed:
- * try to initialize the device and try again.
- *
- * channel >= 0: getting cid for the channel failed
- * channel < 0: entering cid mode failed
- *
- * returns 0 on success, <0 on failure
- */
-static int reinit_and_retry(struct cardstate *cs, int channel)
-{
- int i;
-
- if (--cs->retry_count <= 0)
- return -EFAULT;
-
- for (i = 0; i < cs->channels; ++i)
- if (cs->bcs[i].at_state.cid > 0)
- return -EBUSY;
-
- if (channel < 0)
- dev_warn(cs->dev,
- "Could not enter cid mode. Reinit device and try again.\n");
- else {
- dev_warn(cs->dev,
- "Could not get a call id. Reinit device and try again.\n");
- cs->bcs[channel].at_state.pending_commands |= PC_CID;
- }
- schedule_init(cs, MS_INIT);
- return 0;
-}
-
-static int at_state_invalid(struct cardstate *cs,
- struct at_state_t *test_ptr)
-{
- unsigned long flags;
- unsigned channel;
- struct at_state_t *at_state;
- int retval = 0;
-
- spin_lock_irqsave(&cs->lock, flags);
-
- if (test_ptr == &cs->at_state)
- goto exit;
-
- list_for_each_entry(at_state, &cs->temp_at_states, list)
- if (at_state == test_ptr)
- goto exit;
-
- for (channel = 0; channel < cs->channels; ++channel)
- if (&cs->bcs[channel].at_state == test_ptr)
- goto exit;
-
- retval = 1;
-exit:
- spin_unlock_irqrestore(&cs->lock, flags);
- return retval;
-}
-
-static void handle_icall(struct cardstate *cs, struct bc_state *bcs,
- struct at_state_t *at_state)
-{
- int retval;
-
- retval = gigaset_isdn_icall(at_state);
- switch (retval) {
- case ICALL_ACCEPT:
- break;
- default:
- dev_err(cs->dev, "internal error: disposition=%d\n", retval);
- /* fall through */
- case ICALL_IGNORE:
- case ICALL_REJECT:
- /* hang up actively
- * Device doc says that would reject the call.
- * In fact it doesn't.
- */
- at_state->pending_commands |= PC_HUP;
- cs->commands_pending = 1;
- break;
- }
-}
-
-static int do_lock(struct cardstate *cs)
-{
- int mode;
- int i;
-
- switch (cs->mstate) {
- case MS_UNINITIALIZED:
- case MS_READY:
- if (cs->cur_at_seq || !list_empty(&cs->temp_at_states) ||
- cs->at_state.pending_commands)
- return -EBUSY;
-
- for (i = 0; i < cs->channels; ++i)
- if (cs->bcs[i].at_state.pending_commands)
- return -EBUSY;
-
- if (gigaset_get_channels(cs) < 0)
- return -EBUSY;
-
- break;
- case MS_LOCKED:
- break;
- default:
- return -EBUSY;
- }
-
- mode = cs->mode;
- cs->mstate = MS_LOCKED;
- cs->mode = M_UNKNOWN;
-
- return mode;
-}
-
-static int do_unlock(struct cardstate *cs)
-{
- if (cs->mstate != MS_LOCKED)
- return -EINVAL;
-
- cs->mstate = MS_UNINITIALIZED;
- cs->mode = M_UNKNOWN;
- gigaset_free_channels(cs);
- if (cs->connected)
- schedule_init(cs, MS_INIT);
-
- return 0;
-}
-
-static void do_action(int action, struct cardstate *cs,
- struct bc_state *bcs,
- struct at_state_t **p_at_state, char **pp_command,
- int *p_genresp, int *p_resp_code,
- struct event_t *ev)
-{
- struct at_state_t *at_state = *p_at_state;
- struct bc_state *bcs2;
- unsigned long flags;
-
- int channel;
-
- unsigned char *s, *e;
- int i;
- unsigned long val;
-
- switch (action) {
- case ACT_NOTHING:
- break;
- case ACT_TIMEOUT:
- at_state->waiting = 1;
- break;
- case ACT_INIT:
- cs->at_state.pending_commands &= ~PC_INIT;
- cs->cur_at_seq = SEQ_NONE;
- cs->mode = M_UNIMODEM;
- spin_lock_irqsave(&cs->lock, flags);
- if (!cs->cidmode) {
- spin_unlock_irqrestore(&cs->lock, flags);
- gigaset_free_channels(cs);
- cs->mstate = MS_READY;
- break;
- }
- spin_unlock_irqrestore(&cs->lock, flags);
- cs->at_state.pending_commands |= PC_CIDMODE;
- gig_dbg(DEBUG_EVENT, "Scheduling PC_CIDMODE");
- cs->commands_pending = 1;
- break;
- case ACT_FAILINIT:
- dev_warn(cs->dev, "Could not initialize the device.\n");
- cs->dle = 0;
- init_failed(cs, M_UNKNOWN);
- cs->cur_at_seq = SEQ_NONE;
- break;
- case ACT_CONFIGMODE:
- init_failed(cs, M_CONFIG);
- cs->cur_at_seq = SEQ_NONE;
- break;
- case ACT_SETDLE1:
- cs->dle = 1;
- /* cs->inbuf[0].inputstate |= INS_command | INS_DLE_command; */
- cs->inbuf[0].inputstate &=
- ~(INS_command | INS_DLE_command);
- break;
- case ACT_SETDLE0:
- cs->dle = 0;
- cs->inbuf[0].inputstate =
- (cs->inbuf[0].inputstate & ~INS_DLE_command)
- | INS_command;
- break;
- case ACT_CMODESET:
- if (cs->mstate == MS_INIT || cs->mstate == MS_RECOVER) {
- gigaset_free_channels(cs);
- cs->mstate = MS_READY;
- }
- cs->mode = M_CID;
- cs->cur_at_seq = SEQ_NONE;
- break;
- case ACT_UMODESET:
- cs->mode = M_UNIMODEM;
- cs->cur_at_seq = SEQ_NONE;
- break;
- case ACT_FAILCMODE:
- cs->cur_at_seq = SEQ_NONE;
- if (cs->mstate == MS_INIT || cs->mstate == MS_RECOVER) {
- init_failed(cs, M_UNKNOWN);
- break;
- }
- if (reinit_and_retry(cs, -1) < 0)
- schedule_init(cs, MS_RECOVER);
- break;
- case ACT_FAILUMODE:
- cs->cur_at_seq = SEQ_NONE;
- schedule_init(cs, MS_RECOVER);
- break;
- case ACT_HUPMODEM:
- /* send "+++" (hangup in unimodem mode) */
- if (cs->connected) {
- struct cmdbuf_t *cb;
-
- cb = kmalloc(sizeof(struct cmdbuf_t) + 3, GFP_ATOMIC);
- if (!cb) {
- dev_err(cs->dev, "%s: out of memory\n",
- __func__);
- return;
- }
- memcpy(cb->buf, "+++", 3);
- cb->len = 3;
- cb->offset = 0;
- cb->next = NULL;
- cb->wake_tasklet = NULL;
- cs->ops->write_cmd(cs, cb);
- }
- break;
- case ACT_RING:
- /* get fresh AT state structure for new CID */
- at_state = get_free_channel(cs, ev->parameter);
- if (!at_state) {
- dev_warn(cs->dev,
- "RING ignored: could not allocate channel structure\n");
- break;
- }
-
- /* initialize AT state structure
- * note that bcs may be NULL if no B channel is free
- */
- at_state->ConState = 700;
- for (i = 0; i < STR_NUM; ++i) {
- kfree(at_state->str_var[i]);
- at_state->str_var[i] = NULL;
- }
- at_state->int_var[VAR_ZCTP] = -1;
-
- spin_lock_irqsave(&cs->lock, flags);
- at_state->timer_expires = RING_TIMEOUT;
- at_state->timer_active = 1;
- spin_unlock_irqrestore(&cs->lock, flags);
- break;
- case ACT_ICALL:
- handle_icall(cs, bcs, at_state);
- break;
- case ACT_FAILSDOWN:
- dev_warn(cs->dev, "Could not shut down the device.\n");
- /* fall through */
- case ACT_FAKESDOWN:
- case ACT_SDOWN:
- cs->cur_at_seq = SEQ_NONE;
- finish_shutdown(cs);
- break;
- case ACT_CONNECT:
- if (cs->onechannel) {
- at_state->pending_commands |= PC_DLE1;
- cs->commands_pending = 1;
- break;
- }
- bcs->chstate |= CHS_D_UP;
- gigaset_isdn_connD(bcs);
- cs->ops->init_bchannel(bcs);
- break;
- case ACT_DLE1:
- cs->cur_at_seq = SEQ_NONE;
- bcs = cs->bcs + cs->curchannel;
-
- bcs->chstate |= CHS_D_UP;
- gigaset_isdn_connD(bcs);
- cs->ops->init_bchannel(bcs);
- break;
- case ACT_FAKEHUP:
- at_state->int_var[VAR_ZSAU] = ZSAU_NULL;
- /* fall through */
- case ACT_DISCONNECT:
- cs->cur_at_seq = SEQ_NONE;
- at_state->cid = -1;
- if (!bcs) {
- disconnect_nobc(p_at_state, cs);
- } else if (cs->onechannel && cs->dle) {
- /* Check for other open channels not needed:
- * DLE only used for M10x with one B channel.
- */
- at_state->pending_commands |= PC_DLE0;
- cs->commands_pending = 1;
- } else {
- disconnect_bc(at_state, cs, bcs);
- }
- break;
- case ACT_FAKEDLE0:
- at_state->int_var[VAR_ZDLE] = 0;
- cs->dle = 0;
- /* fall through */
- case ACT_DLE0:
- cs->cur_at_seq = SEQ_NONE;
- bcs2 = cs->bcs + cs->curchannel;
- disconnect_bc(&bcs2->at_state, cs, bcs2);
- break;
- case ACT_ABORTHUP:
- cs->cur_at_seq = SEQ_NONE;
- dev_warn(cs->dev, "Could not hang up.\n");
- at_state->cid = -1;
- if (!bcs)
- disconnect_nobc(p_at_state, cs);
- else if (cs->onechannel)
- at_state->pending_commands |= PC_DLE0;
- else
- disconnect_bc(at_state, cs, bcs);
- schedule_init(cs, MS_RECOVER);
- break;
- case ACT_FAILDLE0:
- cs->cur_at_seq = SEQ_NONE;
- dev_warn(cs->dev, "Error leaving DLE mode.\n");
- cs->dle = 0;
- bcs2 = cs->bcs + cs->curchannel;
- disconnect_bc(&bcs2->at_state, cs, bcs2);
- schedule_init(cs, MS_RECOVER);
- break;
- case ACT_FAILDLE1:
- cs->cur_at_seq = SEQ_NONE;
- dev_warn(cs->dev,
- "Could not enter DLE mode. Trying to hang up.\n");
- channel = cs->curchannel;
- cs->bcs[channel].at_state.pending_commands |= PC_HUP;
- cs->commands_pending = 1;
- break;
-
- case ACT_CID: /* got cid; start dialing */
- cs->cur_at_seq = SEQ_NONE;
- channel = cs->curchannel;
- if (ev->parameter > 0 && ev->parameter <= 65535) {
- cs->bcs[channel].at_state.cid = ev->parameter;
- cs->bcs[channel].at_state.pending_commands |=
- PC_DIAL;
- cs->commands_pending = 1;
- break;
- }
- /* fall through - bad cid */
- case ACT_FAILCID:
- cs->cur_at_seq = SEQ_NONE;
- channel = cs->curchannel;
- if (reinit_and_retry(cs, channel) < 0) {
- dev_warn(cs->dev,
- "Could not get a call ID. Cannot dial.\n");
- bcs2 = cs->bcs + channel;
- disconnect_bc(&bcs2->at_state, cs, bcs2);
- }
- break;
- case ACT_ABORTCID:
- cs->cur_at_seq = SEQ_NONE;
- bcs2 = cs->bcs + cs->curchannel;
- disconnect_bc(&bcs2->at_state, cs, bcs2);
- break;
-
- case ACT_DIALING:
- case ACT_ACCEPTED:
- cs->cur_at_seq = SEQ_NONE;
- break;
-
- case ACT_ABORTACCEPT: /* hangup/error/timeout during ICALL procssng */
- if (bcs)
- disconnect_bc(at_state, cs, bcs);
- else
- disconnect_nobc(p_at_state, cs);
- break;
-
- case ACT_ABORTDIAL: /* error/timeout during dial preparation */
- cs->cur_at_seq = SEQ_NONE;
- at_state->pending_commands |= PC_HUP;
- cs->commands_pending = 1;
- break;
-
- case ACT_REMOTEREJECT: /* DISCONNECT_IND after dialling */
- case ACT_CONNTIMEOUT: /* timeout waiting for ZSAU=ACTIVE */
- case ACT_REMOTEHUP: /* DISCONNECT_IND with established connection */
- at_state->pending_commands |= PC_HUP;
- cs->commands_pending = 1;
- break;
- case ACT_GETSTRING: /* warning: RING, ZDLE, ...
- are not handled properly anymore */
- at_state->getstring = 1;
- break;
- case ACT_SETVER:
- if (!ev->ptr) {
- *p_genresp = 1;
- *p_resp_code = RSP_ERROR;
- break;
- }
- s = ev->ptr;
-
- if (!strcmp(s, "OK")) {
- /* OK without version string: assume old response */
- *p_genresp = 1;
- *p_resp_code = RSP_NONE;
- break;
- }
-
- for (i = 0; i < 4; ++i) {
- val = simple_strtoul(s, (char **) &e, 10);
- if (val > INT_MAX || e == s)
- break;
- if (i == 3) {
- if (*e)
- break;
- } else if (*e != '.')
- break;
- else
- s = e + 1;
- cs->fwver[i] = val;
- }
- if (i != 4) {
- *p_genresp = 1;
- *p_resp_code = RSP_ERROR;
- break;
- }
- cs->gotfwver = 0;
- break;
- case ACT_GOTVER:
- if (cs->gotfwver == 0) {
- cs->gotfwver = 1;
- gig_dbg(DEBUG_EVENT,
- "firmware version %02d.%03d.%02d.%02d",
- cs->fwver[0], cs->fwver[1],
- cs->fwver[2], cs->fwver[3]);
- break;
- }
- /* fall through */
- case ACT_FAILVER:
- cs->gotfwver = -1;
- dev_err(cs->dev, "could not read firmware version.\n");
- break;
- case ACT_ERROR:
- gig_dbg(DEBUG_ANY, "%s: ERROR response in ConState %d",
- __func__, at_state->ConState);
- cs->cur_at_seq = SEQ_NONE;
- break;
- case ACT_DEBUG:
- gig_dbg(DEBUG_ANY, "%s: resp_code %d in ConState %d",
- __func__, ev->type, at_state->ConState);
- break;
- case ACT_WARN:
- dev_warn(cs->dev, "%s: resp_code %d in ConState %d!\n",
- __func__, ev->type, at_state->ConState);
- break;
- case ACT_ZCAU:
- dev_warn(cs->dev, "cause code %04x in connection state %d.\n",
- ev->parameter, at_state->ConState);
- break;
-
- /* events from the LL */
-
- case ACT_DIAL:
- if (!ev->ptr) {
- *p_genresp = 1;
- *p_resp_code = RSP_ERROR;
- break;
- }
- start_dial(at_state, ev->ptr, ev->parameter);
- break;
- case ACT_ACCEPT:
- start_accept(at_state);
- break;
- case ACT_HUP:
- at_state->pending_commands |= PC_HUP;
- gig_dbg(DEBUG_EVENT, "Scheduling PC_HUP");
- cs->commands_pending = 1;
- break;
-
- /* hotplug events */
-
- case ACT_STOP:
- do_stop(cs);
- break;
- case ACT_START:
- do_start(cs);
- break;
-
- /* events from the interface */
-
- case ACT_IF_LOCK:
- cs->cmd_result = ev->parameter ? do_lock(cs) : do_unlock(cs);
- cs->waiting = 0;
- wake_up(&cs->waitqueue);
- break;
- case ACT_IF_VER:
- if (ev->parameter != 0)
- cs->cmd_result = -EINVAL;
- else if (cs->gotfwver != 1) {
- cs->cmd_result = -ENOENT;
- } else {
- memcpy(ev->arg, cs->fwver, sizeof cs->fwver);
- cs->cmd_result = 0;
- }
- cs->waiting = 0;
- wake_up(&cs->waitqueue);
- break;
-
- /* events from the proc file system */
-
- case ACT_PROC_CIDMODE:
- spin_lock_irqsave(&cs->lock, flags);
- if (ev->parameter != cs->cidmode) {
- cs->cidmode = ev->parameter;
- if (ev->parameter) {
- cs->at_state.pending_commands |= PC_CIDMODE;
- gig_dbg(DEBUG_EVENT, "Scheduling PC_CIDMODE");
- } else {
- cs->at_state.pending_commands |= PC_UMMODE;
- gig_dbg(DEBUG_EVENT, "Scheduling PC_UMMODE");
- }
- cs->commands_pending = 1;
- }
- spin_unlock_irqrestore(&cs->lock, flags);
- cs->waiting = 0;
- wake_up(&cs->waitqueue);
- break;
-
- /* events from the hardware drivers */
-
- case ACT_NOTIFY_BC_DOWN:
- bchannel_down(bcs);
- break;
- case ACT_NOTIFY_BC_UP:
- bchannel_up(bcs);
- break;
- case ACT_SHUTDOWN:
- do_shutdown(cs);
- break;
-
-
- default:
- if (action >= ACT_CMD && action < ACT_CMD + AT_NUM) {
- *pp_command = at_state->bcs->commands[action - ACT_CMD];
- if (!*pp_command) {
- *p_genresp = 1;
- *p_resp_code = RSP_NULL;
- }
- } else
- dev_err(cs->dev, "%s: action==%d!\n", __func__, action);
- }
-}
-
-/* State machine to do the calling and hangup procedure */
-static void process_event(struct cardstate *cs, struct event_t *ev)
-{
- struct bc_state *bcs;
- char *p_command = NULL;
- struct reply_t *rep;
- int rcode;
- int genresp = 0;
- int resp_code = RSP_ERROR;
- struct at_state_t *at_state;
- int index;
- int curact;
- unsigned long flags;
-
- if (ev->cid >= 0) {
- at_state = at_state_from_cid(cs, ev->cid);
- if (!at_state) {
- gig_dbg(DEBUG_EVENT, "event %d for invalid cid %d",
- ev->type, ev->cid);
- gigaset_add_event(cs, &cs->at_state, RSP_WRONG_CID,
- NULL, 0, NULL);
- return;
- }
- } else {
- at_state = ev->at_state;
- if (at_state_invalid(cs, at_state)) {
- gig_dbg(DEBUG_EVENT, "event for invalid at_state %p",
- at_state);
- return;
- }
- }
-
- gig_dbg(DEBUG_EVENT, "connection state %d, event %d",
- at_state->ConState, ev->type);
-
- bcs = at_state->bcs;
-
- /* Setting the pointer to the dial array */
- rep = at_state->replystruct;
-
- spin_lock_irqsave(&cs->lock, flags);
- if (ev->type == EV_TIMEOUT) {
- if (ev->parameter != at_state->timer_index
- || !at_state->timer_active) {
- ev->type = RSP_NONE; /* old timeout */
- gig_dbg(DEBUG_EVENT, "old timeout");
- } else {
- if (at_state->waiting)
- gig_dbg(DEBUG_EVENT, "stopped waiting");
- else
- gig_dbg(DEBUG_EVENT, "timeout occurred");
- }
- }
- spin_unlock_irqrestore(&cs->lock, flags);
-
- /* if the response belongs to a variable in at_state->int_var[VAR_XXXX]
- or at_state->str_var[STR_XXXX], set it */
- if (ev->type >= RSP_VAR && ev->type < RSP_VAR + VAR_NUM) {
- index = ev->type - RSP_VAR;
- at_state->int_var[index] = ev->parameter;
- } else if (ev->type >= RSP_STR && ev->type < RSP_STR + STR_NUM) {
- index = ev->type - RSP_STR;
- kfree(at_state->str_var[index]);
- at_state->str_var[index] = ev->ptr;
- ev->ptr = NULL; /* prevent process_events() from
- deallocating ptr */
- }
-
- if (ev->type == EV_TIMEOUT || ev->type == RSP_STRING)
- at_state->getstring = 0;
-
- /* Search row in dial array which matches modem response and current
- constate */
- for (;; rep++) {
- rcode = rep->resp_code;
- if (rcode == RSP_LAST) {
- /* found nothing...*/
- dev_warn(cs->dev, "%s: rcode=RSP_LAST: "
- "resp_code %d in ConState %d!\n",
- __func__, ev->type, at_state->ConState);
- return;
- }
- if ((rcode == RSP_ANY || rcode == ev->type)
- && ((int) at_state->ConState >= rep->min_ConState)
- && (rep->max_ConState < 0
- || (int) at_state->ConState <= rep->max_ConState)
- && (rep->parameter < 0 || rep->parameter == ev->parameter))
- break;
- }
-
- p_command = rep->command;
-
- at_state->waiting = 0;
- for (curact = 0; curact < MAXACT; ++curact) {
- /* The row tells us what we should do ..
- */
- do_action(rep->action[curact], cs, bcs, &at_state, &p_command,
- &genresp, &resp_code, ev);
- if (!at_state)
- /* at_state destroyed by disconnect */
- return;
- }
-
- /* Jump to the next con-state regarding the array */
- if (rep->new_ConState >= 0)
- at_state->ConState = rep->new_ConState;
-
- if (genresp) {
- spin_lock_irqsave(&cs->lock, flags);
- at_state->timer_expires = 0;
- at_state->timer_active = 0;
- spin_unlock_irqrestore(&cs->lock, flags);
- gigaset_add_event(cs, at_state, resp_code, NULL, 0, NULL);
- } else {
- /* Send command to modem if not NULL... */
- if (p_command) {
- if (cs->connected)
- send_command(cs, p_command, at_state);
- else
- gigaset_add_event(cs, at_state, RSP_NODEV,
- NULL, 0, NULL);
- }
-
- spin_lock_irqsave(&cs->lock, flags);
- if (!rep->timeout) {
- at_state->timer_expires = 0;
- at_state->timer_active = 0;
- } else if (rep->timeout > 0) { /* new timeout */
- at_state->timer_expires = rep->timeout * 10;
- at_state->timer_active = 1;
- ++at_state->timer_index;
- }
- spin_unlock_irqrestore(&cs->lock, flags);
- }
-}
-
-static void schedule_sequence(struct cardstate *cs,
- struct at_state_t *at_state, int sequence)
-{
- cs->cur_at_seq = sequence;
- gigaset_add_event(cs, at_state, RSP_INIT, NULL, sequence, NULL);
-}
-
-static void process_command_flags(struct cardstate *cs)
-{
- struct at_state_t *at_state = NULL;
- struct bc_state *bcs;
- int i;
- int sequence;
- unsigned long flags;
-
- cs->commands_pending = 0;
-
- if (cs->cur_at_seq) {
- gig_dbg(DEBUG_EVENT, "not searching scheduled commands: busy");
- return;
- }
-
- gig_dbg(DEBUG_EVENT, "searching scheduled commands");
-
- sequence = SEQ_NONE;
-
- /* clear pending_commands and hangup channels on shutdown */
- if (cs->at_state.pending_commands & PC_SHUTDOWN) {
- cs->at_state.pending_commands &= ~PC_CIDMODE;
- for (i = 0; i < cs->channels; ++i) {
- bcs = cs->bcs + i;
- at_state = &bcs->at_state;
- at_state->pending_commands &=
- ~(PC_DLE1 | PC_ACCEPT | PC_DIAL);
- if (at_state->cid > 0)
- at_state->pending_commands |= PC_HUP;
- if (at_state->pending_commands & PC_CID) {
- at_state->pending_commands |= PC_NOCID;
- at_state->pending_commands &= ~PC_CID;
- }
- }
- }
-
- /* clear pending_commands and hangup channels on reset */
- if (cs->at_state.pending_commands & PC_INIT) {
- cs->at_state.pending_commands &= ~PC_CIDMODE;
- for (i = 0; i < cs->channels; ++i) {
- bcs = cs->bcs + i;
- at_state = &bcs->at_state;
- at_state->pending_commands &=
- ~(PC_DLE1 | PC_ACCEPT | PC_DIAL);
- if (at_state->cid > 0)
- at_state->pending_commands |= PC_HUP;
- if (cs->mstate == MS_RECOVER) {
- if (at_state->pending_commands & PC_CID) {
- at_state->pending_commands |= PC_NOCID;
- at_state->pending_commands &= ~PC_CID;
- }
- }
- }
- }
-
- /* only switch back to unimodem mode if no commands are pending and
- * no channels are up */
- spin_lock_irqsave(&cs->lock, flags);
- if (cs->at_state.pending_commands == PC_UMMODE
- && !cs->cidmode
- && list_empty(&cs->temp_at_states)
- && cs->mode == M_CID) {
- sequence = SEQ_UMMODE;
- at_state = &cs->at_state;
- for (i = 0; i < cs->channels; ++i) {
- bcs = cs->bcs + i;
- if (bcs->at_state.pending_commands ||
- bcs->at_state.cid > 0) {
- sequence = SEQ_NONE;
- break;
- }
- }
- }
- spin_unlock_irqrestore(&cs->lock, flags);
- cs->at_state.pending_commands &= ~PC_UMMODE;
- if (sequence != SEQ_NONE) {
- schedule_sequence(cs, at_state, sequence);
- return;
- }
-
- for (i = 0; i < cs->channels; ++i) {
- bcs = cs->bcs + i;
- if (bcs->at_state.pending_commands & PC_HUP) {
- if (cs->dle) {
- cs->curchannel = bcs->channel;
- schedule_sequence(cs, &cs->at_state, SEQ_DLE0);
- return;
- }
- bcs->at_state.pending_commands &= ~PC_HUP;
- if (bcs->at_state.pending_commands & PC_CID) {
- /* not yet dialing: PC_NOCID is sufficient */
- bcs->at_state.pending_commands |= PC_NOCID;
- bcs->at_state.pending_commands &= ~PC_CID;
- } else {
- schedule_sequence(cs, &bcs->at_state, SEQ_HUP);
- return;
- }
- }
- if (bcs->at_state.pending_commands & PC_NOCID) {
- bcs->at_state.pending_commands &= ~PC_NOCID;
- cs->curchannel = bcs->channel;
- schedule_sequence(cs, &cs->at_state, SEQ_NOCID);
- return;
- } else if (bcs->at_state.pending_commands & PC_DLE0) {
- bcs->at_state.pending_commands &= ~PC_DLE0;
- cs->curchannel = bcs->channel;
- schedule_sequence(cs, &cs->at_state, SEQ_DLE0);
- return;
- }
- }
-
- list_for_each_entry(at_state, &cs->temp_at_states, list)
- if (at_state->pending_commands & PC_HUP) {
- at_state->pending_commands &= ~PC_HUP;
- schedule_sequence(cs, at_state, SEQ_HUP);
- return;
- }
-
- if (cs->at_state.pending_commands & PC_INIT) {
- cs->at_state.pending_commands &= ~PC_INIT;
- cs->dle = 0;
- cs->inbuf->inputstate = INS_command;
- schedule_sequence(cs, &cs->at_state, SEQ_INIT);
- return;
- }
- if (cs->at_state.pending_commands & PC_SHUTDOWN) {
- cs->at_state.pending_commands &= ~PC_SHUTDOWN;
- schedule_sequence(cs, &cs->at_state, SEQ_SHUTDOWN);
- return;
- }
- if (cs->at_state.pending_commands & PC_CIDMODE) {
- cs->at_state.pending_commands &= ~PC_CIDMODE;
- if (cs->mode == M_UNIMODEM) {
- cs->retry_count = 1;
- schedule_sequence(cs, &cs->at_state, SEQ_CIDMODE);
- return;
- }
- }
-
- for (i = 0; i < cs->channels; ++i) {
- bcs = cs->bcs + i;
- if (bcs->at_state.pending_commands & PC_DLE1) {
- bcs->at_state.pending_commands &= ~PC_DLE1;
- cs->curchannel = bcs->channel;
- schedule_sequence(cs, &cs->at_state, SEQ_DLE1);
- return;
- }
- if (bcs->at_state.pending_commands & PC_ACCEPT) {
- bcs->at_state.pending_commands &= ~PC_ACCEPT;
- schedule_sequence(cs, &bcs->at_state, SEQ_ACCEPT);
- return;
- }
- if (bcs->at_state.pending_commands & PC_DIAL) {
- bcs->at_state.pending_commands &= ~PC_DIAL;
- schedule_sequence(cs, &bcs->at_state, SEQ_DIAL);
- return;
- }
- if (bcs->at_state.pending_commands & PC_CID) {
- switch (cs->mode) {
- case M_UNIMODEM:
- cs->at_state.pending_commands |= PC_CIDMODE;
- gig_dbg(DEBUG_EVENT, "Scheduling PC_CIDMODE");
- cs->commands_pending = 1;
- return;
- case M_UNKNOWN:
- schedule_init(cs, MS_INIT);
- return;
- }
- bcs->at_state.pending_commands &= ~PC_CID;
- cs->curchannel = bcs->channel;
- cs->retry_count = 2;
- schedule_sequence(cs, &cs->at_state, SEQ_CID);
- return;
- }
- }
-}
-
-static void process_events(struct cardstate *cs)
-{
- struct event_t *ev;
- unsigned head, tail;
- int i;
- int check_flags = 0;
- int was_busy;
- unsigned long flags;
-
- spin_lock_irqsave(&cs->ev_lock, flags);
- head = cs->ev_head;
-
- for (i = 0; i < 2 * MAX_EVENTS; ++i) {
- tail = cs->ev_tail;
- if (tail == head) {
- if (!check_flags && !cs->commands_pending)
- break;
- check_flags = 0;
- spin_unlock_irqrestore(&cs->ev_lock, flags);
- process_command_flags(cs);
- spin_lock_irqsave(&cs->ev_lock, flags);
- tail = cs->ev_tail;
- if (tail == head) {
- if (!cs->commands_pending)
- break;
- continue;
- }
- }
-
- ev = cs->events + head;
- was_busy = cs->cur_at_seq != SEQ_NONE;
- spin_unlock_irqrestore(&cs->ev_lock, flags);
- process_event(cs, ev);
- spin_lock_irqsave(&cs->ev_lock, flags);
- kfree(ev->ptr);
- ev->ptr = NULL;
- if (was_busy && cs->cur_at_seq == SEQ_NONE)
- check_flags = 1;
-
- head = (head + 1) % MAX_EVENTS;
- cs->ev_head = head;
- }
-
- spin_unlock_irqrestore(&cs->ev_lock, flags);
-
- if (i == 2 * MAX_EVENTS) {
- dev_err(cs->dev,
- "infinite loop in process_events; aborting.\n");
- }
-}
-
-/* tasklet scheduled on any event received from the Gigaset device
- * parameter:
- * data ISDN controller state structure
- */
-void gigaset_handle_event(unsigned long data)
-{
- struct cardstate *cs = (struct cardstate *) data;
-
- /* handle incoming data on control/common channel */
- if (cs->inbuf->head != cs->inbuf->tail) {
- gig_dbg(DEBUG_INTR, "processing new data");
- cs->ops->handle_input(cs->inbuf);
- }
-
- process_events(cs);
-}
diff --git a/drivers/staging/isdn/gigaset/gigaset.h b/drivers/staging/isdn/gigaset/gigaset.h
deleted file mode 100644
index 0ecc2b5ea553..000000000000
--- a/drivers/staging/isdn/gigaset/gigaset.h
+++ /dev/null
@@ -1,827 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Siemens Gigaset 307x driver
- * Common header file for all connection variants
- *
- * Written by Stefan Eilers
- * and Hansjoerg Lipp <hjlipp@web.de>
- *
- * =====================================================================
- * =====================================================================
- */
-
-#ifndef GIGASET_H
-#define GIGASET_H
-
-/* define global prefix for pr_ macros in linux/kernel.h */
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/ctype.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-#include <linux/ppp_defs.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/tty.h>
-#include <linux/tty_driver.h>
-#include <linux/list.h>
-#include <linux/atomic.h>
-
-#define GIG_VERSION {0, 5, 0, 0}
-#define GIG_COMPAT {0, 4, 0, 0}
-
-#define MAX_REC_PARAMS 10 /* Max. number of params in response string */
-#define MAX_RESP_SIZE 511 /* Max. size of a response string */
-
-#define MAX_EVENTS 64 /* size of event queue */
-
-#define RBUFSIZE 8192
-
-#define GIG_TICK 100 /* in milliseconds */
-
-/* timeout values (unit: 1 sec) */
-#define INIT_TIMEOUT 1
-
-/* timeout values (unit: 0.1 sec) */
-#define RING_TIMEOUT 3 /* for additional parameters to RING */
-#define BAS_TIMEOUT 20 /* for response to Base USB ops */
-#define ATRDY_TIMEOUT 3 /* for HD_READY_SEND_ATDATA */
-
-#define BAS_RETRY 3 /* max. retries for base USB ops */
-
-#define MAXACT 3
-
-extern int gigaset_debuglevel; /* "needs" cast to (enum debuglevel) */
-
-/* debug flags, combine by adding/bitwise OR */
-enum debuglevel {
- DEBUG_INTR = 0x00008, /* interrupt processing */
- DEBUG_CMD = 0x00020, /* sent/received LL commands */
- DEBUG_STREAM = 0x00040, /* application data stream I/O events */
- DEBUG_STREAM_DUMP = 0x00080, /* application data stream content */
- DEBUG_LLDATA = 0x00100, /* sent/received LL data */
- DEBUG_EVENT = 0x00200, /* event processing */
- DEBUG_HDLC = 0x00800, /* M10x HDLC processing */
- DEBUG_CHANNEL = 0x01000, /* channel allocation/deallocation */
- DEBUG_TRANSCMD = 0x02000, /* AT-COMMANDS+RESPONSES */
- DEBUG_MCMD = 0x04000, /* COMMANDS THAT ARE SENT VERY OFTEN */
- DEBUG_INIT = 0x08000, /* (de)allocation+initialization of data
- structures */
- DEBUG_SUSPEND = 0x10000, /* suspend/resume processing */
- DEBUG_OUTPUT = 0x20000, /* output to device */
- DEBUG_ISO = 0x40000, /* isochronous transfers */
- DEBUG_IF = 0x80000, /* character device operations */
- DEBUG_USBREQ = 0x100000, /* USB communication (except payload
- data) */
- DEBUG_LOCKCMD = 0x200000, /* AT commands and responses when
- MS_LOCKED */
-
- DEBUG_ANY = 0x3fffff, /* print message if any of the others is
- activated */
-};
-
-#ifdef CONFIG_GIGASET_DEBUG
-
-#define gig_dbg(level, format, arg...) \
- do { \
- if (unlikely(((enum debuglevel)gigaset_debuglevel) & (level))) \
- printk(KERN_DEBUG KBUILD_MODNAME ": " format "\n", \
- ## arg); \
- } while (0)
-#define DEBUG_DEFAULT (DEBUG_TRANSCMD | DEBUG_CMD | DEBUG_USBREQ)
-
-#else
-
-#define gig_dbg(level, format, arg...) do {} while (0)
-#define DEBUG_DEFAULT 0
-
-#endif
-
-void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg,
- size_t len, const unsigned char *buf);
-
-/* connection state */
-#define ZSAU_NONE 0
-#define ZSAU_PROCEEDING 1
-#define ZSAU_CALL_DELIVERED 2
-#define ZSAU_ACTIVE 3
-#define ZSAU_DISCONNECT_IND 4
-#define ZSAU_NULL 5
-#define ZSAU_DISCONNECT_REQ 6
-#define ZSAU_UNKNOWN -1
-
-/* USB control transfer requests */
-#define OUT_VENDOR_REQ (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT)
-#define IN_VENDOR_REQ (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT)
-
-/* interrupt pipe messages */
-#define HD_B1_FLOW_CONTROL 0x80
-#define HD_B2_FLOW_CONTROL 0x81
-#define HD_RECEIVEATDATA_ACK (0x35) /* 3070 */
-#define HD_READY_SEND_ATDATA (0x36) /* 3070 */
-#define HD_OPEN_ATCHANNEL_ACK (0x37) /* 3070 */
-#define HD_CLOSE_ATCHANNEL_ACK (0x38) /* 3070 */
-#define HD_DEVICE_INIT_OK (0x11) /* ISurf USB + 3070 */
-#define HD_OPEN_B1CHANNEL_ACK (0x51) /* ISurf USB + 3070 */
-#define HD_OPEN_B2CHANNEL_ACK (0x52) /* ISurf USB + 3070 */
-#define HD_CLOSE_B1CHANNEL_ACK (0x53) /* ISurf USB + 3070 */
-#define HD_CLOSE_B2CHANNEL_ACK (0x54) /* ISurf USB + 3070 */
-#define HD_SUSPEND_END (0x61) /* ISurf USB */
-#define HD_RESET_INTERRUPT_PIPE_ACK (0xFF) /* ISurf USB + 3070 */
-
-/* control requests */
-#define HD_OPEN_B1CHANNEL (0x23) /* ISurf USB + 3070 */
-#define HD_CLOSE_B1CHANNEL (0x24) /* ISurf USB + 3070 */
-#define HD_OPEN_B2CHANNEL (0x25) /* ISurf USB + 3070 */
-#define HD_CLOSE_B2CHANNEL (0x26) /* ISurf USB + 3070 */
-#define HD_RESET_INTERRUPT_PIPE (0x27) /* ISurf USB + 3070 */
-#define HD_DEVICE_INIT_ACK (0x34) /* ISurf USB + 3070 */
-#define HD_WRITE_ATMESSAGE (0x12) /* 3070 */
-#define HD_READ_ATMESSAGE (0x13) /* 3070 */
-#define HD_OPEN_ATCHANNEL (0x28) /* 3070 */
-#define HD_CLOSE_ATCHANNEL (0x29) /* 3070 */
-
-/* number of B channels supported by base driver */
-#define BAS_CHANNELS 2
-
-/* USB frames for isochronous transfer */
-#define BAS_FRAMETIME 1 /* number of milliseconds between frames */
-#define BAS_NUMFRAMES 8 /* number of frames per URB */
-#define BAS_MAXFRAME 16 /* allocated bytes per frame */
-#define BAS_NORMFRAME 8 /* send size without flow control */
-#define BAS_HIGHFRAME 10 /* " " with positive flow control */
-#define BAS_LOWFRAME 5 /* " " with negative flow control */
-#define BAS_CORRFRAMES 4 /* flow control multiplicator */
-
-#define BAS_INBUFSIZE (BAS_MAXFRAME * BAS_NUMFRAMES) /* size of isoc in buf
- * per URB */
-#define BAS_OUTBUFSIZE 4096 /* size of common isoc out buffer */
-#define BAS_OUTBUFPAD BAS_MAXFRAME /* size of pad area for isoc out buf */
-
-#define BAS_INURBS 3
-#define BAS_OUTURBS 3
-
-/* variable commands in struct bc_state */
-#define AT_ISO 0
-#define AT_DIAL 1
-#define AT_MSN 2
-#define AT_BC 3
-#define AT_PROTO 4
-#define AT_TYPE 5
-#define AT_CLIP 6
-/* total number */
-#define AT_NUM 7
-
-/* variables in struct at_state_t */
-/* - numeric */
-#define VAR_ZSAU 0
-#define VAR_ZDLE 1
-#define VAR_ZCTP 2
-/* total number */
-#define VAR_NUM 3
-/* - string */
-#define STR_NMBR 0
-#define STR_ZCPN 1
-#define STR_ZCON 2
-#define STR_ZBC 3
-#define STR_ZHLC 4
-/* total number */
-#define STR_NUM 5
-
-/* event types */
-#define EV_TIMEOUT -105
-#define EV_IF_VER -106
-#define EV_PROC_CIDMODE -107
-#define EV_SHUTDOWN -108
-#define EV_START -110
-#define EV_STOP -111
-#define EV_IF_LOCK -112
-#define EV_ACCEPT -114
-#define EV_DIAL -115
-#define EV_HUP -116
-#define EV_BC_OPEN -117
-#define EV_BC_CLOSED -118
-
-/* input state */
-#define INS_command 0x0001 /* receiving messages (not payload data) */
-#define INS_DLE_char 0x0002 /* DLE flag received (in DLE mode) */
-#define INS_byte_stuff 0x0004
-#define INS_have_data 0x0008
-#define INS_DLE_command 0x0020 /* DLE message start (<DLE> X) received */
-#define INS_flag_hunt 0x0040
-
-/* channel state */
-#define CHS_D_UP 0x01
-#define CHS_B_UP 0x02
-#define CHS_NOTIFY_LL 0x04
-
-#define ICALL_REJECT 0
-#define ICALL_ACCEPT 1
-#define ICALL_IGNORE 2
-
-/* device state */
-#define MS_UNINITIALIZED 0
-#define MS_INIT 1
-#define MS_LOCKED 2
-#define MS_SHUTDOWN 3
-#define MS_RECOVER 4
-#define MS_READY 5
-
-/* mode */
-#define M_UNKNOWN 0
-#define M_CONFIG 1
-#define M_UNIMODEM 2
-#define M_CID 3
-
-/* start mode */
-#define SM_LOCKED 0
-#define SM_ISDN 1 /* default */
-
-/* layer 2 protocols (AT^SBPR=...) */
-#define L2_BITSYNC 0
-#define L2_HDLC 1
-#define L2_VOICE 2
-
-struct gigaset_ops;
-struct gigaset_driver;
-
-struct usb_cardstate;
-struct ser_cardstate;
-struct bas_cardstate;
-
-struct bc_state;
-struct usb_bc_state;
-struct ser_bc_state;
-struct bas_bc_state;
-
-struct reply_t {
- int resp_code; /* RSP_XXXX */
- int min_ConState; /* <0 => ignore */
- int max_ConState; /* <0 => ignore */
- int parameter; /* e.g. ZSAU_XXXX <0: ignore*/
- int new_ConState; /* <0 => ignore */
- int timeout; /* >0 => *HZ; <=0 => TOUT_XXXX*/
- int action[MAXACT]; /* ACT_XXXX */
- char *command; /* NULL==none */
-};
-
-extern struct reply_t gigaset_tab_cid[];
-extern struct reply_t gigaset_tab_nocid[];
-
-struct inbuf_t {
- struct cardstate *cs;
- int inputstate;
- int head, tail;
- unsigned char data[RBUFSIZE];
-};
-
-/* isochronous write buffer structure
- * circular buffer with pad area for extraction of complete USB frames
- * - data[read..nextread-1] is valid data already submitted to the USB subsystem
- * - data[nextread..write-1] is valid data yet to be sent
- * - data[write] is the next byte to write to
- * - in byte-oriented L2 procotols, it is completely free
- * - in bit-oriented L2 procotols, it may contain a partial byte of valid data
- * - data[write+1..read-1] is free
- * - wbits is the number of valid data bits in data[write], starting at the LSB
- * - writesem is the semaphore for writing to the buffer:
- * if writesem <= 0, data[write..read-1] is currently being written to
- * - idle contains the byte value to repeat when the end of valid data is
- * reached; if nextread==write (buffer contains no data to send), either the
- * BAS_OUTBUFPAD bytes immediately before data[write] (if
- * write>=BAS_OUTBUFPAD) or those of the pad area (if write<BAS_OUTBUFPAD)
- * are also filled with that value
- */
-struct isowbuf_t {
- int read;
- int nextread;
- int write;
- atomic_t writesem;
- int wbits;
- unsigned char data[BAS_OUTBUFSIZE + BAS_OUTBUFPAD];
- unsigned char idle;
-};
-
-/* isochronous write URB context structure
- * data to be stored along with the URB and retrieved when it is returned
- * as completed by the USB subsystem
- * - urb: pointer to the URB itself
- * - bcs: pointer to the B Channel control structure
- * - limit: end of write buffer area covered by this URB
- * - status: URB completion status
- */
-struct isow_urbctx_t {
- struct urb *urb;
- struct bc_state *bcs;
- int limit;
- int status;
-};
-
-/* AT state structure
- * data associated with the state of an ISDN connection, whether or not
- * it is currently assigned a B channel
- */
-struct at_state_t {
- struct list_head list;
- int waiting;
- int getstring;
- unsigned timer_index;
- unsigned long timer_expires;
- int timer_active;
- unsigned int ConState; /* State of connection */
- struct reply_t *replystruct;
- int cid;
- int int_var[VAR_NUM]; /* see VAR_XXXX */
- char *str_var[STR_NUM]; /* see STR_XXXX */
- unsigned pending_commands; /* see PC_XXXX */
- unsigned seq_index;
-
- struct cardstate *cs;
- struct bc_state *bcs;
-};
-
-struct event_t {
- int type;
- void *ptr, *arg;
- int parameter;
- int cid;
- struct at_state_t *at_state;
-};
-
-/* This buffer holds all information about the used B-Channel */
-struct bc_state {
- struct sk_buff *tx_skb; /* Current transfer buffer to modem */
- struct sk_buff_head squeue; /* B-Channel send Queue */
-
- /* Variables for debugging .. */
- int corrupted; /* Counter for corrupted packages */
- int trans_down; /* Counter of packages (downstream) */
- int trans_up; /* Counter of packages (upstream) */
-
- struct at_state_t at_state;
-
- /* receive buffer */
- unsigned rx_bufsize; /* max size accepted by application */
- struct sk_buff *rx_skb;
- __u16 rx_fcs;
- int inputstate; /* see INS_XXXX */
-
- int channel;
-
- struct cardstate *cs;
-
- unsigned chstate; /* bitmap (CHS_*) */
- int ignore;
- unsigned proto2; /* layer 2 protocol (L2_*) */
- char *commands[AT_NUM]; /* see AT_XXXX */
-
-#ifdef CONFIG_GIGASET_DEBUG
- int emptycount;
-#endif
- int busy;
- int use_count;
-
- /* private data of hardware drivers */
- union {
- struct ser_bc_state *ser; /* serial hardware driver */
- struct usb_bc_state *usb; /* usb hardware driver (m105) */
- struct bas_bc_state *bas; /* usb hardware driver (base) */
- } hw;
-
- void *ap; /* associated LL application */
- int apconnstate; /* LL application connection state */
- spinlock_t aplock;
-};
-
-struct cardstate {
- struct gigaset_driver *driver;
- unsigned minor_index;
- struct device *dev;
- struct device *tty_dev;
- unsigned flags;
-
- const struct gigaset_ops *ops;
-
- /* Stuff to handle communication */
- wait_queue_head_t waitqueue;
- int waiting;
- int mode; /* see M_XXXX */
- int mstate; /* Modem state: see MS_XXXX */
- /* only changed by the event layer */
- int cmd_result;
-
- int channels;
- struct bc_state *bcs; /* Array of struct bc_state */
-
- int onechannel; /* data and commands transmitted in one
- stream (M10x) */
-
- spinlock_t lock;
- struct at_state_t at_state; /* at_state_t for cid == 0 */
- struct list_head temp_at_states;/* list of temporary "struct
- at_state_t"s without B channel */
-
- struct inbuf_t *inbuf;
-
- struct cmdbuf_t *cmdbuf, *lastcmdbuf;
- spinlock_t cmdlock;
- unsigned curlen, cmdbytes;
-
- struct tty_port port;
- struct tasklet_struct if_wake_tasklet;
- unsigned control_state;
-
- unsigned fwver[4];
- int gotfwver;
-
- unsigned running; /* !=0 if events are handled */
- unsigned connected; /* !=0 if hardware is connected */
- unsigned isdn_up; /* !=0 after gigaset_isdn_start() */
-
- unsigned cidmode;
-
- int myid; /* id for communication with LL */
- void *iif; /* LL interface structure */
- unsigned short hw_hdr_len; /* headroom needed in data skbs */
-
- struct reply_t *tabnocid;
- struct reply_t *tabcid;
- int cs_init;
- int ignoreframes; /* frames to ignore after setting up the
- B channel */
- struct mutex mutex; /* locks this structure:
- * connected is not changed,
- * hardware_up is not changed,
- * MState is not changed to or from
- * MS_LOCKED */
-
- struct timer_list timer;
- int retry_count;
- int dle; /* !=0 if DLE mode is active
- (ZDLE=1 received -- M10x only) */
- int cur_at_seq; /* sequence of AT commands being
- processed */
- int curchannel; /* channel those commands are meant
- for */
- int commands_pending; /* flag(s) in xxx.commands_pending have
- been set */
- struct tasklet_struct
- event_tasklet; /* tasklet for serializing AT commands.
- * Scheduled
- * -> for modem reponses (and
- * incoming data for M10x)
- * -> on timeout
- * -> after setting bits in
- * xxx.at_state.pending_command
- * (e.g. command from LL) */
- struct tasklet_struct
- write_tasklet; /* tasklet for serial output
- * (not used in base driver) */
-
- /* event queue */
- struct event_t events[MAX_EVENTS];
- unsigned ev_tail, ev_head;
- spinlock_t ev_lock;
-
- /* current modem response */
- unsigned char respdata[MAX_RESP_SIZE + 1];
- unsigned cbytes;
-
- /* private data of hardware drivers */
- union {
- struct usb_cardstate *usb; /* USB hardware driver (m105) */
- struct ser_cardstate *ser; /* serial hardware driver */
- struct bas_cardstate *bas; /* USB hardware driver (base) */
- } hw;
-};
-
-struct gigaset_driver {
- struct list_head list;
- spinlock_t lock; /* locks minor tables and blocked */
- struct tty_driver *tty;
- unsigned have_tty;
- unsigned minor;
- unsigned minors;
- struct cardstate *cs;
- int blocked;
-
- const struct gigaset_ops *ops;
- struct module *owner;
-};
-
-struct cmdbuf_t {
- struct cmdbuf_t *next, *prev;
- int len, offset;
- struct tasklet_struct *wake_tasklet;
- unsigned char buf[0];
-};
-
-struct bas_bc_state {
- /* isochronous output state */
- int running;
- atomic_t corrbytes;
- spinlock_t isooutlock;
- struct isow_urbctx_t isoouturbs[BAS_OUTURBS];
- struct isow_urbctx_t *isooutdone, *isooutfree, *isooutovfl;
- struct isowbuf_t *isooutbuf;
- unsigned numsub; /* submitted URB counter
- (for diagnostic messages only) */
- struct tasklet_struct sent_tasklet;
-
- /* isochronous input state */
- spinlock_t isoinlock;
- struct urb *isoinurbs[BAS_INURBS];
- unsigned char isoinbuf[BAS_INBUFSIZE * BAS_INURBS];
- struct urb *isoindone; /* completed isoc read URB */
- int isoinstatus; /* status of completed URB */
- int loststatus; /* status of dropped URB */
- unsigned isoinlost; /* number of bytes lost */
- /* state of bit unstuffing algorithm
- (in addition to BC_state.inputstate) */
- unsigned seqlen; /* number of '1' bits not yet
- unstuffed */
- unsigned inbyte, inbits; /* collected bits for next byte */
- /* statistics */
- unsigned goodbytes; /* bytes correctly received */
- unsigned alignerrs; /* frames with incomplete byte at end */
- unsigned fcserrs; /* FCS errors */
- unsigned frameerrs; /* framing errors */
- unsigned giants; /* long frames */
- unsigned runts; /* short frames */
- unsigned aborts; /* HDLC aborts */
- unsigned shared0s; /* '0' bits shared between flags */
- unsigned stolen0s; /* '0' stuff bits also serving as
- leading flag bits */
- struct tasklet_struct rcvd_tasklet;
-};
-
-struct gigaset_ops {
- /* Called from ev-layer.c/interface.c for sending AT commands to the
- device */
- int (*write_cmd)(struct cardstate *cs, struct cmdbuf_t *cb);
-
- /* Called from interface.c for additional device control */
- int (*write_room)(struct cardstate *cs);
- int (*chars_in_buffer)(struct cardstate *cs);
- int (*brkchars)(struct cardstate *cs, const unsigned char buf[6]);
-
- /* Called from ev-layer.c after setting up connection
- * Should call gigaset_bchannel_up(), when finished. */
- int (*init_bchannel)(struct bc_state *bcs);
-
- /* Called from ev-layer.c after hanging up
- * Should call gigaset_bchannel_down(), when finished. */
- int (*close_bchannel)(struct bc_state *bcs);
-
- /* Called by gigaset_initcs() for setting up bcs->hw.xxx */
- int (*initbcshw)(struct bc_state *bcs);
-
- /* Called by gigaset_freecs() for freeing bcs->hw.xxx */
- void (*freebcshw)(struct bc_state *bcs);
-
- /* Called by gigaset_bchannel_down() for resetting bcs->hw.xxx */
- void (*reinitbcshw)(struct bc_state *bcs);
-
- /* Called by gigaset_initcs() for setting up cs->hw.xxx */
- int (*initcshw)(struct cardstate *cs);
-
- /* Called by gigaset_freecs() for freeing cs->hw.xxx */
- void (*freecshw)(struct cardstate *cs);
-
- /* Called from common.c/interface.c for additional serial port
- control */
- int (*set_modem_ctrl)(struct cardstate *cs, unsigned old_state,
- unsigned new_state);
- int (*baud_rate)(struct cardstate *cs, unsigned cflag);
- int (*set_line_ctrl)(struct cardstate *cs, unsigned cflag);
-
- /* Called from LL interface to put an skb into the send-queue.
- * After sending is completed, gigaset_skb_sent() must be called
- * with the skb's link layer header preserved. */
- int (*send_skb)(struct bc_state *bcs, struct sk_buff *skb);
-
- /* Called from ev-layer.c to process a block of data
- * received through the common/control channel. */
- void (*handle_input)(struct inbuf_t *inbuf);
-
-};
-
-/* = Common structures and definitions =======================================
- */
-
-/* Parser states for DLE-Event:
- * <DLE-EVENT>: <DLE_FLAG> "X" <EVENT> <DLE_FLAG> "."
- * <DLE_FLAG>: 0x10
- * <EVENT>: ((a-z)* | (A-Z)* | (0-10)*)+
- */
-#define DLE_FLAG 0x10
-
-/* ===========================================================================
- * Functions implemented in asyncdata.c
- */
-
-/* Called from LL interface to put an skb into the send queue. */
-int gigaset_m10x_send_skb(struct bc_state *bcs, struct sk_buff *skb);
-
-/* Called from ev-layer.c to process a block of data
- * received through the common/control channel. */
-void gigaset_m10x_input(struct inbuf_t *inbuf);
-
-/* ===========================================================================
- * Functions implemented in isocdata.c
- */
-
-/* Called from LL interface to put an skb into the send queue. */
-int gigaset_isoc_send_skb(struct bc_state *bcs, struct sk_buff *skb);
-
-/* Called from ev-layer.c to process a block of data
- * received through the common/control channel. */
-void gigaset_isoc_input(struct inbuf_t *inbuf);
-
-/* Called from bas-gigaset.c to process a block of data
- * received through the isochronous channel */
-void gigaset_isoc_receive(unsigned char *src, unsigned count,
- struct bc_state *bcs);
-
-/* Called from bas-gigaset.c to put a block of data
- * into the isochronous output buffer */
-int gigaset_isoc_buildframe(struct bc_state *bcs, unsigned char *in, int len);
-
-/* Called from bas-gigaset.c to initialize the isochronous output buffer */
-void gigaset_isowbuf_init(struct isowbuf_t *iwb, unsigned char idle);
-
-/* Called from bas-gigaset.c to retrieve a block of bytes for sending */
-int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size);
-
-/* ===========================================================================
- * Functions implemented in LL interface
- */
-
-/* Called from common.c for setting up/shutting down with the ISDN subsystem */
-void gigaset_isdn_regdrv(void);
-void gigaset_isdn_unregdrv(void);
-int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid);
-void gigaset_isdn_unregdev(struct cardstate *cs);
-
-/* Called from hardware module to indicate completion of an skb */
-void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb);
-void gigaset_skb_rcvd(struct bc_state *bcs, struct sk_buff *skb);
-void gigaset_isdn_rcv_err(struct bc_state *bcs);
-
-/* Called from common.c/ev-layer.c to indicate events relevant to the LL */
-void gigaset_isdn_start(struct cardstate *cs);
-void gigaset_isdn_stop(struct cardstate *cs);
-int gigaset_isdn_icall(struct at_state_t *at_state);
-void gigaset_isdn_connD(struct bc_state *bcs);
-void gigaset_isdn_hupD(struct bc_state *bcs);
-void gigaset_isdn_connB(struct bc_state *bcs);
-void gigaset_isdn_hupB(struct bc_state *bcs);
-
-/* ===========================================================================
- * Functions implemented in ev-layer.c
- */
-
-/* tasklet called from common.c to process queued events */
-void gigaset_handle_event(unsigned long data);
-
-/* called from isocdata.c / asyncdata.c
- * when a complete modem response line has been received */
-void gigaset_handle_modem_response(struct cardstate *cs);
-
-/* ===========================================================================
- * Functions implemented in proc.c
- */
-
-/* initialize sysfs for device */
-void gigaset_init_dev_sysfs(struct cardstate *cs);
-void gigaset_free_dev_sysfs(struct cardstate *cs);
-
-/* ===========================================================================
- * Functions implemented in common.c/gigaset.h
- */
-
-void gigaset_bcs_reinit(struct bc_state *bcs);
-void gigaset_at_init(struct at_state_t *at_state, struct bc_state *bcs,
- struct cardstate *cs, int cid);
-int gigaset_get_channel(struct bc_state *bcs);
-struct bc_state *gigaset_get_free_channel(struct cardstate *cs);
-void gigaset_free_channel(struct bc_state *bcs);
-int gigaset_get_channels(struct cardstate *cs);
-void gigaset_free_channels(struct cardstate *cs);
-void gigaset_block_channels(struct cardstate *cs);
-
-/* Allocate and initialize driver structure. */
-struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors,
- const char *procname,
- const char *devname,
- const struct gigaset_ops *ops,
- struct module *owner);
-
-/* Deallocate driver structure. */
-void gigaset_freedriver(struct gigaset_driver *drv);
-
-struct cardstate *gigaset_get_cs_by_tty(struct tty_struct *tty);
-struct cardstate *gigaset_get_cs_by_id(int id);
-void gigaset_blockdriver(struct gigaset_driver *drv);
-
-/* Allocate and initialize card state. Calls hardware dependent
- gigaset_init[b]cs(). */
-struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels,
- int onechannel, int ignoreframes,
- int cidmode, const char *modulename);
-
-/* Free card state. Calls hardware dependent gigaset_free[b]cs(). */
-void gigaset_freecs(struct cardstate *cs);
-
-/* Tell common.c that hardware and driver are ready. */
-int gigaset_start(struct cardstate *cs);
-
-/* Tell common.c that the device is not present any more. */
-void gigaset_stop(struct cardstate *cs);
-
-/* Tell common.c that the driver is being unloaded. */
-int gigaset_shutdown(struct cardstate *cs);
-
-/* Append event to the queue.
- * Returns NULL on failure or a pointer to the event on success.
- * ptr must be kmalloc()ed (and not be freed by the caller).
- */
-struct event_t *gigaset_add_event(struct cardstate *cs,
- struct at_state_t *at_state, int type,
- void *ptr, int parameter, void *arg);
-
-/* Called on CONFIG1 command from frontend. */
-int gigaset_enterconfigmode(struct cardstate *cs);
-
-/* cs->lock must not be locked */
-static inline void gigaset_schedule_event(struct cardstate *cs)
-{
- unsigned long flags;
- spin_lock_irqsave(&cs->lock, flags);
- if (cs->running)
- tasklet_schedule(&cs->event_tasklet);
- spin_unlock_irqrestore(&cs->lock, flags);
-}
-
-/* Tell common.c that B channel has been closed. */
-/* cs->lock must not be locked */
-static inline void gigaset_bchannel_down(struct bc_state *bcs)
-{
- gigaset_add_event(bcs->cs, &bcs->at_state, EV_BC_CLOSED, NULL, 0, NULL);
- gigaset_schedule_event(bcs->cs);
-}
-
-/* Tell common.c that B channel has been opened. */
-/* cs->lock must not be locked */
-static inline void gigaset_bchannel_up(struct bc_state *bcs)
-{
- gigaset_add_event(bcs->cs, &bcs->at_state, EV_BC_OPEN, NULL, 0, NULL);
- gigaset_schedule_event(bcs->cs);
-}
-
-/* set up next receive skb for data mode */
-static inline struct sk_buff *gigaset_new_rx_skb(struct bc_state *bcs)
-{
- struct cardstate *cs = bcs->cs;
- unsigned short hw_hdr_len = cs->hw_hdr_len;
-
- if (bcs->ignore) {
- bcs->rx_skb = NULL;
- } else {
- bcs->rx_skb = dev_alloc_skb(bcs->rx_bufsize + hw_hdr_len);
- if (bcs->rx_skb == NULL)
- dev_warn(cs->dev, "could not allocate skb\n");
- else
- skb_reserve(bcs->rx_skb, hw_hdr_len);
- }
- return bcs->rx_skb;
-}
-
-/* append received bytes to inbuf */
-int gigaset_fill_inbuf(struct inbuf_t *inbuf, const unsigned char *src,
- unsigned numbytes);
-
-/* ===========================================================================
- * Functions implemented in interface.c
- */
-
-/* initialize interface */
-void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname,
- const char *devname);
-/* release interface */
-void gigaset_if_freedriver(struct gigaset_driver *drv);
-/* add minor */
-void gigaset_if_init(struct cardstate *cs);
-/* remove minor */
-void gigaset_if_free(struct cardstate *cs);
-/* device received data */
-void gigaset_if_receive(struct cardstate *cs,
- unsigned char *buffer, size_t len);
-
-#endif
diff --git a/drivers/staging/isdn/gigaset/interface.c b/drivers/staging/isdn/gigaset/interface.c
deleted file mode 100644
index 9ddadd07e707..000000000000
--- a/drivers/staging/isdn/gigaset/interface.c
+++ /dev/null
@@ -1,613 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * interface to user space for the gigaset driver
- *
- * Copyright (c) 2004 by Hansjoerg Lipp <hjlipp@web.de>
- *
- * =====================================================================
- * =====================================================================
- */
-
-#include "gigaset.h"
-#include <linux/gigaset_dev.h>
-#include <linux/tty_flip.h>
-#include <linux/module.h>
-
-/*** our ioctls ***/
-
-static int if_lock(struct cardstate *cs, int *arg)
-{
- int cmd = *arg;
-
- gig_dbg(DEBUG_IF, "%u: if_lock (%d)", cs->minor_index, cmd);
-
- if (cmd > 1)
- return -EINVAL;
-
- if (cmd < 0) {
- *arg = cs->mstate == MS_LOCKED;
- return 0;
- }
-
- if (!cmd && cs->mstate == MS_LOCKED && cs->connected) {
- cs->ops->set_modem_ctrl(cs, 0, TIOCM_DTR | TIOCM_RTS);
- cs->ops->baud_rate(cs, B115200);
- cs->ops->set_line_ctrl(cs, CS8);
- cs->control_state = TIOCM_DTR | TIOCM_RTS;
- }
-
- cs->waiting = 1;
- if (!gigaset_add_event(cs, &cs->at_state, EV_IF_LOCK,
- NULL, cmd, NULL)) {
- cs->waiting = 0;
- return -ENOMEM;
- }
- gigaset_schedule_event(cs);
-
- wait_event(cs->waitqueue, !cs->waiting);
-
- if (cs->cmd_result >= 0) {
- *arg = cs->cmd_result;
- return 0;
- }
-
- return cs->cmd_result;
-}
-
-static int if_version(struct cardstate *cs, unsigned arg[4])
-{
- static const unsigned version[4] = GIG_VERSION;
- static const unsigned compat[4] = GIG_COMPAT;
- unsigned cmd = arg[0];
-
- gig_dbg(DEBUG_IF, "%u: if_version (%d)", cs->minor_index, cmd);
-
- switch (cmd) {
- case GIGVER_DRIVER:
- memcpy(arg, version, sizeof version);
- return 0;
- case GIGVER_COMPAT:
- memcpy(arg, compat, sizeof compat);
- return 0;
- case GIGVER_FWBASE:
- cs->waiting = 1;
- if (!gigaset_add_event(cs, &cs->at_state, EV_IF_VER,
- NULL, 0, arg)) {
- cs->waiting = 0;
- return -ENOMEM;
- }
- gigaset_schedule_event(cs);
-
- wait_event(cs->waitqueue, !cs->waiting);
-
- if (cs->cmd_result >= 0)
- return 0;
-
- return cs->cmd_result;
- default:
- return -EINVAL;
- }
-}
-
-static int if_config(struct cardstate *cs, int *arg)
-{
- gig_dbg(DEBUG_IF, "%u: if_config (%d)", cs->minor_index, *arg);
-
- if (*arg != 1)
- return -EINVAL;
-
- if (cs->mstate != MS_LOCKED)
- return -EBUSY;
-
- if (!cs->connected) {
- pr_err("%s: not connected\n", __func__);
- return -ENODEV;
- }
-
- *arg = 0;
- return gigaset_enterconfigmode(cs);
-}
-
-/*** the terminal driver ***/
-
-static int if_open(struct tty_struct *tty, struct file *filp)
-{
- struct cardstate *cs;
-
- gig_dbg(DEBUG_IF, "%d+%d: %s()",
- tty->driver->minor_start, tty->index, __func__);
-
- cs = gigaset_get_cs_by_tty(tty);
- if (!cs || !try_module_get(cs->driver->owner))
- return -ENODEV;
-
- if (mutex_lock_interruptible(&cs->mutex)) {
- module_put(cs->driver->owner);
- return -ERESTARTSYS;
- }
- tty->driver_data = cs;
-
- ++cs->port.count;
-
- if (cs->port.count == 1) {
- tty_port_tty_set(&cs->port, tty);
- cs->port.low_latency = 1;
- }
-
- mutex_unlock(&cs->mutex);
- return 0;
-}
-
-static void if_close(struct tty_struct *tty, struct file *filp)
-{
- struct cardstate *cs = tty->driver_data;
-
- if (!cs) { /* happens if we didn't find cs in open */
- gig_dbg(DEBUG_IF, "%s: no cardstate", __func__);
- return;
- }
-
- gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__);
-
- mutex_lock(&cs->mutex);
-
- if (!cs->connected)
- gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */
- else if (!cs->port.count)
- dev_warn(cs->dev, "%s: device not opened\n", __func__);
- else if (!--cs->port.count)
- tty_port_tty_set(&cs->port, NULL);
-
- mutex_unlock(&cs->mutex);
-
- module_put(cs->driver->owner);
-}
-
-static int if_ioctl(struct tty_struct *tty,
- unsigned int cmd, unsigned long arg)
-{
- struct cardstate *cs = tty->driver_data;
- int retval = -ENODEV;
- int int_arg;
- unsigned char buf[6];
- unsigned version[4];
-
- gig_dbg(DEBUG_IF, "%u: %s(0x%x)", cs->minor_index, __func__, cmd);
-
- if (mutex_lock_interruptible(&cs->mutex))
- return -ERESTARTSYS;
-
- if (!cs->connected) {
- gig_dbg(DEBUG_IF, "not connected");
- retval = -ENODEV;
- } else {
- retval = 0;
- switch (cmd) {
- case GIGASET_REDIR:
- retval = get_user(int_arg, (int __user *) arg);
- if (retval >= 0)
- retval = if_lock(cs, &int_arg);
- if (retval >= 0)
- retval = put_user(int_arg, (int __user *) arg);
- break;
- case GIGASET_CONFIG:
- retval = get_user(int_arg, (int __user *) arg);
- if (retval >= 0)
- retval = if_config(cs, &int_arg);
- if (retval >= 0)
- retval = put_user(int_arg, (int __user *) arg);
- break;
- case GIGASET_BRKCHARS:
- retval = copy_from_user(&buf,
- (const unsigned char __user *) arg, 6)
- ? -EFAULT : 0;
- if (retval >= 0) {
- gigaset_dbg_buffer(DEBUG_IF, "GIGASET_BRKCHARS",
- 6, buf);
- retval = cs->ops->brkchars(cs, buf);
- }
- break;
- case GIGASET_VERSION:
- retval = copy_from_user(version,
- (unsigned __user *) arg, sizeof version)
- ? -EFAULT : 0;
- if (retval >= 0)
- retval = if_version(cs, version);
- if (retval >= 0)
- retval = copy_to_user((unsigned __user *) arg,
- version, sizeof version)
- ? -EFAULT : 0;
- break;
- default:
- gig_dbg(DEBUG_IF, "%s: arg not supported - 0x%04x",
- __func__, cmd);
- retval = -ENOIOCTLCMD;
- }
- }
-
- mutex_unlock(&cs->mutex);
-
- return retval;
-}
-
-#ifdef CONFIG_COMPAT
-static long if_compat_ioctl(struct tty_struct *tty,
- unsigned int cmd, unsigned long arg)
-{
- return if_ioctl(tty, cmd, (unsigned long)compat_ptr(arg));
-}
-#endif
-
-static int if_tiocmget(struct tty_struct *tty)
-{
- struct cardstate *cs = tty->driver_data;
- int retval;
-
- gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__);
-
- if (mutex_lock_interruptible(&cs->mutex))
- return -ERESTARTSYS;
-
- retval = cs->control_state & (TIOCM_RTS | TIOCM_DTR);
-
- mutex_unlock(&cs->mutex);
-
- return retval;
-}
-
-static int if_tiocmset(struct tty_struct *tty,
- unsigned int set, unsigned int clear)
-{
- struct cardstate *cs = tty->driver_data;
- int retval;
- unsigned mc;
-
- gig_dbg(DEBUG_IF, "%u: %s(0x%x, 0x%x)",
- cs->minor_index, __func__, set, clear);
-
- if (mutex_lock_interruptible(&cs->mutex))
- return -ERESTARTSYS;
-
- if (!cs->connected) {
- gig_dbg(DEBUG_IF, "not connected");
- retval = -ENODEV;
- } else {
- mc = (cs->control_state | set) & ~clear & (TIOCM_RTS | TIOCM_DTR);
- retval = cs->ops->set_modem_ctrl(cs, cs->control_state, mc);
- cs->control_state = mc;
- }
-
- mutex_unlock(&cs->mutex);
-
- return retval;
-}
-
-static int if_write(struct tty_struct *tty, const unsigned char *buf, int count)
-{
- struct cardstate *cs = tty->driver_data;
- struct cmdbuf_t *cb;
- int retval;
-
- gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__);
-
- if (mutex_lock_interruptible(&cs->mutex))
- return -ERESTARTSYS;
-
- if (!cs->connected) {
- gig_dbg(DEBUG_IF, "not connected");
- retval = -ENODEV;
- goto done;
- }
- if (cs->mstate != MS_LOCKED) {
- dev_warn(cs->dev, "can't write to unlocked device\n");
- retval = -EBUSY;
- goto done;
- }
- if (count <= 0) {
- /* nothing to do */
- retval = 0;
- goto done;
- }
-
- cb = kmalloc(sizeof(struct cmdbuf_t) + count, GFP_KERNEL);
- if (!cb) {
- dev_err(cs->dev, "%s: out of memory\n", __func__);
- retval = -ENOMEM;
- goto done;
- }
-
- memcpy(cb->buf, buf, count);
- cb->len = count;
- cb->offset = 0;
- cb->next = NULL;
- cb->wake_tasklet = &cs->if_wake_tasklet;
- retval = cs->ops->write_cmd(cs, cb);
-done:
- mutex_unlock(&cs->mutex);
- return retval;
-}
-
-static int if_write_room(struct tty_struct *tty)
-{
- struct cardstate *cs = tty->driver_data;
- int retval;
-
- gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__);
-
- if (mutex_lock_interruptible(&cs->mutex))
- return -ERESTARTSYS;
-
- if (!cs->connected) {
- gig_dbg(DEBUG_IF, "not connected");
- retval = -ENODEV;
- } else if (cs->mstate != MS_LOCKED) {
- dev_warn(cs->dev, "can't write to unlocked device\n");
- retval = -EBUSY;
- } else
- retval = cs->ops->write_room(cs);
-
- mutex_unlock(&cs->mutex);
-
- return retval;
-}
-
-static int if_chars_in_buffer(struct tty_struct *tty)
-{
- struct cardstate *cs = tty->driver_data;
- int retval = 0;
-
- gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__);
-
- mutex_lock(&cs->mutex);
-
- if (!cs->connected)
- gig_dbg(DEBUG_IF, "not connected");
- else if (cs->mstate != MS_LOCKED)
- dev_warn(cs->dev, "can't write to unlocked device\n");
- else
- retval = cs->ops->chars_in_buffer(cs);
-
- mutex_unlock(&cs->mutex);
-
- return retval;
-}
-
-static void if_throttle(struct tty_struct *tty)
-{
- struct cardstate *cs = tty->driver_data;
-
- gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__);
-
- mutex_lock(&cs->mutex);
-
- if (!cs->connected)
- gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */
- else
- gig_dbg(DEBUG_IF, "%s: not implemented\n", __func__);
-
- mutex_unlock(&cs->mutex);
-}
-
-static void if_unthrottle(struct tty_struct *tty)
-{
- struct cardstate *cs = tty->driver_data;
-
- gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__);
-
- mutex_lock(&cs->mutex);
-
- if (!cs->connected)
- gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */
- else
- gig_dbg(DEBUG_IF, "%s: not implemented\n", __func__);
-
- mutex_unlock(&cs->mutex);
-}
-
-static void if_set_termios(struct tty_struct *tty, struct ktermios *old)
-{
- struct cardstate *cs = tty->driver_data;
- unsigned int iflag;
- unsigned int cflag;
- unsigned int old_cflag;
- unsigned int control_state, new_state;
-
- gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__);
-
- mutex_lock(&cs->mutex);
-
- if (!cs->connected) {
- gig_dbg(DEBUG_IF, "not connected");
- goto out;
- }
-
- iflag = tty->termios.c_iflag;
- cflag = tty->termios.c_cflag;
- old_cflag = old ? old->c_cflag : cflag;
- gig_dbg(DEBUG_IF, "%u: iflag %x cflag %x old %x",
- cs->minor_index, iflag, cflag, old_cflag);
-
- /* get a local copy of the current port settings */
- control_state = cs->control_state;
-
- /*
- * Update baud rate.
- * Do not attempt to cache old rates and skip settings,
- * disconnects screw such tricks up completely.
- * Premature optimization is the root of all evil.
- */
-
- /* reassert DTR and (maybe) RTS on transition from B0 */
- if ((old_cflag & CBAUD) == B0) {
- new_state = control_state | TIOCM_DTR;
- /* don't set RTS if using hardware flow control */
- if (!(old_cflag & CRTSCTS))
- new_state |= TIOCM_RTS;
- gig_dbg(DEBUG_IF, "%u: from B0 - set DTR%s",
- cs->minor_index,
- (new_state & TIOCM_RTS) ? " only" : "/RTS");
- cs->ops->set_modem_ctrl(cs, control_state, new_state);
- control_state = new_state;
- }
-
- cs->ops->baud_rate(cs, cflag & CBAUD);
-
- if ((cflag & CBAUD) == B0) {
- /* Drop RTS and DTR */
- gig_dbg(DEBUG_IF, "%u: to B0 - drop DTR/RTS", cs->minor_index);
- new_state = control_state & ~(TIOCM_DTR | TIOCM_RTS);
- cs->ops->set_modem_ctrl(cs, control_state, new_state);
- control_state = new_state;
- }
-
- /*
- * Update line control register (LCR)
- */
-
- cs->ops->set_line_ctrl(cs, cflag);
-
- /* save off the modified port settings */
- cs->control_state = control_state;
-
-out:
- mutex_unlock(&cs->mutex);
-}
-
-static const struct tty_operations if_ops = {
- .open = if_open,
- .close = if_close,
- .ioctl = if_ioctl,
-#ifdef CONFIG_COMPAT
- .compat_ioctl = if_compat_ioctl,
-#endif
- .write = if_write,
- .write_room = if_write_room,
- .chars_in_buffer = if_chars_in_buffer,
- .set_termios = if_set_termios,
- .throttle = if_throttle,
- .unthrottle = if_unthrottle,
- .tiocmget = if_tiocmget,
- .tiocmset = if_tiocmset,
-};
-
-
-/* wakeup tasklet for the write operation */
-static void if_wake(unsigned long data)
-{
- struct cardstate *cs = (struct cardstate *)data;
-
- tty_port_tty_wakeup(&cs->port);
-}
-
-/*** interface to common ***/
-
-void gigaset_if_init(struct cardstate *cs)
-{
- struct gigaset_driver *drv;
-
- drv = cs->driver;
- if (!drv->have_tty)
- return;
-
- tasklet_init(&cs->if_wake_tasklet, if_wake, (unsigned long) cs);
-
- mutex_lock(&cs->mutex);
- cs->tty_dev = tty_port_register_device(&cs->port, drv->tty,
- cs->minor_index, NULL);
-
- if (!IS_ERR(cs->tty_dev))
- dev_set_drvdata(cs->tty_dev, cs);
- else {
- pr_warn("could not register device to the tty subsystem\n");
- cs->tty_dev = NULL;
- }
- mutex_unlock(&cs->mutex);
-}
-
-void gigaset_if_free(struct cardstate *cs)
-{
- struct gigaset_driver *drv;
-
- drv = cs->driver;
- if (!drv->have_tty)
- return;
-
- tasklet_disable(&cs->if_wake_tasklet);
- tasklet_kill(&cs->if_wake_tasklet);
- cs->tty_dev = NULL;
- tty_unregister_device(drv->tty, cs->minor_index);
-}
-
-/**
- * gigaset_if_receive() - pass a received block of data to the tty device
- * @cs: device descriptor structure.
- * @buffer: received data.
- * @len: number of bytes received.
- *
- * Called by asyncdata/isocdata if a block of data received from the
- * device must be sent to userspace through the ttyG* device.
- */
-void gigaset_if_receive(struct cardstate *cs,
- unsigned char *buffer, size_t len)
-{
- tty_insert_flip_string(&cs->port, buffer, len);
- tty_flip_buffer_push(&cs->port);
-}
-EXPORT_SYMBOL_GPL(gigaset_if_receive);
-
-/* gigaset_if_initdriver
- * Initialize tty interface.
- * parameters:
- * drv Driver
- * procname Name of the driver (e.g. for /proc/tty/drivers)
- * devname Name of the device files (prefix without minor number)
- */
-void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname,
- const char *devname)
-{
- int ret;
- struct tty_driver *tty;
-
- drv->have_tty = 0;
-
- drv->tty = tty = alloc_tty_driver(drv->minors);
- if (tty == NULL)
- goto enomem;
-
- tty->type = TTY_DRIVER_TYPE_SERIAL;
- tty->subtype = SERIAL_TYPE_NORMAL;
- tty->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
-
- tty->driver_name = procname;
- tty->name = devname;
- tty->minor_start = drv->minor;
-
- tty->init_termios = tty_std_termios;
- tty->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
- tty_set_operations(tty, &if_ops);
-
- ret = tty_register_driver(tty);
- if (ret < 0) {
- pr_err("error %d registering tty driver\n", ret);
- goto error;
- }
- gig_dbg(DEBUG_IF, "tty driver initialized");
- drv->have_tty = 1;
- return;
-
-enomem:
- pr_err("out of memory\n");
-error:
- if (drv->tty)
- put_tty_driver(drv->tty);
-}
-
-void gigaset_if_freedriver(struct gigaset_driver *drv)
-{
- if (!drv->have_tty)
- return;
-
- drv->have_tty = 0;
- tty_unregister_driver(drv->tty);
- put_tty_driver(drv->tty);
-}
diff --git a/drivers/staging/isdn/gigaset/isocdata.c b/drivers/staging/isdn/gigaset/isocdata.c
deleted file mode 100644
index 3ecf6e33ed15..000000000000
--- a/drivers/staging/isdn/gigaset/isocdata.c
+++ /dev/null
@@ -1,1006 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Common data handling layer for bas_gigaset
- *
- * Copyright (c) 2005 by Tilman Schmidt <tilman@imap.cc>,
- * Hansjoerg Lipp <hjlipp@web.de>.
- *
- * =====================================================================
- * =====================================================================
- */
-
-#include "gigaset.h"
-#include <linux/crc-ccitt.h>
-#include <linux/bitrev.h>
-
-/* access methods for isowbuf_t */
-/* ============================ */
-
-/* initialize buffer structure
- */
-void gigaset_isowbuf_init(struct isowbuf_t *iwb, unsigned char idle)
-{
- iwb->read = 0;
- iwb->nextread = 0;
- iwb->write = 0;
- atomic_set(&iwb->writesem, 1);
- iwb->wbits = 0;
- iwb->idle = idle;
- memset(iwb->data + BAS_OUTBUFSIZE, idle, BAS_OUTBUFPAD);
-}
-
-/* compute number of bytes which can be appended to buffer
- * so that there is still room to append a maximum frame of flags
- */
-static inline int isowbuf_freebytes(struct isowbuf_t *iwb)
-{
- int read, write, freebytes;
-
- read = iwb->read;
- write = iwb->write;
- freebytes = read - write;
- if (freebytes > 0) {
- /* no wraparound: need padding space within regular area */
- return freebytes - BAS_OUTBUFPAD;
- } else if (read < BAS_OUTBUFPAD) {
- /* wraparound: can use space up to end of regular area */
- return BAS_OUTBUFSIZE - write;
- } else {
- /* following the wraparound yields more space */
- return freebytes + BAS_OUTBUFSIZE - BAS_OUTBUFPAD;
- }
-}
-
-/* start writing
- * acquire the write semaphore
- * return 0 if acquired, <0 if busy
- */
-static inline int isowbuf_startwrite(struct isowbuf_t *iwb)
-{
- if (!atomic_dec_and_test(&iwb->writesem)) {
- atomic_inc(&iwb->writesem);
- gig_dbg(DEBUG_ISO, "%s: couldn't acquire iso write semaphore",
- __func__);
- return -EBUSY;
- }
- gig_dbg(DEBUG_ISO,
- "%s: acquired iso write semaphore, data[write]=%02x, nbits=%d",
- __func__, iwb->data[iwb->write], iwb->wbits);
- return 0;
-}
-
-/* finish writing
- * release the write semaphore
- * returns the current write position
- */
-static inline int isowbuf_donewrite(struct isowbuf_t *iwb)
-{
- int write = iwb->write;
- atomic_inc(&iwb->writesem);
- return write;
-}
-
-/* append bits to buffer without any checks
- * - data contains bits to append, starting at LSB
- * - nbits is number of bits to append (0..24)
- * must be called with the write semaphore held
- * If more than nbits bits are set in data, the extraneous bits are set in the
- * buffer too, but the write position is only advanced by nbits.
- */
-static inline void isowbuf_putbits(struct isowbuf_t *iwb, u32 data, int nbits)
-{
- int write = iwb->write;
- data <<= iwb->wbits;
- data |= iwb->data[write];
- nbits += iwb->wbits;
- while (nbits >= 8) {
- iwb->data[write++] = data & 0xff;
- write %= BAS_OUTBUFSIZE;
- data >>= 8;
- nbits -= 8;
- }
- iwb->wbits = nbits;
- iwb->data[write] = data & 0xff;
- iwb->write = write;
-}
-
-/* put final flag on HDLC bitstream
- * also sets the idle fill byte to the correspondingly shifted flag pattern
- * must be called with the write semaphore held
- */
-static inline void isowbuf_putflag(struct isowbuf_t *iwb)
-{
- int write;
-
- /* add two flags, thus reliably covering one byte */
- isowbuf_putbits(iwb, 0x7e7e, 8);
- /* recover the idle flag byte */
- write = iwb->write;
- iwb->idle = iwb->data[write];
- gig_dbg(DEBUG_ISO, "idle fill byte %02x", iwb->idle);
- /* mask extraneous bits in buffer */
- iwb->data[write] &= (1 << iwb->wbits) - 1;
-}
-
-/* retrieve a block of bytes for sending
- * The requested number of bytes is provided as a contiguous block.
- * If necessary, the frame is filled to the requested number of bytes
- * with the idle value.
- * returns offset to frame, < 0 on busy or error
- */
-int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size)
-{
- int read, write, limit, src, dst;
- unsigned char pbyte;
-
- read = iwb->nextread;
- write = iwb->write;
- if (likely(read == write)) {
- /* return idle frame */
- return read < BAS_OUTBUFPAD ?
- BAS_OUTBUFSIZE : read - BAS_OUTBUFPAD;
- }
-
- limit = read + size;
- gig_dbg(DEBUG_STREAM, "%s: read=%d write=%d limit=%d",
- __func__, read, write, limit);
-#ifdef CONFIG_GIGASET_DEBUG
- if (unlikely(size < 0 || size > BAS_OUTBUFPAD)) {
- pr_err("invalid size %d\n", size);
- return -EINVAL;
- }
-#endif
-
- if (read < write) {
- /* no wraparound in valid data */
- if (limit >= write) {
- /* append idle frame */
- if (isowbuf_startwrite(iwb) < 0)
- return -EBUSY;
- /* write position could have changed */
- write = iwb->write;
- if (limit >= write) {
- pbyte = iwb->data[write]; /* save
- partial byte */
- limit = write + BAS_OUTBUFPAD;
- gig_dbg(DEBUG_STREAM,
- "%s: filling %d->%d with %02x",
- __func__, write, limit, iwb->idle);
- if (write + BAS_OUTBUFPAD < BAS_OUTBUFSIZE)
- memset(iwb->data + write, iwb->idle,
- BAS_OUTBUFPAD);
- else {
- /* wraparound, fill entire pad area */
- memset(iwb->data + write, iwb->idle,
- BAS_OUTBUFSIZE + BAS_OUTBUFPAD
- - write);
- limit = 0;
- }
- gig_dbg(DEBUG_STREAM,
- "%s: restoring %02x at %d",
- __func__, pbyte, limit);
- iwb->data[limit] = pbyte; /* restore
- partial byte */
- iwb->write = limit;
- }
- isowbuf_donewrite(iwb);
- }
- } else {
- /* valid data wraparound */
- if (limit >= BAS_OUTBUFSIZE) {
- /* copy wrapped part into pad area */
- src = 0;
- dst = BAS_OUTBUFSIZE;
- while (dst < limit && src < write)
- iwb->data[dst++] = iwb->data[src++];
- if (dst <= limit) {
- /* fill pad area with idle byte */
- memset(iwb->data + dst, iwb->idle,
- BAS_OUTBUFSIZE + BAS_OUTBUFPAD - dst);
- }
- limit = src;
- }
- }
- iwb->nextread = limit;
- return read;
-}
-
-/* dump_bytes
- * write hex bytes to syslog for debugging
- */
-static inline void dump_bytes(enum debuglevel level, const char *tag,
- unsigned char *bytes, int count)
-{
-#ifdef CONFIG_GIGASET_DEBUG
- unsigned char c;
- static char dbgline[3 * 32 + 1];
- int i = 0;
-
- if (!(gigaset_debuglevel & level))
- return;
-
- while (count-- > 0) {
- if (i > sizeof(dbgline) - 4) {
- dbgline[i] = '\0';
- gig_dbg(level, "%s:%s", tag, dbgline);
- i = 0;
- }
- c = *bytes++;
- dbgline[i] = (i && !(i % 12)) ? '-' : ' ';
- i++;
- dbgline[i++] = hex_asc_hi(c);
- dbgline[i++] = hex_asc_lo(c);
- }
- dbgline[i] = '\0';
- gig_dbg(level, "%s:%s", tag, dbgline);
-#endif
-}
-
-/*============================================================================*/
-
-/* bytewise HDLC bitstuffing via table lookup
- * lookup table: 5 subtables for 0..4 preceding consecutive '1' bits
- * index: 256*(number of preceding '1' bits) + (next byte to stuff)
- * value: bit 9.. 0 = result bits
- * bit 12..10 = number of trailing '1' bits in result
- * bit 14..13 = number of bits added by stuffing
- */
-static const u16 stufftab[5 * 256] = {
-/* previous 1s = 0: */
- 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
- 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x201f,
- 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x203e, 0x205f,
- 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x209f,
- 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
- 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x207c, 0x207d, 0x20be, 0x20df,
- 0x0480, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x0487, 0x0488, 0x0489, 0x048a, 0x048b, 0x048c, 0x048d, 0x048e, 0x048f,
- 0x0490, 0x0491, 0x0492, 0x0493, 0x0494, 0x0495, 0x0496, 0x0497, 0x0498, 0x0499, 0x049a, 0x049b, 0x049c, 0x049d, 0x049e, 0x251f,
- 0x04a0, 0x04a1, 0x04a2, 0x04a3, 0x04a4, 0x04a5, 0x04a6, 0x04a7, 0x04a8, 0x04a9, 0x04aa, 0x04ab, 0x04ac, 0x04ad, 0x04ae, 0x04af,
- 0x04b0, 0x04b1, 0x04b2, 0x04b3, 0x04b4, 0x04b5, 0x04b6, 0x04b7, 0x04b8, 0x04b9, 0x04ba, 0x04bb, 0x04bc, 0x04bd, 0x253e, 0x255f,
- 0x08c0, 0x08c1, 0x08c2, 0x08c3, 0x08c4, 0x08c5, 0x08c6, 0x08c7, 0x08c8, 0x08c9, 0x08ca, 0x08cb, 0x08cc, 0x08cd, 0x08ce, 0x08cf,
- 0x08d0, 0x08d1, 0x08d2, 0x08d3, 0x08d4, 0x08d5, 0x08d6, 0x08d7, 0x08d8, 0x08d9, 0x08da, 0x08db, 0x08dc, 0x08dd, 0x08de, 0x299f,
- 0x0ce0, 0x0ce1, 0x0ce2, 0x0ce3, 0x0ce4, 0x0ce5, 0x0ce6, 0x0ce7, 0x0ce8, 0x0ce9, 0x0cea, 0x0ceb, 0x0cec, 0x0ced, 0x0cee, 0x0cef,
- 0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6, 0x10f7, 0x20f8, 0x20f9, 0x20fa, 0x20fb, 0x257c, 0x257d, 0x29be, 0x2ddf,
-
-/* previous 1s = 1: */
- 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x200f,
- 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x202f,
- 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x204f,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x203e, 0x206f,
- 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x208f,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x20af,
- 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x20cf,
- 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x207c, 0x207d, 0x20be, 0x20ef,
- 0x0480, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x0487, 0x0488, 0x0489, 0x048a, 0x048b, 0x048c, 0x048d, 0x048e, 0x250f,
- 0x0490, 0x0491, 0x0492, 0x0493, 0x0494, 0x0495, 0x0496, 0x0497, 0x0498, 0x0499, 0x049a, 0x049b, 0x049c, 0x049d, 0x049e, 0x252f,
- 0x04a0, 0x04a1, 0x04a2, 0x04a3, 0x04a4, 0x04a5, 0x04a6, 0x04a7, 0x04a8, 0x04a9, 0x04aa, 0x04ab, 0x04ac, 0x04ad, 0x04ae, 0x254f,
- 0x04b0, 0x04b1, 0x04b2, 0x04b3, 0x04b4, 0x04b5, 0x04b6, 0x04b7, 0x04b8, 0x04b9, 0x04ba, 0x04bb, 0x04bc, 0x04bd, 0x253e, 0x256f,
- 0x08c0, 0x08c1, 0x08c2, 0x08c3, 0x08c4, 0x08c5, 0x08c6, 0x08c7, 0x08c8, 0x08c9, 0x08ca, 0x08cb, 0x08cc, 0x08cd, 0x08ce, 0x298f,
- 0x08d0, 0x08d1, 0x08d2, 0x08d3, 0x08d4, 0x08d5, 0x08d6, 0x08d7, 0x08d8, 0x08d9, 0x08da, 0x08db, 0x08dc, 0x08dd, 0x08de, 0x29af,
- 0x0ce0, 0x0ce1, 0x0ce2, 0x0ce3, 0x0ce4, 0x0ce5, 0x0ce6, 0x0ce7, 0x0ce8, 0x0ce9, 0x0cea, 0x0ceb, 0x0cec, 0x0ced, 0x0cee, 0x2dcf,
- 0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6, 0x10f7, 0x20f8, 0x20f9, 0x20fa, 0x20fb, 0x257c, 0x257d, 0x29be, 0x31ef,
-
-/* previous 1s = 2: */
- 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x2007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x2017,
- 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x2027, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x2037,
- 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x2047, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x2057,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x2067, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x203e, 0x2077,
- 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x2087, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x2097,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x20a7, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x20b7,
- 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x20c7, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x20d7,
- 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x20e7, 0x0078, 0x0079, 0x007a, 0x007b, 0x207c, 0x207d, 0x20be, 0x20f7,
- 0x0480, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x2507, 0x0488, 0x0489, 0x048a, 0x048b, 0x048c, 0x048d, 0x048e, 0x2517,
- 0x0490, 0x0491, 0x0492, 0x0493, 0x0494, 0x0495, 0x0496, 0x2527, 0x0498, 0x0499, 0x049a, 0x049b, 0x049c, 0x049d, 0x049e, 0x2537,
- 0x04a0, 0x04a1, 0x04a2, 0x04a3, 0x04a4, 0x04a5, 0x04a6, 0x2547, 0x04a8, 0x04a9, 0x04aa, 0x04ab, 0x04ac, 0x04ad, 0x04ae, 0x2557,
- 0x04b0, 0x04b1, 0x04b2, 0x04b3, 0x04b4, 0x04b5, 0x04b6, 0x2567, 0x04b8, 0x04b9, 0x04ba, 0x04bb, 0x04bc, 0x04bd, 0x253e, 0x2577,
- 0x08c0, 0x08c1, 0x08c2, 0x08c3, 0x08c4, 0x08c5, 0x08c6, 0x2987, 0x08c8, 0x08c9, 0x08ca, 0x08cb, 0x08cc, 0x08cd, 0x08ce, 0x2997,
- 0x08d0, 0x08d1, 0x08d2, 0x08d3, 0x08d4, 0x08d5, 0x08d6, 0x29a7, 0x08d8, 0x08d9, 0x08da, 0x08db, 0x08dc, 0x08dd, 0x08de, 0x29b7,
- 0x0ce0, 0x0ce1, 0x0ce2, 0x0ce3, 0x0ce4, 0x0ce5, 0x0ce6, 0x2dc7, 0x0ce8, 0x0ce9, 0x0cea, 0x0ceb, 0x0cec, 0x0ced, 0x0cee, 0x2dd7,
- 0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6, 0x31e7, 0x20f8, 0x20f9, 0x20fa, 0x20fb, 0x257c, 0x257d, 0x29be, 0x41f7,
-
-/* previous 1s = 3: */
- 0x0000, 0x0001, 0x0002, 0x2003, 0x0004, 0x0005, 0x0006, 0x200b, 0x0008, 0x0009, 0x000a, 0x2013, 0x000c, 0x000d, 0x000e, 0x201b,
- 0x0010, 0x0011, 0x0012, 0x2023, 0x0014, 0x0015, 0x0016, 0x202b, 0x0018, 0x0019, 0x001a, 0x2033, 0x001c, 0x001d, 0x001e, 0x203b,
- 0x0020, 0x0021, 0x0022, 0x2043, 0x0024, 0x0025, 0x0026, 0x204b, 0x0028, 0x0029, 0x002a, 0x2053, 0x002c, 0x002d, 0x002e, 0x205b,
- 0x0030, 0x0031, 0x0032, 0x2063, 0x0034, 0x0035, 0x0036, 0x206b, 0x0038, 0x0039, 0x003a, 0x2073, 0x003c, 0x003d, 0x203e, 0x207b,
- 0x0040, 0x0041, 0x0042, 0x2083, 0x0044, 0x0045, 0x0046, 0x208b, 0x0048, 0x0049, 0x004a, 0x2093, 0x004c, 0x004d, 0x004e, 0x209b,
- 0x0050, 0x0051, 0x0052, 0x20a3, 0x0054, 0x0055, 0x0056, 0x20ab, 0x0058, 0x0059, 0x005a, 0x20b3, 0x005c, 0x005d, 0x005e, 0x20bb,
- 0x0060, 0x0061, 0x0062, 0x20c3, 0x0064, 0x0065, 0x0066, 0x20cb, 0x0068, 0x0069, 0x006a, 0x20d3, 0x006c, 0x006d, 0x006e, 0x20db,
- 0x0070, 0x0071, 0x0072, 0x20e3, 0x0074, 0x0075, 0x0076, 0x20eb, 0x0078, 0x0079, 0x007a, 0x20f3, 0x207c, 0x207d, 0x20be, 0x40fb,
- 0x0480, 0x0481, 0x0482, 0x2503, 0x0484, 0x0485, 0x0486, 0x250b, 0x0488, 0x0489, 0x048a, 0x2513, 0x048c, 0x048d, 0x048e, 0x251b,
- 0x0490, 0x0491, 0x0492, 0x2523, 0x0494, 0x0495, 0x0496, 0x252b, 0x0498, 0x0499, 0x049a, 0x2533, 0x049c, 0x049d, 0x049e, 0x253b,
- 0x04a0, 0x04a1, 0x04a2, 0x2543, 0x04a4, 0x04a5, 0x04a6, 0x254b, 0x04a8, 0x04a9, 0x04aa, 0x2553, 0x04ac, 0x04ad, 0x04ae, 0x255b,
- 0x04b0, 0x04b1, 0x04b2, 0x2563, 0x04b4, 0x04b5, 0x04b6, 0x256b, 0x04b8, 0x04b9, 0x04ba, 0x2573, 0x04bc, 0x04bd, 0x253e, 0x257b,
- 0x08c0, 0x08c1, 0x08c2, 0x2983, 0x08c4, 0x08c5, 0x08c6, 0x298b, 0x08c8, 0x08c9, 0x08ca, 0x2993, 0x08cc, 0x08cd, 0x08ce, 0x299b,
- 0x08d0, 0x08d1, 0x08d2, 0x29a3, 0x08d4, 0x08d5, 0x08d6, 0x29ab, 0x08d8, 0x08d9, 0x08da, 0x29b3, 0x08dc, 0x08dd, 0x08de, 0x29bb,
- 0x0ce0, 0x0ce1, 0x0ce2, 0x2dc3, 0x0ce4, 0x0ce5, 0x0ce6, 0x2dcb, 0x0ce8, 0x0ce9, 0x0cea, 0x2dd3, 0x0cec, 0x0ced, 0x0cee, 0x2ddb,
- 0x10f0, 0x10f1, 0x10f2, 0x31e3, 0x10f4, 0x10f5, 0x10f6, 0x31eb, 0x20f8, 0x20f9, 0x20fa, 0x41f3, 0x257c, 0x257d, 0x29be, 0x46fb,
-
-/* previous 1s = 4: */
- 0x0000, 0x2001, 0x0002, 0x2005, 0x0004, 0x2009, 0x0006, 0x200d, 0x0008, 0x2011, 0x000a, 0x2015, 0x000c, 0x2019, 0x000e, 0x201d,
- 0x0010, 0x2021, 0x0012, 0x2025, 0x0014, 0x2029, 0x0016, 0x202d, 0x0018, 0x2031, 0x001a, 0x2035, 0x001c, 0x2039, 0x001e, 0x203d,
- 0x0020, 0x2041, 0x0022, 0x2045, 0x0024, 0x2049, 0x0026, 0x204d, 0x0028, 0x2051, 0x002a, 0x2055, 0x002c, 0x2059, 0x002e, 0x205d,
- 0x0030, 0x2061, 0x0032, 0x2065, 0x0034, 0x2069, 0x0036, 0x206d, 0x0038, 0x2071, 0x003a, 0x2075, 0x003c, 0x2079, 0x203e, 0x407d,
- 0x0040, 0x2081, 0x0042, 0x2085, 0x0044, 0x2089, 0x0046, 0x208d, 0x0048, 0x2091, 0x004a, 0x2095, 0x004c, 0x2099, 0x004e, 0x209d,
- 0x0050, 0x20a1, 0x0052, 0x20a5, 0x0054, 0x20a9, 0x0056, 0x20ad, 0x0058, 0x20b1, 0x005a, 0x20b5, 0x005c, 0x20b9, 0x005e, 0x20bd,
- 0x0060, 0x20c1, 0x0062, 0x20c5, 0x0064, 0x20c9, 0x0066, 0x20cd, 0x0068, 0x20d1, 0x006a, 0x20d5, 0x006c, 0x20d9, 0x006e, 0x20dd,
- 0x0070, 0x20e1, 0x0072, 0x20e5, 0x0074, 0x20e9, 0x0076, 0x20ed, 0x0078, 0x20f1, 0x007a, 0x20f5, 0x207c, 0x40f9, 0x20be, 0x417d,
- 0x0480, 0x2501, 0x0482, 0x2505, 0x0484, 0x2509, 0x0486, 0x250d, 0x0488, 0x2511, 0x048a, 0x2515, 0x048c, 0x2519, 0x048e, 0x251d,
- 0x0490, 0x2521, 0x0492, 0x2525, 0x0494, 0x2529, 0x0496, 0x252d, 0x0498, 0x2531, 0x049a, 0x2535, 0x049c, 0x2539, 0x049e, 0x253d,
- 0x04a0, 0x2541, 0x04a2, 0x2545, 0x04a4, 0x2549, 0x04a6, 0x254d, 0x04a8, 0x2551, 0x04aa, 0x2555, 0x04ac, 0x2559, 0x04ae, 0x255d,
- 0x04b0, 0x2561, 0x04b2, 0x2565, 0x04b4, 0x2569, 0x04b6, 0x256d, 0x04b8, 0x2571, 0x04ba, 0x2575, 0x04bc, 0x2579, 0x253e, 0x467d,
- 0x08c0, 0x2981, 0x08c2, 0x2985, 0x08c4, 0x2989, 0x08c6, 0x298d, 0x08c8, 0x2991, 0x08ca, 0x2995, 0x08cc, 0x2999, 0x08ce, 0x299d,
- 0x08d0, 0x29a1, 0x08d2, 0x29a5, 0x08d4, 0x29a9, 0x08d6, 0x29ad, 0x08d8, 0x29b1, 0x08da, 0x29b5, 0x08dc, 0x29b9, 0x08de, 0x29bd,
- 0x0ce0, 0x2dc1, 0x0ce2, 0x2dc5, 0x0ce4, 0x2dc9, 0x0ce6, 0x2dcd, 0x0ce8, 0x2dd1, 0x0cea, 0x2dd5, 0x0cec, 0x2dd9, 0x0cee, 0x2ddd,
- 0x10f0, 0x31e1, 0x10f2, 0x31e5, 0x10f4, 0x31e9, 0x10f6, 0x31ed, 0x20f8, 0x41f1, 0x20fa, 0x41f5, 0x257c, 0x46f9, 0x29be, 0x4b7d
-};
-
-/* hdlc_bitstuff_byte
- * perform HDLC bitstuffing for one input byte (8 bits, LSB first)
- * parameters:
- * cin input byte
- * ones number of trailing '1' bits in result before this step
- * iwb pointer to output buffer structure
- * (write semaphore must be held)
- * return value:
- * number of trailing '1' bits in result after this step
- */
-
-static inline int hdlc_bitstuff_byte(struct isowbuf_t *iwb, unsigned char cin,
- int ones)
-{
- u16 stuff;
- int shiftinc, newones;
-
- /* get stuffing information for input byte
- * value: bit 9.. 0 = result bits
- * bit 12..10 = number of trailing '1' bits in result
- * bit 14..13 = number of bits added by stuffing
- */
- stuff = stufftab[256 * ones + cin];
- shiftinc = (stuff >> 13) & 3;
- newones = (stuff >> 10) & 7;
- stuff &= 0x3ff;
-
- /* append stuffed byte to output stream */
- isowbuf_putbits(iwb, stuff, 8 + shiftinc);
- return newones;
-}
-
-/* hdlc_buildframe
- * Perform HDLC framing with bitstuffing on a byte buffer
- * The input buffer is regarded as a sequence of bits, starting with the least
- * significant bit of the first byte and ending with the most significant bit
- * of the last byte. A 16 bit FCS is appended as defined by RFC 1662.
- * Whenever five consecutive '1' bits appear in the resulting bit sequence, a
- * '0' bit is inserted after them.
- * The resulting bit string and a closing flag pattern (PPP_FLAG, '01111110')
- * are appended to the output buffer starting at the given bit position, which
- * is assumed to already contain a leading flag.
- * The output buffer must have sufficient length; count + count/5 + 6 bytes
- * starting at *out are safe and are verified to be present.
- * parameters:
- * in input buffer
- * count number of bytes in input buffer
- * iwb pointer to output buffer structure
- * (write semaphore must be held)
- * return value:
- * position of end of packet in output buffer on success,
- * -EAGAIN if write semaphore busy or buffer full
- */
-
-static inline int hdlc_buildframe(struct isowbuf_t *iwb,
- unsigned char *in, int count)
-{
- int ones;
- u16 fcs;
- int end;
- unsigned char c;
-
- if (isowbuf_freebytes(iwb) < count + count / 5 + 6 ||
- isowbuf_startwrite(iwb) < 0) {
- gig_dbg(DEBUG_ISO, "%s: %d bytes free -> -EAGAIN",
- __func__, isowbuf_freebytes(iwb));
- return -EAGAIN;
- }
-
- dump_bytes(DEBUG_STREAM_DUMP, "snd data", in, count);
-
- /* bitstuff and checksum input data */
- fcs = PPP_INITFCS;
- ones = 0;
- while (count-- > 0) {
- c = *in++;
- ones = hdlc_bitstuff_byte(iwb, c, ones);
- fcs = crc_ccitt_byte(fcs, c);
- }
-
- /* bitstuff and append FCS
- * (complemented, least significant byte first) */
- fcs ^= 0xffff;
- ones = hdlc_bitstuff_byte(iwb, fcs & 0x00ff, ones);
- ones = hdlc_bitstuff_byte(iwb, (fcs >> 8) & 0x00ff, ones);
-
- /* put closing flag and repeat byte for flag idle */
- isowbuf_putflag(iwb);
- end = isowbuf_donewrite(iwb);
- return end;
-}
-
-/* trans_buildframe
- * Append a block of 'transparent' data to the output buffer,
- * inverting the bytes.
- * The output buffer must have sufficient length; count bytes
- * starting at *out are safe and are verified to be present.
- * parameters:
- * in input buffer
- * count number of bytes in input buffer
- * iwb pointer to output buffer structure
- * (write semaphore must be held)
- * return value:
- * position of end of packet in output buffer on success,
- * -EAGAIN if write semaphore busy or buffer full
- */
-
-static inline int trans_buildframe(struct isowbuf_t *iwb,
- unsigned char *in, int count)
-{
- int write;
- unsigned char c;
-
- if (unlikely(count <= 0))
- return iwb->write;
-
- if (isowbuf_freebytes(iwb) < count ||
- isowbuf_startwrite(iwb) < 0) {
- gig_dbg(DEBUG_ISO, "can't put %d bytes", count);
- return -EAGAIN;
- }
-
- gig_dbg(DEBUG_STREAM, "put %d bytes", count);
- dump_bytes(DEBUG_STREAM_DUMP, "snd data", in, count);
-
- write = iwb->write;
- do {
- c = bitrev8(*in++);
- iwb->data[write++] = c;
- write %= BAS_OUTBUFSIZE;
- } while (--count > 0);
- iwb->write = write;
- iwb->idle = c;
-
- return isowbuf_donewrite(iwb);
-}
-
-int gigaset_isoc_buildframe(struct bc_state *bcs, unsigned char *in, int len)
-{
- int result;
-
- switch (bcs->proto2) {
- case L2_HDLC:
- result = hdlc_buildframe(bcs->hw.bas->isooutbuf, in, len);
- gig_dbg(DEBUG_ISO, "%s: %d bytes HDLC -> %d",
- __func__, len, result);
- break;
- default: /* assume transparent */
- result = trans_buildframe(bcs->hw.bas->isooutbuf, in, len);
- gig_dbg(DEBUG_ISO, "%s: %d bytes trans -> %d",
- __func__, len, result);
- }
- return result;
-}
-
-/* hdlc_putbyte
- * append byte c to current skb of B channel structure *bcs, updating fcs
- */
-static inline void hdlc_putbyte(unsigned char c, struct bc_state *bcs)
-{
- bcs->rx_fcs = crc_ccitt_byte(bcs->rx_fcs, c);
- if (bcs->rx_skb == NULL)
- /* skipping */
- return;
- if (bcs->rx_skb->len >= bcs->rx_bufsize) {
- dev_warn(bcs->cs->dev, "received oversized packet discarded\n");
- bcs->hw.bas->giants++;
- dev_kfree_skb_any(bcs->rx_skb);
- bcs->rx_skb = NULL;
- return;
- }
- __skb_put_u8(bcs->rx_skb, c);
-}
-
-/* hdlc_flush
- * drop partial HDLC data packet
- */
-static inline void hdlc_flush(struct bc_state *bcs)
-{
- /* clear skb or allocate new if not skipping */
- if (bcs->rx_skb != NULL)
- skb_trim(bcs->rx_skb, 0);
- else
- gigaset_new_rx_skb(bcs);
-
- /* reset packet state */
- bcs->rx_fcs = PPP_INITFCS;
-}
-
-/* hdlc_done
- * process completed HDLC data packet
- */
-static inline void hdlc_done(struct bc_state *bcs)
-{
- struct cardstate *cs = bcs->cs;
- struct sk_buff *procskb;
- unsigned int len;
-
- if (unlikely(bcs->ignore)) {
- bcs->ignore--;
- hdlc_flush(bcs);
- return;
- }
- procskb = bcs->rx_skb;
- if (procskb == NULL) {
- /* previous error */
- gig_dbg(DEBUG_ISO, "%s: skb=NULL", __func__);
- gigaset_isdn_rcv_err(bcs);
- } else if (procskb->len < 2) {
- dev_notice(cs->dev, "received short frame (%d octets)\n",
- procskb->len);
- bcs->hw.bas->runts++;
- dev_kfree_skb_any(procskb);
- gigaset_isdn_rcv_err(bcs);
- } else if (bcs->rx_fcs != PPP_GOODFCS) {
- dev_notice(cs->dev, "frame check error\n");
- bcs->hw.bas->fcserrs++;
- dev_kfree_skb_any(procskb);
- gigaset_isdn_rcv_err(bcs);
- } else {
- len = procskb->len;
- __skb_trim(procskb, len -= 2); /* subtract FCS */
- gig_dbg(DEBUG_ISO, "%s: good frame (%d octets)", __func__, len);
- dump_bytes(DEBUG_STREAM_DUMP,
- "rcv data", procskb->data, len);
- bcs->hw.bas->goodbytes += len;
- gigaset_skb_rcvd(bcs, procskb);
- }
- gigaset_new_rx_skb(bcs);
- bcs->rx_fcs = PPP_INITFCS;
-}
-
-/* hdlc_frag
- * drop HDLC data packet with non-integral last byte
- */
-static inline void hdlc_frag(struct bc_state *bcs, unsigned inbits)
-{
- if (unlikely(bcs->ignore)) {
- bcs->ignore--;
- hdlc_flush(bcs);
- return;
- }
-
- dev_notice(bcs->cs->dev, "received partial byte (%d bits)\n", inbits);
- bcs->hw.bas->alignerrs++;
- gigaset_isdn_rcv_err(bcs);
- __skb_trim(bcs->rx_skb, 0);
- bcs->rx_fcs = PPP_INITFCS;
-}
-
-/* bit counts lookup table for HDLC bit unstuffing
- * index: input byte
- * value: bit 0..3 = number of consecutive '1' bits starting from LSB
- * bit 4..6 = number of consecutive '1' bits starting from MSB
- * (replacing 8 by 7 to make it fit; the algorithm won't care)
- * bit 7 set if there are 5 or more "interior" consecutive '1' bits
- */
-static const unsigned char bitcounts[256] = {
- 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04,
- 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x05,
- 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04,
- 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x80, 0x06,
- 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04,
- 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x05,
- 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04,
- 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x80, 0x81, 0x80, 0x07,
- 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x13, 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x14,
- 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x13, 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x15,
- 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x13, 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x14,
- 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x13, 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x90, 0x16,
- 0x20, 0x21, 0x20, 0x22, 0x20, 0x21, 0x20, 0x23, 0x20, 0x21, 0x20, 0x22, 0x20, 0x21, 0x20, 0x24,
- 0x20, 0x21, 0x20, 0x22, 0x20, 0x21, 0x20, 0x23, 0x20, 0x21, 0x20, 0x22, 0x20, 0x21, 0x20, 0x25,
- 0x30, 0x31, 0x30, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x31, 0x30, 0x32, 0x30, 0x31, 0x30, 0x34,
- 0x40, 0x41, 0x40, 0x42, 0x40, 0x41, 0x40, 0x43, 0x50, 0x51, 0x50, 0x52, 0x60, 0x61, 0x70, 0x78
-};
-
-/* hdlc_unpack
- * perform HDLC frame processing (bit unstuffing, flag detection, FCS
- * calculation) on a sequence of received data bytes (8 bits each, LSB first)
- * pass on successfully received, complete frames as SKBs via gigaset_skb_rcvd
- * notify of errors via gigaset_isdn_rcv_err
- * tally frames, errors etc. in BC structure counters
- * parameters:
- * src received data
- * count number of received bytes
- * bcs receiving B channel structure
- */
-static inline void hdlc_unpack(unsigned char *src, unsigned count,
- struct bc_state *bcs)
-{
- struct bas_bc_state *ubc = bcs->hw.bas;
- int inputstate;
- unsigned seqlen, inbyte, inbits;
-
- /* load previous state:
- * inputstate = set of flag bits:
- * - INS_flag_hunt: no complete opening flag received since connection
- * setup or last abort
- * - INS_have_data: at least one complete data byte received since last
- * flag
- * seqlen = number of consecutive '1' bits in last 7 input stream bits
- * (0..7)
- * inbyte = accumulated partial data byte (if !INS_flag_hunt)
- * inbits = number of valid bits in inbyte, starting at LSB (0..6)
- */
- inputstate = bcs->inputstate;
- seqlen = ubc->seqlen;
- inbyte = ubc->inbyte;
- inbits = ubc->inbits;
-
- /* bit unstuffing a byte a time
- * Take your time to understand this; it's straightforward but tedious.
- * The "bitcounts" lookup table is used to speed up the counting of
- * leading and trailing '1' bits.
- */
- while (count--) {
- unsigned char c = *src++;
- unsigned char tabentry = bitcounts[c];
- unsigned lead1 = tabentry & 0x0f;
- unsigned trail1 = (tabentry >> 4) & 0x0f;
-
- seqlen += lead1;
-
- if (unlikely(inputstate & INS_flag_hunt)) {
- if (c == PPP_FLAG) {
- /* flag-in-one */
- inputstate &= ~(INS_flag_hunt | INS_have_data);
- inbyte = 0;
- inbits = 0;
- } else if (seqlen == 6 && trail1 != 7) {
- /* flag completed & not followed by abort */
- inputstate &= ~(INS_flag_hunt | INS_have_data);
- inbyte = c >> (lead1 + 1);
- inbits = 7 - lead1;
- if (trail1 >= 8) {
- /* interior stuffing:
- * omitting the MSB handles most cases,
- * correct the incorrectly handled
- * cases individually */
- inbits--;
- switch (c) {
- case 0xbe:
- inbyte = 0x3f;
- break;
- }
- }
- }
- /* else: continue flag-hunting */
- } else if (likely(seqlen < 5 && trail1 < 7)) {
- /* streamlined case: 8 data bits, no stuffing */
- inbyte |= c << inbits;
- hdlc_putbyte(inbyte & 0xff, bcs);
- inputstate |= INS_have_data;
- inbyte >>= 8;
- /* inbits unchanged */
- } else if (likely(seqlen == 6 && inbits == 7 - lead1 &&
- trail1 + 1 == inbits &&
- !(inputstate & INS_have_data))) {
- /* streamlined case: flag idle - state unchanged */
- } else if (unlikely(seqlen > 6)) {
- /* abort sequence */
- ubc->aborts++;
- hdlc_flush(bcs);
- inputstate |= INS_flag_hunt;
- } else if (seqlen == 6) {
- /* closing flag, including (6 - lead1) '1's
- * and one '0' from inbits */
- if (inbits > 7 - lead1) {
- hdlc_frag(bcs, inbits + lead1 - 7);
- inputstate &= ~INS_have_data;
- } else {
- if (inbits < 7 - lead1)
- ubc->stolen0s++;
- if (inputstate & INS_have_data) {
- hdlc_done(bcs);
- inputstate &= ~INS_have_data;
- }
- }
-
- if (c == PPP_FLAG) {
- /* complete flag, LSB overlaps preceding flag */
- ubc->shared0s++;
- inbits = 0;
- inbyte = 0;
- } else if (trail1 != 7) {
- /* remaining bits */
- inbyte = c >> (lead1 + 1);
- inbits = 7 - lead1;
- if (trail1 >= 8) {
- /* interior stuffing:
- * omitting the MSB handles most cases,
- * correct the incorrectly handled
- * cases individually */
- inbits--;
- switch (c) {
- case 0xbe:
- inbyte = 0x3f;
- break;
- }
- }
- } else {
- /* abort sequence follows,
- * skb already empty anyway */
- ubc->aborts++;
- inputstate |= INS_flag_hunt;
- }
- } else { /* (seqlen < 6) && (seqlen == 5 || trail1 >= 7) */
-
- if (c == PPP_FLAG) {
- /* complete flag */
- if (seqlen == 5)
- ubc->stolen0s++;
- if (inbits) {
- hdlc_frag(bcs, inbits);
- inbits = 0;
- inbyte = 0;
- } else if (inputstate & INS_have_data)
- hdlc_done(bcs);
- inputstate &= ~INS_have_data;
- } else if (trail1 == 7) {
- /* abort sequence */
- ubc->aborts++;
- hdlc_flush(bcs);
- inputstate |= INS_flag_hunt;
- } else {
- /* stuffed data */
- if (trail1 < 7) { /* => seqlen == 5 */
- /* stuff bit at position lead1,
- * no interior stuffing */
- unsigned char mask = (1 << lead1) - 1;
- c = (c & mask) | ((c & ~mask) >> 1);
- inbyte |= c << inbits;
- inbits += 7;
- } else if (seqlen < 5) { /* trail1 >= 8 */
- /* interior stuffing:
- * omitting the MSB handles most cases,
- * correct the incorrectly handled
- * cases individually */
- switch (c) {
- case 0xbe:
- c = 0x7e;
- break;
- }
- inbyte |= c << inbits;
- inbits += 7;
- } else { /* seqlen == 5 && trail1 >= 8 */
-
- /* stuff bit at lead1 *and* interior
- * stuffing -- unstuff individually */
- switch (c) {
- case 0x7d:
- c = 0x3f;
- break;
- case 0xbe:
- c = 0x3f;
- break;
- case 0x3e:
- c = 0x1f;
- break;
- case 0x7c:
- c = 0x3e;
- break;
- }
- inbyte |= c << inbits;
- inbits += 6;
- }
- if (inbits >= 8) {
- inbits -= 8;
- hdlc_putbyte(inbyte & 0xff, bcs);
- inputstate |= INS_have_data;
- inbyte >>= 8;
- }
- }
- }
- seqlen = trail1 & 7;
- }
-
- /* save new state */
- bcs->inputstate = inputstate;
- ubc->seqlen = seqlen;
- ubc->inbyte = inbyte;
- ubc->inbits = inbits;
-}
-
-/* trans_receive
- * pass on received USB frame transparently as SKB via gigaset_skb_rcvd
- * invert bytes
- * tally frames, errors etc. in BC structure counters
- * parameters:
- * src received data
- * count number of received bytes
- * bcs receiving B channel structure
- */
-static inline void trans_receive(unsigned char *src, unsigned count,
- struct bc_state *bcs)
-{
- struct sk_buff *skb;
- int dobytes;
- unsigned char *dst;
-
- if (unlikely(bcs->ignore)) {
- bcs->ignore--;
- return;
- }
- skb = bcs->rx_skb;
- if (skb == NULL) {
- skb = gigaset_new_rx_skb(bcs);
- if (skb == NULL)
- return;
- }
- dobytes = bcs->rx_bufsize - skb->len;
- while (count > 0) {
- dst = skb_put(skb, count < dobytes ? count : dobytes);
- while (count > 0 && dobytes > 0) {
- *dst++ = bitrev8(*src++);
- count--;
- dobytes--;
- }
- if (dobytes == 0) {
- dump_bytes(DEBUG_STREAM_DUMP,
- "rcv data", skb->data, skb->len);
- bcs->hw.bas->goodbytes += skb->len;
- gigaset_skb_rcvd(bcs, skb);
- skb = gigaset_new_rx_skb(bcs);
- if (skb == NULL)
- return;
- dobytes = bcs->rx_bufsize;
- }
- }
-}
-
-void gigaset_isoc_receive(unsigned char *src, unsigned count,
- struct bc_state *bcs)
-{
- switch (bcs->proto2) {
- case L2_HDLC:
- hdlc_unpack(src, count, bcs);
- break;
- default: /* assume transparent */
- trans_receive(src, count, bcs);
- }
-}
-
-/* == data input =========================================================== */
-
-/* process a block of received bytes in command mode (mstate != MS_LOCKED)
- * Append received bytes to the command response buffer and forward them
- * line by line to the response handler.
- * Note: Received lines may be terminated by CR, LF, or CR LF, which will be
- * removed before passing the line to the response handler.
- */
-static void cmd_loop(unsigned char *src, int numbytes, struct inbuf_t *inbuf)
-{
- struct cardstate *cs = inbuf->cs;
- unsigned cbytes = cs->cbytes;
- unsigned char c;
-
- while (numbytes--) {
- c = *src++;
- switch (c) {
- case '\n':
- if (cbytes == 0 && cs->respdata[0] == '\r') {
- /* collapse LF with preceding CR */
- cs->respdata[0] = 0;
- break;
- }
- /* fall through */
- case '\r':
- /* end of message line, pass to response handler */
- if (cbytes >= MAX_RESP_SIZE) {
- dev_warn(cs->dev, "response too large (%d)\n",
- cbytes);
- cbytes = MAX_RESP_SIZE;
- }
- cs->cbytes = cbytes;
- gigaset_dbg_buffer(DEBUG_TRANSCMD, "received response",
- cbytes, cs->respdata);
- gigaset_handle_modem_response(cs);
- cbytes = 0;
-
- /* store EOL byte for CRLF collapsing */
- cs->respdata[0] = c;
- break;
- default:
- /* append to line buffer if possible */
- if (cbytes < MAX_RESP_SIZE)
- cs->respdata[cbytes] = c;
- cbytes++;
- }
- }
-
- /* save state */
- cs->cbytes = cbytes;
-}
-
-
-/* process a block of data received through the control channel
- */
-void gigaset_isoc_input(struct inbuf_t *inbuf)
-{
- struct cardstate *cs = inbuf->cs;
- unsigned tail, head, numbytes;
- unsigned char *src;
-
- head = inbuf->head;
- while (head != (tail = inbuf->tail)) {
- gig_dbg(DEBUG_INTR, "buffer state: %u -> %u", head, tail);
- if (head > tail)
- tail = RBUFSIZE;
- src = inbuf->data + head;
- numbytes = tail - head;
- gig_dbg(DEBUG_INTR, "processing %u bytes", numbytes);
-
- if (cs->mstate == MS_LOCKED) {
- gigaset_dbg_buffer(DEBUG_LOCKCMD, "received response",
- numbytes, src);
- gigaset_if_receive(inbuf->cs, src, numbytes);
- } else {
- cmd_loop(src, numbytes, inbuf);
- }
-
- head += numbytes;
- if (head == RBUFSIZE)
- head = 0;
- gig_dbg(DEBUG_INTR, "setting head to %u", head);
- inbuf->head = head;
- }
-}
-
-
-/* == data output ========================================================== */
-
-/**
- * gigaset_isoc_send_skb() - queue an skb for sending
- * @bcs: B channel descriptor structure.
- * @skb: data to send.
- *
- * Called by LL to queue an skb for sending, and start transmission if
- * necessary.
- * Once the payload data has been transmitted completely, gigaset_skb_sent()
- * will be called with the skb's link layer header preserved.
- *
- * Return value:
- * number of bytes accepted for sending (skb->len) if ok,
- * error code < 0 (eg. -ENODEV) on error
- */
-int gigaset_isoc_send_skb(struct bc_state *bcs, struct sk_buff *skb)
-{
- int len = skb->len;
- unsigned long flags;
-
- spin_lock_irqsave(&bcs->cs->lock, flags);
- if (!bcs->cs->connected) {
- spin_unlock_irqrestore(&bcs->cs->lock, flags);
- return -ENODEV;
- }
-
- skb_queue_tail(&bcs->squeue, skb);
- gig_dbg(DEBUG_ISO, "%s: skb queued, qlen=%d",
- __func__, skb_queue_len(&bcs->squeue));
-
- /* tasklet submits URB if necessary */
- tasklet_schedule(&bcs->hw.bas->sent_tasklet);
- spin_unlock_irqrestore(&bcs->cs->lock, flags);
-
- return len; /* ok so far */
-}
diff --git a/drivers/staging/isdn/gigaset/proc.c b/drivers/staging/isdn/gigaset/proc.c
deleted file mode 100644
index 8914439a4237..000000000000
--- a/drivers/staging/isdn/gigaset/proc.c
+++ /dev/null
@@ -1,77 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Stuff used by all variants of the driver
- *
- * Copyright (c) 2001 by Stefan Eilers,
- * Hansjoerg Lipp <hjlipp@web.de>,
- * Tilman Schmidt <tilman@imap.cc>.
- *
- * =====================================================================
- * =====================================================================
- */
-
-#include "gigaset.h"
-
-static ssize_t show_cidmode(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct cardstate *cs = dev_get_drvdata(dev);
-
- return sprintf(buf, "%u\n", cs->cidmode);
-}
-
-static ssize_t set_cidmode(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct cardstate *cs = dev_get_drvdata(dev);
- long int value;
- char *end;
-
- value = simple_strtol(buf, &end, 0);
- while (*end)
- if (!isspace(*end++))
- return -EINVAL;
- if (value < 0 || value > 1)
- return -EINVAL;
-
- if (mutex_lock_interruptible(&cs->mutex))
- return -ERESTARTSYS;
-
- cs->waiting = 1;
- if (!gigaset_add_event(cs, &cs->at_state, EV_PROC_CIDMODE,
- NULL, value, NULL)) {
- cs->waiting = 0;
- mutex_unlock(&cs->mutex);
- return -ENOMEM;
- }
- gigaset_schedule_event(cs);
-
- wait_event(cs->waitqueue, !cs->waiting);
-
- mutex_unlock(&cs->mutex);
-
- return count;
-}
-
-static DEVICE_ATTR(cidmode, S_IRUGO | S_IWUSR, show_cidmode, set_cidmode);
-
-/* free sysfs for device */
-void gigaset_free_dev_sysfs(struct cardstate *cs)
-{
- if (!cs->tty_dev)
- return;
-
- gig_dbg(DEBUG_INIT, "removing sysfs entries");
- device_remove_file(cs->tty_dev, &dev_attr_cidmode);
-}
-
-/* initialize sysfs for device */
-void gigaset_init_dev_sysfs(struct cardstate *cs)
-{
- if (!cs->tty_dev)
- return;
-
- gig_dbg(DEBUG_INIT, "setting up sysfs");
- if (device_create_file(cs->tty_dev, &dev_attr_cidmode))
- pr_err("could not create sysfs attribute\n");
-}
diff --git a/drivers/staging/isdn/gigaset/ser-gigaset.c b/drivers/staging/isdn/gigaset/ser-gigaset.c
deleted file mode 100644
index 5587e9e7fc73..000000000000
--- a/drivers/staging/isdn/gigaset/ser-gigaset.c
+++ /dev/null
@@ -1,796 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/* This is the serial hardware link layer (HLL) for the Gigaset 307x isdn
- * DECT base (aka Sinus 45 isdn) using the RS232 DECT data module M101,
- * written as a line discipline.
- *
- * =====================================================================
- * =====================================================================
- */
-
-#include "gigaset.h"
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/platform_device.h>
-#include <linux/completion.h>
-
-/* Version Information */
-#define DRIVER_AUTHOR "Tilman Schmidt"
-#define DRIVER_DESC "Serial Driver for Gigaset 307x using Siemens M101"
-
-#define GIGASET_MINORS 1
-#define GIGASET_MINOR 0
-#define GIGASET_MODULENAME "ser_gigaset"
-#define GIGASET_DEVNAME "ttyGS"
-
-/* length limit according to Siemens 3070usb-protokoll.doc ch. 2.1 */
-#define IF_WRITEBUF 264
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_LDISC(N_GIGASET_M101);
-
-static int startmode = SM_ISDN;
-module_param(startmode, int, S_IRUGO);
-MODULE_PARM_DESC(startmode, "initial operation mode");
-static int cidmode = 1;
-module_param(cidmode, int, S_IRUGO);
-MODULE_PARM_DESC(cidmode, "stay in CID mode when idle");
-
-static struct gigaset_driver *driver;
-
-struct ser_cardstate {
- struct platform_device dev;
- struct tty_struct *tty;
- atomic_t refcnt;
- struct completion dead_cmp;
-};
-
-static struct platform_driver device_driver = {
- .driver = {
- .name = GIGASET_MODULENAME,
- },
-};
-
-static void flush_send_queue(struct cardstate *);
-
-/* transmit data from current open skb
- * result: number of bytes sent or error code < 0
- */
-static int write_modem(struct cardstate *cs)
-{
- struct tty_struct *tty = cs->hw.ser->tty;
- struct bc_state *bcs = &cs->bcs[0]; /* only one channel */
- struct sk_buff *skb = bcs->tx_skb;
- int sent = -EOPNOTSUPP;
-
- WARN_ON(!tty || !tty->ops || !skb);
-
- if (!skb->len) {
- dev_kfree_skb_any(skb);
- bcs->tx_skb = NULL;
- return -EINVAL;
- }
-
- set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
- if (tty->ops->write)
- sent = tty->ops->write(tty, skb->data, skb->len);
- gig_dbg(DEBUG_OUTPUT, "write_modem: sent %d", sent);
- if (sent < 0) {
- /* error */
- flush_send_queue(cs);
- return sent;
- }
- skb_pull(skb, sent);
- if (!skb->len) {
- /* skb sent completely */
- gigaset_skb_sent(bcs, skb);
-
- gig_dbg(DEBUG_INTR, "kfree skb (Adr: %lx)!",
- (unsigned long) skb);
- dev_kfree_skb_any(skb);
- bcs->tx_skb = NULL;
- }
- return sent;
-}
-
-/*
- * transmit first queued command buffer
- * result: number of bytes sent or error code < 0
- */
-static int send_cb(struct cardstate *cs)
-{
- struct tty_struct *tty = cs->hw.ser->tty;
- struct cmdbuf_t *cb, *tcb;
- unsigned long flags;
- int sent = 0;
-
- WARN_ON(!tty || !tty->ops);
-
- cb = cs->cmdbuf;
- if (!cb)
- return 0; /* nothing to do */
-
- if (cb->len) {
- set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
- sent = tty->ops->write(tty, cb->buf + cb->offset, cb->len);
- if (sent < 0) {
- /* error */
- gig_dbg(DEBUG_OUTPUT, "send_cb: write error %d", sent);
- flush_send_queue(cs);
- return sent;
- }
- cb->offset += sent;
- cb->len -= sent;
- gig_dbg(DEBUG_OUTPUT, "send_cb: sent %d, left %u, queued %u",
- sent, cb->len, cs->cmdbytes);
- }
-
- while (cb && !cb->len) {
- spin_lock_irqsave(&cs->cmdlock, flags);
- cs->cmdbytes -= cs->curlen;
- tcb = cb;
- cs->cmdbuf = cb = cb->next;
- if (cb) {
- cb->prev = NULL;
- cs->curlen = cb->len;
- } else {
- cs->lastcmdbuf = NULL;
- cs->curlen = 0;
- }
- spin_unlock_irqrestore(&cs->cmdlock, flags);
-
- if (tcb->wake_tasklet)
- tasklet_schedule(tcb->wake_tasklet);
- kfree(tcb);
- }
- return sent;
-}
-
-/*
- * send queue tasklet
- * If there is already a skb opened, put data to the transfer buffer
- * by calling "write_modem".
- * Otherwise take a new skb out of the queue.
- */
-static void gigaset_modem_fill(unsigned long data)
-{
- struct cardstate *cs = (struct cardstate *) data;
- struct bc_state *bcs;
- struct sk_buff *nextskb;
- int sent = 0;
-
- if (!cs) {
- gig_dbg(DEBUG_OUTPUT, "%s: no cardstate", __func__);
- return;
- }
- bcs = cs->bcs;
- if (!bcs) {
- gig_dbg(DEBUG_OUTPUT, "%s: no cardstate", __func__);
- return;
- }
- if (!bcs->tx_skb) {
- /* no skb is being sent; send command if any */
- sent = send_cb(cs);
- gig_dbg(DEBUG_OUTPUT, "%s: send_cb -> %d", __func__, sent);
- if (sent)
- /* something sent or error */
- return;
-
- /* no command to send; get skb */
- nextskb = skb_dequeue(&bcs->squeue);
- if (!nextskb)
- /* no skb either, nothing to do */
- return;
- bcs->tx_skb = nextskb;
-
- gig_dbg(DEBUG_INTR, "Dequeued skb (Adr: %lx)",
- (unsigned long) bcs->tx_skb);
- }
-
- /* send skb */
- gig_dbg(DEBUG_OUTPUT, "%s: tx_skb", __func__);
- if (write_modem(cs) < 0)
- gig_dbg(DEBUG_OUTPUT, "%s: write_modem failed", __func__);
-}
-
-/*
- * throw away all data queued for sending
- */
-static void flush_send_queue(struct cardstate *cs)
-{
- struct sk_buff *skb;
- struct cmdbuf_t *cb;
- unsigned long flags;
-
- /* command queue */
- spin_lock_irqsave(&cs->cmdlock, flags);
- while ((cb = cs->cmdbuf) != NULL) {
- cs->cmdbuf = cb->next;
- if (cb->wake_tasklet)
- tasklet_schedule(cb->wake_tasklet);
- kfree(cb);
- }
- cs->cmdbuf = cs->lastcmdbuf = NULL;
- cs->cmdbytes = cs->curlen = 0;
- spin_unlock_irqrestore(&cs->cmdlock, flags);
-
- /* data queue */
- if (cs->bcs->tx_skb)
- dev_kfree_skb_any(cs->bcs->tx_skb);
- while ((skb = skb_dequeue(&cs->bcs->squeue)) != NULL)
- dev_kfree_skb_any(skb);
-}
-
-
-/* Gigaset Driver Interface */
-/* ======================== */
-
-/*
- * queue an AT command string for transmission to the Gigaset device
- * parameters:
- * cs controller state structure
- * buf buffer containing the string to send
- * len number of characters to send
- * wake_tasklet tasklet to run when transmission is complete, or NULL
- * return value:
- * number of bytes queued, or error code < 0
- */
-static int gigaset_write_cmd(struct cardstate *cs, struct cmdbuf_t *cb)
-{
- unsigned long flags;
-
- gigaset_dbg_buffer(cs->mstate != MS_LOCKED ?
- DEBUG_TRANSCMD : DEBUG_LOCKCMD,
- "CMD Transmit", cb->len, cb->buf);
-
- spin_lock_irqsave(&cs->cmdlock, flags);
- cb->prev = cs->lastcmdbuf;
- if (cs->lastcmdbuf)
- cs->lastcmdbuf->next = cb;
- else {
- cs->cmdbuf = cb;
- cs->curlen = cb->len;
- }
- cs->cmdbytes += cb->len;
- cs->lastcmdbuf = cb;
- spin_unlock_irqrestore(&cs->cmdlock, flags);
-
- spin_lock_irqsave(&cs->lock, flags);
- if (cs->connected)
- tasklet_schedule(&cs->write_tasklet);
- spin_unlock_irqrestore(&cs->lock, flags);
- return cb->len;
-}
-
-/*
- * tty_driver.write_room interface routine
- * return number of characters the driver will accept to be written
- * parameter:
- * controller state structure
- * return value:
- * number of characters
- */
-static int gigaset_write_room(struct cardstate *cs)
-{
- unsigned bytes;
-
- bytes = cs->cmdbytes;
- return bytes < IF_WRITEBUF ? IF_WRITEBUF - bytes : 0;
-}
-
-/*
- * tty_driver.chars_in_buffer interface routine
- * return number of characters waiting to be sent
- * parameter:
- * controller state structure
- * return value:
- * number of characters
- */
-static int gigaset_chars_in_buffer(struct cardstate *cs)
-{
- return cs->cmdbytes;
-}
-
-/*
- * implementation of ioctl(GIGASET_BRKCHARS)
- * parameter:
- * controller state structure
- * return value:
- * -EINVAL (unimplemented function)
- */
-static int gigaset_brkchars(struct cardstate *cs, const unsigned char buf[6])
-{
- /* not implemented */
- return -EINVAL;
-}
-
-/*
- * Open B channel
- * Called by "do_action" in ev-layer.c
- */
-static int gigaset_init_bchannel(struct bc_state *bcs)
-{
- /* nothing to do for M10x */
- gigaset_bchannel_up(bcs);
- return 0;
-}
-
-/*
- * Close B channel
- * Called by "do_action" in ev-layer.c
- */
-static int gigaset_close_bchannel(struct bc_state *bcs)
-{
- /* nothing to do for M10x */
- gigaset_bchannel_down(bcs);
- return 0;
-}
-
-/*
- * Set up B channel structure
- * This is called by "gigaset_initcs" in common.c
- */
-static int gigaset_initbcshw(struct bc_state *bcs)
-{
- /* unused */
- bcs->hw.ser = NULL;
- return 0;
-}
-
-/*
- * Free B channel structure
- * Called by "gigaset_freebcs" in common.c
- */
-static void gigaset_freebcshw(struct bc_state *bcs)
-{
- /* unused */
-}
-
-/*
- * Reinitialize B channel structure
- * This is called by "bcs_reinit" in common.c
- */
-static void gigaset_reinitbcshw(struct bc_state *bcs)
-{
- /* nothing to do for M10x */
-}
-
-/*
- * Free hardware specific device data
- * This will be called by "gigaset_freecs" in common.c
- */
-static void gigaset_freecshw(struct cardstate *cs)
-{
- tasklet_kill(&cs->write_tasklet);
- if (!cs->hw.ser)
- return;
- platform_device_unregister(&cs->hw.ser->dev);
-}
-
-static void gigaset_device_release(struct device *dev)
-{
- kfree(container_of(dev, struct ser_cardstate, dev.dev));
-}
-
-/*
- * Set up hardware specific device data
- * This is called by "gigaset_initcs" in common.c
- */
-static int gigaset_initcshw(struct cardstate *cs)
-{
- int rc;
- struct ser_cardstate *scs;
-
- scs = kzalloc(sizeof(struct ser_cardstate), GFP_KERNEL);
- if (!scs) {
- pr_err("out of memory\n");
- return -ENOMEM;
- }
- cs->hw.ser = scs;
-
- cs->hw.ser->dev.name = GIGASET_MODULENAME;
- cs->hw.ser->dev.id = cs->minor_index;
- cs->hw.ser->dev.dev.release = gigaset_device_release;
- rc = platform_device_register(&cs->hw.ser->dev);
- if (rc != 0) {
- pr_err("error %d registering platform device\n", rc);
- kfree(cs->hw.ser);
- cs->hw.ser = NULL;
- return rc;
- }
-
- tasklet_init(&cs->write_tasklet,
- gigaset_modem_fill, (unsigned long) cs);
- return 0;
-}
-
-/*
- * set modem control lines
- * Parameters:
- * card state structure
- * modem control line state ([TIOCM_DTR]|[TIOCM_RTS])
- * Called by "gigaset_start" and "gigaset_enterconfigmode" in common.c
- * and by "if_lock" and "if_termios" in interface.c
- */
-static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state,
- unsigned new_state)
-{
- struct tty_struct *tty = cs->hw.ser->tty;
- unsigned int set, clear;
-
- WARN_ON(!tty || !tty->ops);
- /* tiocmset is an optional tty driver method */
- if (!tty->ops->tiocmset)
- return -EINVAL;
- set = new_state & ~old_state;
- clear = old_state & ~new_state;
- if (!set && !clear)
- return 0;
- gig_dbg(DEBUG_IF, "tiocmset set %x clear %x", set, clear);
- return tty->ops->tiocmset(tty, set, clear);
-}
-
-static int gigaset_baud_rate(struct cardstate *cs, unsigned cflag)
-{
- return -EINVAL;
-}
-
-static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag)
-{
- return -EINVAL;
-}
-
-static const struct gigaset_ops ops = {
- .write_cmd = gigaset_write_cmd,
- .write_room = gigaset_write_room,
- .chars_in_buffer = gigaset_chars_in_buffer,
- .brkchars = gigaset_brkchars,
- .init_bchannel = gigaset_init_bchannel,
- .close_bchannel = gigaset_close_bchannel,
- .initbcshw = gigaset_initbcshw,
- .freebcshw = gigaset_freebcshw,
- .reinitbcshw = gigaset_reinitbcshw,
- .initcshw = gigaset_initcshw,
- .freecshw = gigaset_freecshw,
- .set_modem_ctrl = gigaset_set_modem_ctrl,
- .baud_rate = gigaset_baud_rate,
- .set_line_ctrl = gigaset_set_line_ctrl,
- .send_skb = gigaset_m10x_send_skb, /* asyncdata.c */
- .handle_input = gigaset_m10x_input, /* asyncdata.c */
-};
-
-
-/* Line Discipline Interface */
-/* ========================= */
-
-/* helper functions for cardstate refcounting */
-static struct cardstate *cs_get(struct tty_struct *tty)
-{
- struct cardstate *cs = tty->disc_data;
-
- if (!cs || !cs->hw.ser) {
- gig_dbg(DEBUG_ANY, "%s: no cardstate", __func__);
- return NULL;
- }
- atomic_inc(&cs->hw.ser->refcnt);
- return cs;
-}
-
-static void cs_put(struct cardstate *cs)
-{
- if (atomic_dec_and_test(&cs->hw.ser->refcnt))
- complete(&cs->hw.ser->dead_cmp);
-}
-
-/*
- * Called by the tty driver when the line discipline is pushed onto the tty.
- * Called in process context.
- */
-static int
-gigaset_tty_open(struct tty_struct *tty)
-{
- struct cardstate *cs;
- int rc;
-
- gig_dbg(DEBUG_INIT, "Starting HLL for Gigaset M101");
-
- pr_info(DRIVER_DESC "\n");
-
- if (!driver) {
- pr_err("%s: no driver structure\n", __func__);
- return -ENODEV;
- }
-
- /* allocate memory for our device state and initialize it */
- cs = gigaset_initcs(driver, 1, 1, 0, cidmode, GIGASET_MODULENAME);
- if (!cs) {
- rc = -ENODEV;
- goto error;
- }
-
- cs->dev = &cs->hw.ser->dev.dev;
- cs->hw.ser->tty = tty;
- atomic_set(&cs->hw.ser->refcnt, 1);
- init_completion(&cs->hw.ser->dead_cmp);
- tty->disc_data = cs;
-
- /* Set the amount of data we're willing to receive per call
- * from the hardware driver to half of the input buffer size
- * to leave some reserve.
- * Note: We don't do flow control towards the hardware driver.
- * If more data is received than will fit into the input buffer,
- * it will be dropped and an error will be logged. This should
- * never happen as the device is slow and the buffer size ample.
- */
- tty->receive_room = RBUFSIZE/2;
-
- /* OK.. Initialization of the datastructures and the HW is done.. Now
- * startup system and notify the LL that we are ready to run
- */
- if (startmode == SM_LOCKED)
- cs->mstate = MS_LOCKED;
- rc = gigaset_start(cs);
- if (rc < 0) {
- tasklet_kill(&cs->write_tasklet);
- goto error;
- }
-
- gig_dbg(DEBUG_INIT, "Startup of HLL done");
- return 0;
-
-error:
- gig_dbg(DEBUG_INIT, "Startup of HLL failed");
- tty->disc_data = NULL;
- gigaset_freecs(cs);
- return rc;
-}
-
-/*
- * Called by the tty driver when the line discipline is removed.
- * Called from process context.
- */
-static void
-gigaset_tty_close(struct tty_struct *tty)
-{
- struct cardstate *cs = tty->disc_data;
-
- gig_dbg(DEBUG_INIT, "Stopping HLL for Gigaset M101");
-
- if (!cs) {
- gig_dbg(DEBUG_INIT, "%s: no cardstate", __func__);
- return;
- }
-
- /* prevent other callers from entering ldisc methods */
- tty->disc_data = NULL;
-
- if (!cs->hw.ser)
- pr_err("%s: no hw cardstate\n", __func__);
- else {
- /* wait for running methods to finish */
- if (!atomic_dec_and_test(&cs->hw.ser->refcnt))
- wait_for_completion(&cs->hw.ser->dead_cmp);
- }
-
- /* stop operations */
- gigaset_stop(cs);
- tasklet_kill(&cs->write_tasklet);
- flush_send_queue(cs);
- cs->dev = NULL;
- gigaset_freecs(cs);
-
- gig_dbg(DEBUG_INIT, "Shutdown of HLL done");
-}
-
-/*
- * Called by the tty driver when the tty line is hung up.
- * Wait for I/O to driver to complete and unregister ISDN device.
- * This is already done by the close routine, so just call that.
- * Called from process context.
- */
-static int gigaset_tty_hangup(struct tty_struct *tty)
-{
- gigaset_tty_close(tty);
- return 0;
-}
-
-/*
- * Ioctl on the tty.
- * Called in process context only.
- * May be re-entered by multiple ioctl calling threads.
- */
-static int
-gigaset_tty_ioctl(struct tty_struct *tty, struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- struct cardstate *cs = cs_get(tty);
- int rc, val;
- int __user *p = (int __user *)arg;
-
- if (!cs)
- return -ENXIO;
-
- switch (cmd) {
-
- case FIONREAD:
- /* unused, always return zero */
- val = 0;
- rc = put_user(val, p);
- break;
-
- case TCFLSH:
- /* flush our buffers and the serial port's buffer */
- switch (arg) {
- case TCIFLUSH:
- /* no own input buffer to flush */
- break;
- case TCIOFLUSH:
- case TCOFLUSH:
- flush_send_queue(cs);
- break;
- }
- /* fall through */
-
- default:
- /* pass through to underlying serial device */
- rc = n_tty_ioctl_helper(tty, file, cmd, arg);
- break;
- }
- cs_put(cs);
- return rc;
-}
-
-/*
- * Called by the tty driver when a block of data has been received.
- * Will not be re-entered while running but other ldisc functions
- * may be called in parallel.
- * Can be called from hard interrupt level as well as soft interrupt
- * level or mainline.
- * Parameters:
- * tty tty structure
- * buf buffer containing received characters
- * cflags buffer containing error flags for received characters (ignored)
- * count number of received characters
- */
-static void
-gigaset_tty_receive(struct tty_struct *tty, const unsigned char *buf,
- char *cflags, int count)
-{
- struct cardstate *cs = cs_get(tty);
- unsigned tail, head, n;
- struct inbuf_t *inbuf;
-
- if (!cs)
- return;
- inbuf = cs->inbuf;
- if (!inbuf) {
- dev_err(cs->dev, "%s: no inbuf\n", __func__);
- cs_put(cs);
- return;
- }
-
- tail = inbuf->tail;
- head = inbuf->head;
- gig_dbg(DEBUG_INTR, "buffer state: %u -> %u, receive %u bytes",
- head, tail, count);
-
- if (head <= tail) {
- /* possible buffer wraparound */
- n = min_t(unsigned, count, RBUFSIZE - tail);
- memcpy(inbuf->data + tail, buf, n);
- tail = (tail + n) % RBUFSIZE;
- buf += n;
- count -= n;
- }
-
- if (count > 0) {
- /* tail < head and some data left */
- n = head - tail - 1;
- if (count > n) {
- dev_err(cs->dev,
- "inbuf overflow, discarding %d bytes\n",
- count - n);
- count = n;
- }
- memcpy(inbuf->data + tail, buf, count);
- tail += count;
- }
-
- gig_dbg(DEBUG_INTR, "setting tail to %u", tail);
- inbuf->tail = tail;
-
- /* Everything was received .. Push data into handler */
- gig_dbg(DEBUG_INTR, "%s-->BH", __func__);
- gigaset_schedule_event(cs);
- cs_put(cs);
-}
-
-/*
- * Called by the tty driver when there's room for more data to send.
- */
-static void
-gigaset_tty_wakeup(struct tty_struct *tty)
-{
- struct cardstate *cs = cs_get(tty);
-
- clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
- if (!cs)
- return;
- tasklet_schedule(&cs->write_tasklet);
- cs_put(cs);
-}
-
-static struct tty_ldisc_ops gigaset_ldisc = {
- .owner = THIS_MODULE,
- .magic = TTY_LDISC_MAGIC,
- .name = "ser_gigaset",
- .open = gigaset_tty_open,
- .close = gigaset_tty_close,
- .hangup = gigaset_tty_hangup,
- .ioctl = gigaset_tty_ioctl,
- .receive_buf = gigaset_tty_receive,
- .write_wakeup = gigaset_tty_wakeup,
-};
-
-
-/* Initialization / Shutdown */
-/* ========================= */
-
-static int __init ser_gigaset_init(void)
-{
- int rc;
-
- gig_dbg(DEBUG_INIT, "%s", __func__);
- rc = platform_driver_register(&device_driver);
- if (rc != 0) {
- pr_err("error %d registering platform driver\n", rc);
- return rc;
- }
-
- /* allocate memory for our driver state and initialize it */
- driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS,
- GIGASET_MODULENAME, GIGASET_DEVNAME,
- &ops, THIS_MODULE);
- if (!driver) {
- rc = -ENOMEM;
- goto error;
- }
-
- rc = tty_register_ldisc(N_GIGASET_M101, &gigaset_ldisc);
- if (rc != 0) {
- pr_err("error %d registering line discipline\n", rc);
- goto error;
- }
-
- return 0;
-
-error:
- if (driver) {
- gigaset_freedriver(driver);
- driver = NULL;
- }
- platform_driver_unregister(&device_driver);
- return rc;
-}
-
-static void __exit ser_gigaset_exit(void)
-{
- int rc;
-
- gig_dbg(DEBUG_INIT, "%s", __func__);
-
- if (driver) {
- gigaset_freedriver(driver);
- driver = NULL;
- }
-
- rc = tty_unregister_ldisc(N_GIGASET_M101);
- if (rc != 0)
- pr_err("error %d unregistering line discipline\n", rc);
-
- platform_driver_unregister(&device_driver);
-}
-
-module_init(ser_gigaset_init);
-module_exit(ser_gigaset_exit);
diff --git a/drivers/staging/isdn/gigaset/usb-gigaset.c b/drivers/staging/isdn/gigaset/usb-gigaset.c
deleted file mode 100644
index a20c0bfa68f3..000000000000
--- a/drivers/staging/isdn/gigaset/usb-gigaset.c
+++ /dev/null
@@ -1,959 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * USB driver for Gigaset 307x directly or using M105 Data.
- *
- * Copyright (c) 2001 by Stefan Eilers
- * and Hansjoerg Lipp <hjlipp@web.de>.
- *
- * This driver was derived from the USB skeleton driver by
- * Greg Kroah-Hartman <greg@kroah.com>
- *
- * =====================================================================
- * =====================================================================
- */
-
-#include "gigaset.h"
-#include <linux/usb.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-
-/* Version Information */
-#define DRIVER_AUTHOR "Hansjoerg Lipp <hjlipp@web.de>, Stefan Eilers"
-#define DRIVER_DESC "USB Driver for Gigaset 307x using M105"
-
-/* Module parameters */
-
-static int startmode = SM_ISDN;
-static int cidmode = 1;
-
-module_param(startmode, int, S_IRUGO);
-module_param(cidmode, int, S_IRUGO);
-MODULE_PARM_DESC(startmode, "start in isdn4linux mode");
-MODULE_PARM_DESC(cidmode, "Call-ID mode");
-
-#define GIGASET_MINORS 1
-#define GIGASET_MINOR 8
-#define GIGASET_MODULENAME "usb_gigaset"
-#define GIGASET_DEVNAME "ttyGU"
-
-/* length limit according to Siemens 3070usb-protokoll.doc ch. 2.1 */
-#define IF_WRITEBUF 264
-
-/* Values for the Gigaset M105 Data */
-#define USB_M105_VENDOR_ID 0x0681
-#define USB_M105_PRODUCT_ID 0x0009
-
-/* table of devices that work with this driver */
-static const struct usb_device_id gigaset_table[] = {
- { USB_DEVICE(USB_M105_VENDOR_ID, USB_M105_PRODUCT_ID) },
- { } /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(usb, gigaset_table);
-
-/*
- * Control requests (empty fields: 00)
- *
- * RT|RQ|VALUE|INDEX|LEN |DATA
- * In:
- * C1 08 01
- * Get flags (1 byte). Bits: 0=dtr,1=rts,3-7:?
- * C1 0F ll ll
- * Get device information/status (llll: 0x200 and 0x40 seen).
- * Real size: I only saw MIN(llll,0x64).
- * Contents: seems to be always the same...
- * offset 0x00: Length of this structure (0x64) (len: 1,2,3 bytes)
- * offset 0x3c: String (16 bit chars): "MCCI USB Serial V2.0"
- * rest: ?
- * Out:
- * 41 11
- * Initialize/reset device ?
- * 41 00 xx 00
- * ? (xx=00 or 01; 01 on start, 00 on close)
- * 41 07 vv mm
- * Set/clear flags vv=value, mm=mask (see RQ 08)
- * 41 12 xx
- * Used before the following configuration requests are issued
- * (with xx=0x0f). I've seen other values<0xf, though.
- * 41 01 xx xx
- * Set baud rate. xxxx=ceil(0x384000/rate)=trunc(0x383fff/rate)+1.
- * 41 03 ps bb
- * Set byte size and parity. p: 0x20=even,0x10=odd,0x00=no parity
- * [ 0x30: m, 0x40: s ]
- * [s: 0: 1 stop bit; 1: 1.5; 2: 2]
- * bb: bits/byte (seen 7 and 8)
- * 41 13 -- -- -- -- 10 00 ww 00 00 00 xx 00 00 00 yy 00 00 00 zz 00 00 00
- * ??
- * Initialization: 01, 40, 00, 00
- * Open device: 00 40, 00, 00
- * yy and zz seem to be equal, either 0x00 or 0x0a
- * (ww,xx) pairs seen: (00,00), (00,40), (01,40), (09,80), (19,80)
- * 41 19 -- -- -- -- 06 00 00 00 00 xx 11 13
- * Used after every "configuration sequence" (RQ 12, RQs 01/03/13).
- * xx is usually 0x00 but was 0x7e before starting data transfer
- * in unimodem mode. So, this might be an array of characters that
- * need special treatment ("commit all bufferd data"?), 11=^Q, 13=^S.
- *
- * Unimodem mode: use "modprobe ppp_async flag_time=0" as the device _needs_ two
- * flags per packet.
- */
-
-/* functions called if a device of this driver is connected/disconnected */
-static int gigaset_probe(struct usb_interface *interface,
- const struct usb_device_id *id);
-static void gigaset_disconnect(struct usb_interface *interface);
-
-/* functions called before/after suspend */
-static int gigaset_suspend(struct usb_interface *intf, pm_message_t message);
-static int gigaset_resume(struct usb_interface *intf);
-static int gigaset_pre_reset(struct usb_interface *intf);
-
-static struct gigaset_driver *driver;
-
-/* usb specific object needed to register this driver with the usb subsystem */
-static struct usb_driver gigaset_usb_driver = {
- .name = GIGASET_MODULENAME,
- .probe = gigaset_probe,
- .disconnect = gigaset_disconnect,
- .id_table = gigaset_table,
- .suspend = gigaset_suspend,
- .resume = gigaset_resume,
- .reset_resume = gigaset_resume,
- .pre_reset = gigaset_pre_reset,
- .post_reset = gigaset_resume,
- .disable_hub_initiated_lpm = 1,
-};
-
-struct usb_cardstate {
- struct usb_device *udev; /* usb device pointer */
- struct usb_interface *interface; /* interface for this device */
- int busy; /* bulk output in progress */
-
- /* Output buffer */
- unsigned char *bulk_out_buffer;
- int bulk_out_size;
- int bulk_out_epnum;
- struct urb *bulk_out_urb;
-
- /* Input buffer */
- unsigned char *rcvbuf;
- int rcvbuf_size;
- struct urb *read_urb;
-
- char bchars[6]; /* for request 0x19 */
-};
-
-static inline unsigned tiocm_to_gigaset(unsigned state)
-{
- return ((state & TIOCM_DTR) ? 1 : 0) | ((state & TIOCM_RTS) ? 2 : 0);
-}
-
-static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state,
- unsigned new_state)
-{
- struct usb_device *udev = cs->hw.usb->udev;
- unsigned mask, val;
- int r;
-
- mask = tiocm_to_gigaset(old_state ^ new_state);
- val = tiocm_to_gigaset(new_state);
-
- gig_dbg(DEBUG_USBREQ, "set flags 0x%02x with mask 0x%02x", val, mask);
- r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 7, 0x41,
- (val & 0xff) | ((mask & 0xff) << 8), 0,
- NULL, 0, 2000 /* timeout? */);
- if (r < 0)
- return r;
- return 0;
-}
-
-/*
- * Set M105 configuration value
- * using undocumented device commands reverse engineered from USB traces
- * of the Siemens Windows driver
- */
-static int set_value(struct cardstate *cs, u8 req, u16 val)
-{
- struct usb_device *udev = cs->hw.usb->udev;
- int r, r2;
-
- gig_dbg(DEBUG_USBREQ, "request %02x (%04x)",
- (unsigned)req, (unsigned)val);
- r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x12, 0x41,
- 0xf /*?*/, 0, NULL, 0, 2000 /*?*/);
- /* no idea what this does */
- if (r < 0) {
- dev_err(&udev->dev, "error %d on request 0x12\n", -r);
- return r;
- }
-
- r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), req, 0x41,
- val, 0, NULL, 0, 2000 /*?*/);
- if (r < 0)
- dev_err(&udev->dev, "error %d on request 0x%02x\n",
- -r, (unsigned)req);
-
- r2 = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x19, 0x41,
- 0, 0, cs->hw.usb->bchars, 6, 2000 /*?*/);
- if (r2 < 0)
- dev_err(&udev->dev, "error %d on request 0x19\n", -r2);
-
- return r < 0 ? r : (r2 < 0 ? r2 : 0);
-}
-
-/*
- * set the baud rate on the internal serial adapter
- * using the undocumented parameter setting command
- */
-static int gigaset_baud_rate(struct cardstate *cs, unsigned cflag)
-{
- u16 val;
- u32 rate;
-
- cflag &= CBAUD;
-
- switch (cflag) {
- case B300: rate = 300; break;
- case B600: rate = 600; break;
- case B1200: rate = 1200; break;
- case B2400: rate = 2400; break;
- case B4800: rate = 4800; break;
- case B9600: rate = 9600; break;
- case B19200: rate = 19200; break;
- case B38400: rate = 38400; break;
- case B57600: rate = 57600; break;
- case B115200: rate = 115200; break;
- default:
- rate = 9600;
- dev_err(cs->dev, "unsupported baudrate request 0x%x,"
- " using default of B9600\n", cflag);
- }
-
- val = 0x383fff / rate + 1;
-
- return set_value(cs, 1, val);
-}
-
-/*
- * set the line format on the internal serial adapter
- * using the undocumented parameter setting command
- */
-static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag)
-{
- u16 val = 0;
-
- /* set the parity */
- if (cflag & PARENB)
- val |= (cflag & PARODD) ? 0x10 : 0x20;
-
- /* set the number of data bits */
- switch (cflag & CSIZE) {
- case CS5:
- val |= 5 << 8; break;
- case CS6:
- val |= 6 << 8; break;
- case CS7:
- val |= 7 << 8; break;
- case CS8:
- val |= 8 << 8; break;
- default:
- dev_err(cs->dev, "CSIZE was not CS5-CS8, using default of 8\n");
- val |= 8 << 8;
- break;
- }
-
- /* set the number of stop bits */
- if (cflag & CSTOPB) {
- if ((cflag & CSIZE) == CS5)
- val |= 1; /* 1.5 stop bits */
- else
- val |= 2; /* 2 stop bits */
- }
-
- return set_value(cs, 3, val);
-}
-
-
-/*============================================================================*/
-static int gigaset_init_bchannel(struct bc_state *bcs)
-{
- /* nothing to do for M10x */
- gigaset_bchannel_up(bcs);
- return 0;
-}
-
-static int gigaset_close_bchannel(struct bc_state *bcs)
-{
- /* nothing to do for M10x */
- gigaset_bchannel_down(bcs);
- return 0;
-}
-
-static int write_modem(struct cardstate *cs);
-static int send_cb(struct cardstate *cs);
-
-
-/* Write tasklet handler: Continue sending current skb, or send command, or
- * start sending an skb from the send queue.
- */
-static void gigaset_modem_fill(unsigned long data)
-{
- struct cardstate *cs = (struct cardstate *) data;
- struct bc_state *bcs = &cs->bcs[0]; /* only one channel */
-
- gig_dbg(DEBUG_OUTPUT, "modem_fill");
-
- if (cs->hw.usb->busy) {
- gig_dbg(DEBUG_OUTPUT, "modem_fill: busy");
- return;
- }
-
-again:
- if (!bcs->tx_skb) { /* no skb is being sent */
- if (cs->cmdbuf) { /* commands to send? */
- gig_dbg(DEBUG_OUTPUT, "modem_fill: cb");
- if (send_cb(cs) < 0) {
- gig_dbg(DEBUG_OUTPUT,
- "modem_fill: send_cb failed");
- goto again; /* no callback will be called! */
- }
- return;
- }
-
- /* skbs to send? */
- bcs->tx_skb = skb_dequeue(&bcs->squeue);
- if (!bcs->tx_skb)
- return;
-
- gig_dbg(DEBUG_INTR, "Dequeued skb (Adr: %lx)!",
- (unsigned long) bcs->tx_skb);
- }
-
- gig_dbg(DEBUG_OUTPUT, "modem_fill: tx_skb");
- if (write_modem(cs) < 0) {
- gig_dbg(DEBUG_OUTPUT, "modem_fill: write_modem failed");
- goto again; /* no callback will be called! */
- }
-}
-
-/*
- * Interrupt Input URB completion routine
- */
-static void gigaset_read_int_callback(struct urb *urb)
-{
- struct cardstate *cs = urb->context;
- struct inbuf_t *inbuf = cs->inbuf;
- int status = urb->status;
- int r;
- unsigned numbytes;
- unsigned char *src;
- unsigned long flags;
-
- if (!status) {
- numbytes = urb->actual_length;
-
- if (numbytes) {
- src = cs->hw.usb->rcvbuf;
- if (unlikely(*src))
- dev_warn(cs->dev,
- "%s: There was no leading 0, but 0x%02x!\n",
- __func__, (unsigned) *src);
- ++src; /* skip leading 0x00 */
- --numbytes;
- if (gigaset_fill_inbuf(inbuf, src, numbytes)) {
- gig_dbg(DEBUG_INTR, "%s-->BH", __func__);
- gigaset_schedule_event(inbuf->cs);
- }
- } else
- gig_dbg(DEBUG_INTR, "Received zero block length");
- } else {
- /* The urb might have been killed. */
- gig_dbg(DEBUG_ANY, "%s - nonzero status received: %d",
- __func__, status);
- if (status == -ENOENT || status == -ESHUTDOWN)
- /* killed or endpoint shutdown: don't resubmit */
- return;
- }
-
- /* resubmit URB */
- spin_lock_irqsave(&cs->lock, flags);
- if (!cs->connected) {
- spin_unlock_irqrestore(&cs->lock, flags);
- pr_err("%s: disconnected\n", __func__);
- return;
- }
- r = usb_submit_urb(urb, GFP_ATOMIC);
- spin_unlock_irqrestore(&cs->lock, flags);
- if (r)
- dev_err(cs->dev, "error %d resubmitting URB\n", -r);
-}
-
-
-/* This callback routine is called when data was transmitted to the device. */
-static void gigaset_write_bulk_callback(struct urb *urb)
-{
- struct cardstate *cs = urb->context;
- int status = urb->status;
- unsigned long flags;
-
- switch (status) {
- case 0: /* normal completion */
- break;
- case -ENOENT: /* killed */
- gig_dbg(DEBUG_ANY, "%s: killed", __func__);
- cs->hw.usb->busy = 0;
- return;
- default:
- dev_err(cs->dev, "bulk transfer failed (status %d)\n",
- -status);
- /* That's all we can do. Communication problems
- are handled by timeouts or network protocols. */
- }
-
- spin_lock_irqsave(&cs->lock, flags);
- if (!cs->connected) {
- pr_err("%s: disconnected\n", __func__);
- } else {
- cs->hw.usb->busy = 0;
- tasklet_schedule(&cs->write_tasklet);
- }
- spin_unlock_irqrestore(&cs->lock, flags);
-}
-
-static int send_cb(struct cardstate *cs)
-{
- struct cmdbuf_t *cb = cs->cmdbuf;
- unsigned long flags;
- int count;
- int status = -ENOENT;
- struct usb_cardstate *ucs = cs->hw.usb;
-
- do {
- if (!cb->len) {
- spin_lock_irqsave(&cs->cmdlock, flags);
- cs->cmdbytes -= cs->curlen;
- gig_dbg(DEBUG_OUTPUT, "send_cb: sent %u bytes, %u left",
- cs->curlen, cs->cmdbytes);
- cs->cmdbuf = cb->next;
- if (cs->cmdbuf) {
- cs->cmdbuf->prev = NULL;
- cs->curlen = cs->cmdbuf->len;
- } else {
- cs->lastcmdbuf = NULL;
- cs->curlen = 0;
- }
- spin_unlock_irqrestore(&cs->cmdlock, flags);
-
- if (cb->wake_tasklet)
- tasklet_schedule(cb->wake_tasklet);
- kfree(cb);
-
- cb = cs->cmdbuf;
- }
-
- if (cb) {
- count = min(cb->len, ucs->bulk_out_size);
- gig_dbg(DEBUG_OUTPUT, "send_cb: send %d bytes", count);
-
- usb_fill_bulk_urb(ucs->bulk_out_urb, ucs->udev,
- usb_sndbulkpipe(ucs->udev,
- ucs->bulk_out_epnum),
- cb->buf + cb->offset, count,
- gigaset_write_bulk_callback, cs);
-
- cb->offset += count;
- cb->len -= count;
- ucs->busy = 1;
-
- spin_lock_irqsave(&cs->lock, flags);
- status = cs->connected ?
- usb_submit_urb(ucs->bulk_out_urb, GFP_ATOMIC) :
- -ENODEV;
- spin_unlock_irqrestore(&cs->lock, flags);
-
- if (status) {
- ucs->busy = 0;
- dev_err(cs->dev,
- "could not submit urb (error %d)\n",
- -status);
- cb->len = 0; /* skip urb => remove cb+wakeup
- in next loop cycle */
- }
- }
- } while (cb && status); /* next command on error */
-
- return status;
-}
-
-/* Send command to device. */
-static int gigaset_write_cmd(struct cardstate *cs, struct cmdbuf_t *cb)
-{
- unsigned long flags;
- int len;
-
- gigaset_dbg_buffer(cs->mstate != MS_LOCKED ?
- DEBUG_TRANSCMD : DEBUG_LOCKCMD,
- "CMD Transmit", cb->len, cb->buf);
-
- spin_lock_irqsave(&cs->cmdlock, flags);
- cb->prev = cs->lastcmdbuf;
- if (cs->lastcmdbuf)
- cs->lastcmdbuf->next = cb;
- else {
- cs->cmdbuf = cb;
- cs->curlen = cb->len;
- }
- cs->cmdbytes += cb->len;
- cs->lastcmdbuf = cb;
- spin_unlock_irqrestore(&cs->cmdlock, flags);
-
- spin_lock_irqsave(&cs->lock, flags);
- len = cb->len;
- if (cs->connected)
- tasklet_schedule(&cs->write_tasklet);
- spin_unlock_irqrestore(&cs->lock, flags);
- return len;
-}
-
-static int gigaset_write_room(struct cardstate *cs)
-{
- unsigned bytes;
-
- bytes = cs->cmdbytes;
- return bytes < IF_WRITEBUF ? IF_WRITEBUF - bytes : 0;
-}
-
-static int gigaset_chars_in_buffer(struct cardstate *cs)
-{
- return cs->cmdbytes;
-}
-
-/*
- * set the break characters on the internal serial adapter
- * using undocumented device commands reverse engineered from USB traces
- * of the Siemens Windows driver
- */
-static int gigaset_brkchars(struct cardstate *cs, const unsigned char buf[6])
-{
- struct usb_device *udev = cs->hw.usb->udev;
-
- gigaset_dbg_buffer(DEBUG_USBREQ, "brkchars", 6, buf);
- memcpy(cs->hw.usb->bchars, buf, 6);
- return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x19, 0x41,
- 0, 0, &buf, 6, 2000);
-}
-
-static void gigaset_freebcshw(struct bc_state *bcs)
-{
- /* unused */
-}
-
-/* Initialize the b-channel structure */
-static int gigaset_initbcshw(struct bc_state *bcs)
-{
- /* unused */
- bcs->hw.usb = NULL;
- return 0;
-}
-
-static void gigaset_reinitbcshw(struct bc_state *bcs)
-{
- /* nothing to do for M10x */
-}
-
-static void gigaset_freecshw(struct cardstate *cs)
-{
- tasklet_kill(&cs->write_tasklet);
- kfree(cs->hw.usb);
-}
-
-static int gigaset_initcshw(struct cardstate *cs)
-{
- struct usb_cardstate *ucs;
-
- cs->hw.usb = ucs = kzalloc(sizeof(struct usb_cardstate), GFP_KERNEL);
- if (!ucs) {
- pr_err("out of memory\n");
- return -ENOMEM;
- }
-
- ucs->bchars[0] = 0;
- ucs->bchars[1] = 0;
- ucs->bchars[2] = 0;
- ucs->bchars[3] = 0;
- ucs->bchars[4] = 0x11;
- ucs->bchars[5] = 0x13;
- tasklet_init(&cs->write_tasklet,
- gigaset_modem_fill, (unsigned long) cs);
-
- return 0;
-}
-
-/* Send data from current skb to the device. */
-static int write_modem(struct cardstate *cs)
-{
- int ret = 0;
- int count;
- struct bc_state *bcs = &cs->bcs[0]; /* only one channel */
- struct usb_cardstate *ucs = cs->hw.usb;
- unsigned long flags;
-
- gig_dbg(DEBUG_OUTPUT, "len: %d...", bcs->tx_skb->len);
-
- if (!bcs->tx_skb->len) {
- dev_kfree_skb_any(bcs->tx_skb);
- bcs->tx_skb = NULL;
- return -EINVAL;
- }
-
- /* Copy data to bulk out buffer and transmit data */
- count = min(bcs->tx_skb->len, (unsigned) ucs->bulk_out_size);
- skb_copy_from_linear_data(bcs->tx_skb, ucs->bulk_out_buffer, count);
- skb_pull(bcs->tx_skb, count);
- ucs->busy = 1;
- gig_dbg(DEBUG_OUTPUT, "write_modem: send %d bytes", count);
-
- spin_lock_irqsave(&cs->lock, flags);
- if (cs->connected) {
- usb_fill_bulk_urb(ucs->bulk_out_urb, ucs->udev,
- usb_sndbulkpipe(ucs->udev,
- ucs->bulk_out_epnum),
- ucs->bulk_out_buffer, count,
- gigaset_write_bulk_callback, cs);
- ret = usb_submit_urb(ucs->bulk_out_urb, GFP_ATOMIC);
- } else {
- ret = -ENODEV;
- }
- spin_unlock_irqrestore(&cs->lock, flags);
-
- if (ret) {
- dev_err(cs->dev, "could not submit urb (error %d)\n", -ret);
- ucs->busy = 0;
- }
-
- if (!bcs->tx_skb->len) {
- /* skb sent completely */
- gigaset_skb_sent(bcs, bcs->tx_skb);
-
- gig_dbg(DEBUG_INTR, "kfree skb (Adr: %lx)!",
- (unsigned long) bcs->tx_skb);
- dev_kfree_skb_any(bcs->tx_skb);
- bcs->tx_skb = NULL;
- }
-
- return ret;
-}
-
-static int gigaset_probe(struct usb_interface *interface,
- const struct usb_device_id *id)
-{
- int retval;
- struct usb_device *udev = interface_to_usbdev(interface);
- struct usb_host_interface *hostif = interface->cur_altsetting;
- struct cardstate *cs = NULL;
- struct usb_cardstate *ucs = NULL;
- struct usb_endpoint_descriptor *endpoint;
- int buffer_size;
-
- gig_dbg(DEBUG_ANY, "%s: Check if device matches ...", __func__);
-
- /* See if the device offered us matches what we can accept */
- if ((le16_to_cpu(udev->descriptor.idVendor) != USB_M105_VENDOR_ID) ||
- (le16_to_cpu(udev->descriptor.idProduct) != USB_M105_PRODUCT_ID)) {
- gig_dbg(DEBUG_ANY, "device ID (0x%x, 0x%x) not for me - skip",
- le16_to_cpu(udev->descriptor.idVendor),
- le16_to_cpu(udev->descriptor.idProduct));
- return -ENODEV;
- }
- if (hostif->desc.bInterfaceNumber != 0) {
- gig_dbg(DEBUG_ANY, "interface %d not for me - skip",
- hostif->desc.bInterfaceNumber);
- return -ENODEV;
- }
- if (hostif->desc.bAlternateSetting != 0) {
- dev_notice(&udev->dev, "unsupported altsetting %d - skip",
- hostif->desc.bAlternateSetting);
- return -ENODEV;
- }
- if (hostif->desc.bInterfaceClass != 255) {
- dev_notice(&udev->dev, "unsupported interface class %d - skip",
- hostif->desc.bInterfaceClass);
- return -ENODEV;
- }
-
- if (hostif->desc.bNumEndpoints < 2) {
- dev_err(&interface->dev, "missing endpoints\n");
- return -ENODEV;
- }
-
- dev_info(&udev->dev, "%s: Device matched ... !\n", __func__);
-
- /* allocate memory for our device state and initialize it */
- cs = gigaset_initcs(driver, 1, 1, 0, cidmode, GIGASET_MODULENAME);
- if (!cs)
- return -ENODEV;
- ucs = cs->hw.usb;
-
- /* save off device structure ptrs for later use */
- usb_get_dev(udev);
- ucs->udev = udev;
- ucs->interface = interface;
- cs->dev = &interface->dev;
-
- /* save address of controller structure */
- usb_set_intfdata(interface, cs);
-
- endpoint = &hostif->endpoint[0].desc;
-
- if (!usb_endpoint_is_bulk_out(endpoint)) {
- dev_err(&interface->dev, "missing bulk-out endpoint\n");
- retval = -ENODEV;
- goto error;
- }
-
- buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
- ucs->bulk_out_size = buffer_size;
- ucs->bulk_out_epnum = usb_endpoint_num(endpoint);
- ucs->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL);
- if (!ucs->bulk_out_buffer) {
- dev_err(cs->dev, "Couldn't allocate bulk_out_buffer\n");
- retval = -ENOMEM;
- goto error;
- }
-
- ucs->bulk_out_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!ucs->bulk_out_urb) {
- dev_err(cs->dev, "Couldn't allocate bulk_out_urb\n");
- retval = -ENOMEM;
- goto error;
- }
-
- endpoint = &hostif->endpoint[1].desc;
-
- if (!usb_endpoint_is_int_in(endpoint)) {
- dev_err(&interface->dev, "missing int-in endpoint\n");
- retval = -ENODEV;
- goto error;
- }
-
- ucs->busy = 0;
-
- ucs->read_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!ucs->read_urb) {
- dev_err(cs->dev, "No free urbs available\n");
- retval = -ENOMEM;
- goto error;
- }
- buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
- ucs->rcvbuf_size = buffer_size;
- ucs->rcvbuf = kmalloc(buffer_size, GFP_KERNEL);
- if (!ucs->rcvbuf) {
- dev_err(cs->dev, "Couldn't allocate rcvbuf\n");
- retval = -ENOMEM;
- goto error;
- }
- /* Fill the interrupt urb and send it to the core */
- usb_fill_int_urb(ucs->read_urb, udev,
- usb_rcvintpipe(udev, usb_endpoint_num(endpoint)),
- ucs->rcvbuf, buffer_size,
- gigaset_read_int_callback,
- cs, endpoint->bInterval);
-
- retval = usb_submit_urb(ucs->read_urb, GFP_KERNEL);
- if (retval) {
- dev_err(cs->dev, "Could not submit URB (error %d)\n", -retval);
- goto error;
- }
-
- /* tell common part that the device is ready */
- if (startmode == SM_LOCKED)
- cs->mstate = MS_LOCKED;
-
- retval = gigaset_start(cs);
- if (retval < 0) {
- tasklet_kill(&cs->write_tasklet);
- goto error;
- }
- return 0;
-
-error:
- usb_kill_urb(ucs->read_urb);
- kfree(ucs->bulk_out_buffer);
- usb_free_urb(ucs->bulk_out_urb);
- kfree(ucs->rcvbuf);
- usb_free_urb(ucs->read_urb);
- usb_set_intfdata(interface, NULL);
- ucs->read_urb = ucs->bulk_out_urb = NULL;
- ucs->rcvbuf = ucs->bulk_out_buffer = NULL;
- usb_put_dev(ucs->udev);
- ucs->udev = NULL;
- ucs->interface = NULL;
- gigaset_freecs(cs);
- return retval;
-}
-
-static void gigaset_disconnect(struct usb_interface *interface)
-{
- struct cardstate *cs;
- struct usb_cardstate *ucs;
-
- cs = usb_get_intfdata(interface);
- ucs = cs->hw.usb;
-
- dev_info(cs->dev, "disconnecting Gigaset USB adapter\n");
-
- usb_kill_urb(ucs->read_urb);
-
- gigaset_stop(cs);
-
- usb_set_intfdata(interface, NULL);
- tasklet_kill(&cs->write_tasklet);
-
- usb_kill_urb(ucs->bulk_out_urb);
-
- kfree(ucs->bulk_out_buffer);
- usb_free_urb(ucs->bulk_out_urb);
- kfree(ucs->rcvbuf);
- usb_free_urb(ucs->read_urb);
- ucs->read_urb = ucs->bulk_out_urb = NULL;
- ucs->rcvbuf = ucs->bulk_out_buffer = NULL;
-
- usb_put_dev(ucs->udev);
- ucs->interface = NULL;
- ucs->udev = NULL;
- cs->dev = NULL;
- gigaset_freecs(cs);
-}
-
-/* gigaset_suspend
- * This function is called before the USB connection is suspended or reset.
- */
-static int gigaset_suspend(struct usb_interface *intf, pm_message_t message)
-{
- struct cardstate *cs = usb_get_intfdata(intf);
-
- /* stop activity */
- cs->connected = 0; /* prevent rescheduling */
- usb_kill_urb(cs->hw.usb->read_urb);
- tasklet_kill(&cs->write_tasklet);
- usb_kill_urb(cs->hw.usb->bulk_out_urb);
-
- gig_dbg(DEBUG_SUSPEND, "suspend complete");
- return 0;
-}
-
-/* gigaset_resume
- * This function is called after the USB connection has been resumed or reset.
- */
-static int gigaset_resume(struct usb_interface *intf)
-{
- struct cardstate *cs = usb_get_intfdata(intf);
- int rc;
-
- /* resubmit interrupt URB */
- cs->connected = 1;
- rc = usb_submit_urb(cs->hw.usb->read_urb, GFP_KERNEL);
- if (rc) {
- dev_err(cs->dev, "Could not submit read URB (error %d)\n", -rc);
- return rc;
- }
-
- gig_dbg(DEBUG_SUSPEND, "resume complete");
- return 0;
-}
-
-/* gigaset_pre_reset
- * This function is called before the USB connection is reset.
- */
-static int gigaset_pre_reset(struct usb_interface *intf)
-{
- /* same as suspend */
- return gigaset_suspend(intf, PMSG_ON);
-}
-
-static const struct gigaset_ops ops = {
- .write_cmd = gigaset_write_cmd,
- .write_room = gigaset_write_room,
- .chars_in_buffer = gigaset_chars_in_buffer,
- .brkchars = gigaset_brkchars,
- .init_bchannel = gigaset_init_bchannel,
- .close_bchannel = gigaset_close_bchannel,
- .initbcshw = gigaset_initbcshw,
- .freebcshw = gigaset_freebcshw,
- .reinitbcshw = gigaset_reinitbcshw,
- .initcshw = gigaset_initcshw,
- .freecshw = gigaset_freecshw,
- .set_modem_ctrl = gigaset_set_modem_ctrl,
- .baud_rate = gigaset_baud_rate,
- .set_line_ctrl = gigaset_set_line_ctrl,
- .send_skb = gigaset_m10x_send_skb,
- .handle_input = gigaset_m10x_input,
-};
-
-/*
- * This function is called while kernel-module is loaded
- */
-static int __init usb_gigaset_init(void)
-{
- int result;
-
- /* allocate memory for our driver state and initialize it */
- driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS,
- GIGASET_MODULENAME, GIGASET_DEVNAME,
- &ops, THIS_MODULE);
- if (driver == NULL) {
- result = -ENOMEM;
- goto error;
- }
-
- /* register this driver with the USB subsystem */
- result = usb_register(&gigaset_usb_driver);
- if (result < 0) {
- pr_err("error %d registering USB driver\n", -result);
- goto error;
- }
-
- pr_info(DRIVER_DESC "\n");
- return 0;
-
-error:
- if (driver)
- gigaset_freedriver(driver);
- driver = NULL;
- return result;
-}
-
-/*
- * This function is called while unloading the kernel-module
- */
-static void __exit usb_gigaset_exit(void)
-{
- int i;
-
- gigaset_blockdriver(driver); /* => probe will fail
- * => no gigaset_start any more
- */
-
- /* stop all connected devices */
- for (i = 0; i < driver->minors; i++)
- gigaset_shutdown(driver->cs + i);
-
- /* from now on, no isdn callback should be possible */
-
- /* deregister this driver with the USB subsystem */
- usb_deregister(&gigaset_usb_driver);
- /* this will call the disconnect-callback */
- /* from now on, no disconnect/probe callback should be running */
-
- gigaset_freedriver(driver);
- driver = NULL;
-}
-
-
-module_init(usb_gigaset_init);
-module_exit(usb_gigaset_exit);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/isdn/hysdn/Kconfig b/drivers/staging/isdn/hysdn/Kconfig
deleted file mode 100644
index 4c8a9283b9dd..000000000000
--- a/drivers/staging/isdn/hysdn/Kconfig
+++ /dev/null
@@ -1,15 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-config HYSDN
- tristate "Hypercope HYSDN cards (Champ, Ergo, Metro) support (module only)"
- depends on m && PROC_FS && PCI
- help
- Say Y here if you have one of Hypercope's active PCI ISDN cards
- Champ, Ergo and Metro. You will then get a module called hysdn.
- Please read the file <file:Documentation/isdn/hysdn.rst> for more
- information.
-
-config HYSDN_CAPI
- bool "HYSDN CAPI 2.0 support"
- depends on HYSDN && ISDN_CAPI
- help
- Say Y here if you like to use Hypercope's CAPI 2.0 interface.
diff --git a/drivers/staging/isdn/hysdn/Makefile b/drivers/staging/isdn/hysdn/Makefile
deleted file mode 100644
index e01f17f22ebb..000000000000
--- a/drivers/staging/isdn/hysdn/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-# Makefile for the hysdn ISDN device driver
-
-# Each configuration option enables a list of files.
-
-obj-$(CONFIG_HYSDN) += hysdn.o
-
-# Multipart objects.
-
-hysdn-y := hysdn_procconf.o hysdn_proclog.o boardergo.o \
- hysdn_boot.o hysdn_sched.o hysdn_net.o hysdn_init.o
-hysdn-$(CONFIG_HYSDN_CAPI) += hycapi.o
diff --git a/drivers/staging/isdn/hysdn/boardergo.c b/drivers/staging/isdn/hysdn/boardergo.c
deleted file mode 100644
index 2aa2a0e08247..000000000000
--- a/drivers/staging/isdn/hysdn/boardergo.c
+++ /dev/null
@@ -1,445 +0,0 @@
-/* $Id: boardergo.c,v 1.5.6.7 2001/11/06 21:58:19 kai Exp $
- *
- * Linux driver for HYSDN cards, specific routines for ergo type boards.
- *
- * Author Werner Cornelius (werner@titro.de) for Hypercope GmbH
- * Copyright 1999 by Werner Cornelius (werner@titro.de)
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- * As all Linux supported cards Champ2, Ergo and Metro2/4 use the same
- * DPRAM interface and layout with only minor differences all related
- * stuff is done here, not in separate modules.
- *
- */
-
-#include <linux/signal.h>
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/vmalloc.h>
-#include <linux/delay.h>
-#include <asm/io.h>
-
-#include "hysdn_defs.h"
-#include "boardergo.h"
-
-#define byteout(addr, val) outb(val, addr)
-#define bytein(addr) inb(addr)
-
-/***************************************************/
-/* The cards interrupt handler. Called from system */
-/***************************************************/
-static irqreturn_t
-ergo_interrupt(int intno, void *dev_id)
-{
- hysdn_card *card = dev_id; /* parameter from irq */
- tErgDpram *dpr;
- unsigned long flags;
- unsigned char volatile b;
-
- if (!card)
- return IRQ_NONE; /* error -> spurious interrupt */
- if (!card->irq_enabled)
- return IRQ_NONE; /* other device interrupting or irq switched off */
-
- spin_lock_irqsave(&card->hysdn_lock, flags); /* no further irqs allowed */
-
- if (!(bytein(card->iobase + PCI9050_INTR_REG) & PCI9050_INTR_REG_STAT1)) {
- spin_unlock_irqrestore(&card->hysdn_lock, flags); /* restore old state */
- return IRQ_NONE; /* no interrupt requested by E1 */
- }
- /* clear any pending ints on the board */
- dpr = card->dpram;
- b = dpr->ToPcInt; /* clear for ergo */
- b |= dpr->ToPcIntMetro; /* same for metro */
- b |= dpr->ToHyInt; /* and for champ */
-
- /* start kernel task immediately after leaving all interrupts */
- if (!card->hw_lock)
- schedule_work(&card->irq_queue);
- spin_unlock_irqrestore(&card->hysdn_lock, flags);
- return IRQ_HANDLED;
-} /* ergo_interrupt */
-
-/******************************************************************************/
-/* ergo_irq_bh will be called as part of the kernel clearing its shared work */
-/* queue sometime after a call to schedule_work has been made passing our */
-/* work_struct. This task is the only one handling data transfer from or to */
-/* the card after booting. The task may be queued from everywhere */
-/* (interrupts included). */
-/******************************************************************************/
-static void
-ergo_irq_bh(struct work_struct *ugli_api)
-{
- hysdn_card *card = container_of(ugli_api, hysdn_card, irq_queue);
- tErgDpram *dpr;
- int again;
- unsigned long flags;
-
- if (card->state != CARD_STATE_RUN)
- return; /* invalid call */
-
- dpr = card->dpram; /* point to DPRAM */
-
- spin_lock_irqsave(&card->hysdn_lock, flags);
- if (card->hw_lock) {
- spin_unlock_irqrestore(&card->hysdn_lock, flags); /* hardware currently unavailable */
- return;
- }
- card->hw_lock = 1; /* we now lock the hardware */
-
- do {
- again = 0; /* assume loop not to be repeated */
-
- if (!dpr->ToHyFlag) {
- /* we are able to send a buffer */
-
- if (hysdn_sched_tx(card, dpr->ToHyBuf, &dpr->ToHySize, &dpr->ToHyChannel,
- ERG_TO_HY_BUF_SIZE)) {
- dpr->ToHyFlag = 1; /* enable tx */
- again = 1; /* restart loop */
- }
- } /* we are able to send a buffer */
- if (dpr->ToPcFlag) {
- /* a message has arrived for us, handle it */
-
- if (hysdn_sched_rx(card, dpr->ToPcBuf, dpr->ToPcSize, dpr->ToPcChannel)) {
- dpr->ToPcFlag = 0; /* we worked the data */
- again = 1; /* restart loop */
- }
- } /* a message has arrived for us */
- if (again) {
- dpr->ToHyInt = 1;
- dpr->ToPcInt = 1; /* interrupt to E1 for all cards */
- } else
- card->hw_lock = 0; /* free hardware again */
- } while (again); /* until nothing more to do */
-
- spin_unlock_irqrestore(&card->hysdn_lock, flags);
-} /* ergo_irq_bh */
-
-
-/*********************************************************/
-/* stop the card (hardware reset) and disable interrupts */
-/*********************************************************/
-static void
-ergo_stopcard(hysdn_card *card)
-{
- unsigned long flags;
- unsigned char val;
-
- hysdn_net_release(card); /* first release the net device if existing */
-#ifdef CONFIG_HYSDN_CAPI
- hycapi_capi_stop(card);
-#endif /* CONFIG_HYSDN_CAPI */
- spin_lock_irqsave(&card->hysdn_lock, flags);
- val = bytein(card->iobase + PCI9050_INTR_REG); /* get actual value */
- val &= ~(PCI9050_INTR_REG_ENPCI | PCI9050_INTR_REG_EN1); /* mask irq */
- byteout(card->iobase + PCI9050_INTR_REG, val);
- card->irq_enabled = 0;
- byteout(card->iobase + PCI9050_USER_IO, PCI9050_E1_RESET); /* reset E1 processor */
- card->state = CARD_STATE_UNUSED;
- card->err_log_state = ERRLOG_STATE_OFF; /* currently no log active */
-
- spin_unlock_irqrestore(&card->hysdn_lock, flags);
-} /* ergo_stopcard */
-
-/**************************************************************************/
-/* enable or disable the cards error log. The event is queued if possible */
-/**************************************************************************/
-static void
-ergo_set_errlog_state(hysdn_card *card, int on)
-{
- unsigned long flags;
-
- if (card->state != CARD_STATE_RUN) {
- card->err_log_state = ERRLOG_STATE_OFF; /* must be off */
- return;
- }
- spin_lock_irqsave(&card->hysdn_lock, flags);
-
- if (((card->err_log_state == ERRLOG_STATE_OFF) && !on) ||
- ((card->err_log_state == ERRLOG_STATE_ON) && on)) {
- spin_unlock_irqrestore(&card->hysdn_lock, flags);
- return; /* nothing to do */
- }
- if (on)
- card->err_log_state = ERRLOG_STATE_START; /* request start */
- else
- card->err_log_state = ERRLOG_STATE_STOP; /* request stop */
-
- spin_unlock_irqrestore(&card->hysdn_lock, flags);
- schedule_work(&card->irq_queue);
-} /* ergo_set_errlog_state */
-
-/******************************************/
-/* test the cards RAM and return 0 if ok. */
-/******************************************/
-static const char TestText[36] = "This Message is filler, why read it";
-
-static int
-ergo_testram(hysdn_card *card)
-{
- tErgDpram *dpr = card->dpram;
-
- memset(dpr->TrapTable, 0, sizeof(dpr->TrapTable)); /* clear all Traps */
- dpr->ToHyInt = 1; /* E1 INTR state forced */
-
- memcpy(&dpr->ToHyBuf[ERG_TO_HY_BUF_SIZE - sizeof(TestText)], TestText,
- sizeof(TestText));
- if (memcmp(&dpr->ToHyBuf[ERG_TO_HY_BUF_SIZE - sizeof(TestText)], TestText,
- sizeof(TestText)))
- return (-1);
-
- memcpy(&dpr->ToPcBuf[ERG_TO_PC_BUF_SIZE - sizeof(TestText)], TestText,
- sizeof(TestText));
- if (memcmp(&dpr->ToPcBuf[ERG_TO_PC_BUF_SIZE - sizeof(TestText)], TestText,
- sizeof(TestText)))
- return (-1);
-
- return (0);
-} /* ergo_testram */
-
-/*****************************************************************************/
-/* this function is intended to write stage 1 boot image to the cards buffer */
-/* this is done in two steps. First the 1024 hi-words are written (offs=0), */
-/* then the 1024 lo-bytes are written. The remaining DPRAM is cleared, the */
-/* PCI-write-buffers flushed and the card is taken out of reset. */
-/* The function then waits for a reaction of the E1 processor or a timeout. */
-/* Negative return values are interpreted as errors. */
-/*****************************************************************************/
-static int
-ergo_writebootimg(struct HYSDN_CARD *card, unsigned char *buf,
- unsigned long offs)
-{
- unsigned char *dst;
- tErgDpram *dpram;
- int cnt = (BOOT_IMG_SIZE >> 2); /* number of words to move and swap (byte order!) */
-
- if (card->debug_flags & LOG_POF_CARD)
- hysdn_addlog(card, "ERGO: write bootldr offs=0x%lx ", offs);
-
- dst = card->dpram; /* pointer to start of DPRAM */
- dst += (offs + ERG_DPRAM_FILL_SIZE); /* offset in the DPRAM */
- while (cnt--) {
- *dst++ = *(buf + 1); /* high byte */
- *dst++ = *buf; /* low byte */
- dst += 2; /* point to next longword */
- buf += 2; /* buffer only filled with words */
- }
-
- /* if low words (offs = 2) have been written, clear the rest of the DPRAM, */
- /* flush the PCI-write-buffer and take the E1 out of reset */
- if (offs) {
- memset(card->dpram, 0, ERG_DPRAM_FILL_SIZE); /* fill the DPRAM still not cleared */
- dpram = card->dpram; /* get pointer to dpram structure */
- dpram->ToHyNoDpramErrLog = 0xFF; /* write a dpram register */
- while (!dpram->ToHyNoDpramErrLog); /* reread volatile register to flush PCI */
-
- byteout(card->iobase + PCI9050_USER_IO, PCI9050_E1_RUN); /* start E1 processor */
- /* the interrupts are still masked */
-
- msleep_interruptible(20); /* Timeout 20ms */
-
- if (((tDpramBootSpooler *) card->dpram)->Len != DPRAM_SPOOLER_DATA_SIZE) {
- if (card->debug_flags & LOG_POF_CARD)
- hysdn_addlog(card, "ERGO: write bootldr no answer");
- return (-ERR_BOOTIMG_FAIL);
- }
- } /* start_boot_img */
- return (0); /* successful */
-} /* ergo_writebootimg */
-
-/********************************************************************************/
-/* ergo_writebootseq writes the buffer containing len bytes to the E1 processor */
-/* using the boot spool mechanism. If everything works fine 0 is returned. In */
-/* case of errors a negative error value is returned. */
-/********************************************************************************/
-static int
-ergo_writebootseq(struct HYSDN_CARD *card, unsigned char *buf, int len)
-{
- tDpramBootSpooler *sp = (tDpramBootSpooler *) card->dpram;
- unsigned char *dst;
- unsigned char buflen;
- int nr_write;
- unsigned char tmp_rdptr;
- unsigned char wr_mirror;
- int i;
-
- if (card->debug_flags & LOG_POF_CARD)
- hysdn_addlog(card, "ERGO: write boot seq len=%d ", len);
-
- dst = sp->Data; /* point to data in spool structure */
- buflen = sp->Len; /* maximum len of spooled data */
- wr_mirror = sp->WrPtr; /* only once read */
-
- /* try until all bytes written or error */
- i = 0x1000; /* timeout value */
- while (len) {
-
- /* first determine the number of bytes that may be buffered */
- do {
- tmp_rdptr = sp->RdPtr; /* first read the pointer */
- i--; /* decrement timeout */
- } while (i && (tmp_rdptr != sp->RdPtr)); /* wait for stable pointer */
-
- if (!i) {
- if (card->debug_flags & LOG_POF_CARD)
- hysdn_addlog(card, "ERGO: write boot seq timeout");
- return (-ERR_BOOTSEQ_FAIL); /* value not stable -> timeout */
- }
- if ((nr_write = tmp_rdptr - wr_mirror - 1) < 0)
- nr_write += buflen; /* now we got number of free bytes - 1 in buffer */
-
- if (!nr_write)
- continue; /* no free bytes in buffer */
-
- if (nr_write > len)
- nr_write = len; /* limit if last few bytes */
- i = 0x1000; /* reset timeout value */
-
- /* now we know how much bytes we may put in the puffer */
- len -= nr_write; /* we savely could adjust len before output */
- while (nr_write--) {
- *(dst + wr_mirror) = *buf++; /* output one byte */
- if (++wr_mirror >= buflen)
- wr_mirror = 0;
- sp->WrPtr = wr_mirror; /* announce the next byte to E1 */
- } /* while (nr_write) */
-
- } /* while (len) */
- return (0);
-} /* ergo_writebootseq */
-
-/***********************************************************************************/
-/* ergo_waitpofready waits for a maximum of 10 seconds for the completition of the */
-/* boot process. If the process has been successful 0 is returned otherwise a */
-/* negative error code is returned. */
-/***********************************************************************************/
-static int
-ergo_waitpofready(struct HYSDN_CARD *card)
-{
- tErgDpram *dpr = card->dpram; /* pointer to DPRAM structure */
- int timecnt = 10000 / 50; /* timeout is 10 secs max. */
- unsigned long flags;
- int msg_size;
- int i;
-
- if (card->debug_flags & LOG_POF_CARD)
- hysdn_addlog(card, "ERGO: waiting for pof ready");
- while (timecnt--) {
- /* wait until timeout */
-
- if (dpr->ToPcFlag) {
- /* data has arrived */
-
- if ((dpr->ToPcChannel != CHAN_SYSTEM) ||
- (dpr->ToPcSize < MIN_RDY_MSG_SIZE) ||
- (dpr->ToPcSize > MAX_RDY_MSG_SIZE) ||
- ((*(unsigned long *) dpr->ToPcBuf) != RDY_MAGIC))
- break; /* an error occurred */
-
- /* Check for additional data delivered during SysReady */
- msg_size = dpr->ToPcSize - RDY_MAGIC_SIZE;
- if (msg_size > 0)
- if (EvalSysrTokData(card, dpr->ToPcBuf + RDY_MAGIC_SIZE, msg_size))
- break;
-
- if (card->debug_flags & LOG_POF_RECORD)
- hysdn_addlog(card, "ERGO: pof boot success");
- spin_lock_irqsave(&card->hysdn_lock, flags);
-
- card->state = CARD_STATE_RUN; /* now card is running */
- /* enable the cards interrupt */
- byteout(card->iobase + PCI9050_INTR_REG,
- bytein(card->iobase + PCI9050_INTR_REG) |
- (PCI9050_INTR_REG_ENPCI | PCI9050_INTR_REG_EN1));
- card->irq_enabled = 1; /* we are ready to receive interrupts */
-
- dpr->ToPcFlag = 0; /* reset data indicator */
- dpr->ToHyInt = 1;
- dpr->ToPcInt = 1; /* interrupt to E1 for all cards */
-
- spin_unlock_irqrestore(&card->hysdn_lock, flags);
- if ((hynet_enable & (1 << card->myid))
- && (i = hysdn_net_create(card)))
- {
- ergo_stopcard(card);
- card->state = CARD_STATE_BOOTERR;
- return (i);
- }
-#ifdef CONFIG_HYSDN_CAPI
- if ((i = hycapi_capi_create(card))) {
- printk(KERN_WARNING "HYSDN: failed to create capi-interface.\n");
- }
-#endif /* CONFIG_HYSDN_CAPI */
- return (0); /* success */
- } /* data has arrived */
- msleep_interruptible(50); /* Timeout 50ms */
- } /* wait until timeout */
-
- if (card->debug_flags & LOG_POF_CARD)
- hysdn_addlog(card, "ERGO: pof boot ready timeout");
- return (-ERR_POF_TIMEOUT);
-} /* ergo_waitpofready */
-
-
-
-/************************************************************************************/
-/* release the cards hardware. Before releasing do a interrupt disable and hardware */
-/* reset. Also unmap dpram. */
-/* Use only during module release. */
-/************************************************************************************/
-static void
-ergo_releasehardware(hysdn_card *card)
-{
- ergo_stopcard(card); /* first stop the card if not already done */
- free_irq(card->irq, card); /* release interrupt */
- release_region(card->iobase + PCI9050_INTR_REG, 1); /* release all io ports */
- release_region(card->iobase + PCI9050_USER_IO, 1);
- iounmap(card->dpram);
- card->dpram = NULL; /* release shared mem */
-} /* ergo_releasehardware */
-
-
-/*********************************************************************************/
-/* acquire the needed hardware ports and map dpram. If an error occurs a nonzero */
-/* value is returned. */
-/* Use only during module init. */
-/*********************************************************************************/
-int
-ergo_inithardware(hysdn_card *card)
-{
- if (!request_region(card->iobase + PCI9050_INTR_REG, 1, "HYSDN"))
- return (-1);
- if (!request_region(card->iobase + PCI9050_USER_IO, 1, "HYSDN")) {
- release_region(card->iobase + PCI9050_INTR_REG, 1);
- return (-1); /* ports already in use */
- }
- card->memend = card->membase + ERG_DPRAM_PAGE_SIZE - 1;
- if (!(card->dpram = ioremap(card->membase, ERG_DPRAM_PAGE_SIZE))) {
- release_region(card->iobase + PCI9050_INTR_REG, 1);
- release_region(card->iobase + PCI9050_USER_IO, 1);
- return (-1);
- }
-
- ergo_stopcard(card); /* disable interrupts */
- if (request_irq(card->irq, ergo_interrupt, IRQF_SHARED, "HYSDN", card)) {
- ergo_releasehardware(card); /* return the acquired hardware */
- return (-1);
- }
- /* success, now setup the function pointers */
- card->stopcard = ergo_stopcard;
- card->releasehardware = ergo_releasehardware;
- card->testram = ergo_testram;
- card->writebootimg = ergo_writebootimg;
- card->writebootseq = ergo_writebootseq;
- card->waitpofready = ergo_waitpofready;
- card->set_errlog_state = ergo_set_errlog_state;
- INIT_WORK(&card->irq_queue, ergo_irq_bh);
- spin_lock_init(&card->hysdn_lock);
-
- return (0);
-} /* ergo_inithardware */
diff --git a/drivers/staging/isdn/hysdn/boardergo.h b/drivers/staging/isdn/hysdn/boardergo.h
deleted file mode 100644
index e99bd81c4034..000000000000
--- a/drivers/staging/isdn/hysdn/boardergo.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/* $Id: boardergo.h,v 1.2.6.1 2001/09/23 22:24:54 kai Exp $
- *
- * Linux driver for HYSDN cards, definitions for ergo type boards (buffers..).
- *
- * Author Werner Cornelius (werner@titro.de) for Hypercope GmbH
- * Copyright 1999 by Werner Cornelius (werner@titro.de)
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-
-/************************************************/
-/* defines for the dual port memory of the card */
-/************************************************/
-#define ERG_DPRAM_PAGE_SIZE 0x2000 /* DPRAM occupies a 8K page */
-#define BOOT_IMG_SIZE 4096
-#define ERG_DPRAM_FILL_SIZE (ERG_DPRAM_PAGE_SIZE - BOOT_IMG_SIZE)
-
-#define ERG_TO_HY_BUF_SIZE 0x0E00 /* 3072 bytes buffer size to card */
-#define ERG_TO_PC_BUF_SIZE 0x0E00 /* 3072 bytes to PC, too */
-
-/* following DPRAM layout copied from OS2-driver boarderg.h */
-typedef struct ErgDpram_tag {
- /*0000 */ unsigned char ToHyBuf[ERG_TO_HY_BUF_SIZE];
- /*0E00 */ unsigned char ToPcBuf[ERG_TO_PC_BUF_SIZE];
-
- /*1C00 */ unsigned char bSoftUart[SIZE_RSV_SOFT_UART];
- /* size 0x1B0 */
-
- /*1DB0 *//* tErrLogEntry */ unsigned char volatile ErrLogMsg[64];
- /* size 64 bytes */
- /*1DB0 unsigned long ulErrType; */
- /*1DB4 unsigned long ulErrSubtype; */
- /*1DB8 unsigned long ucTextSize; */
- /*1DB9 unsigned long ucText[ERRLOG_TEXT_SIZE]; *//* ASCIIZ of len ucTextSize-1 */
- /*1DF0 */
-
- /*1DF0 */ unsigned short volatile ToHyChannel;
- /*1DF2 */ unsigned short volatile ToHySize;
- /*1DF4 */ unsigned char volatile ToHyFlag;
- /* !=0: msg for Hy waiting */
- /*1DF5 */ unsigned char volatile ToPcFlag;
- /* !=0: msg for PC waiting */
- /*1DF6 */ unsigned short volatile ToPcChannel;
- /*1DF8 */ unsigned short volatile ToPcSize;
- /*1DFA */ unsigned char bRes1DBA[0x1E00 - 0x1DFA];
- /* 6 bytes */
-
- /*1E00 */ unsigned char bRestOfEntryTbl[0x1F00 - 0x1E00];
- /*1F00 */ unsigned long TrapTable[62];
- /*1FF8 */ unsigned char bRes1FF8[0x1FFB - 0x1FF8];
- /* low part of reset vetor */
- /*1FFB */ unsigned char ToPcIntMetro;
- /* notes:
- * - metro has 32-bit boot ram - accessing
- * ToPcInt and ToHyInt would be the same;
- * so we moved ToPcInt to 1FFB.
- * Because on the PC side both vars are
- * readonly (reseting on int from E1 to PC),
- * we can read both vars on both cards
- * without destroying anything.
- * - 1FFB is the high byte of the reset vector,
- * so E1 side should NOT change this byte
- * when writing!
- */
- /*1FFC */ unsigned char volatile ToHyNoDpramErrLog;
- /* note: ToHyNoDpramErrLog is used to inform
- * boot loader, not to use DPRAM based
- * ErrLog; when DOS driver is rewritten
- * this becomes obsolete
- */
- /*1FFD */ unsigned char bRes1FFD;
- /*1FFE */ unsigned char ToPcInt;
- /* E1_intclear; on CHAMP2: E1_intset */
- /*1FFF */ unsigned char ToHyInt;
- /* E1_intset; on CHAMP2: E1_intclear */
-} tErgDpram;
-
-/**********************************************/
-/* PCI9050 controller local register offsets: */
-/* copied from boarderg.c */
-/**********************************************/
-#define PCI9050_INTR_REG 0x4C /* Interrupt register */
-#define PCI9050_USER_IO 0x51 /* User I/O register */
-
-/* bitmask for PCI9050_INTR_REG: */
-#define PCI9050_INTR_REG_EN1 0x01 /* 1= enable (def.), 0= disable */
-#define PCI9050_INTR_REG_POL1 0x02 /* 1= active high (def.), 0= active low */
-#define PCI9050_INTR_REG_STAT1 0x04 /* 1= intr. active, 0= intr. not active (def.) */
-#define PCI9050_INTR_REG_ENPCI 0x40 /* 1= PCI interrupts enable (def.) */
-
-/* bitmask for PCI9050_USER_IO: */
-#define PCI9050_USER_IO_EN3 0x02 /* 1= disable , 0= enable (def.) */
-#define PCI9050_USER_IO_DIR3 0x04 /* 1= output (def.), 0= input */
-#define PCI9050_USER_IO_DAT3 0x08 /* 1= high (def.) , 0= low */
-
-#define PCI9050_E1_RESET (PCI9050_USER_IO_DIR3) /* 0x04 */
-#define PCI9050_E1_RUN (PCI9050_USER_IO_DAT3 | PCI9050_USER_IO_DIR3) /* 0x0C */
diff --git a/drivers/staging/isdn/hysdn/hycapi.c b/drivers/staging/isdn/hysdn/hycapi.c
deleted file mode 100644
index a2c15cd7bf67..000000000000
--- a/drivers/staging/isdn/hysdn/hycapi.c
+++ /dev/null
@@ -1,785 +0,0 @@
-/* $Id: hycapi.c,v 1.8.6.4 2001/09/23 22:24:54 kai Exp $
- *
- * Linux driver for HYSDN cards, CAPI2.0-Interface.
- *
- * Author Ulrich Albrecht <u.albrecht@hypercope.de> for Hypercope GmbH
- * Copyright 2000 by Hypercope GmbH
- *
- * 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/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/signal.h>
-#include <linux/kernel.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-#include <linux/slab.h>
-
-#define VER_DRIVER 0
-#define VER_CARDTYPE 1
-#define VER_HWID 2
-#define VER_SERIAL 3
-#define VER_OPTION 4
-#define VER_PROTO 5
-#define VER_PROFILE 6
-#define VER_CAPI 7
-
-#include "hysdn_defs.h"
-#include <linux/kernelcapi.h>
-
-static char hycapi_revision[] = "$Revision: 1.8.6.4 $";
-
-unsigned int hycapi_enable = 0xffffffff;
-module_param(hycapi_enable, uint, 0);
-
-typedef struct _hycapi_appl {
- unsigned int ctrl_mask;
- capi_register_params rp;
- struct sk_buff *listen_req[CAPI_MAXCONTR];
-} hycapi_appl;
-
-static hycapi_appl hycapi_applications[CAPI_MAXAPPL];
-
-static u16 hycapi_send_message(struct capi_ctr *ctrl, struct sk_buff *skb);
-
-static inline int _hycapi_appCheck(int app_id, int ctrl_no)
-{
- if ((ctrl_no <= 0) || (ctrl_no > CAPI_MAXCONTR) || (app_id <= 0) ||
- (app_id > CAPI_MAXAPPL))
- {
- printk(KERN_ERR "HYCAPI: Invalid request app_id %d for controller %d", app_id, ctrl_no);
- return -1;
- }
- return ((hycapi_applications[app_id - 1].ctrl_mask & (1 << (ctrl_no-1))) != 0);
-}
-
-/******************************
-Kernel-Capi callback reset_ctr
-******************************/
-
-static void
-hycapi_reset_ctr(struct capi_ctr *ctrl)
-{
- hycapictrl_info *cinfo = ctrl->driverdata;
-
-#ifdef HYCAPI_PRINTFNAMES
- printk(KERN_NOTICE "HYCAPI hycapi_reset_ctr\n");
-#endif
- capilib_release(&cinfo->ncci_head);
- capi_ctr_down(ctrl);
-}
-
-/******************************
-Kernel-Capi callback remove_ctr
-******************************/
-
-static void
-hycapi_remove_ctr(struct capi_ctr *ctrl)
-{
- int i;
- hycapictrl_info *cinfo = NULL;
- hysdn_card *card = NULL;
-#ifdef HYCAPI_PRINTFNAMES
- printk(KERN_NOTICE "HYCAPI hycapi_remove_ctr\n");
-#endif
- cinfo = (hycapictrl_info *)(ctrl->driverdata);
- if (!cinfo) {
- printk(KERN_ERR "No hycapictrl_info set!");
- return;
- }
- card = cinfo->card;
- capi_ctr_suspend_output(ctrl);
- for (i = 0; i < CAPI_MAXAPPL; i++) {
- if (hycapi_applications[i].listen_req[ctrl->cnr - 1]) {
- kfree_skb(hycapi_applications[i].listen_req[ctrl->cnr - 1]);
- hycapi_applications[i].listen_req[ctrl->cnr - 1] = NULL;
- }
- }
- detach_capi_ctr(ctrl);
- ctrl->driverdata = NULL;
- kfree(card->hyctrlinfo);
-
-
- card->hyctrlinfo = NULL;
-}
-
-/***********************************************************
-
-Queue a CAPI-message to the controller.
-
-***********************************************************/
-
-static void
-hycapi_sendmsg_internal(struct capi_ctr *ctrl, struct sk_buff *skb)
-{
- hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata);
- hysdn_card *card = cinfo->card;
-
- spin_lock_irq(&cinfo->lock);
-#ifdef HYCAPI_PRINTFNAMES
- printk(KERN_NOTICE "hycapi_send_message\n");
-#endif
- cinfo->skbs[cinfo->in_idx++] = skb; /* add to buffer list */
- if (cinfo->in_idx >= HYSDN_MAX_CAPI_SKB)
- cinfo->in_idx = 0; /* wrap around */
- cinfo->sk_count++; /* adjust counter */
- if (cinfo->sk_count >= HYSDN_MAX_CAPI_SKB) {
- /* inform upper layers we're full */
- printk(KERN_ERR "HYSDN Card%d: CAPI-buffer overrun!\n",
- card->myid);
- capi_ctr_suspend_output(ctrl);
- }
- cinfo->tx_skb = skb;
- spin_unlock_irq(&cinfo->lock);
- schedule_work(&card->irq_queue);
-}
-
-/***********************************************************
-hycapi_register_internal
-
-Send down the CAPI_REGISTER-Command to the controller.
-This functions will also be used if the adapter has been rebooted to
-re-register any applications in the private list.
-
-************************************************************/
-
-static void
-hycapi_register_internal(struct capi_ctr *ctrl, __u16 appl,
- capi_register_params *rp)
-{
- char ExtFeatureDefaults[] = "49 /0/0/0/0,*/1,*/2,*/3,*/4,*/5,*/6,*/7,*/8,*/9,*";
- hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata);
- hysdn_card *card = cinfo->card;
- struct sk_buff *skb;
- __u16 len;
- __u8 _command = 0xa0, _subcommand = 0x80;
- __u16 MessageNumber = 0x0000;
- __u16 MessageBufferSize = 0;
- int slen = strlen(ExtFeatureDefaults);
-#ifdef HYCAPI_PRINTFNAMES
- printk(KERN_NOTICE "hycapi_register_appl\n");
-#endif
- MessageBufferSize = rp->level3cnt * rp->datablkcnt * rp->datablklen;
-
- len = CAPI_MSG_BASELEN + 8 + slen + 1;
- if (!(skb = alloc_skb(len, GFP_ATOMIC))) {
- printk(KERN_ERR "HYSDN card%d: memory squeeze in hycapi_register_appl\n",
- card->myid);
- return;
- }
- skb_put_data(skb, &len, sizeof(__u16));
- skb_put_data(skb, &appl, sizeof(__u16));
- skb_put_data(skb, &_command, sizeof(__u8));
- skb_put_data(skb, &_subcommand, sizeof(__u8));
- skb_put_data(skb, &MessageNumber, sizeof(__u16));
- skb_put_data(skb, &MessageBufferSize, sizeof(__u16));
- skb_put_data(skb, &(rp->level3cnt), sizeof(__u16));
- skb_put_data(skb, &(rp->datablkcnt), sizeof(__u16));
- skb_put_data(skb, &(rp->datablklen), sizeof(__u16));
- skb_put_data(skb, ExtFeatureDefaults, slen);
- hycapi_applications[appl - 1].ctrl_mask |= (1 << (ctrl->cnr - 1));
- hycapi_send_message(ctrl, skb);
-}
-
-/************************************************************
-hycapi_restart_internal
-
-After an adapter has been rebootet, re-register all applications and
-send a LISTEN_REQ (if there has been such a thing )
-
-*************************************************************/
-
-static void hycapi_restart_internal(struct capi_ctr *ctrl)
-{
- int i;
- struct sk_buff *skb;
-#ifdef HYCAPI_PRINTFNAMES
- printk(KERN_WARNING "HYSDN: hycapi_restart_internal");
-#endif
- for (i = 0; i < CAPI_MAXAPPL; i++) {
- if (_hycapi_appCheck(i + 1, ctrl->cnr) == 1) {
- hycapi_register_internal(ctrl, i + 1,
- &hycapi_applications[i].rp);
- if (hycapi_applications[i].listen_req[ctrl->cnr - 1]) {
- skb = skb_copy(hycapi_applications[i].listen_req[ctrl->cnr - 1], GFP_ATOMIC);
- hycapi_sendmsg_internal(ctrl, skb);
- }
- }
- }
-}
-
-/*************************************************************
-Register an application.
-Error-checking is done for CAPI-compliance.
-
-The application is recorded in the internal list.
-*************************************************************/
-
-static void
-hycapi_register_appl(struct capi_ctr *ctrl, __u16 appl,
- capi_register_params *rp)
-{
- int MaxLogicalConnections = 0, MaxBDataBlocks = 0, MaxBDataLen = 0;
- hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata);
- hysdn_card *card = cinfo->card;
- int chk = _hycapi_appCheck(appl, ctrl->cnr);
- if (chk < 0) {
- return;
- }
- if (chk == 1) {
- printk(KERN_INFO "HYSDN: apl %d already registered\n", appl);
- return;
- }
- MaxBDataBlocks = rp->datablkcnt > CAPI_MAXDATAWINDOW ? CAPI_MAXDATAWINDOW : rp->datablkcnt;
- rp->datablkcnt = MaxBDataBlocks;
- MaxBDataLen = rp->datablklen < 1024 ? 1024 : rp->datablklen;
- rp->datablklen = MaxBDataLen;
-
- MaxLogicalConnections = rp->level3cnt;
- if (MaxLogicalConnections < 0) {
- MaxLogicalConnections = card->bchans * -MaxLogicalConnections;
- }
- if (MaxLogicalConnections == 0) {
- MaxLogicalConnections = card->bchans;
- }
-
- rp->level3cnt = MaxLogicalConnections;
- memcpy(&hycapi_applications[appl - 1].rp,
- rp, sizeof(capi_register_params));
-}
-
-/*********************************************************************
-
-hycapi_release_internal
-
-Send down a CAPI_RELEASE to the controller.
-*********************************************************************/
-
-static void hycapi_release_internal(struct capi_ctr *ctrl, __u16 appl)
-{
- hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata);
- hysdn_card *card = cinfo->card;
- struct sk_buff *skb;
- __u16 len;
- __u8 _command = 0xa1, _subcommand = 0x80;
- __u16 MessageNumber = 0x0000;
-
- capilib_release_appl(&cinfo->ncci_head, appl);
-
-#ifdef HYCAPI_PRINTFNAMES
- printk(KERN_NOTICE "hycapi_release_appl\n");
-#endif
- len = CAPI_MSG_BASELEN;
- if (!(skb = alloc_skb(len, GFP_ATOMIC))) {
- printk(KERN_ERR "HYSDN card%d: memory squeeze in hycapi_register_appl\n",
- card->myid);
- return;
- }
- skb_put_data(skb, &len, sizeof(__u16));
- skb_put_data(skb, &appl, sizeof(__u16));
- skb_put_data(skb, &_command, sizeof(__u8));
- skb_put_data(skb, &_subcommand, sizeof(__u8));
- skb_put_data(skb, &MessageNumber, sizeof(__u16));
- hycapi_send_message(ctrl, skb);
- hycapi_applications[appl - 1].ctrl_mask &= ~(1 << (ctrl->cnr - 1));
-}
-
-/******************************************************************
-hycapi_release_appl
-
-Release the application from the internal list an remove it's
-registration at controller-level
-******************************************************************/
-
-static void
-hycapi_release_appl(struct capi_ctr *ctrl, __u16 appl)
-{
- int chk;
-
- chk = _hycapi_appCheck(appl, ctrl->cnr);
- if (chk < 0) {
- printk(KERN_ERR "HYCAPI: Releasing invalid appl %d on controller %d\n", appl, ctrl->cnr);
- return;
- }
- if (hycapi_applications[appl - 1].listen_req[ctrl->cnr - 1]) {
- kfree_skb(hycapi_applications[appl - 1].listen_req[ctrl->cnr - 1]);
- hycapi_applications[appl - 1].listen_req[ctrl->cnr - 1] = NULL;
- }
- if (chk == 1)
- {
- hycapi_release_internal(ctrl, appl);
- }
-}
-
-
-/**************************************************************
-Kill a single controller.
-**************************************************************/
-
-int hycapi_capi_release(hysdn_card *card)
-{
- hycapictrl_info *cinfo = card->hyctrlinfo;
- struct capi_ctr *ctrl;
-#ifdef HYCAPI_PRINTFNAMES
- printk(KERN_NOTICE "hycapi_capi_release\n");
-#endif
- if (cinfo) {
- ctrl = &cinfo->capi_ctrl;
- hycapi_remove_ctr(ctrl);
- }
- return 0;
-}
-
-/**************************************************************
-hycapi_capi_stop
-
-Stop CAPI-Output on a card. (e.g. during reboot)
-***************************************************************/
-
-int hycapi_capi_stop(hysdn_card *card)
-{
- hycapictrl_info *cinfo = card->hyctrlinfo;
- struct capi_ctr *ctrl;
-#ifdef HYCAPI_PRINTFNAMES
- printk(KERN_NOTICE "hycapi_capi_stop\n");
-#endif
- if (cinfo) {
- ctrl = &cinfo->capi_ctrl;
-/* ctrl->suspend_output(ctrl); */
- capi_ctr_down(ctrl);
- }
- return 0;
-}
-
-/***************************************************************
-hycapi_send_message
-
-Send a message to the controller.
-
-Messages are parsed for their Command/Subcommand-type, and appropriate
-action's are performed.
-
-Note that we have to muck around with a 64Bit-DATA_REQ as there are
-firmware-releases that do not check the MsgLen-Indication!
-
-***************************************************************/
-
-static u16 hycapi_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
-{
- __u16 appl_id;
- int _len, _len2;
- __u8 msghead[64];
- hycapictrl_info *cinfo = ctrl->driverdata;
- u16 retval = CAPI_NOERROR;
-
- appl_id = CAPIMSG_APPID(skb->data);
- switch (_hycapi_appCheck(appl_id, ctrl->cnr))
- {
- case 0:
-/* printk(KERN_INFO "Need to register\n"); */
- hycapi_register_internal(ctrl,
- appl_id,
- &(hycapi_applications[appl_id - 1].rp));
- break;
- case 1:
- break;
- default:
- printk(KERN_ERR "HYCAPI: Controller mixup!\n");
- retval = CAPI_ILLAPPNR;
- goto out;
- }
- switch (CAPIMSG_CMD(skb->data)) {
- case CAPI_DISCONNECT_B3_RESP:
- capilib_free_ncci(&cinfo->ncci_head, appl_id,
- CAPIMSG_NCCI(skb->data));
- break;
- case CAPI_DATA_B3_REQ:
- _len = CAPIMSG_LEN(skb->data);
- if (_len > 22) {
- _len2 = _len - 22;
- skb_copy_from_linear_data(skb, msghead, 22);
- skb_copy_to_linear_data_offset(skb, _len2,
- msghead, 22);
- skb_pull(skb, _len2);
- CAPIMSG_SETLEN(skb->data, 22);
- retval = capilib_data_b3_req(&cinfo->ncci_head,
- CAPIMSG_APPID(skb->data),
- CAPIMSG_NCCI(skb->data),
- CAPIMSG_MSGID(skb->data));
- }
- break;
- case CAPI_LISTEN_REQ:
- if (hycapi_applications[appl_id - 1].listen_req[ctrl->cnr - 1])
- {
- kfree_skb(hycapi_applications[appl_id - 1].listen_req[ctrl->cnr - 1]);
- hycapi_applications[appl_id - 1].listen_req[ctrl->cnr - 1] = NULL;
- }
- if (!(hycapi_applications[appl_id -1].listen_req[ctrl->cnr - 1] = skb_copy(skb, GFP_ATOMIC)))
- {
- printk(KERN_ERR "HYSDN: memory squeeze in private_listen\n");
- }
- break;
- default:
- break;
- }
-out:
- if (retval == CAPI_NOERROR)
- hycapi_sendmsg_internal(ctrl, skb);
- else
- dev_kfree_skb_any(skb);
-
- return retval;
-}
-
-static int hycapi_proc_show(struct seq_file *m, void *v)
-{
- struct capi_ctr *ctrl = m->private;
- hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata);
- hysdn_card *card = cinfo->card;
- char *s;
-
- seq_printf(m, "%-16s %s\n", "name", cinfo->cardname);
- seq_printf(m, "%-16s 0x%x\n", "io", card->iobase);
- seq_printf(m, "%-16s %d\n", "irq", card->irq);
-
- switch (card->brdtype) {
- case BD_PCCARD: s = "HYSDN Hycard"; break;
- case BD_ERGO: s = "HYSDN Ergo2"; break;
- case BD_METRO: s = "HYSDN Metro4"; break;
- case BD_CHAMP2: s = "HYSDN Champ2"; break;
- case BD_PLEXUS: s = "HYSDN Plexus30"; break;
- default: s = "???"; break;
- }
- seq_printf(m, "%-16s %s\n", "type", s);
- if ((s = cinfo->version[VER_DRIVER]) != NULL)
- seq_printf(m, "%-16s %s\n", "ver_driver", s);
- if ((s = cinfo->version[VER_CARDTYPE]) != NULL)
- seq_printf(m, "%-16s %s\n", "ver_cardtype", s);
- if ((s = cinfo->version[VER_SERIAL]) != NULL)
- seq_printf(m, "%-16s %s\n", "ver_serial", s);
-
- seq_printf(m, "%-16s %s\n", "cardname", cinfo->cardname);
-
- return 0;
-}
-
-/**************************************************************
-hycapi_load_firmware
-
-This does NOT load any firmware, but the callback somehow is needed
-on capi-interface registration.
-
-**************************************************************/
-
-static int hycapi_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
-{
-#ifdef HYCAPI_PRINTFNAMES
- printk(KERN_NOTICE "hycapi_load_firmware\n");
-#endif
- return 0;
-}
-
-
-static char *hycapi_procinfo(struct capi_ctr *ctrl)
-{
- hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata);
-#ifdef HYCAPI_PRINTFNAMES
- printk(KERN_NOTICE "%s\n", __func__);
-#endif
- if (!cinfo)
- return "";
- sprintf(cinfo->infobuf, "%s %s 0x%x %d %s",
- cinfo->cardname[0] ? cinfo->cardname : "-",
- cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-",
- cinfo->card ? cinfo->card->iobase : 0x0,
- cinfo->card ? cinfo->card->irq : 0,
- hycapi_revision
- );
- return cinfo->infobuf;
-}
-
-/******************************************************************
-hycapi_rx_capipkt
-
-Receive a capi-message.
-
-All B3_DATA_IND are converted to 64K-extension compatible format.
-New nccis are created if necessary.
-*******************************************************************/
-
-void
-hycapi_rx_capipkt(hysdn_card *card, unsigned char *buf, unsigned short len)
-{
- struct sk_buff *skb;
- hycapictrl_info *cinfo = card->hyctrlinfo;
- struct capi_ctr *ctrl;
- __u16 ApplId;
- __u16 MsgLen, info;
- __u16 len2, CapiCmd;
- __u32 CP64[2] = {0, 0};
-#ifdef HYCAPI_PRINTFNAMES
- printk(KERN_NOTICE "hycapi_rx_capipkt\n");
-#endif
- if (!cinfo) {
- return;
- }
- ctrl = &cinfo->capi_ctrl;
- if (len < CAPI_MSG_BASELEN) {
- printk(KERN_ERR "HYSDN Card%d: invalid CAPI-message, length %d!\n",
- card->myid, len);
- return;
- }
- MsgLen = CAPIMSG_LEN(buf);
- ApplId = CAPIMSG_APPID(buf);
- CapiCmd = CAPIMSG_CMD(buf);
-
- if ((CapiCmd == CAPI_DATA_B3_IND) && (MsgLen < 30)) {
- len2 = len + (30 - MsgLen);
- if (!(skb = alloc_skb(len2, GFP_ATOMIC))) {
- printk(KERN_ERR "HYSDN Card%d: incoming packet dropped\n",
- card->myid);
- return;
- }
- skb_put_data(skb, buf, MsgLen);
- skb_put_data(skb, CP64, 2 * sizeof(__u32));
- skb_put_data(skb, buf + MsgLen, len - MsgLen);
- CAPIMSG_SETLEN(skb->data, 30);
- } else {
- if (!(skb = alloc_skb(len, GFP_ATOMIC))) {
- printk(KERN_ERR "HYSDN Card%d: incoming packet dropped\n",
- card->myid);
- return;
- }
- skb_put_data(skb, buf, len);
- }
- switch (CAPIMSG_CMD(skb->data))
- {
- case CAPI_CONNECT_B3_CONF:
-/* Check info-field for error-indication: */
- info = CAPIMSG_U16(skb->data, 12);
- switch (info)
- {
- case 0:
- capilib_new_ncci(&cinfo->ncci_head, ApplId, CAPIMSG_NCCI(skb->data),
- hycapi_applications[ApplId - 1].rp.datablkcnt);
-
- break;
- case 0x0001:
- printk(KERN_ERR "HYSDN Card%d: NCPI not supported by current "
- "protocol. NCPI ignored.\n", card->myid);
- break;
- case 0x2001:
- printk(KERN_ERR "HYSDN Card%d: Message not supported in"
- " current state\n", card->myid);
- break;
- case 0x2002:
- printk(KERN_ERR "HYSDN Card%d: invalid PLCI\n", card->myid);
- break;
- case 0x2004:
- printk(KERN_ERR "HYSDN Card%d: out of NCCI\n", card->myid);
- break;
- case 0x3008:
- printk(KERN_ERR "HYSDN Card%d: NCPI not supported\n",
- card->myid);
- break;
- default:
- printk(KERN_ERR "HYSDN Card%d: Info in CONNECT_B3_CONF: %d\n",
- card->myid, info);
- break;
- }
- break;
- case CAPI_CONNECT_B3_IND:
- capilib_new_ncci(&cinfo->ncci_head, ApplId,
- CAPIMSG_NCCI(skb->data),
- hycapi_applications[ApplId - 1].rp.datablkcnt);
- break;
- case CAPI_DATA_B3_CONF:
- capilib_data_b3_conf(&cinfo->ncci_head, ApplId,
- CAPIMSG_NCCI(skb->data),
- CAPIMSG_MSGID(skb->data));
- break;
- default:
- break;
- }
- capi_ctr_handle_message(ctrl, ApplId, skb);
-}
-
-/******************************************************************
-hycapi_tx_capiack
-
-Internally acknowledge a msg sent. This will remove the msg from the
-internal queue.
-
-*******************************************************************/
-
-void hycapi_tx_capiack(hysdn_card *card)
-{
- hycapictrl_info *cinfo = card->hyctrlinfo;
-#ifdef HYCAPI_PRINTFNAMES
- printk(KERN_NOTICE "hycapi_tx_capiack\n");
-#endif
- if (!cinfo) {
- return;
- }
- spin_lock_irq(&cinfo->lock);
- kfree_skb(cinfo->skbs[cinfo->out_idx]); /* free skb */
- cinfo->skbs[cinfo->out_idx++] = NULL;
- if (cinfo->out_idx >= HYSDN_MAX_CAPI_SKB)
- cinfo->out_idx = 0; /* wrap around */
-
- if (cinfo->sk_count-- == HYSDN_MAX_CAPI_SKB) /* dec usage count */
- capi_ctr_resume_output(&cinfo->capi_ctrl);
- spin_unlock_irq(&cinfo->lock);
-}
-
-/***************************************************************
-hycapi_tx_capiget(hysdn_card *card)
-
-This is called when polling for messages to SEND.
-
-****************************************************************/
-
-struct sk_buff *
-hycapi_tx_capiget(hysdn_card *card)
-{
- hycapictrl_info *cinfo = card->hyctrlinfo;
- if (!cinfo) {
- return (struct sk_buff *)NULL;
- }
- if (!cinfo->sk_count)
- return (struct sk_buff *)NULL; /* nothing available */
-
- return (cinfo->skbs[cinfo->out_idx]); /* next packet to send */
-}
-
-
-/**********************************************************
-int hycapi_init()
-
-attach the capi-driver to the kernel-capi.
-
-***********************************************************/
-
-int hycapi_init(void)
-{
- int i;
- for (i = 0; i < CAPI_MAXAPPL; i++) {
- memset(&(hycapi_applications[i]), 0, sizeof(hycapi_appl));
- }
- return (0);
-}
-
-/**************************************************************
-hycapi_cleanup(void)
-
-detach the capi-driver to the kernel-capi. Actually this should
-free some more ressources. Do that later.
-**************************************************************/
-
-void
-hycapi_cleanup(void)
-{
-}
-
-/********************************************************************
-hycapi_capi_create(hysdn_card *card)
-
-Attach the card with its capi-ctrl.
-*********************************************************************/
-
-static void hycapi_fill_profile(hysdn_card *card)
-{
- hycapictrl_info *cinfo = NULL;
- struct capi_ctr *ctrl = NULL;
- cinfo = card->hyctrlinfo;
- if (!cinfo) return;
- ctrl = &cinfo->capi_ctrl;
- strcpy(ctrl->manu, "Hypercope");
- ctrl->version.majorversion = 2;
- ctrl->version.minorversion = 0;
- ctrl->version.majormanuversion = 3;
- ctrl->version.minormanuversion = 2;
- ctrl->profile.ncontroller = card->myid;
- ctrl->profile.nbchannel = card->bchans;
- ctrl->profile.goptions = GLOBAL_OPTION_INTERNAL_CONTROLLER |
- GLOBAL_OPTION_B_CHANNEL_OPERATION;
- ctrl->profile.support1 = B1_PROT_64KBIT_HDLC |
- (card->faxchans ? B1_PROT_T30 : 0) |
- B1_PROT_64KBIT_TRANSPARENT;
- ctrl->profile.support2 = B2_PROT_ISO7776 |
- (card->faxchans ? B2_PROT_T30 : 0) |
- B2_PROT_TRANSPARENT;
- ctrl->profile.support3 = B3_PROT_TRANSPARENT |
- B3_PROT_T90NL |
- (card->faxchans ? B3_PROT_T30 : 0) |
- (card->faxchans ? B3_PROT_T30EXT : 0) |
- B3_PROT_ISO8208;
-}
-
-int
-hycapi_capi_create(hysdn_card *card)
-{
- hycapictrl_info *cinfo = NULL;
- struct capi_ctr *ctrl = NULL;
- int retval;
-#ifdef HYCAPI_PRINTFNAMES
- printk(KERN_NOTICE "hycapi_capi_create\n");
-#endif
- if ((hycapi_enable & (1 << card->myid)) == 0) {
- return 1;
- }
- if (!card->hyctrlinfo) {
- cinfo = kzalloc(sizeof(hycapictrl_info), GFP_ATOMIC);
- if (!cinfo) {
- printk(KERN_WARNING "HYSDN: no memory for capi-ctrl.\n");
- return -ENOMEM;
- }
- card->hyctrlinfo = cinfo;
- cinfo->card = card;
- spin_lock_init(&cinfo->lock);
- INIT_LIST_HEAD(&cinfo->ncci_head);
-
- switch (card->brdtype) {
- case BD_PCCARD: strcpy(cinfo->cardname, "HYSDN Hycard"); break;
- case BD_ERGO: strcpy(cinfo->cardname, "HYSDN Ergo2"); break;
- case BD_METRO: strcpy(cinfo->cardname, "HYSDN Metro4"); break;
- case BD_CHAMP2: strcpy(cinfo->cardname, "HYSDN Champ2"); break;
- case BD_PLEXUS: strcpy(cinfo->cardname, "HYSDN Plexus30"); break;
- default: strcpy(cinfo->cardname, "HYSDN ???"); break;
- }
-
- ctrl = &cinfo->capi_ctrl;
- ctrl->driver_name = "hycapi";
- ctrl->driverdata = cinfo;
- ctrl->register_appl = hycapi_register_appl;
- ctrl->release_appl = hycapi_release_appl;
- ctrl->send_message = hycapi_send_message;
- ctrl->load_firmware = hycapi_load_firmware;
- ctrl->reset_ctr = hycapi_reset_ctr;
- ctrl->procinfo = hycapi_procinfo;
- ctrl->proc_show = hycapi_proc_show;
- strcpy(ctrl->name, cinfo->cardname);
- ctrl->owner = THIS_MODULE;
-
- retval = attach_capi_ctr(ctrl);
- if (retval) {
- printk(KERN_ERR "hycapi: attach controller failed.\n");
- return -EBUSY;
- }
- /* fill in the blanks: */
- hycapi_fill_profile(card);
- capi_ctr_ready(ctrl);
- } else {
- /* resume output on stopped ctrl */
- ctrl = &card->hyctrlinfo->capi_ctrl;
- hycapi_fill_profile(card);
- capi_ctr_ready(ctrl);
- hycapi_restart_internal(ctrl);
-/* ctrl->resume_output(ctrl); */
- }
- return 0;
-}
diff --git a/drivers/staging/isdn/hysdn/hysdn_boot.c b/drivers/staging/isdn/hysdn/hysdn_boot.c
deleted file mode 100644
index ba177c3a621b..000000000000
--- a/drivers/staging/isdn/hysdn/hysdn_boot.c
+++ /dev/null
@@ -1,400 +0,0 @@
-/* $Id: hysdn_boot.c,v 1.4.6.4 2001/09/23 22:24:54 kai Exp $
- *
- * Linux driver for HYSDN cards
- * specific routines for booting and pof handling
- *
- * Author Werner Cornelius (werner@titro.de) for Hypercope GmbH
- * Copyright 1999 by Werner Cornelius (werner@titro.de)
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#include <linux/vmalloc.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-
-#include "hysdn_defs.h"
-#include "hysdn_pof.h"
-
-/********************************/
-/* defines for pof read handler */
-/********************************/
-#define POF_READ_FILE_HEAD 0
-#define POF_READ_TAG_HEAD 1
-#define POF_READ_TAG_DATA 2
-
-/************************************************************/
-/* definition of boot specific data area. This data is only */
-/* needed during boot and so allocated dynamically. */
-/************************************************************/
-struct boot_data {
- unsigned short Cryptor; /* for use with Decrypt function */
- unsigned short Nrecs; /* records remaining in file */
- unsigned char pof_state;/* actual state of read handler */
- unsigned char is_crypted;/* card data is crypted */
- int BufSize; /* actual number of bytes bufferd */
- int last_error; /* last occurred error */
- unsigned short pof_recid;/* actual pof recid */
- unsigned long pof_reclen;/* total length of pof record data */
- unsigned long pof_recoffset;/* actual offset inside pof record */
- union {
- unsigned char BootBuf[BOOT_BUF_SIZE];/* buffer as byte count */
- tPofRecHdr PofRecHdr; /* header for actual record/chunk */
- tPofFileHdr PofFileHdr; /* header from POF file */
- tPofTimeStamp PofTime; /* time information */
- } buf;
-};
-
-/*****************************************************/
-/* start decryption of successive POF file chuncks. */
-/* */
-/* to be called at start of POF file reading, */
-/* before starting any decryption on any POF record. */
-/*****************************************************/
-static void
-StartDecryption(struct boot_data *boot)
-{
- boot->Cryptor = CRYPT_STARTTERM;
-} /* StartDecryption */
-
-
-/***************************************************************/
-/* decrypt complete BootBuf */
-/* NOTE: decryption must be applied to all or none boot tags - */
-/* to HI and LO boot loader and (all) seq tags, because */
-/* global Cryptor is started for whole POF. */
-/***************************************************************/
-static void
-DecryptBuf(struct boot_data *boot, int cnt)
-{
- unsigned char *bufp = boot->buf.BootBuf;
-
- while (cnt--) {
- boot->Cryptor = (boot->Cryptor >> 1) ^ ((boot->Cryptor & 1U) ? CRYPT_FEEDTERM : 0);
- *bufp++ ^= (unsigned char)boot->Cryptor;
- }
-} /* DecryptBuf */
-
-/********************************************************************************/
-/* pof_handle_data executes the required actions dependent on the active record */
-/* id. If successful 0 is returned, a negative value shows an error. */
-/********************************************************************************/
-static int
-pof_handle_data(hysdn_card *card, int datlen)
-{
- struct boot_data *boot = card->boot; /* pointer to boot specific data */
- long l;
- unsigned char *imgp;
- int img_len;
-
- /* handle the different record types */
- switch (boot->pof_recid) {
-
- case TAG_TIMESTMP:
- if (card->debug_flags & LOG_POF_RECORD)
- hysdn_addlog(card, "POF created %s", boot->buf.PofTime.DateTimeText);
- break;
-
- case TAG_CBOOTDTA:
- DecryptBuf(boot, datlen); /* we need to encrypt the buffer */
- /* fall through */
- case TAG_BOOTDTA:
- if (card->debug_flags & LOG_POF_RECORD)
- hysdn_addlog(card, "POF got %s len=%d offs=0x%lx",
- (boot->pof_recid == TAG_CBOOTDTA) ? "CBOOTDATA" : "BOOTDTA",
- datlen, boot->pof_recoffset);
-
- if (boot->pof_reclen != POF_BOOT_LOADER_TOTAL_SIZE) {
- boot->last_error = EPOF_BAD_IMG_SIZE; /* invalid length */
- return (boot->last_error);
- }
- imgp = boot->buf.BootBuf; /* start of buffer */
- img_len = datlen; /* maximum length to transfer */
-
- l = POF_BOOT_LOADER_OFF_IN_PAGE -
- (boot->pof_recoffset & (POF_BOOT_LOADER_PAGE_SIZE - 1));
- if (l > 0) {
- /* buffer needs to be truncated */
- imgp += l; /* advance pointer */
- img_len -= l; /* adjust len */
- }
- /* at this point no special handling for data wrapping over buffer */
- /* is necessary, because the boot image always will be adjusted to */
- /* match a page boundary inside the buffer. */
- /* The buffer for the boot image on the card is filled in 2 cycles */
- /* first the 1024 hi-words are put in the buffer, then the low 1024 */
- /* word are handled in the same way with different offset. */
-
- if (img_len > 0) {
- /* data available for copy */
- if ((boot->last_error =
- card->writebootimg(card, imgp,
- (boot->pof_recoffset > POF_BOOT_LOADER_PAGE_SIZE) ? 2 : 0)) < 0)
- return (boot->last_error);
- }
- break; /* end of case boot image hi/lo */
-
- case TAG_CABSDATA:
- DecryptBuf(boot, datlen); /* we need to encrypt the buffer */
- /* fall through */
- case TAG_ABSDATA:
- if (card->debug_flags & LOG_POF_RECORD)
- hysdn_addlog(card, "POF got %s len=%d offs=0x%lx",
- (boot->pof_recid == TAG_CABSDATA) ? "CABSDATA" : "ABSDATA",
- datlen, boot->pof_recoffset);
-
- if ((boot->last_error = card->writebootseq(card, boot->buf.BootBuf, datlen)) < 0)
- return (boot->last_error); /* error writing data */
-
- if (boot->pof_recoffset + datlen >= boot->pof_reclen)
- return (card->waitpofready(card)); /* data completely spooled, wait for ready */
-
- break; /* end of case boot seq data */
-
- default:
- if (card->debug_flags & LOG_POF_RECORD)
- hysdn_addlog(card, "POF got data(id=0x%lx) len=%d offs=0x%lx", boot->pof_recid,
- datlen, boot->pof_recoffset);
-
- break; /* simply skip record */
- } /* switch boot->pof_recid */
-
- return (0);
-} /* pof_handle_data */
-
-
-/******************************************************************************/
-/* pof_write_buffer is called when the buffer has been filled with the needed */
-/* number of data bytes. The number delivered is additionally supplied for */
-/* verification. The functions handles the data and returns the needed number */
-/* of bytes for the next action. If the returned value is 0 or less an error */
-/* occurred and booting must be aborted. */
-/******************************************************************************/
-int
-pof_write_buffer(hysdn_card *card, int datlen)
-{
- struct boot_data *boot = card->boot; /* pointer to boot specific data */
-
- if (!boot)
- return (-EFAULT); /* invalid call */
- if (boot->last_error < 0)
- return (boot->last_error); /* repeated error */
-
- if (card->debug_flags & LOG_POF_WRITE)
- hysdn_addlog(card, "POF write: got %d bytes ", datlen);
-
- switch (boot->pof_state) {
- case POF_READ_FILE_HEAD:
- if (card->debug_flags & LOG_POF_WRITE)
- hysdn_addlog(card, "POF write: checking file header");
-
- if (datlen != sizeof(tPofFileHdr)) {
- boot->last_error = -EPOF_INTERNAL;
- break;
- }
- if (boot->buf.PofFileHdr.Magic != TAGFILEMAGIC) {
- boot->last_error = -EPOF_BAD_MAGIC;
- break;
- }
- /* Setup the new state and vars */
- boot->Nrecs = (unsigned short)(boot->buf.PofFileHdr.N_PofRecs); /* limited to 65535 */
- boot->pof_state = POF_READ_TAG_HEAD; /* now start with single tags */
- boot->last_error = sizeof(tPofRecHdr); /* new length */
- break;
-
- case POF_READ_TAG_HEAD:
- if (card->debug_flags & LOG_POF_WRITE)
- hysdn_addlog(card, "POF write: checking tag header");
-
- if (datlen != sizeof(tPofRecHdr)) {
- boot->last_error = -EPOF_INTERNAL;
- break;
- }
- boot->pof_recid = boot->buf.PofRecHdr.PofRecId; /* actual pof recid */
- boot->pof_reclen = boot->buf.PofRecHdr.PofRecDataLen; /* total length */
- boot->pof_recoffset = 0; /* no starting offset */
-
- if (card->debug_flags & LOG_POF_RECORD)
- hysdn_addlog(card, "POF: got record id=0x%lx length=%ld ",
- boot->pof_recid, boot->pof_reclen);
-
- boot->pof_state = POF_READ_TAG_DATA; /* now start with tag data */
- if (boot->pof_reclen < BOOT_BUF_SIZE)
- boot->last_error = boot->pof_reclen; /* limit size */
- else
- boot->last_error = BOOT_BUF_SIZE; /* maximum */
-
- if (!boot->last_error) { /* no data inside record */
- boot->pof_state = POF_READ_TAG_HEAD; /* now start with single tags */
- boot->last_error = sizeof(tPofRecHdr); /* new length */
- }
- break;
-
- case POF_READ_TAG_DATA:
- if (card->debug_flags & LOG_POF_WRITE)
- hysdn_addlog(card, "POF write: getting tag data");
-
- if (datlen != boot->last_error) {
- boot->last_error = -EPOF_INTERNAL;
- break;
- }
- if ((boot->last_error = pof_handle_data(card, datlen)) < 0)
- return (boot->last_error); /* an error occurred */
- boot->pof_recoffset += datlen;
- if (boot->pof_recoffset >= boot->pof_reclen) {
- boot->pof_state = POF_READ_TAG_HEAD; /* now start with single tags */
- boot->last_error = sizeof(tPofRecHdr); /* new length */
- } else {
- if (boot->pof_reclen - boot->pof_recoffset < BOOT_BUF_SIZE)
- boot->last_error = boot->pof_reclen - boot->pof_recoffset; /* limit size */
- else
- boot->last_error = BOOT_BUF_SIZE; /* maximum */
- }
- break;
-
- default:
- boot->last_error = -EPOF_INTERNAL; /* unknown state */
- break;
- } /* switch (boot->pof_state) */
-
- return (boot->last_error);
-} /* pof_write_buffer */
-
-
-/*******************************************************************************/
-/* pof_write_open is called when an open for boot on the cardlog device occurs. */
-/* The function returns the needed number of bytes for the next operation. If */
-/* the returned number is less or equal 0 an error specified by this code */
-/* occurred. Additionally the pointer to the buffer data area is set on success */
-/*******************************************************************************/
-int
-pof_write_open(hysdn_card *card, unsigned char **bufp)
-{
- struct boot_data *boot; /* pointer to boot specific data */
-
- if (card->boot) {
- if (card->debug_flags & LOG_POF_OPEN)
- hysdn_addlog(card, "POF open: already opened for boot");
- return (-ERR_ALREADY_BOOT); /* boot already active */
- }
- /* error no mem available */
- if (!(boot = kzalloc(sizeof(struct boot_data), GFP_KERNEL))) {
- if (card->debug_flags & LOG_MEM_ERR)
- hysdn_addlog(card, "POF open: unable to allocate mem");
- return (-EFAULT);
- }
- card->boot = boot;
- card->state = CARD_STATE_BOOTING;
-
- card->stopcard(card); /* first stop the card */
- if (card->testram(card)) {
- if (card->debug_flags & LOG_POF_OPEN)
- hysdn_addlog(card, "POF open: DPRAM test failure");
- boot->last_error = -ERR_BOARD_DPRAM;
- card->state = CARD_STATE_BOOTERR; /* show boot error */
- return (boot->last_error);
- }
- boot->BufSize = 0; /* Buffer is empty */
- boot->pof_state = POF_READ_FILE_HEAD; /* read file header */
- StartDecryption(boot); /* if POF File should be encrypted */
-
- if (card->debug_flags & LOG_POF_OPEN)
- hysdn_addlog(card, "POF open: success");
-
- *bufp = boot->buf.BootBuf; /* point to buffer */
- return (sizeof(tPofFileHdr));
-} /* pof_write_open */
-
-/********************************************************************************/
-/* pof_write_close is called when an close of boot on the cardlog device occurs. */
-/* The return value must be 0 if everything has happened as desired. */
-/********************************************************************************/
-int
-pof_write_close(hysdn_card *card)
-{
- struct boot_data *boot = card->boot; /* pointer to boot specific data */
-
- if (!boot)
- return (-EFAULT); /* invalid call */
-
- card->boot = NULL; /* no boot active */
- kfree(boot);
-
- if (card->state == CARD_STATE_RUN)
- card->set_errlog_state(card, 1); /* activate error log */
-
- if (card->debug_flags & LOG_POF_OPEN)
- hysdn_addlog(card, "POF close: success");
-
- return (0);
-} /* pof_write_close */
-
-/*********************************************************************************/
-/* EvalSysrTokData checks additional records delivered with the Sysready Message */
-/* when POF has been booted. A return value of 0 is used if no error occurred. */
-/*********************************************************************************/
-int
-EvalSysrTokData(hysdn_card *card, unsigned char *cp, int len)
-{
- u_char *p;
- u_char crc;
-
- if (card->debug_flags & LOG_POF_RECORD)
- hysdn_addlog(card, "SysReady Token data length %d", len);
-
- if (len < 2) {
- hysdn_addlog(card, "SysReady Token Data to short");
- return (1);
- }
- for (p = cp, crc = 0; p < (cp + len - 2); p++)
- if ((crc & 0x80))
- crc = (((u_char) (crc << 1)) + 1) + *p;
- else
- crc = ((u_char) (crc << 1)) + *p;
- crc = ~crc;
- if (crc != *(cp + len - 1)) {
- hysdn_addlog(card, "SysReady Token Data invalid CRC");
- return (1);
- }
- len--; /* don't check CRC byte */
- while (len > 0) {
-
- if (*cp == SYSR_TOK_END)
- return (0); /* End of Token stream */
-
- if (len < (*(cp + 1) + 2)) {
- hysdn_addlog(card, "token 0x%x invalid length %d", *cp, *(cp + 1));
- return (1);
- }
- switch (*cp) {
- case SYSR_TOK_B_CHAN: /* 1 */
- if (*(cp + 1) != 1)
- return (1); /* length invalid */
- card->bchans = *(cp + 2);
- break;
-
- case SYSR_TOK_FAX_CHAN: /* 2 */
- if (*(cp + 1) != 1)
- return (1); /* length invalid */
- card->faxchans = *(cp + 2);
- break;
-
- case SYSR_TOK_MAC_ADDR: /* 3 */
- if (*(cp + 1) != 6)
- return (1); /* length invalid */
- memcpy(card->mac_addr, cp + 2, 6);
- break;
-
- default:
- hysdn_addlog(card, "unknown token 0x%02x length %d", *cp, *(cp + 1));
- break;
- }
- len -= (*(cp + 1) + 2); /* adjust len */
- cp += (*(cp + 1) + 2); /* and pointer */
- }
-
- hysdn_addlog(card, "no end token found");
- return (1);
-} /* EvalSysrTokData */
diff --git a/drivers/staging/isdn/hysdn/hysdn_defs.h b/drivers/staging/isdn/hysdn/hysdn_defs.h
deleted file mode 100644
index cdac46a21692..000000000000
--- a/drivers/staging/isdn/hysdn/hysdn_defs.h
+++ /dev/null
@@ -1,282 +0,0 @@
-/* $Id: hysdn_defs.h,v 1.5.6.3 2001/09/23 22:24:54 kai Exp $
- *
- * Linux driver for HYSDN cards
- * global definitions and exported vars and functions.
- *
- * Author Werner Cornelius (werner@titro.de) for Hypercope GmbH
- * Copyright 1999 by Werner Cornelius (werner@titro.de)
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#ifndef HYSDN_DEFS_H
-#define HYSDN_DEFS_H
-
-#include <linux/hysdn_if.h>
-#include <linux/interrupt.h>
-#include <linux/workqueue.h>
-#include <linux/skbuff.h>
-
-#include "ince1pc.h"
-
-#ifdef CONFIG_HYSDN_CAPI
-#include <linux/capi.h>
-#include <linux/isdn/capicmd.h>
-#include <linux/isdn/capiutil.h>
-#include <linux/isdn/capilli.h>
-
-/***************************/
-/* CAPI-Profile values. */
-/***************************/
-
-#define GLOBAL_OPTION_INTERNAL_CONTROLLER 0x0001
-#define GLOBAL_OPTION_EXTERNAL_CONTROLLER 0x0002
-#define GLOBAL_OPTION_HANDSET 0x0004
-#define GLOBAL_OPTION_DTMF 0x0008
-#define GLOBAL_OPTION_SUPPL_SERVICES 0x0010
-#define GLOBAL_OPTION_CHANNEL_ALLOCATION 0x0020
-#define GLOBAL_OPTION_B_CHANNEL_OPERATION 0x0040
-
-#define B1_PROT_64KBIT_HDLC 0x0001
-#define B1_PROT_64KBIT_TRANSPARENT 0x0002
-#define B1_PROT_V110_ASYNCH 0x0004
-#define B1_PROT_V110_SYNCH 0x0008
-#define B1_PROT_T30 0x0010
-#define B1_PROT_64KBIT_INV_HDLC 0x0020
-#define B1_PROT_56KBIT_TRANSPARENT 0x0040
-
-#define B2_PROT_ISO7776 0x0001
-#define B2_PROT_TRANSPARENT 0x0002
-#define B2_PROT_SDLC 0x0004
-#define B2_PROT_LAPD 0x0008
-#define B2_PROT_T30 0x0010
-#define B2_PROT_PPP 0x0020
-#define B2_PROT_TRANSPARENT_IGNORE_B1_FRAMING_ERRORS 0x0040
-
-#define B3_PROT_TRANSPARENT 0x0001
-#define B3_PROT_T90NL 0x0002
-#define B3_PROT_ISO8208 0x0004
-#define B3_PROT_X25_DCE 0x0008
-#define B3_PROT_T30 0x0010
-#define B3_PROT_T30EXT 0x0020
-
-#define HYSDN_MAXVERSION 8
-
-/* Number of sendbuffers in CAPI-queue */
-#define HYSDN_MAX_CAPI_SKB 20
-
-#endif /* CONFIG_HYSDN_CAPI*/
-
-/************************************************/
-/* constants and bits for debugging/log outputs */
-/************************************************/
-#define LOG_MAX_LINELEN 120
-#define DEB_OUT_SYSLOG 0x80000000 /* output to syslog instead of proc fs */
-#define LOG_MEM_ERR 0x00000001 /* log memory errors like kmalloc failure */
-#define LOG_POF_OPEN 0x00000010 /* log pof open and close activities */
-#define LOG_POF_RECORD 0x00000020 /* log pof record parser */
-#define LOG_POF_WRITE 0x00000040 /* log detailed pof write operation */
-#define LOG_POF_CARD 0x00000080 /* log pof related card functions */
-#define LOG_CNF_LINE 0x00000100 /* all conf lines are put to procfs */
-#define LOG_CNF_DATA 0x00000200 /* non comment conf lines are shown with channel */
-#define LOG_CNF_MISC 0x00000400 /* additional conf line debug outputs */
-#define LOG_SCHED_ASYN 0x00001000 /* debug schedulers async tx routines */
-#define LOG_PROC_OPEN 0x00100000 /* open and close from procfs are logged */
-#define LOG_PROC_ALL 0x00200000 /* all actions from procfs are logged */
-#define LOG_NET_INIT 0x00010000 /* network init and deinit logging */
-
-#define DEF_DEB_FLAGS 0x7fff000f /* everything is logged to procfs */
-
-/**********************************/
-/* proc filesystem name constants */
-/**********************************/
-#define PROC_SUBDIR_NAME "hysdn"
-#define PROC_CONF_BASENAME "cardconf"
-#define PROC_LOG_BASENAME "cardlog"
-
-/***********************************/
-/* PCI 32 bit parms for IO and MEM */
-/***********************************/
-#define PCI_REG_PLX_MEM_BASE 0
-#define PCI_REG_PLX_IO_BASE 1
-#define PCI_REG_MEMORY_BASE 3
-
-/**************/
-/* card types */
-/**************/
-#define BD_NONE 0U
-#define BD_PERFORMANCE 1U
-#define BD_VALUE 2U
-#define BD_PCCARD 3U
-#define BD_ERGO 4U
-#define BD_METRO 5U
-#define BD_CHAMP2 6U
-#define BD_PLEXUS 7U
-
-/******************************************************/
-/* defined states for cards shown by reading cardconf */
-/******************************************************/
-#define CARD_STATE_UNUSED 0 /* never been used or booted */
-#define CARD_STATE_BOOTING 1 /* booting is in progress */
-#define CARD_STATE_BOOTERR 2 /* a previous boot was aborted */
-#define CARD_STATE_RUN 3 /* card is active */
-
-/*******************************/
-/* defines for error_log_state */
-/*******************************/
-#define ERRLOG_STATE_OFF 0 /* error log is switched off, nothing to do */
-#define ERRLOG_STATE_ON 1 /* error log is switched on, wait for data */
-#define ERRLOG_STATE_START 2 /* start error logging */
-#define ERRLOG_STATE_STOP 3 /* stop error logging */
-
-/*******************************/
-/* data structure for one card */
-/*******************************/
-typedef struct HYSDN_CARD {
-
- /* general variables for the cards */
- int myid; /* own driver card id */
- unsigned char bus; /* pci bus the card is connected to */
- unsigned char devfn; /* slot+function bit encoded */
- unsigned short subsysid;/* PCI subsystem id */
- unsigned char brdtype; /* type of card */
- unsigned int bchans; /* number of available B-channels */
- unsigned int faxchans; /* number of available fax-channels */
- unsigned char mac_addr[6];/* MAC Address read from card */
- unsigned int irq; /* interrupt number */
- unsigned int iobase; /* IO-port base address */
- unsigned long plxbase; /* PLX memory base */
- unsigned long membase; /* DPRAM memory base */
- unsigned long memend; /* DPRAM memory end */
- void *dpram; /* mapped dpram */
- int state; /* actual state of card -> CARD_STATE_** */
- struct HYSDN_CARD *next; /* pointer to next card */
-
- /* data areas for the /proc file system */
- void *proclog; /* pointer to proclog filesystem specific data */
- void *procconf; /* pointer to procconf filesystem specific data */
-
- /* debugging and logging */
- unsigned char err_log_state;/* actual error log state of the card */
- unsigned long debug_flags;/* tells what should be debugged and where */
- void (*set_errlog_state) (struct HYSDN_CARD *, int);
-
- /* interrupt handler + interrupt synchronisation */
- struct work_struct irq_queue; /* interrupt task queue */
- unsigned char volatile irq_enabled;/* interrupt enabled if != 0 */
- unsigned char volatile hw_lock;/* hardware is currently locked -> no access */
-
- /* boot process */
- void *boot; /* pointer to boot private data */
- int (*writebootimg) (struct HYSDN_CARD *, unsigned char *, unsigned long);
- int (*writebootseq) (struct HYSDN_CARD *, unsigned char *, int);
- int (*waitpofready) (struct HYSDN_CARD *);
- int (*testram) (struct HYSDN_CARD *);
-
- /* scheduler for data transfer (only async parts) */
- unsigned char async_data[256];/* async data to be sent (normally for config) */
- unsigned short volatile async_len;/* length of data to sent */
- unsigned short volatile async_channel;/* channel number for async transfer */
- int volatile async_busy; /* flag != 0 sending in progress */
- int volatile net_tx_busy; /* a network packet tx is in progress */
-
- /* network interface */
- void *netif; /* pointer to network structure */
-
- /* init and deinit stopcard for booting, too */
- void (*stopcard) (struct HYSDN_CARD *);
- void (*releasehardware) (struct HYSDN_CARD *);
-
- spinlock_t hysdn_lock;
-#ifdef CONFIG_HYSDN_CAPI
- struct hycapictrl_info {
- char cardname[32];
- spinlock_t lock;
- int versionlen;
- char versionbuf[1024];
- char *version[HYSDN_MAXVERSION];
-
- char infobuf[128]; /* for function procinfo */
-
- struct HYSDN_CARD *card;
- struct capi_ctr capi_ctrl;
- struct sk_buff *skbs[HYSDN_MAX_CAPI_SKB];
- int in_idx, out_idx; /* indexes to buffer ring */
- int sk_count; /* number of buffers currently in ring */
- struct sk_buff *tx_skb; /* buffer for tx operation */
-
- struct list_head ncci_head;
- } *hyctrlinfo;
-#endif /* CONFIG_HYSDN_CAPI */
-} hysdn_card;
-
-#ifdef CONFIG_HYSDN_CAPI
-typedef struct hycapictrl_info hycapictrl_info;
-#endif /* CONFIG_HYSDN_CAPI */
-
-
-/*****************/
-/* exported vars */
-/*****************/
-extern hysdn_card *card_root; /* pointer to first card */
-
-
-
-/*************************/
-/* im/exported functions */
-/*************************/
-
-/* hysdn_procconf.c */
-extern int hysdn_procconf_init(void); /* init proc config filesys */
-extern void hysdn_procconf_release(void); /* deinit proc config filesys */
-
-/* hysdn_proclog.c */
-extern int hysdn_proclog_init(hysdn_card *); /* init proc log entry */
-extern void hysdn_proclog_release(hysdn_card *); /* deinit proc log entry */
-extern void hysdn_addlog(hysdn_card *, char *, ...); /* output data to log */
-extern void hysdn_card_errlog(hysdn_card *, tErrLogEntry *, int); /* output card log */
-
-/* boardergo.c */
-extern int ergo_inithardware(hysdn_card *card); /* get hardware -> module init */
-
-/* hysdn_boot.c */
-extern int pof_write_close(hysdn_card *); /* close proc file after writing pof */
-extern int pof_write_open(hysdn_card *, unsigned char **); /* open proc file for writing pof */
-extern int pof_write_buffer(hysdn_card *, int); /* write boot data to card */
-extern int EvalSysrTokData(hysdn_card *, unsigned char *, int); /* Check Sysready Token Data */
-
-/* hysdn_sched.c */
-extern int hysdn_sched_tx(hysdn_card *, unsigned char *,
- unsigned short volatile *, unsigned short volatile *,
- unsigned short);
-extern int hysdn_sched_rx(hysdn_card *, unsigned char *, unsigned short,
- unsigned short);
-extern int hysdn_tx_cfgline(hysdn_card *, unsigned char *,
- unsigned short); /* send one cfg line */
-
-/* hysdn_net.c */
-extern unsigned int hynet_enable;
-extern int hysdn_net_create(hysdn_card *); /* create a new net device */
-extern int hysdn_net_release(hysdn_card *); /* delete the device */
-extern char *hysdn_net_getname(hysdn_card *); /* get name of net interface */
-extern void hysdn_tx_netack(hysdn_card *); /* acknowledge a packet tx */
-extern struct sk_buff *hysdn_tx_netget(hysdn_card *); /* get next network packet */
-extern void hysdn_rx_netpkt(hysdn_card *, unsigned char *,
- unsigned short); /* rxed packet from network */
-
-#ifdef CONFIG_HYSDN_CAPI
-extern unsigned int hycapi_enable;
-extern int hycapi_capi_create(hysdn_card *); /* create a new capi device */
-extern int hycapi_capi_release(hysdn_card *); /* delete the device */
-extern int hycapi_capi_stop(hysdn_card *card); /* suspend */
-extern void hycapi_rx_capipkt(hysdn_card *card, unsigned char *buf,
- unsigned short len);
-extern void hycapi_tx_capiack(hysdn_card *card);
-extern struct sk_buff *hycapi_tx_capiget(hysdn_card *card);
-extern int hycapi_init(void);
-extern void hycapi_cleanup(void);
-#endif /* CONFIG_HYSDN_CAPI */
-
-#endif /* HYSDN_DEFS_H */
diff --git a/drivers/staging/isdn/hysdn/hysdn_init.c b/drivers/staging/isdn/hysdn/hysdn_init.c
deleted file mode 100644
index 0db2f7506250..000000000000
--- a/drivers/staging/isdn/hysdn/hysdn_init.c
+++ /dev/null
@@ -1,213 +0,0 @@
-/* $Id: hysdn_init.c,v 1.6.6.6 2001/09/23 22:24:54 kai Exp $
- *
- * Linux driver for HYSDN cards, init functions.
- *
- * Author Werner Cornelius (werner@titro.de) for Hypercope GmbH
- * Copyright 1999 by Werner Cornelius (werner@titro.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/init.h>
-#include <linux/poll.h>
-#include <linux/vmalloc.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-
-#include "hysdn_defs.h"
-
-static struct pci_device_id hysdn_pci_tbl[] = {
- { PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX,
- PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_METRO, 0, 0, BD_METRO },
- { PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX,
- PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_CHAMP2, 0, 0, BD_CHAMP2 },
- { PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX,
- PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_ERGO, 0, 0, BD_ERGO },
- { PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX,
- PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_OLD_ERGO, 0, 0, BD_ERGO },
-
- { } /* Terminating entry */
-};
-MODULE_DEVICE_TABLE(pci, hysdn_pci_tbl);
-MODULE_DESCRIPTION("ISDN4Linux: Driver for HYSDN cards");
-MODULE_AUTHOR("Werner Cornelius");
-MODULE_LICENSE("GPL");
-
-static int cardmax; /* number of found cards */
-hysdn_card *card_root = NULL; /* pointer to first card */
-static hysdn_card *card_last = NULL; /* pointer to first card */
-
-
-/****************************************************************************/
-/* The module startup and shutdown code. Only compiled when used as module. */
-/* Using the driver as module is always advisable, because the booting */
-/* image becomes smaller and the driver code is only loaded when needed. */
-/* Additionally newer versions may be activated without rebooting. */
-/****************************************************************************/
-
-/****************************************************************************/
-/* init_module is called once when the module is loaded to do all necessary */
-/* things like autodetect... */
-/* If the return value of this function is 0 the init has been successful */
-/* and the module is added to the list in /proc/modules, otherwise an error */
-/* is assumed and the module will not be kept in memory. */
-/****************************************************************************/
-
-static int hysdn_pci_init_one(struct pci_dev *akt_pcidev,
- const struct pci_device_id *ent)
-{
- hysdn_card *card;
- int rc;
-
- rc = pci_enable_device(akt_pcidev);
- if (rc)
- return rc;
-
- if (!(card = kzalloc(sizeof(hysdn_card), GFP_KERNEL))) {
- printk(KERN_ERR "HYSDN: unable to alloc device mem \n");
- rc = -ENOMEM;
- goto err_out;
- }
- card->myid = cardmax; /* set own id */
- card->bus = akt_pcidev->bus->number;
- card->devfn = akt_pcidev->devfn; /* slot + function */
- card->subsysid = akt_pcidev->subsystem_device;
- card->irq = akt_pcidev->irq;
- card->iobase = pci_resource_start(akt_pcidev, PCI_REG_PLX_IO_BASE);
- card->plxbase = pci_resource_start(akt_pcidev, PCI_REG_PLX_MEM_BASE);
- card->membase = pci_resource_start(akt_pcidev, PCI_REG_MEMORY_BASE);
- card->brdtype = BD_NONE; /* unknown */
- card->debug_flags = DEF_DEB_FLAGS; /* set default debug */
- card->faxchans = 0; /* default no fax channels */
- card->bchans = 2; /* and 2 b-channels */
- card->brdtype = ent->driver_data;
-
- if (ergo_inithardware(card)) {
- printk(KERN_WARNING "HYSDN: card at io 0x%04x already in use\n", card->iobase);
- rc = -EBUSY;
- goto err_out_card;
- }
-
- cardmax++;
- card->next = NULL; /*end of chain */
- if (card_last)
- card_last->next = card; /* pointer to next card */
- else
- card_root = card;
- card_last = card; /* new chain end */
-
- pci_set_drvdata(akt_pcidev, card);
- return 0;
-
-err_out_card:
- kfree(card);
-err_out:
- pci_disable_device(akt_pcidev);
- return rc;
-}
-
-static void hysdn_pci_remove_one(struct pci_dev *akt_pcidev)
-{
- hysdn_card *card = pci_get_drvdata(akt_pcidev);
-
- pci_set_drvdata(akt_pcidev, NULL);
-
- if (card->stopcard)
- card->stopcard(card);
-
-#ifdef CONFIG_HYSDN_CAPI
- hycapi_capi_release(card);
-#endif
-
- if (card->releasehardware)
- card->releasehardware(card); /* free all hardware resources */
-
- if (card == card_root) {
- card_root = card_root->next;
- if (!card_root)
- card_last = NULL;
- } else {
- hysdn_card *tmp = card_root;
- while (tmp) {
- if (tmp->next == card)
- tmp->next = card->next;
- card_last = tmp;
- tmp = tmp->next;
- }
- }
-
- kfree(card);
- pci_disable_device(akt_pcidev);
-}
-
-static struct pci_driver hysdn_pci_driver = {
- .name = "hysdn",
- .id_table = hysdn_pci_tbl,
- .probe = hysdn_pci_init_one,
- .remove = hysdn_pci_remove_one,
-};
-
-static int hysdn_have_procfs;
-
-static int __init
-hysdn_init(void)
-{
- int rc;
-
- printk(KERN_NOTICE "HYSDN: module loaded\n");
-
- rc = pci_register_driver(&hysdn_pci_driver);
- if (rc)
- return rc;
-
- printk(KERN_INFO "HYSDN: %d card(s) found.\n", cardmax);
-
- if (!hysdn_procconf_init())
- hysdn_have_procfs = 1;
-
-#ifdef CONFIG_HYSDN_CAPI
- if (cardmax > 0) {
- if (hycapi_init()) {
- printk(KERN_ERR "HYCAPI: init failed\n");
-
- if (hysdn_have_procfs)
- hysdn_procconf_release();
-
- pci_unregister_driver(&hysdn_pci_driver);
- return -ESPIPE;
- }
- }
-#endif /* CONFIG_HYSDN_CAPI */
-
- return 0; /* no error */
-} /* init_module */
-
-
-/***********************************************************************/
-/* cleanup_module is called when the module is released by the kernel. */
-/* The routine is only called if init_module has been successful and */
-/* the module counter has a value of 0. Otherwise this function will */
-/* not be called. This function must release all resources still allo- */
-/* cated as after the return from this function the module code will */
-/* be removed from memory. */
-/***********************************************************************/
-static void __exit
-hysdn_exit(void)
-{
- if (hysdn_have_procfs)
- hysdn_procconf_release();
-
- pci_unregister_driver(&hysdn_pci_driver);
-
-#ifdef CONFIG_HYSDN_CAPI
- hycapi_cleanup();
-#endif /* CONFIG_HYSDN_CAPI */
-
- printk(KERN_NOTICE "HYSDN: module unloaded\n");
-} /* cleanup_module */
-
-module_init(hysdn_init);
-module_exit(hysdn_exit);
diff --git a/drivers/staging/isdn/hysdn/hysdn_net.c b/drivers/staging/isdn/hysdn/hysdn_net.c
deleted file mode 100644
index dcb9ef7a2651..000000000000
--- a/drivers/staging/isdn/hysdn/hysdn_net.c
+++ /dev/null
@@ -1,330 +0,0 @@
-/* $Id: hysdn_net.c,v 1.8.6.4 2001/09/23 22:24:54 kai Exp $
- *
- * Linux driver for HYSDN cards, net (ethernet type) handling routines.
- *
- * Author Werner Cornelius (werner@titro.de) for Hypercope GmbH
- * Copyright 1999 by Werner Cornelius (werner@titro.de)
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- * This net module has been inspired by the skeleton driver from
- * Donald Becker (becker@CESDIS.gsfc.nasa.gov)
- *
- */
-
-#include <linux/module.h>
-#include <linux/signal.h>
-#include <linux/kernel.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/inetdevice.h>
-
-#include "hysdn_defs.h"
-
-unsigned int hynet_enable = 0xffffffff;
-module_param(hynet_enable, uint, 0);
-
-#define MAX_SKB_BUFFERS 20 /* number of buffers for keeping TX-data */
-
-/****************************************************************************/
-/* structure containing the complete network data. The structure is aligned */
-/* in a way that both, the device and statistics are kept inside it. */
-/* for proper access, the device structure MUST be the first var/struct */
-/* inside the definition. */
-/****************************************************************************/
-struct net_local {
- /* Tx control lock. This protects the transmit buffer ring
- * state along with the "tx full" state of the driver. This
- * means all netif_queue flow control actions are protected
- * by this lock as well.
- */
- struct net_device *dev;
- spinlock_t lock;
- struct sk_buff *skbs[MAX_SKB_BUFFERS]; /* pointers to tx-skbs */
- int in_idx, out_idx; /* indexes to buffer ring */
- int sk_count; /* number of buffers currently in ring */
-}; /* net_local */
-
-
-
-/*********************************************************************/
-/* Open/initialize the board. This is called (in the current kernel) */
-/* sometime after booting when the 'ifconfig' program is run. */
-/* This routine should set everything up anew at each open, even */
-/* registers that "should" only need to be set once at boot, so that */
-/* there is non-reboot way to recover if something goes wrong. */
-/*********************************************************************/
-static int
-net_open(struct net_device *dev)
-{
- struct in_device *in_dev;
- hysdn_card *card = dev->ml_priv;
- int i;
-
- netif_start_queue(dev); /* start tx-queueing */
-
- /* Fill in the MAC-level header (if not already set) */
- if (!card->mac_addr[0]) {
- for (i = 0; i < ETH_ALEN; i++)
- dev->dev_addr[i] = 0xfc;
- if ((in_dev = dev->ip_ptr) != NULL) {
- const struct in_ifaddr *ifa;
-
- rcu_read_lock();
- ifa = rcu_dereference(in_dev->ifa_list);
- if (ifa != NULL)
- memcpy(dev->dev_addr + (ETH_ALEN - sizeof(ifa->ifa_local)), &ifa->ifa_local, sizeof(ifa->ifa_local));
- rcu_read_unlock();
- }
- } else
- memcpy(dev->dev_addr, card->mac_addr, ETH_ALEN);
-
- return (0);
-} /* net_open */
-
-/*******************************************/
-/* flush the currently occupied tx-buffers */
-/* must only be called when device closed */
-/*******************************************/
-static void
-flush_tx_buffers(struct net_local *nl)
-{
-
- while (nl->sk_count) {
- dev_kfree_skb(nl->skbs[nl->out_idx++]); /* free skb */
- if (nl->out_idx >= MAX_SKB_BUFFERS)
- nl->out_idx = 0; /* wrap around */
- nl->sk_count--;
- }
-} /* flush_tx_buffers */
-
-
-/*********************************************************************/
-/* close/decativate the device. The device is not removed, but only */
-/* deactivated. */
-/*********************************************************************/
-static int
-net_close(struct net_device *dev)
-{
-
- netif_stop_queue(dev); /* disable queueing */
-
- flush_tx_buffers((struct net_local *) dev);
-
- return (0); /* success */
-} /* net_close */
-
-/************************************/
-/* send a packet on this interface. */
-/* new style for kernel >= 2.3.33 */
-/************************************/
-static netdev_tx_t
-net_send_packet(struct sk_buff *skb, struct net_device *dev)
-{
- struct net_local *lp = (struct net_local *) dev;
-
- spin_lock_irq(&lp->lock);
-
- lp->skbs[lp->in_idx++] = skb; /* add to buffer list */
- if (lp->in_idx >= MAX_SKB_BUFFERS)
- lp->in_idx = 0; /* wrap around */
- lp->sk_count++; /* adjust counter */
- netif_trans_update(dev);
-
- /* If we just used up the very last entry in the
- * TX ring on this device, tell the queueing
- * layer to send no more.
- */
- if (lp->sk_count >= MAX_SKB_BUFFERS)
- netif_stop_queue(dev);
-
- /* When the TX completion hw interrupt arrives, this
- * is when the transmit statistics are updated.
- */
-
- spin_unlock_irq(&lp->lock);
-
- if (lp->sk_count <= 3) {
- schedule_work(&((hysdn_card *) dev->ml_priv)->irq_queue);
- }
- return NETDEV_TX_OK; /* success */
-} /* net_send_packet */
-
-
-
-/***********************************************************************/
-/* acknowlegde a packet send. The network layer will be informed about */
-/* completion */
-/***********************************************************************/
-void
-hysdn_tx_netack(hysdn_card *card)
-{
- struct net_local *lp = card->netif;
-
- if (!lp)
- return; /* non existing device */
-
-
- if (!lp->sk_count)
- return; /* error condition */
-
- lp->dev->stats.tx_packets++;
- lp->dev->stats.tx_bytes += lp->skbs[lp->out_idx]->len;
-
- dev_kfree_skb(lp->skbs[lp->out_idx++]); /* free skb */
- if (lp->out_idx >= MAX_SKB_BUFFERS)
- lp->out_idx = 0; /* wrap around */
-
- if (lp->sk_count-- == MAX_SKB_BUFFERS) /* dec usage count */
- netif_start_queue((struct net_device *) lp);
-} /* hysdn_tx_netack */
-
-/*****************************************************/
-/* we got a packet from the network, go and queue it */
-/*****************************************************/
-void
-hysdn_rx_netpkt(hysdn_card *card, unsigned char *buf, unsigned short len)
-{
- struct net_local *lp = card->netif;
- struct net_device *dev;
- struct sk_buff *skb;
-
- if (!lp)
- return; /* non existing device */
-
- dev = lp->dev;
- dev->stats.rx_bytes += len;
-
- skb = dev_alloc_skb(len);
- if (skb == NULL) {
- printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n",
- dev->name);
- dev->stats.rx_dropped++;
- return;
- }
- /* copy the data */
- skb_put_data(skb, buf, len);
-
- /* determine the used protocol */
- skb->protocol = eth_type_trans(skb, dev);
-
- dev->stats.rx_packets++; /* adjust packet count */
-
- netif_rx(skb);
-} /* hysdn_rx_netpkt */
-
-/*****************************************************/
-/* return the pointer to a network packet to be send */
-/*****************************************************/
-struct sk_buff *
-hysdn_tx_netget(hysdn_card *card)
-{
- struct net_local *lp = card->netif;
-
- if (!lp)
- return (NULL); /* non existing device */
-
- if (!lp->sk_count)
- return (NULL); /* nothing available */
-
- return (lp->skbs[lp->out_idx]); /* next packet to send */
-} /* hysdn_tx_netget */
-
-static const struct net_device_ops hysdn_netdev_ops = {
- .ndo_open = net_open,
- .ndo_stop = net_close,
- .ndo_start_xmit = net_send_packet,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
-};
-
-
-/*****************************************************************************/
-/* hysdn_net_create creates a new net device for the given card. If a device */
-/* already exists, it will be deleted and created a new one. The return value */
-/* 0 announces success, else a negative error code will be returned. */
-/*****************************************************************************/
-int
-hysdn_net_create(hysdn_card *card)
-{
- struct net_device *dev;
- int i;
- struct net_local *lp;
-
- if (!card) {
- printk(KERN_WARNING "No card-pt in hysdn_net_create!\n");
- return (-ENOMEM);
- }
- hysdn_net_release(card); /* release an existing net device */
-
- dev = alloc_etherdev(sizeof(struct net_local));
- if (!dev) {
- printk(KERN_WARNING "HYSDN: unable to allocate mem\n");
- return (-ENOMEM);
- }
-
- lp = netdev_priv(dev);
- lp->dev = dev;
-
- dev->netdev_ops = &hysdn_netdev_ops;
- spin_lock_init(&((struct net_local *) dev)->lock);
-
- /* initialise necessary or informing fields */
- dev->base_addr = card->iobase; /* IO address */
- dev->irq = card->irq; /* irq */
-
- dev->netdev_ops = &hysdn_netdev_ops;
- if ((i = register_netdev(dev))) {
- printk(KERN_WARNING "HYSDN: unable to create network device\n");
- free_netdev(dev);
- return (i);
- }
- dev->ml_priv = card; /* remember pointer to own data structure */
- card->netif = dev; /* setup the local pointer */
-
- if (card->debug_flags & LOG_NET_INIT)
- hysdn_addlog(card, "network device created");
- return 0; /* and return success */
-} /* hysdn_net_create */
-
-/***************************************************************************/
-/* hysdn_net_release deletes the net device for the given card. The return */
-/* value 0 announces success, else a negative error code will be returned. */
-/***************************************************************************/
-int
-hysdn_net_release(hysdn_card *card)
-{
- struct net_device *dev = card->netif;
-
- if (!dev)
- return (0); /* non existing */
-
- card->netif = NULL; /* clear out pointer */
- net_close(dev);
-
- flush_tx_buffers((struct net_local *) dev); /* empty buffers */
-
- unregister_netdev(dev); /* release the device */
- free_netdev(dev); /* release the memory allocated */
- if (card->debug_flags & LOG_NET_INIT)
- hysdn_addlog(card, "network device deleted");
-
- return (0); /* always successful */
-} /* hysdn_net_release */
-
-/*****************************************************************************/
-/* hysdn_net_getname returns a pointer to the name of the network interface. */
-/* if the interface is not existing, a "-" is returned. */
-/*****************************************************************************/
-char *
-hysdn_net_getname(hysdn_card *card)
-{
- struct net_device *dev = card->netif;
-
- if (!dev)
- return ("-"); /* non existing */
-
- return (dev->name);
-} /* hysdn_net_getname */
diff --git a/drivers/staging/isdn/hysdn/hysdn_pof.h b/drivers/staging/isdn/hysdn/hysdn_pof.h
deleted file mode 100644
index f63f5fa59d7e..000000000000
--- a/drivers/staging/isdn/hysdn/hysdn_pof.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/* $Id: hysdn_pof.h,v 1.2.6.1 2001/09/23 22:24:54 kai Exp $
- *
- * Linux driver for HYSDN cards, definitions used for handling pof-files.
- *
- * Author Werner Cornelius (werner@titro.de) for Hypercope GmbH
- * Copyright 1999 by Werner Cornelius (werner@titro.de)
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-/************************/
-/* POF specific defines */
-/************************/
-#define BOOT_BUF_SIZE 0x1000 /* =4096, maybe moved to other h file */
-#define CRYPT_FEEDTERM 0x8142
-#define CRYPT_STARTTERM 0x81a5
-/* max. timeout time in seconds
- * from end of booting to POF is ready
- */
-#define POF_READY_TIME_OUT_SEC 10
-
-/**********************************/
-/* defines for 1.stage boot image */
-/**********************************/
-
-/* the POF file record containing the boot loader image
- * has 2 pages a 16KB:
- * 1. page contains the high 16-bit part of the 32-bit E1 words
- * 2. page contains the low 16-bit part of the 32-bit E1 words
- *
- * In each 16KB page we assume the start of the boot loader code
- * in the highest 2KB part (at offset 0x3800);
- * the rest (0x0000..0x37FF) is assumed to contain 0 bytes.
- */
-
-#define POF_BOOT_LOADER_PAGE_SIZE 0x4000 /* =16384U */
-#define POF_BOOT_LOADER_TOTAL_SIZE (2U * POF_BOOT_LOADER_PAGE_SIZE)
-
-#define POF_BOOT_LOADER_CODE_SIZE 0x0800 /* =2KB =2048U */
-
-/* offset in boot page, where loader code may start */
-/* =0x3800= 14336U */
-#define POF_BOOT_LOADER_OFF_IN_PAGE (POF_BOOT_LOADER_PAGE_SIZE-POF_BOOT_LOADER_CODE_SIZE)
-
-
-/*--------------------------------------POF file record structs------------*/
-typedef struct PofFileHdr_tag { /* Pof file header */
- /*00 */ unsigned long Magic __attribute__((packed));
- /*04 */ unsigned long N_PofRecs __attribute__((packed));
-/*08 */
-} tPofFileHdr;
-
-typedef struct PofRecHdr_tag { /* Pof record header */
- /*00 */ unsigned short PofRecId __attribute__((packed));
- /*02 */ unsigned long PofRecDataLen __attribute__((packed));
-/*06 */
-} tPofRecHdr;
-
-typedef struct PofTimeStamp_tag {
- /*00 */ unsigned long UnixTime __attribute__((packed));
- /*04 */ unsigned char DateTimeText[0x28];
- /* =40 */
-/*2C */
-} tPofTimeStamp;
-
-/* tPofFileHdr.Magic value: */
-#define TAGFILEMAGIC 0x464F501AUL
-/* tPofRecHdr.PofRecId values: */
-#define TAG_ABSDATA 0x1000 /* abs. data */
-#define TAG_BOOTDTA 0x1001 /* boot data */
-#define TAG_COMMENT 0x0020
-#define TAG_SYSCALL 0x0021
-#define TAG_FLOWCTRL 0x0022
-#define TAG_TIMESTMP 0x0010 /* date/time stamp of version */
-#define TAG_CABSDATA 0x1100 /* crypted abs. data */
-#define TAG_CBOOTDTA 0x1101 /* crypted boot data */
diff --git a/drivers/staging/isdn/hysdn/hysdn_procconf.c b/drivers/staging/isdn/hysdn/hysdn_procconf.c
deleted file mode 100644
index 48afd9f5316e..000000000000
--- a/drivers/staging/isdn/hysdn/hysdn_procconf.c
+++ /dev/null
@@ -1,411 +0,0 @@
-/* $Id: hysdn_procconf.c,v 1.8.6.4 2001/09/23 22:24:54 kai Exp $
- *
- * Linux driver for HYSDN cards, /proc/net filesystem dir and conf functions.
- *
- * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH
- *
- * Copyright 1999 by Werner Cornelius (werner@titro.de)
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#include <linux/cred.h>
-#include <linux/module.h>
-#include <linux/poll.h>
-#include <linux/proc_fs.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/mutex.h>
-#include <net/net_namespace.h>
-
-#include "hysdn_defs.h"
-
-static DEFINE_MUTEX(hysdn_conf_mutex);
-
-#define INFO_OUT_LEN 80 /* length of info line including lf */
-
-/********************************************************/
-/* defines and data structure for conf write operations */
-/********************************************************/
-#define CONF_STATE_DETECT 0 /* waiting for detect */
-#define CONF_STATE_CONF 1 /* writing config data */
-#define CONF_STATE_POF 2 /* writing pof data */
-#define CONF_LINE_LEN 255 /* 255 chars max */
-
-struct conf_writedata {
- hysdn_card *card; /* card the device is connected to */
- int buf_size; /* actual number of bytes in the buffer */
- int needed_size; /* needed size when reading pof */
- int state; /* actual interface states from above constants */
- unsigned char conf_line[CONF_LINE_LEN]; /* buffered conf line */
- unsigned short channel; /* active channel number */
- unsigned char *pof_buffer; /* buffer when writing pof */
-};
-
-/***********************************************************************/
-/* process_line parses one config line and transfers it to the card if */
-/* necessary. */
-/* if the return value is negative an error occurred. */
-/***********************************************************************/
-static int
-process_line(struct conf_writedata *cnf)
-{
- unsigned char *cp = cnf->conf_line;
- int i;
-
- if (cnf->card->debug_flags & LOG_CNF_LINE)
- hysdn_addlog(cnf->card, "conf line: %s", cp);
-
- if (*cp == '-') { /* option */
- cp++; /* point to option char */
-
- if (*cp++ != 'c')
- return (0); /* option unknown or used */
- i = 0; /* start value for channel */
- while ((*cp <= '9') && (*cp >= '0'))
- i = i * 10 + *cp++ - '0'; /* get decimal number */
- if (i > 65535) {
- if (cnf->card->debug_flags & LOG_CNF_MISC)
- hysdn_addlog(cnf->card, "conf channel invalid %d", i);
- return (-ERR_INV_CHAN); /* invalid channel */
- }
- cnf->channel = i & 0xFFFF; /* set new channel number */
- return (0); /* success */
- } /* option */
- if (*cp == '*') { /* line to send */
- if (cnf->card->debug_flags & LOG_CNF_DATA)
- hysdn_addlog(cnf->card, "conf chan=%d %s", cnf->channel, cp);
- return (hysdn_tx_cfgline(cnf->card, cnf->conf_line + 1,
- cnf->channel)); /* send the line without * */
- } /* line to send */
- return (0);
-} /* process_line */
-
-/***********************************/
-/* conf file operations and tables */
-/***********************************/
-
-/****************************************************/
-/* write conf file -> boot or send cfg line to card */
-/****************************************************/
-static ssize_t
-hysdn_conf_write(struct file *file, const char __user *buf, size_t count, loff_t *off)
-{
- struct conf_writedata *cnf;
- int i;
- unsigned char ch, *cp;
-
- if (!count)
- return (0); /* nothing to handle */
-
- if (!(cnf = file->private_data))
- return (-EFAULT); /* should never happen */
-
- if (cnf->state == CONF_STATE_DETECT) { /* auto detect cnf or pof data */
- if (copy_from_user(&ch, buf, 1)) /* get first char for detect */
- return (-EFAULT);
-
- if (ch == 0x1A) {
- /* we detected a pof file */
- if ((cnf->needed_size = pof_write_open(cnf->card, &cnf->pof_buffer)) <= 0)
- return (cnf->needed_size); /* an error occurred -> exit */
- cnf->buf_size = 0; /* buffer is empty */
- cnf->state = CONF_STATE_POF; /* new state */
- } else {
- /* conf data has been detected */
- cnf->buf_size = 0; /* buffer is empty */
- cnf->state = CONF_STATE_CONF; /* requested conf data write */
- if (cnf->card->state != CARD_STATE_RUN)
- return (-ERR_NOT_BOOTED);
- cnf->conf_line[CONF_LINE_LEN - 1] = 0; /* limit string length */
- cnf->channel = 4098; /* default channel for output */
- }
- } /* state was auto detect */
- if (cnf->state == CONF_STATE_POF) { /* pof write active */
- i = cnf->needed_size - cnf->buf_size; /* bytes still missing for write */
- if (i <= 0)
- return (-EINVAL); /* size error handling pof */
-
- if (i < count)
- count = i; /* limit requested number of bytes */
- if (copy_from_user(cnf->pof_buffer + cnf->buf_size, buf, count))
- return (-EFAULT); /* error while copying */
- cnf->buf_size += count;
-
- if (cnf->needed_size == cnf->buf_size) {
- cnf->needed_size = pof_write_buffer(cnf->card, cnf->buf_size); /* write data */
- if (cnf->needed_size <= 0) {
- cnf->card->state = CARD_STATE_BOOTERR; /* show boot error */
- return (cnf->needed_size); /* an error occurred */
- }
- cnf->buf_size = 0; /* buffer is empty again */
- }
- }
- /* pof write active */
- else { /* conf write active */
-
- if (cnf->card->state != CARD_STATE_RUN) {
- if (cnf->card->debug_flags & LOG_CNF_MISC)
- hysdn_addlog(cnf->card, "cnf write denied -> not booted");
- return (-ERR_NOT_BOOTED);
- }
- i = (CONF_LINE_LEN - 1) - cnf->buf_size; /* bytes available in buffer */
- if (i > 0) {
- /* copy remaining bytes into buffer */
-
- if (count > i)
- count = i; /* limit transfer */
- if (copy_from_user(cnf->conf_line + cnf->buf_size, buf, count))
- return (-EFAULT); /* error while copying */
-
- i = count; /* number of chars in buffer */
- cp = cnf->conf_line + cnf->buf_size;
- while (i) {
- /* search for end of line */
- if ((*cp < ' ') && (*cp != 9))
- break; /* end of line found */
- cp++;
- i--;
- } /* search for end of line */
-
- if (i) {
- /* delimiter found */
- *cp++ = 0; /* string termination */
- count -= (i - 1); /* subtract remaining bytes from count */
- while ((i) && (*cp < ' ') && (*cp != 9)) {
- i--; /* discard next char */
- count++; /* mark as read */
- cp++; /* next char */
- }
- cnf->buf_size = 0; /* buffer is empty after transfer */
- if ((i = process_line(cnf)) < 0) /* handle the line */
- count = i; /* return the error */
- }
- /* delimiter found */
- else {
- cnf->buf_size += count; /* add chars to string */
- if (cnf->buf_size >= CONF_LINE_LEN - 1) {
- if (cnf->card->debug_flags & LOG_CNF_MISC)
- hysdn_addlog(cnf->card, "cnf line too long %d chars pos %d", cnf->buf_size, count);
- return (-ERR_CONF_LONG);
- }
- } /* not delimited */
-
- }
- /* copy remaining bytes into buffer */
- else {
- if (cnf->card->debug_flags & LOG_CNF_MISC)
- hysdn_addlog(cnf->card, "cnf line too long");
- return (-ERR_CONF_LONG);
- }
- } /* conf write active */
-
- return (count);
-} /* hysdn_conf_write */
-
-/*******************************************/
-/* read conf file -> output card info data */
-/*******************************************/
-static ssize_t
-hysdn_conf_read(struct file *file, char __user *buf, size_t count, loff_t *off)
-{
- char *cp;
-
- if (!(file->f_mode & FMODE_READ))
- return -EPERM; /* no permission to read */
-
- if (!(cp = file->private_data))
- return -EFAULT; /* should never happen */
-
- return simple_read_from_buffer(buf, count, off, cp, strlen(cp));
-} /* hysdn_conf_read */
-
-/******************/
-/* open conf file */
-/******************/
-static int
-hysdn_conf_open(struct inode *ino, struct file *filep)
-{
- hysdn_card *card;
- struct conf_writedata *cnf;
- char *cp, *tmp;
-
- /* now search the addressed card */
- mutex_lock(&hysdn_conf_mutex);
- card = PDE_DATA(ino);
- if (card->debug_flags & (LOG_PROC_OPEN | LOG_PROC_ALL))
- hysdn_addlog(card, "config open for uid=%d gid=%d mode=0x%x",
- filep->f_cred->fsuid, filep->f_cred->fsgid,
- filep->f_mode);
-
- if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) {
- /* write only access -> write boot file or conf line */
-
- if (!(cnf = kmalloc(sizeof(struct conf_writedata), GFP_KERNEL))) {
- mutex_unlock(&hysdn_conf_mutex);
- return (-EFAULT);
- }
- cnf->card = card;
- cnf->buf_size = 0; /* nothing buffered */
- cnf->state = CONF_STATE_DETECT; /* start auto detect */
- filep->private_data = cnf;
-
- } else if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) {
- /* read access -> output card info data */
-
- if (!(tmp = kmalloc(INFO_OUT_LEN * 2 + 2, GFP_KERNEL))) {
- mutex_unlock(&hysdn_conf_mutex);
- return (-EFAULT); /* out of memory */
- }
- filep->private_data = tmp; /* start of string */
-
- /* first output a headline */
- sprintf(tmp, "id bus slot type irq iobase dp-mem b-chans fax-chans state device");
- cp = tmp; /* start of string */
- while (*cp)
- cp++;
- while (((cp - tmp) % (INFO_OUT_LEN + 1)) != INFO_OUT_LEN)
- *cp++ = ' ';
- *cp++ = '\n';
-
- /* and now the data */
- sprintf(cp, "%d %3d %4d %4d %3d 0x%04x 0x%08lx %7d %9d %3d %s",
- card->myid,
- card->bus,
- PCI_SLOT(card->devfn),
- card->brdtype,
- card->irq,
- card->iobase,
- card->membase,
- card->bchans,
- card->faxchans,
- card->state,
- hysdn_net_getname(card));
- while (*cp)
- cp++;
- while (((cp - tmp) % (INFO_OUT_LEN + 1)) != INFO_OUT_LEN)
- *cp++ = ' ';
- *cp++ = '\n';
- *cp = 0; /* end of string */
- } else { /* simultaneous read/write access forbidden ! */
- mutex_unlock(&hysdn_conf_mutex);
- return (-EPERM); /* no permission this time */
- }
- mutex_unlock(&hysdn_conf_mutex);
- return nonseekable_open(ino, filep);
-} /* hysdn_conf_open */
-
-/***************************/
-/* close a config file. */
-/***************************/
-static int
-hysdn_conf_close(struct inode *ino, struct file *filep)
-{
- hysdn_card *card;
- struct conf_writedata *cnf;
- int retval = 0;
-
- mutex_lock(&hysdn_conf_mutex);
- card = PDE_DATA(ino);
- if (card->debug_flags & (LOG_PROC_OPEN | LOG_PROC_ALL))
- hysdn_addlog(card, "config close for uid=%d gid=%d mode=0x%x",
- filep->f_cred->fsuid, filep->f_cred->fsgid,
- filep->f_mode);
-
- if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) {
- /* write only access -> write boot file or conf line */
- if (filep->private_data) {
- cnf = filep->private_data;
-
- if (cnf->state == CONF_STATE_POF)
- retval = pof_write_close(cnf->card); /* close the pof write */
- kfree(filep->private_data); /* free allocated memory for buffer */
-
- } /* handle write private data */
- } else if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) {
- /* read access -> output card info data */
-
- kfree(filep->private_data); /* release memory */
- }
- mutex_unlock(&hysdn_conf_mutex);
- return (retval);
-} /* hysdn_conf_close */
-
-/******************************************************/
-/* table for conf filesystem functions defined above. */
-/******************************************************/
-static const struct file_operations conf_fops =
-{
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .read = hysdn_conf_read,
- .write = hysdn_conf_write,
- .open = hysdn_conf_open,
- .release = hysdn_conf_close,
-};
-
-/*****************************/
-/* hysdn subdir in /proc/net */
-/*****************************/
-struct proc_dir_entry *hysdn_proc_entry = NULL;
-
-/*******************************************************************************/
-/* hysdn_procconf_init is called when the module is loaded and after the cards */
-/* have been detected. The needed proc dir and card config files are created. */
-/* The log init is called at last. */
-/*******************************************************************************/
-int
-hysdn_procconf_init(void)
-{
- hysdn_card *card;
- unsigned char conf_name[20];
-
- hysdn_proc_entry = proc_mkdir(PROC_SUBDIR_NAME, init_net.proc_net);
- if (!hysdn_proc_entry) {
- printk(KERN_ERR "HYSDN: unable to create hysdn subdir\n");
- return (-1);
- }
- card = card_root; /* point to first card */
- while (card) {
-
- sprintf(conf_name, "%s%d", PROC_CONF_BASENAME, card->myid);
- if ((card->procconf = (void *) proc_create_data(conf_name,
- S_IFREG | S_IRUGO | S_IWUSR,
- hysdn_proc_entry,
- &conf_fops,
- card)) != NULL) {
- hysdn_proclog_init(card); /* init the log file entry */
- }
- card = card->next; /* next entry */
- }
-
- printk(KERN_NOTICE "HYSDN: procfs initialised\n");
- return 0;
-} /* hysdn_procconf_init */
-
-/*************************************************************************************/
-/* hysdn_procconf_release is called when the module is unloaded and before the cards */
-/* resources are released. The module counter is assumed to be 0 ! */
-/*************************************************************************************/
-void
-hysdn_procconf_release(void)
-{
- hysdn_card *card;
- unsigned char conf_name[20];
-
- card = card_root; /* start with first card */
- while (card) {
-
- sprintf(conf_name, "%s%d", PROC_CONF_BASENAME, card->myid);
- if (card->procconf)
- remove_proc_entry(conf_name, hysdn_proc_entry);
-
- hysdn_proclog_release(card); /* init the log file entry */
-
- card = card->next; /* point to next card */
- }
-
- remove_proc_entry(PROC_SUBDIR_NAME, init_net.proc_net);
-}
diff --git a/drivers/staging/isdn/hysdn/hysdn_proclog.c b/drivers/staging/isdn/hysdn/hysdn_proclog.c
deleted file mode 100644
index 6e898b90e86e..000000000000
--- a/drivers/staging/isdn/hysdn/hysdn_proclog.c
+++ /dev/null
@@ -1,357 +0,0 @@
-/* $Id: hysdn_proclog.c,v 1.9.6.3 2001/09/23 22:24:54 kai Exp $
- *
- * Linux driver for HYSDN cards, /proc/net filesystem log functions.
- *
- * Author Werner Cornelius (werner@titro.de) for Hypercope GmbH
- * Copyright 1999 by Werner Cornelius (werner@titro.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/poll.h>
-#include <linux/proc_fs.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/mutex.h>
-#include <linux/kernel.h>
-
-#include "hysdn_defs.h"
-
-/* the proc subdir for the interface is defined in the procconf module */
-extern struct proc_dir_entry *hysdn_proc_entry;
-
-static DEFINE_MUTEX(hysdn_log_mutex);
-static void put_log_buffer(hysdn_card *card, char *cp);
-
-/*************************************************/
-/* structure keeping ascii log for device output */
-/*************************************************/
-struct log_data {
- struct log_data *next;
- unsigned long usage_cnt;/* number of files still to work */
- void *proc_ctrl; /* pointer to own control procdata structure */
- char log_start[2]; /* log string start (final len aligned by size) */
-};
-
-/**********************************************/
-/* structure holding proc entrys for one card */
-/**********************************************/
-struct procdata {
- struct proc_dir_entry *log; /* log entry */
- char log_name[15]; /* log filename */
- struct log_data *log_head, *log_tail; /* head and tail for queue */
- int if_used; /* open count for interface */
- unsigned char logtmp[LOG_MAX_LINELEN];
- wait_queue_head_t rd_queue;
-};
-
-
-/**********************************************/
-/* log function for cards error log interface */
-/**********************************************/
-void
-hysdn_card_errlog(hysdn_card *card, tErrLogEntry *logp, int maxsize)
-{
- char buf[ERRLOG_TEXT_SIZE + 40];
-
- sprintf(buf, "LOG 0x%08lX 0x%08lX : %s\n", logp->ulErrType, logp->ulErrSubtype, logp->ucText);
- put_log_buffer(card, buf); /* output the string */
-} /* hysdn_card_errlog */
-
-/***************************************************/
-/* Log function using format specifiers for output */
-/***************************************************/
-void
-hysdn_addlog(hysdn_card *card, char *fmt, ...)
-{
- struct procdata *pd = card->proclog;
- char *cp;
- va_list args;
-
- if (!pd)
- return; /* log structure non existent */
-
- cp = pd->logtmp;
- cp += sprintf(cp, "HYSDN: card %d ", card->myid);
-
- va_start(args, fmt);
- cp += vsprintf(cp, fmt, args);
- va_end(args);
- *cp++ = '\n';
- *cp = 0;
-
- if (card->debug_flags & DEB_OUT_SYSLOG)
- printk(KERN_INFO "%s", pd->logtmp);
- else
- put_log_buffer(card, pd->logtmp);
-
-} /* hysdn_addlog */
-
-/********************************************/
-/* put an log buffer into the log queue. */
-/* This buffer will be kept until all files */
-/* opened for read got the contents. */
-/* Flushes buffers not longer in use. */
-/********************************************/
-static void
-put_log_buffer(hysdn_card *card, char *cp)
-{
- struct log_data *ib;
- struct procdata *pd = card->proclog;
- unsigned long flags;
-
- if (!pd)
- return;
- if (!cp)
- return;
- if (!*cp)
- return;
- if (pd->if_used <= 0)
- return; /* no open file for read */
-
- if (!(ib = kmalloc(sizeof(struct log_data) + strlen(cp), GFP_ATOMIC)))
- return; /* no memory */
- strcpy(ib->log_start, cp); /* set output string */
- ib->next = NULL;
- ib->proc_ctrl = pd; /* point to own control structure */
- spin_lock_irqsave(&card->hysdn_lock, flags);
- ib->usage_cnt = pd->if_used;
- if (!pd->log_head)
- pd->log_head = ib; /* new head */
- else
- pd->log_tail->next = ib; /* follows existing messages */
- pd->log_tail = ib; /* new tail */
-
- /* delete old entrys */
- while (pd->log_head->next) {
- if ((pd->log_head->usage_cnt <= 0) &&
- (pd->log_head->next->usage_cnt <= 0)) {
- ib = pd->log_head;
- pd->log_head = pd->log_head->next;
- kfree(ib);
- } else {
- break;
- }
- } /* pd->log_head->next */
-
- spin_unlock_irqrestore(&card->hysdn_lock, flags);
-
- wake_up_interruptible(&(pd->rd_queue)); /* announce new entry */
-} /* put_log_buffer */
-
-
-/******************************/
-/* file operations and tables */
-/******************************/
-
-/****************************************/
-/* write log file -> set log level bits */
-/****************************************/
-static ssize_t
-hysdn_log_write(struct file *file, const char __user *buf, size_t count, loff_t *off)
-{
- int rc;
- hysdn_card *card = file->private_data;
-
- rc = kstrtoul_from_user(buf, count, 0, &card->debug_flags);
- if (rc < 0)
- return rc;
- hysdn_addlog(card, "debug set to 0x%lx", card->debug_flags);
- return (count);
-} /* hysdn_log_write */
-
-/******************/
-/* read log file */
-/******************/
-static ssize_t
-hysdn_log_read(struct file *file, char __user *buf, size_t count, loff_t *off)
-{
- struct log_data *inf;
- int len;
- hysdn_card *card = PDE_DATA(file_inode(file));
-
- if (!(inf = *((struct log_data **) file->private_data))) {
- struct procdata *pd = card->proclog;
- if (file->f_flags & O_NONBLOCK)
- return (-EAGAIN);
-
- wait_event_interruptible(pd->rd_queue, (inf =
- *((struct log_data **) file->private_data)));
- }
- if (!inf)
- return (0);
-
- inf->usage_cnt--; /* new usage count */
- file->private_data = &inf->next; /* next structure */
- if ((len = strlen(inf->log_start)) <= count) {
- if (copy_to_user(buf, inf->log_start, len))
- return -EFAULT;
- *off += len;
- return (len);
- }
- return (0);
-} /* hysdn_log_read */
-
-/******************/
-/* open log file */
-/******************/
-static int
-hysdn_log_open(struct inode *ino, struct file *filep)
-{
- hysdn_card *card = PDE_DATA(ino);
-
- mutex_lock(&hysdn_log_mutex);
- if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) {
- /* write only access -> write log level only */
- filep->private_data = card; /* remember our own card */
- } else if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) {
- struct procdata *pd = card->proclog;
- unsigned long flags;
-
- /* read access -> log/debug read */
- spin_lock_irqsave(&card->hysdn_lock, flags);
- pd->if_used++;
- if (pd->log_head)
- filep->private_data = &pd->log_tail->next;
- else
- filep->private_data = &pd->log_head;
- spin_unlock_irqrestore(&card->hysdn_lock, flags);
- } else { /* simultaneous read/write access forbidden ! */
- mutex_unlock(&hysdn_log_mutex);
- return (-EPERM); /* no permission this time */
- }
- mutex_unlock(&hysdn_log_mutex);
- return nonseekable_open(ino, filep);
-} /* hysdn_log_open */
-
-/*******************************************************************************/
-/* close a cardlog file. If the file has been opened for exclusive write it is */
-/* assumed as pof data input and the pof loader is noticed about. */
-/* Otherwise file is handled as log output. In this case the interface usage */
-/* count is decremented and all buffers are noticed of closing. If this file */
-/* was the last one to be closed, all buffers are freed. */
-/*******************************************************************************/
-static int
-hysdn_log_close(struct inode *ino, struct file *filep)
-{
- struct log_data *inf;
- struct procdata *pd;
- hysdn_card *card;
- int retval = 0;
-
- mutex_lock(&hysdn_log_mutex);
- if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) {
- /* write only access -> write debug level written */
- retval = 0; /* success */
- } else {
- /* read access -> log/debug read, mark one further file as closed */
-
- inf = *((struct log_data **) filep->private_data); /* get first log entry */
- if (inf)
- pd = (struct procdata *) inf->proc_ctrl; /* still entries there */
- else {
- /* no info available -> search card */
- card = PDE_DATA(file_inode(filep));
- pd = card->proclog; /* pointer to procfs log */
- }
- if (pd)
- pd->if_used--; /* decrement interface usage count by one */
-
- while (inf) {
- inf->usage_cnt--; /* decrement usage count for buffers */
- inf = inf->next;
- }
-
- if (pd)
- if (pd->if_used <= 0) /* delete buffers if last file closed */
- while (pd->log_head) {
- inf = pd->log_head;
- pd->log_head = pd->log_head->next;
- kfree(inf);
- }
- } /* read access */
- mutex_unlock(&hysdn_log_mutex);
-
- return (retval);
-} /* hysdn_log_close */
-
-/*************************************************/
-/* select/poll routine to be able using select() */
-/*************************************************/
-static __poll_t
-hysdn_log_poll(struct file *file, poll_table *wait)
-{
- __poll_t mask = 0;
- hysdn_card *card = PDE_DATA(file_inode(file));
- struct procdata *pd = card->proclog;
-
- if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE)
- return (mask); /* no polling for write supported */
-
- poll_wait(file, &(pd->rd_queue), wait);
-
- if (*((struct log_data **) file->private_data))
- mask |= EPOLLIN | EPOLLRDNORM;
-
- return mask;
-} /* hysdn_log_poll */
-
-/**************************************************/
-/* table for log filesystem functions defined above. */
-/**************************************************/
-static const struct file_operations log_fops =
-{
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .read = hysdn_log_read,
- .write = hysdn_log_write,
- .poll = hysdn_log_poll,
- .open = hysdn_log_open,
- .release = hysdn_log_close,
-};
-
-
-/***********************************************************************************/
-/* hysdn_proclog_init is called when the module is loaded after creating the cards */
-/* conf files. */
-/***********************************************************************************/
-int
-hysdn_proclog_init(hysdn_card *card)
-{
- struct procdata *pd;
-
- /* create a cardlog proc entry */
-
- if ((pd = kzalloc(sizeof(struct procdata), GFP_KERNEL)) != NULL) {
- sprintf(pd->log_name, "%s%d", PROC_LOG_BASENAME, card->myid);
- pd->log = proc_create_data(pd->log_name,
- S_IFREG | S_IRUGO | S_IWUSR, hysdn_proc_entry,
- &log_fops, card);
-
- init_waitqueue_head(&(pd->rd_queue));
-
- card->proclog = (void *) pd; /* remember procfs structure */
- }
- return (0);
-} /* hysdn_proclog_init */
-
-/************************************************************************************/
-/* hysdn_proclog_release is called when the module is unloaded and before the cards */
-/* conf file is released */
-/* The module counter is assumed to be 0 ! */
-/************************************************************************************/
-void
-hysdn_proclog_release(hysdn_card *card)
-{
- struct procdata *pd;
-
- if ((pd = (struct procdata *) card->proclog) != NULL) {
- if (pd->log)
- remove_proc_entry(pd->log_name, hysdn_proc_entry);
- kfree(pd); /* release memory */
- card->proclog = NULL;
- }
-} /* hysdn_proclog_release */
diff --git a/drivers/staging/isdn/hysdn/hysdn_sched.c b/drivers/staging/isdn/hysdn/hysdn_sched.c
deleted file mode 100644
index 31d7c1415543..000000000000
--- a/drivers/staging/isdn/hysdn/hysdn_sched.c
+++ /dev/null
@@ -1,197 +0,0 @@
-/* $Id: hysdn_sched.c,v 1.5.6.4 2001/11/06 21:58:19 kai Exp $
- *
- * Linux driver for HYSDN cards
- * scheduler routines for handling exchange card <-> pc.
- *
- * Author Werner Cornelius (werner@titro.de) for Hypercope GmbH
- * Copyright 1999 by Werner Cornelius (werner@titro.de)
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#include <linux/signal.h>
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <asm/io.h>
-
-#include "hysdn_defs.h"
-
-/*****************************************************************************/
-/* hysdn_sched_rx is called from the cards handler to announce new data is */
-/* available from the card. The routine has to handle the data and return */
-/* with a nonzero code if the data could be worked (or even thrown away), if */
-/* no room to buffer the data is available a zero return tells the card */
-/* to keep the data until later. */
-/*****************************************************************************/
-int
-hysdn_sched_rx(hysdn_card *card, unsigned char *buf, unsigned short len,
- unsigned short chan)
-{
-
- switch (chan) {
- case CHAN_NDIS_DATA:
- if (hynet_enable & (1 << card->myid)) {
- /* give packet to network handler */
- hysdn_rx_netpkt(card, buf, len);
- }
- break;
-
- case CHAN_ERRLOG:
- hysdn_card_errlog(card, (tErrLogEntry *) buf, len);
- if (card->err_log_state == ERRLOG_STATE_ON)
- card->err_log_state = ERRLOG_STATE_START; /* start new fetch */
- break;
-#ifdef CONFIG_HYSDN_CAPI
- case CHAN_CAPI:
-/* give packet to CAPI handler */
- if (hycapi_enable & (1 << card->myid)) {
- hycapi_rx_capipkt(card, buf, len);
- }
- break;
-#endif /* CONFIG_HYSDN_CAPI */
- default:
- printk(KERN_INFO "irq message channel %d len %d unhandled \n", chan, len);
- break;
-
- } /* switch rx channel */
-
- return (1); /* always handled */
-} /* hysdn_sched_rx */
-
-/*****************************************************************************/
-/* hysdn_sched_tx is called from the cards handler to announce that there is */
-/* room in the tx-buffer to the card and data may be sent if needed. */
-/* If the routine wants to send data it must fill buf, len and chan with the */
-/* appropriate data and return a nonzero value. With a zero return no new */
-/* data to send is assumed. maxlen specifies the buffer size available for */
-/* sending. */
-/*****************************************************************************/
-int
-hysdn_sched_tx(hysdn_card *card, unsigned char *buf,
- unsigned short volatile *len, unsigned short volatile *chan,
- unsigned short maxlen)
-{
- struct sk_buff *skb;
-
- if (card->net_tx_busy) {
- card->net_tx_busy = 0; /* reset flag */
- hysdn_tx_netack(card); /* acknowledge packet send */
- } /* a network packet has completely been transferred */
- /* first of all async requests are handled */
- if (card->async_busy) {
- if (card->async_len <= maxlen) {
- memcpy(buf, card->async_data, card->async_len);
- *len = card->async_len;
- *chan = card->async_channel;
- card->async_busy = 0; /* reset request */
- return (1);
- }
- card->async_busy = 0; /* in case of length error */
- } /* async request */
- if ((card->err_log_state == ERRLOG_STATE_START) &&
- (maxlen >= ERRLOG_CMD_REQ_SIZE)) {
- strcpy(buf, ERRLOG_CMD_REQ); /* copy the command */
- *len = ERRLOG_CMD_REQ_SIZE; /* buffer length */
- *chan = CHAN_ERRLOG; /* and channel */
- card->err_log_state = ERRLOG_STATE_ON; /* new state is on */
- return (1); /* tell that data should be send */
- } /* error log start and able to send */
- if ((card->err_log_state == ERRLOG_STATE_STOP) &&
- (maxlen >= ERRLOG_CMD_STOP_SIZE)) {
- strcpy(buf, ERRLOG_CMD_STOP); /* copy the command */
- *len = ERRLOG_CMD_STOP_SIZE; /* buffer length */
- *chan = CHAN_ERRLOG; /* and channel */
- card->err_log_state = ERRLOG_STATE_OFF; /* new state is off */
- return (1); /* tell that data should be send */
- } /* error log start and able to send */
- /* now handle network interface packets */
- if ((hynet_enable & (1 << card->myid)) &&
- (skb = hysdn_tx_netget(card)) != NULL)
- {
- if (skb->len <= maxlen) {
- /* copy the packet to the buffer */
- skb_copy_from_linear_data(skb, buf, skb->len);
- *len = skb->len;
- *chan = CHAN_NDIS_DATA;
- card->net_tx_busy = 1; /* we are busy sending network data */
- return (1); /* go and send the data */
- } else
- hysdn_tx_netack(card); /* aknowledge packet -> throw away */
- } /* send a network packet if available */
-#ifdef CONFIG_HYSDN_CAPI
- if (((hycapi_enable & (1 << card->myid))) &&
- ((skb = hycapi_tx_capiget(card)) != NULL))
- {
- if (skb->len <= maxlen) {
- skb_copy_from_linear_data(skb, buf, skb->len);
- *len = skb->len;
- *chan = CHAN_CAPI;
- hycapi_tx_capiack(card);
- return (1); /* go and send the data */
- }
- }
-#endif /* CONFIG_HYSDN_CAPI */
- return (0); /* nothing to send */
-} /* hysdn_sched_tx */
-
-
-/*****************************************************************************/
-/* send one config line to the card and return 0 if successful, otherwise a */
-/* negative error code. */
-/* The function works with timeouts perhaps not giving the greatest speed */
-/* sending the line, but this should be meaningless because only some lines */
-/* are to be sent and this happens very seldom. */
-/*****************************************************************************/
-int
-hysdn_tx_cfgline(hysdn_card *card, unsigned char *line, unsigned short chan)
-{
- int cnt = 50; /* timeout intervalls */
- unsigned long flags;
-
- if (card->debug_flags & LOG_SCHED_ASYN)
- hysdn_addlog(card, "async tx-cfg chan=%d len=%d", chan, strlen(line) + 1);
-
- while (card->async_busy) {
-
- if (card->debug_flags & LOG_SCHED_ASYN)
- hysdn_addlog(card, "async tx-cfg delayed");
-
- msleep_interruptible(20); /* Timeout 20ms */
- if (!--cnt)
- return (-ERR_ASYNC_TIME); /* timed out */
- } /* wait for buffer to become free */
-
- spin_lock_irqsave(&card->hysdn_lock, flags);
- strcpy(card->async_data, line);
- card->async_len = strlen(line) + 1;
- card->async_channel = chan;
- card->async_busy = 1; /* request transfer */
-
- /* now queue the task */
- schedule_work(&card->irq_queue);
- spin_unlock_irqrestore(&card->hysdn_lock, flags);
-
- if (card->debug_flags & LOG_SCHED_ASYN)
- hysdn_addlog(card, "async tx-cfg data queued");
-
- cnt++; /* short delay */
-
- while (card->async_busy) {
-
- if (card->debug_flags & LOG_SCHED_ASYN)
- hysdn_addlog(card, "async tx-cfg waiting for tx-ready");
-
- msleep_interruptible(20); /* Timeout 20ms */
- if (!--cnt)
- return (-ERR_ASYNC_TIME); /* timed out */
- } /* wait for buffer to become free again */
-
- if (card->debug_flags & LOG_SCHED_ASYN)
- hysdn_addlog(card, "async tx-cfg data send");
-
- return (0); /* line send correctly */
-} /* hysdn_tx_cfgline */
diff --git a/drivers/staging/isdn/hysdn/ince1pc.h b/drivers/staging/isdn/hysdn/ince1pc.h
deleted file mode 100644
index cab68361de65..000000000000
--- a/drivers/staging/isdn/hysdn/ince1pc.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Linux driver for HYSDN cards
- * common definitions for both sides of the bus:
- * - conventions both spoolers must know
- * - channel numbers agreed upon
- *
- * Author M. Steinkopf
- * Copyright 1999 by M. Steinkopf
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#ifndef __INCE1PC_H__
-#define __INCE1PC_H__
-
-/* basic scalar definitions have same meanning,
- * but their declaration location depends on environment
- */
-
-/*--------------------------------------channel numbers---------------------*/
-#define CHAN_SYSTEM 0x0001 /* system channel (spooler to spooler) */
-#define CHAN_ERRLOG 0x0005 /* error logger */
-#define CHAN_CAPI 0x0064 /* CAPI interface */
-#define CHAN_NDIS_DATA 0x1001 /* NDIS data transfer */
-
-/*--------------------------------------POF ready msg-----------------------*/
-/* NOTE: after booting POF sends system ready message to PC: */
-#define RDY_MAGIC 0x52535953UL /* 'SYSR' reversed */
-#define RDY_MAGIC_SIZE 4 /* size in bytes */
-
-#define MAX_N_TOK_BYTES 255
-
-#define MIN_RDY_MSG_SIZE RDY_MAGIC_SIZE
-#define MAX_RDY_MSG_SIZE (RDY_MAGIC_SIZE + MAX_N_TOK_BYTES)
-
-#define SYSR_TOK_END 0
-#define SYSR_TOK_B_CHAN 1 /* nr. of B-Channels; DataLen=1; def: 2 */
-#define SYSR_TOK_FAX_CHAN 2 /* nr. of FAX Channels; DataLen=1; def: 0 */
-#define SYSR_TOK_MAC_ADDR 3 /* MAC-Address; DataLen=6; def: auto */
-#define SYSR_TOK_ESC 255 /* undefined data size yet */
-/* default values, if not corrected by token: */
-#define SYSR_TOK_B_CHAN_DEF 2 /* assume 2 B-Channels */
-#define SYSR_TOK_FAX_CHAN_DEF 1 /* assume 1 FAX Channel */
-
-/* syntax of new SYSR token stream:
- * channel: CHAN_SYSTEM
- * msgsize: MIN_RDY_MSG_SIZE <= x <= MAX_RDY_MSG_SIZE
- * RDY_MAGIC_SIZE <= x <= (RDY_MAGIC_SIZE+MAX_N_TOK_BYTES)
- * msg : 0 1 2 3 {4 5 6 ..}
- * S Y S R MAX_N_TOK_BYTES bytes of TokenStream
- *
- * TokenStream := empty
- * | {NonEndTokenChunk} EndToken RotlCRC
- * NonEndTokenChunk:= NonEndTokenId DataLen [Data]
- * NonEndTokenId := 0x01 .. 0xFE 1 BYTE
- * DataLen := 0x00 .. 0xFF 1 BYTE
- * Data := DataLen bytes
- * EndToken := 0x00
- * RotlCRC := special 1 byte CRC over all NonEndTokenChunk bytes
- * s. RotlCRC algorithm
- *
- * RotlCRC algorithm:
- * ucSum= 0 1 unsigned char
- * for all NonEndTokenChunk bytes:
- * ROTL(ucSum,1) rotate left by 1
- * ucSum += Char; add current byte with swap around
- * RotlCRC= ~ucSum; invert all bits for result
- *
- * note:
- * - for 16-bit FIFO add padding 0 byte to achieve even token data bytes!
- */
-
-/*--------------------------------------error logger------------------------*/
-/* note: pof needs final 0 ! */
-#define ERRLOG_CMD_REQ "ERRLOG ON"
-#define ERRLOG_CMD_REQ_SIZE 10 /* with final 0 byte ! */
-#define ERRLOG_CMD_STOP "ERRLOG OFF"
-#define ERRLOG_CMD_STOP_SIZE 11 /* with final 0 byte ! */
-
-#define ERRLOG_ENTRY_SIZE 64 /* sizeof(tErrLogEntry) */
- /* remaining text size = 55 */
-#define ERRLOG_TEXT_SIZE (ERRLOG_ENTRY_SIZE - 2 * 4 - 1)
-
-typedef struct ErrLogEntry_tag {
-
- /*00 */ unsigned long ulErrType;
-
- /*04 */ unsigned long ulErrSubtype;
-
- /*08 */ unsigned char ucTextSize;
-
- /*09 */ unsigned char ucText[ERRLOG_TEXT_SIZE];
- /* ASCIIZ of len ucTextSize-1 */
-
-/*40 */
-} tErrLogEntry;
-
-
-#if defined(__TURBOC__)
-#if sizeof(tErrLogEntry) != ERRLOG_ENTRY_SIZE
-#error size of tErrLogEntry != ERRLOG_ENTRY_SIZE
-#endif /* */
-#endif /* */
-
-/*--------------------------------------DPRAM boot spooler------------------*/
-/* this is the struture used between pc and
- * hyperstone to exchange boot data
- */
-#define DPRAM_SPOOLER_DATA_SIZE 0x20
-typedef struct DpramBootSpooler_tag {
-
- /*00 */ unsigned char Len;
-
- /*01 */ volatile unsigned char RdPtr;
-
- /*02 */ unsigned char WrPtr;
-
- /*03 */ unsigned char Data[DPRAM_SPOOLER_DATA_SIZE];
-
-/*23 */
-} tDpramBootSpooler;
-
-
-#define DPRAM_SPOOLER_MIN_SIZE 5 /* Len+RdPtr+Wrptr+2*data */
-#define DPRAM_SPOOLER_DEF_SIZE 0x23 /* current default size */
-
-/*--------------------------------------HYCARD/ERGO DPRAM SoftUart----------*/
-/* at DPRAM offset 0x1C00: */
-#define SIZE_RSV_SOFT_UART 0x1B0 /* 432 bytes reserved for SoftUart */
-
-
-#endif /* __INCE1PC_H__ */
diff --git a/drivers/staging/most/cdev/cdev.c b/drivers/staging/most/cdev/cdev.c
index f880147c82fd..59f346d1f4af 100644
--- a/drivers/staging/most/cdev/cdev.c
+++ b/drivers/staging/most/cdev/cdev.c
@@ -16,7 +16,7 @@
#include <linux/kfifo.h>
#include <linux/uaccess.h>
#include <linux/idr.h>
-#include "most/core.h"
+#include <most/most.h>
#define CHRDEV_REGION_SIZE 50
@@ -25,7 +25,7 @@ static struct cdev_component {
struct ida minor_id;
unsigned int major;
struct class *class;
- struct core_component cc;
+ struct most_component cc;
} comp;
struct comp_channel {
diff --git a/drivers/staging/most/configfs.c b/drivers/staging/most/configfs.c
index 34a9fb53985c..9818f6c8b22a 100644
--- a/drivers/staging/most/configfs.c
+++ b/drivers/staging/most/configfs.c
@@ -10,7 +10,9 @@
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/configfs.h>
-#include <most/core.h>
+#include <most/most.h>
+
+#define MAX_STRING_SIZE 80
struct mdev_link {
struct config_item item;
@@ -22,13 +24,13 @@ struct mdev_link {
u16 subbuffer_size;
u16 packets_per_xact;
u16 dbr_size;
- char datatype[PAGE_SIZE];
- char direction[PAGE_SIZE];
- char name[PAGE_SIZE];
- char device[PAGE_SIZE];
- char channel[PAGE_SIZE];
- char comp[PAGE_SIZE];
- char comp_params[PAGE_SIZE];
+ char datatype[MAX_STRING_SIZE];
+ char direction[MAX_STRING_SIZE];
+ char name[MAX_STRING_SIZE];
+ char device[MAX_STRING_SIZE];
+ char channel[MAX_STRING_SIZE];
+ char comp[MAX_STRING_SIZE];
+ char comp_params[MAX_STRING_SIZE];
};
static struct list_head mdev_link_list;
@@ -197,7 +199,7 @@ static ssize_t mdev_link_device_store(struct config_item *item,
{
struct mdev_link *mdev_link = to_mdev_link(item);
- strcpy(mdev_link->device, page);
+ strlcpy(mdev_link->device, page, sizeof(mdev_link->device));
strim(mdev_link->device);
return count;
}
@@ -212,7 +214,7 @@ static ssize_t mdev_link_channel_store(struct config_item *item,
{
struct mdev_link *mdev_link = to_mdev_link(item);
- strcpy(mdev_link->channel, page);
+ strlcpy(mdev_link->channel, page, sizeof(mdev_link->channel));
strim(mdev_link->channel);
return count;
}
@@ -227,7 +229,8 @@ static ssize_t mdev_link_comp_store(struct config_item *item,
{
struct mdev_link *mdev_link = to_mdev_link(item);
- strcpy(mdev_link->comp, page);
+ strlcpy(mdev_link->comp, page, sizeof(mdev_link->comp));
+ strim(mdev_link->comp);
return count;
}
@@ -242,7 +245,8 @@ static ssize_t mdev_link_comp_params_store(struct config_item *item,
{
struct mdev_link *mdev_link = to_mdev_link(item);
- strcpy(mdev_link->comp_params, page);
+ strlcpy(mdev_link->comp_params, page, sizeof(mdev_link->comp_params));
+ strim(mdev_link->comp_params);
return count;
}
@@ -630,7 +634,7 @@ static struct most_sound most_sound_subsys = {
},
};
-int most_register_configfs_subsys(struct core_component *c)
+int most_register_configfs_subsys(struct most_component *c)
{
int ret;
@@ -674,7 +678,7 @@ void most_interface_register_notify(const char *mdev)
most_cfg_complete("sound");
}
-void most_deregister_configfs_subsys(struct core_component *c)
+void most_deregister_configfs_subsys(struct most_component *c)
{
if (!strcmp(c->name, "cdev"))
configfs_unregister_subsystem(&most_cdev.subsys);
diff --git a/drivers/staging/most/core.c b/drivers/staging/most/core.c
index 51a6b41d5b82..af542ed6c7f0 100644
--- a/drivers/staging/most/core.c
+++ b/drivers/staging/most/core.c
@@ -21,7 +21,7 @@
#include <linux/kthread.h>
#include <linux/dma-mapping.h>
#include <linux/idr.h>
-#include <most/core.h>
+#include <most/most.h>
#define MAX_CHANNELS 64
#define STRING_SIZE 80
@@ -39,7 +39,7 @@ static struct mostcore {
#define to_driver(d) container_of(d, struct mostcore, drv)
struct pipe {
- struct core_component *comp;
+ struct most_component *comp;
int refs;
int num_buffers;
};
@@ -454,9 +454,9 @@ static const struct attribute_group *interface_attr_groups[] = {
NULL,
};
-static struct core_component *match_component(char *name)
+static struct most_component *match_component(char *name)
{
- struct core_component *comp;
+ struct most_component *comp;
list_for_each_entry(comp, &mc.comp_list, list) {
if (!strcmp(comp->name, name))
@@ -510,7 +510,7 @@ static ssize_t links_show(struct device_driver *drv, char *buf)
static ssize_t components_show(struct device_driver *drv, char *buf)
{
- struct core_component *comp;
+ struct most_component *comp;
int offs = 0;
list_for_each_entry(comp, &mc.comp_list, list) {
@@ -544,12 +544,12 @@ static struct most_channel *get_channel(char *mdev, char *mdev_ch)
static
inline int link_channel_to_component(struct most_channel *c,
- struct core_component *comp,
+ struct most_component *comp,
char *name,
char *comp_param)
{
int ret;
- struct core_component **comp_ptr;
+ struct most_component **comp_ptr;
if (!c->pipe0.comp)
comp_ptr = &c->pipe0.comp;
@@ -660,7 +660,7 @@ int most_set_cfg_packets_xact(char *mdev, char *mdev_ch, u16 val)
int most_cfg_complete(char *comp_name)
{
- struct core_component *comp;
+ struct most_component *comp;
comp = match_component(comp_name);
if (!comp)
@@ -673,7 +673,7 @@ int most_add_link(char *mdev, char *mdev_ch, char *comp_name, char *link_name,
char *comp_param)
{
struct most_channel *c = get_channel(mdev, mdev_ch);
- struct core_component *comp = match_component(comp_name);
+ struct most_component *comp = match_component(comp_name);
if (!c || !comp)
return -ENODEV;
@@ -684,7 +684,7 @@ int most_add_link(char *mdev, char *mdev_ch, char *comp_name, char *link_name,
int most_remove_link(char *mdev, char *mdev_ch, char *comp_name)
{
struct most_channel *c;
- struct core_component *comp;
+ struct most_component *comp;
comp = match_component(comp_name);
if (!comp)
@@ -950,7 +950,7 @@ static void most_write_completion(struct mbo *mbo)
}
int channel_has_mbo(struct most_interface *iface, int id,
- struct core_component *comp)
+ struct most_component *comp)
{
struct most_channel *c = iface->p->channel[id];
unsigned long flags;
@@ -981,7 +981,7 @@ EXPORT_SYMBOL_GPL(channel_has_mbo);
* Returns a pointer to MBO on success or NULL otherwise.
*/
struct mbo *most_get_mbo(struct most_interface *iface, int id,
- struct core_component *comp)
+ struct most_component *comp)
{
struct mbo *mbo;
struct most_channel *c;
@@ -1087,7 +1087,7 @@ static void most_read_completion(struct mbo *mbo)
* Returns 0 on success or error code otherwise.
*/
int most_start_channel(struct most_interface *iface, int id,
- struct core_component *comp)
+ struct most_component *comp)
{
int num_buffer;
int ret;
@@ -1157,7 +1157,7 @@ EXPORT_SYMBOL_GPL(most_start_channel);
* @comp: driver component
*/
int most_stop_channel(struct most_interface *iface, int id,
- struct core_component *comp)
+ struct most_component *comp)
{
struct most_channel *c;
@@ -1215,7 +1215,7 @@ EXPORT_SYMBOL_GPL(most_stop_channel);
* most_register_component - registers a driver component with the core
* @comp: driver component
*/
-int most_register_component(struct core_component *comp)
+int most_register_component(struct most_component *comp)
{
if (!comp) {
pr_err("Bad component\n");
@@ -1231,7 +1231,7 @@ static int disconnect_channels(struct device *dev, void *data)
{
struct most_interface *iface;
struct most_channel *c, *tmp;
- struct core_component *comp = data;
+ struct most_component *comp = data;
iface = to_most_interface(dev);
list_for_each_entry_safe(c, tmp, &iface->p->channel_list, list) {
@@ -1249,7 +1249,7 @@ static int disconnect_channels(struct device *dev, void *data)
* most_deregister_component - deregisters a driver component with the core
* @comp: driver component
*/
-int most_deregister_component(struct core_component *comp)
+int most_deregister_component(struct most_component *comp)
{
if (!comp) {
pr_err("Bad component\n");
diff --git a/drivers/staging/most/dim2/dim2.c b/drivers/staging/most/dim2/dim2.c
index 64c979155a49..9eb10fc0903e 100644
--- a/drivers/staging/most/dim2/dim2.c
+++ b/drivers/staging/most/dim2/dim2.c
@@ -21,7 +21,7 @@
#include <linux/sched.h>
#include <linux/kthread.h>
-#include "most/core.h"
+#include <most/most.h>
#include "hal.h"
#include "errors.h"
#include "sysfs.h"
diff --git a/drivers/staging/most/i2c/i2c.c b/drivers/staging/most/i2c/i2c.c
index 4a4fc1005932..d07719c38fc9 100644
--- a/drivers/staging/most/i2c/i2c.c
+++ b/drivers/staging/most/i2c/i2c.c
@@ -14,7 +14,7 @@
#include <linux/interrupt.h>
#include <linux/err.h>
-#include "most/core.h"
+#include <most/most.h>
enum { CH_RX, CH_TX, NUM_CHANNELS };
diff --git a/drivers/staging/most/core.h b/drivers/staging/most/most.h
index 49859aef98df..d93c6cea3a17 100644
--- a/drivers/staging/most/core.h
+++ b/drivers/staging/most/most.h
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* most.h - API for component and adapter drivers
*
@@ -47,7 +47,7 @@ enum most_channel_data_type {
MOST_CH_SYNC = 1 << 5,
};
-enum mbo_status_flags {
+enum most_status_flags {
/* MBO was processed successfully (data was send or received )*/
MBO_SUCCESS = 0,
/* The MBO contains wrong or missing information. */
@@ -184,7 +184,7 @@ struct mbo {
dma_addr_t bus_address;
u16 buffer_length;
u16 processed_length;
- enum mbo_status_flags status;
+ enum most_status_flags status;
void (*complete)(struct mbo *mbo);
};
@@ -254,7 +254,7 @@ struct most_interface {
#define to_most_interface(d) container_of(d, struct most_interface, dev)
/**
- * struct core_component - identifies a loadable component for the mostcore
+ * struct most_component - identifies a loadable component for the mostcore
* @list: list_head
* @name: component name
* @probe_channel: function for core to notify driver about channel connection
@@ -262,7 +262,7 @@ struct most_interface {
* @rx_completion: completion handler for received packets
* @tx_completion: completion handler for transmitted packets
*/
-struct core_component {
+struct most_component {
struct list_head list;
const char *name;
struct module *mod;
@@ -310,20 +310,20 @@ void most_stop_enqueue(struct most_interface *iface, int channel_idx);
* in wait fifo.
*/
void most_resume_enqueue(struct most_interface *iface, int channel_idx);
-int most_register_component(struct core_component *comp);
-int most_deregister_component(struct core_component *comp);
+int most_register_component(struct most_component *comp);
+int most_deregister_component(struct most_component *comp);
struct mbo *most_get_mbo(struct most_interface *iface, int channel_idx,
- struct core_component *comp);
+ struct most_component *comp);
void most_put_mbo(struct mbo *mbo);
int channel_has_mbo(struct most_interface *iface, int channel_idx,
- struct core_component *comp);
+ struct most_component *comp);
int most_start_channel(struct most_interface *iface, int channel_idx,
- struct core_component *comp);
+ struct most_component *comp);
int most_stop_channel(struct most_interface *iface, int channel_idx,
- struct core_component *comp);
+ struct most_component *comp);
int __init configfs_init(void);
-int most_register_configfs_subsys(struct core_component *comp);
-void most_deregister_configfs_subsys(struct core_component *comp);
+int most_register_configfs_subsys(struct most_component *comp);
+void most_deregister_configfs_subsys(struct most_component *comp);
int most_add_link(char *mdev, char *mdev_ch, char *comp_name, char *link_name,
char *comp_param);
int most_remove_link(char *mdev, char *mdev_ch, char *comp_name);
diff --git a/drivers/staging/most/net/net.c b/drivers/staging/most/net/net.c
index 6cab1bb8956e..db4273256ce8 100644
--- a/drivers/staging/most/net/net.c
+++ b/drivers/staging/most/net/net.c
@@ -15,7 +15,7 @@
#include <linux/list.h>
#include <linux/wait.h>
#include <linux/kobject.h>
-#include "most/core.h"
+#include <most/most.h>
#define MEP_HDR_LEN 8
#define MDP_HDR_LEN 16
@@ -70,7 +70,7 @@ struct net_dev_context {
static struct list_head net_devices = LIST_HEAD_INIT(net_devices);
static struct mutex probe_disc_mt; /* ch->linked = true, most_nd_open */
static DEFINE_SPINLOCK(list_lock); /* list_head, ch->linked = false, dev_hold */
-static struct core_component comp;
+static struct most_component comp;
static int skb_to_mamac(const struct sk_buff *skb, struct mbo *mbo)
{
@@ -497,7 +497,7 @@ put_nd:
return ret;
}
-static struct core_component comp = {
+static struct most_component comp = {
.mod = THIS_MODULE,
.name = "net",
.probe_channel = comp_probe_channel,
diff --git a/drivers/staging/most/sound/sound.c b/drivers/staging/most/sound/sound.c
index 723d0bd1cc21..23baf4bd7c12 100644
--- a/drivers/staging/most/sound/sound.c
+++ b/drivers/staging/most/sound/sound.c
@@ -17,12 +17,12 @@
#include <sound/pcm_params.h>
#include <linux/sched.h>
#include <linux/kthread.h>
-#include <most/core.h>
+#include <most/most.h>
#define DRIVER_NAME "sound"
#define STRING_SIZE 80
-static struct core_component comp;
+static struct most_component comp;
/**
* struct channel - private structure to keep channel specific data
@@ -323,45 +323,6 @@ static int pcm_close(struct snd_pcm_substream *substream)
}
/**
- * pcm_hw_params - implements hw_params callback function for PCM middle layer
- * @substream: sub-stream pointer
- * @hw_params: contains the hardware parameters set by the application
- *
- * This is called when the hardware parameters is set by the application, that
- * is, once when the buffer size, the period size, the format, etc. are defined
- * for the PCM substream. Many hardware setups should be done is this callback,
- * including the allocation of buffers.
- *
- * Returns 0 on success or error code otherwise.
- */
-static int pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct channel *channel = substream->private_data;
-
- if ((params_channels(hw_params) > channel->pcm_hardware.channels_max) ||
- (params_channels(hw_params) < channel->pcm_hardware.channels_min)) {
- pr_err("Requested number of channels not supported.\n");
- return -EINVAL;
- }
- return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
-}
-
-/**
- * pcm_hw_free - implements hw_free callback function for PCM middle layer
- * @substream: substream pointer
- *
- * This is called to release the resources allocated via hw_params.
- * This function will be always called before the close callback is called.
- *
- * Returns 0 on success or error code otherwise.
- */
-static int pcm_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
-/**
* pcm_prepare - implements prepare callback function for PCM middle layer
* @substream: substream pointer
*
@@ -462,9 +423,6 @@ static snd_pcm_uframes_t pcm_pointer(struct snd_pcm_substream *substream)
static const struct snd_pcm_ops pcm_ops = {
.open = pcm_open,
.close = pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = pcm_hw_params,
- .hw_free = pcm_hw_free,
.prepare = pcm_prepare,
.trigger = pcm_trigger,
.pointer = pcm_pointer,
@@ -661,8 +619,7 @@ skip_adpt_alloc:
pcm->private_data = channel;
strscpy(pcm->name, device_name, sizeof(pcm->name));
snd_pcm_set_ops(pcm, direction, &pcm_ops);
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_VMALLOC,
- NULL, 0, 0);
+ snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_VMALLOC, NULL, 0, 0);
return 0;
@@ -779,9 +736,9 @@ static int audio_tx_completion(struct most_interface *iface, int channel_id)
}
/**
- * Initialization of the struct core_component
+ * Initialization of the struct most_component
*/
-static struct core_component comp = {
+static struct most_component comp = {
.mod = THIS_MODULE,
.name = DRIVER_NAME,
.probe_channel = audio_probe_channel,
diff --git a/drivers/staging/most/usb/usb.c b/drivers/staging/most/usb/usb.c
index 360cb5b7a10b..491b38e91e9d 100644
--- a/drivers/staging/most/usb/usb.c
+++ b/drivers/staging/most/usb/usb.c
@@ -23,7 +23,7 @@
#include <linux/dma-mapping.h>
#include <linux/etherdevice.h>
#include <linux/uaccess.h>
-#include "most/core.h"
+#include <most/most.h>
#define USB_MTU 512
#define NO_ISOCHRONOUS_URB 0
diff --git a/drivers/staging/most/video/video.c b/drivers/staging/most/video/video.c
index 10c1ef7e3a3e..9e9e45ac386e 100644
--- a/drivers/staging/most/video/video.c
+++ b/drivers/staging/most/video/video.c
@@ -21,11 +21,11 @@
#include <media/v4l2-ctrls.h>
#include <media/v4l2-fh.h>
-#include "most/core.h"
+#include <most/most.h>
#define V4L2_CMP_MAX_INPUT 1
-static struct core_component comp;
+static struct most_component comp;
struct most_video_dev {
struct most_interface *iface;
@@ -527,7 +527,7 @@ static int comp_disconnect_channel(struct most_interface *iface,
return 0;
}
-static struct core_component comp = {
+static struct most_component comp = {
.mod = THIS_MODULE,
.name = "video",
.probe_channel = comp_probe_channel,
diff --git a/drivers/staging/octeon-usb/Kconfig b/drivers/staging/octeon-usb/Kconfig
deleted file mode 100644
index 6a5d842ee0f2..000000000000
--- a/drivers/staging/octeon-usb/Kconfig
+++ /dev/null
@@ -1,11 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-config OCTEON_USB
- tristate "Cavium Networks Octeon USB support"
- depends on CAVIUM_OCTEON_SOC && USB
- help
- This driver supports USB host controller on some Cavium
- Networks' products in the Octeon family.
-
- To compile this driver as a module, choose M here. The module
- will be called octeon-hcd.
-
diff --git a/drivers/staging/octeon-usb/Makefile b/drivers/staging/octeon-usb/Makefile
deleted file mode 100644
index 9873a0130ad5..000000000000
--- a/drivers/staging/octeon-usb/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-obj-${CONFIG_OCTEON_USB} := octeon-hcd.o
diff --git a/drivers/staging/octeon-usb/TODO b/drivers/staging/octeon-usb/TODO
deleted file mode 100644
index 2b29acca5caa..000000000000
--- a/drivers/staging/octeon-usb/TODO
+++ /dev/null
@@ -1,8 +0,0 @@
-This driver is functional and has been tested on EdgeRouter Lite,
-D-Link DSR-1000N and EBH5600 evaluation board with USB mass storage.
-
-TODO:
- - kernel coding style
- - checkpatch warnings
-
-Contact: Aaro Koskinen <aaro.koskinen@iki.fi>
diff --git a/drivers/staging/octeon-usb/octeon-hcd.c b/drivers/staging/octeon-usb/octeon-hcd.c
deleted file mode 100644
index 582c9187559d..000000000000
--- a/drivers/staging/octeon-usb/octeon-hcd.c
+++ /dev/null
@@ -1,3737 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2008 Cavium Networks
- *
- * Some parts of the code were originally released under BSD license:
- *
- * Copyright (c) 2003-2010 Cavium Networks (support@cavium.com). All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * * Neither the name of Cavium Networks nor the names of
- * its contributors may be used to endorse or promote products
- * derived from this software without specific prior written
- * permission.
- *
- * This Software, including technical data, may be subject to U.S. export
- * control laws, including the U.S. Export Administration Act and its associated
- * regulations, and may be subject to export or import regulations in other
- * countries.
- *
- * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
- * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS OR
- * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
- * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION
- * OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
- * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
- * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
- * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
- * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR
- * PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
- */
-
-#include <linux/usb.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/usb/hcd.h>
-#include <linux/prefetch.h>
-#include <linux/dma-mapping.h>
-#include <linux/platform_device.h>
-
-#include <asm/octeon/octeon.h>
-
-#include "octeon-hcd.h"
-
-/**
- * enum cvmx_usb_speed - the possible USB device speeds
- *
- * @CVMX_USB_SPEED_HIGH: Device is operation at 480Mbps
- * @CVMX_USB_SPEED_FULL: Device is operation at 12Mbps
- * @CVMX_USB_SPEED_LOW: Device is operation at 1.5Mbps
- */
-enum cvmx_usb_speed {
- CVMX_USB_SPEED_HIGH = 0,
- CVMX_USB_SPEED_FULL = 1,
- CVMX_USB_SPEED_LOW = 2,
-};
-
-/**
- * enum cvmx_usb_transfer - the possible USB transfer types
- *
- * @CVMX_USB_TRANSFER_CONTROL: USB transfer type control for hub and status
- * transfers
- * @CVMX_USB_TRANSFER_ISOCHRONOUS: USB transfer type isochronous for low
- * priority periodic transfers
- * @CVMX_USB_TRANSFER_BULK: USB transfer type bulk for large low priority
- * transfers
- * @CVMX_USB_TRANSFER_INTERRUPT: USB transfer type interrupt for high priority
- * periodic transfers
- */
-enum cvmx_usb_transfer {
- CVMX_USB_TRANSFER_CONTROL = 0,
- CVMX_USB_TRANSFER_ISOCHRONOUS = 1,
- CVMX_USB_TRANSFER_BULK = 2,
- CVMX_USB_TRANSFER_INTERRUPT = 3,
-};
-
-/**
- * enum cvmx_usb_direction - the transfer directions
- *
- * @CVMX_USB_DIRECTION_OUT: Data is transferring from Octeon to the device/host
- * @CVMX_USB_DIRECTION_IN: Data is transferring from the device/host to Octeon
- */
-enum cvmx_usb_direction {
- CVMX_USB_DIRECTION_OUT,
- CVMX_USB_DIRECTION_IN,
-};
-
-/**
- * enum cvmx_usb_status - possible callback function status codes
- *
- * @CVMX_USB_STATUS_OK: The transaction / operation finished without
- * any errors
- * @CVMX_USB_STATUS_SHORT: FIXME: This is currently not implemented
- * @CVMX_USB_STATUS_CANCEL: The transaction was canceled while in flight
- * by a user call to cvmx_usb_cancel
- * @CVMX_USB_STATUS_ERROR: The transaction aborted with an unexpected
- * error status
- * @CVMX_USB_STATUS_STALL: The transaction received a USB STALL response
- * from the device
- * @CVMX_USB_STATUS_XACTERR: The transaction failed with an error from the
- * device even after a number of retries
- * @CVMX_USB_STATUS_DATATGLERR: The transaction failed with a data toggle
- * error even after a number of retries
- * @CVMX_USB_STATUS_BABBLEERR: The transaction failed with a babble error
- * @CVMX_USB_STATUS_FRAMEERR: The transaction failed with a frame error
- * even after a number of retries
- */
-enum cvmx_usb_status {
- CVMX_USB_STATUS_OK,
- CVMX_USB_STATUS_SHORT,
- CVMX_USB_STATUS_CANCEL,
- CVMX_USB_STATUS_ERROR,
- CVMX_USB_STATUS_STALL,
- CVMX_USB_STATUS_XACTERR,
- CVMX_USB_STATUS_DATATGLERR,
- CVMX_USB_STATUS_BABBLEERR,
- CVMX_USB_STATUS_FRAMEERR,
-};
-
-/**
- * struct cvmx_usb_port_status - the USB port status information
- *
- * @port_enabled: 1 = Usb port is enabled, 0 = disabled
- * @port_over_current: 1 = Over current detected, 0 = Over current not
- * detected. Octeon doesn't support over current detection.
- * @port_powered: 1 = Port power is being supplied to the device, 0 =
- * power is off. Octeon doesn't support turning port power
- * off.
- * @port_speed: Current port speed.
- * @connected: 1 = A device is connected to the port, 0 = No device is
- * connected.
- * @connect_change: 1 = Device connected state changed since the last set
- * status call.
- */
-struct cvmx_usb_port_status {
- u32 reserved : 25;
- u32 port_enabled : 1;
- u32 port_over_current : 1;
- u32 port_powered : 1;
- enum cvmx_usb_speed port_speed : 2;
- u32 connected : 1;
- u32 connect_change : 1;
-};
-
-/**
- * struct cvmx_usb_iso_packet - descriptor for Isochronous packets
- *
- * @offset: This is the offset in bytes into the main buffer where this data
- * is stored.
- * @length: This is the length in bytes of the data.
- * @status: This is the status of this individual packet transfer.
- */
-struct cvmx_usb_iso_packet {
- int offset;
- int length;
- enum cvmx_usb_status status;
-};
-
-/**
- * enum cvmx_usb_initialize_flags - flags used by the initialization function
- *
- * @CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_XI: The USB port uses a 12MHz crystal
- * as clock source at USB_XO and
- * USB_XI.
- * @CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND: The USB port uses 12/24/48MHz 2.5V
- * board clock source at USB_XO.
- * USB_XI should be tied to GND.
- * @CVMX_USB_INITIALIZE_FLAGS_CLOCK_MHZ_MASK: Mask for clock speed field
- * @CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ: Speed of reference clock or
- * crystal
- * @CVMX_USB_INITIALIZE_FLAGS_CLOCK_24MHZ: Speed of reference clock
- * @CVMX_USB_INITIALIZE_FLAGS_CLOCK_48MHZ: Speed of reference clock
- * @CVMX_USB_INITIALIZE_FLAGS_NO_DMA: Disable DMA and used polled IO for
- * data transfer use for the USB
- */
-enum cvmx_usb_initialize_flags {
- CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_XI = 1 << 0,
- CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND = 1 << 1,
- CVMX_USB_INITIALIZE_FLAGS_CLOCK_MHZ_MASK = 3 << 3,
- CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ = 1 << 3,
- CVMX_USB_INITIALIZE_FLAGS_CLOCK_24MHZ = 2 << 3,
- CVMX_USB_INITIALIZE_FLAGS_CLOCK_48MHZ = 3 << 3,
- /* Bits 3-4 used to encode the clock frequency */
- CVMX_USB_INITIALIZE_FLAGS_NO_DMA = 1 << 5,
-};
-
-/**
- * enum cvmx_usb_pipe_flags - internal flags for a pipe.
- *
- * @CVMX_USB_PIPE_FLAGS_SCHEDULED: Used internally to determine if a pipe is
- * actively using hardware.
- * @CVMX_USB_PIPE_FLAGS_NEED_PING: Used internally to determine if a high speed
- * pipe is in the ping state.
- */
-enum cvmx_usb_pipe_flags {
- CVMX_USB_PIPE_FLAGS_SCHEDULED = 1 << 17,
- CVMX_USB_PIPE_FLAGS_NEED_PING = 1 << 18,
-};
-
-/* Maximum number of times to retry failed transactions */
-#define MAX_RETRIES 3
-
-/* Maximum number of hardware channels supported by the USB block */
-#define MAX_CHANNELS 8
-
-/*
- * The low level hardware can transfer a maximum of this number of bytes in each
- * transfer. The field is 19 bits wide
- */
-#define MAX_TRANSFER_BYTES ((1 << 19) - 1)
-
-/*
- * The low level hardware can transfer a maximum of this number of packets in
- * each transfer. The field is 10 bits wide
- */
-#define MAX_TRANSFER_PACKETS ((1 << 10) - 1)
-
-/**
- * Logical transactions may take numerous low level
- * transactions, especially when splits are concerned. This
- * enum represents all of the possible stages a transaction can
- * be in. Note that split completes are always even. This is so
- * the NAK handler can backup to the previous low level
- * transaction with a simple clearing of bit 0.
- */
-enum cvmx_usb_stage {
- CVMX_USB_STAGE_NON_CONTROL,
- CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE,
- CVMX_USB_STAGE_SETUP,
- CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE,
- CVMX_USB_STAGE_DATA,
- CVMX_USB_STAGE_DATA_SPLIT_COMPLETE,
- CVMX_USB_STAGE_STATUS,
- CVMX_USB_STAGE_STATUS_SPLIT_COMPLETE,
-};
-
-/**
- * struct cvmx_usb_transaction - describes each pending USB transaction
- * regardless of type. These are linked together
- * to form a list of pending requests for a pipe.
- *
- * @node: List node for transactions in the pipe.
- * @type: Type of transaction, duplicated of the pipe.
- * @flags: State flags for this transaction.
- * @buffer: User's physical buffer address to read/write.
- * @buffer_length: Size of the user's buffer in bytes.
- * @control_header: For control transactions, physical address of the 8
- * byte standard header.
- * @iso_start_frame: For ISO transactions, the starting frame number.
- * @iso_number_packets: For ISO transactions, the number of packets in the
- * request.
- * @iso_packets: For ISO transactions, the sub packets in the request.
- * @actual_bytes: Actual bytes transfer for this transaction.
- * @stage: For control transactions, the current stage.
- * @urb: URB.
- */
-struct cvmx_usb_transaction {
- struct list_head node;
- enum cvmx_usb_transfer type;
- u64 buffer;
- int buffer_length;
- u64 control_header;
- int iso_start_frame;
- int iso_number_packets;
- struct cvmx_usb_iso_packet *iso_packets;
- int xfersize;
- int pktcnt;
- int retries;
- int actual_bytes;
- enum cvmx_usb_stage stage;
- struct urb *urb;
-};
-
-/**
- * struct cvmx_usb_pipe - a pipe represents a virtual connection between Octeon
- * and some USB device. It contains a list of pending
- * request to the device.
- *
- * @node: List node for pipe list
- * @next: Pipe after this one in the list
- * @transactions: List of pending transactions
- * @interval: For periodic pipes, the interval between packets in
- * frames
- * @next_tx_frame: The next frame this pipe is allowed to transmit on
- * @flags: State flags for this pipe
- * @device_speed: Speed of device connected to this pipe
- * @transfer_type: Type of transaction supported by this pipe
- * @transfer_dir: IN or OUT. Ignored for Control
- * @multi_count: Max packet in a row for the device
- * @max_packet: The device's maximum packet size in bytes
- * @device_addr: USB device address at other end of pipe
- * @endpoint_num: USB endpoint number at other end of pipe
- * @hub_device_addr: Hub address this device is connected to
- * @hub_port: Hub port this device is connected to
- * @pid_toggle: This toggles between 0/1 on every packet send to track
- * the data pid needed
- * @channel: Hardware DMA channel for this pipe
- * @split_sc_frame: The low order bits of the frame number the split
- * complete should be sent on
- */
-struct cvmx_usb_pipe {
- struct list_head node;
- struct list_head transactions;
- u64 interval;
- u64 next_tx_frame;
- enum cvmx_usb_pipe_flags flags;
- enum cvmx_usb_speed device_speed;
- enum cvmx_usb_transfer transfer_type;
- enum cvmx_usb_direction transfer_dir;
- int multi_count;
- u16 max_packet;
- u8 device_addr;
- u8 endpoint_num;
- u8 hub_device_addr;
- u8 hub_port;
- u8 pid_toggle;
- u8 channel;
- s8 split_sc_frame;
-};
-
-struct cvmx_usb_tx_fifo {
- struct {
- int channel;
- int size;
- u64 address;
- } entry[MAX_CHANNELS + 1];
- int head;
- int tail;
-};
-
-/**
- * struct octeon_hcd - the state of the USB block
- *
- * lock: Serialization lock.
- * init_flags: Flags passed to initialize.
- * index: Which USB block this is for.
- * idle_hardware_channels: Bit set for every idle hardware channel.
- * usbcx_hprt: Stored port status so we don't need to read a CSR to
- * determine splits.
- * pipe_for_channel: Map channels to pipes.
- * pipe: Storage for pipes.
- * indent: Used by debug output to indent functions.
- * port_status: Last port status used for change notification.
- * idle_pipes: List of open pipes that have no transactions.
- * active_pipes: Active pipes indexed by transfer type.
- * frame_number: Increments every SOF interrupt for time keeping.
- * active_split: Points to the current active split, or NULL.
- */
-struct octeon_hcd {
- spinlock_t lock; /* serialization lock */
- int init_flags;
- int index;
- int idle_hardware_channels;
- union cvmx_usbcx_hprt usbcx_hprt;
- struct cvmx_usb_pipe *pipe_for_channel[MAX_CHANNELS];
- int indent;
- struct cvmx_usb_port_status port_status;
- struct list_head idle_pipes;
- struct list_head active_pipes[4];
- u64 frame_number;
- struct cvmx_usb_transaction *active_split;
- struct cvmx_usb_tx_fifo periodic;
- struct cvmx_usb_tx_fifo nonperiodic;
-};
-
-/*
- * This macro logically sets a single field in a CSR. It does the sequence
- * read, modify, and write
- */
-#define USB_SET_FIELD32(address, _union, field, value) \
- do { \
- union _union c; \
- \
- c.u32 = cvmx_usb_read_csr32(usb, address); \
- c.s.field = value; \
- cvmx_usb_write_csr32(usb, address, c.u32); \
- } while (0)
-
-/* Returns the IO address to push/pop stuff data from the FIFOs */
-#define USB_FIFO_ADDRESS(channel, usb_index) \
- (CVMX_USBCX_GOTGCTL(usb_index) + ((channel) + 1) * 0x1000)
-
-/**
- * struct octeon_temp_buffer - a bounce buffer for USB transfers
- * @orig_buffer: the original buffer passed by the USB stack
- * @data: the newly allocated temporary buffer (excluding meta-data)
- *
- * Both the DMA engine and FIFO mode will always transfer full 32-bit words. If
- * the buffer is too short, we need to allocate a temporary one, and this struct
- * represents it.
- */
-struct octeon_temp_buffer {
- void *orig_buffer;
- u8 data[0];
-};
-
-static inline struct usb_hcd *octeon_to_hcd(struct octeon_hcd *p)
-{
- return container_of((void *)p, struct usb_hcd, hcd_priv);
-}
-
-/**
- * octeon_alloc_temp_buffer - allocate a temporary buffer for USB transfer
- * (if needed)
- * @urb: URB.
- * @mem_flags: Memory allocation flags.
- *
- * This function allocates a temporary bounce buffer whenever it's needed
- * due to HW limitations.
- */
-static int octeon_alloc_temp_buffer(struct urb *urb, gfp_t mem_flags)
-{
- struct octeon_temp_buffer *temp;
-
- if (urb->num_sgs || urb->sg ||
- (urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP) ||
- !(urb->transfer_buffer_length % sizeof(u32)))
- return 0;
-
- temp = kmalloc(ALIGN(urb->transfer_buffer_length, sizeof(u32)) +
- sizeof(*temp), mem_flags);
- if (!temp)
- return -ENOMEM;
-
- temp->orig_buffer = urb->transfer_buffer;
- if (usb_urb_dir_out(urb))
- memcpy(temp->data, urb->transfer_buffer,
- urb->transfer_buffer_length);
- urb->transfer_buffer = temp->data;
- urb->transfer_flags |= URB_ALIGNED_TEMP_BUFFER;
-
- return 0;
-}
-
-/**
- * octeon_free_temp_buffer - free a temporary buffer used by USB transfers.
- * @urb: URB.
- *
- * Frees a buffer allocated by octeon_alloc_temp_buffer().
- */
-static void octeon_free_temp_buffer(struct urb *urb)
-{
- struct octeon_temp_buffer *temp;
- size_t length;
-
- if (!(urb->transfer_flags & URB_ALIGNED_TEMP_BUFFER))
- return;
-
- temp = container_of(urb->transfer_buffer, struct octeon_temp_buffer,
- data);
- if (usb_urb_dir_in(urb)) {
- if (usb_pipeisoc(urb->pipe))
- length = urb->transfer_buffer_length;
- else
- length = urb->actual_length;
-
- memcpy(temp->orig_buffer, urb->transfer_buffer, length);
- }
- urb->transfer_buffer = temp->orig_buffer;
- urb->transfer_flags &= ~URB_ALIGNED_TEMP_BUFFER;
- kfree(temp);
-}
-
-/**
- * octeon_map_urb_for_dma - Octeon-specific map_urb_for_dma().
- * @hcd: USB HCD structure.
- * @urb: URB.
- * @mem_flags: Memory allocation flags.
- */
-static int octeon_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
- gfp_t mem_flags)
-{
- int ret;
-
- ret = octeon_alloc_temp_buffer(urb, mem_flags);
- if (ret)
- return ret;
-
- ret = usb_hcd_map_urb_for_dma(hcd, urb, mem_flags);
- if (ret)
- octeon_free_temp_buffer(urb);
-
- return ret;
-}
-
-/**
- * octeon_unmap_urb_for_dma - Octeon-specific unmap_urb_for_dma()
- * @hcd: USB HCD structure.
- * @urb: URB.
- */
-static void octeon_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
-{
- usb_hcd_unmap_urb_for_dma(hcd, urb);
- octeon_free_temp_buffer(urb);
-}
-
-/**
- * Read a USB 32bit CSR. It performs the necessary address swizzle
- * for 32bit CSRs and logs the value in a readable format if
- * debugging is on.
- *
- * @usb: USB block this access is for
- * @address: 64bit address to read
- *
- * Returns: Result of the read
- */
-static inline u32 cvmx_usb_read_csr32(struct octeon_hcd *usb, u64 address)
-{
- return cvmx_read64_uint32(address ^ 4);
-}
-
-/**
- * Write a USB 32bit CSR. It performs the necessary address
- * swizzle for 32bit CSRs and logs the value in a readable format
- * if debugging is on.
- *
- * @usb: USB block this access is for
- * @address: 64bit address to write
- * @value: Value to write
- */
-static inline void cvmx_usb_write_csr32(struct octeon_hcd *usb,
- u64 address, u32 value)
-{
- cvmx_write64_uint32(address ^ 4, value);
- cvmx_read64_uint64(CVMX_USBNX_DMA0_INB_CHN0(usb->index));
-}
-
-/**
- * Return non zero if this pipe connects to a non HIGH speed
- * device through a high speed hub.
- *
- * @usb: USB block this access is for
- * @pipe: Pipe to check
- *
- * Returns: Non zero if we need to do split transactions
- */
-static inline int cvmx_usb_pipe_needs_split(struct octeon_hcd *usb,
- struct cvmx_usb_pipe *pipe)
-{
- return pipe->device_speed != CVMX_USB_SPEED_HIGH &&
- usb->usbcx_hprt.s.prtspd == CVMX_USB_SPEED_HIGH;
-}
-
-/**
- * Trivial utility function to return the correct PID for a pipe
- *
- * @pipe: pipe to check
- *
- * Returns: PID for pipe
- */
-static inline int cvmx_usb_get_data_pid(struct cvmx_usb_pipe *pipe)
-{
- if (pipe->pid_toggle)
- return 2; /* Data1 */
- return 0; /* Data0 */
-}
-
-/* Loops through register until txfflsh or rxfflsh become zero.*/
-static int cvmx_wait_tx_rx(struct octeon_hcd *usb, int fflsh_type)
-{
- int result;
- u64 address = CVMX_USBCX_GRSTCTL(usb->index);
- u64 done = cvmx_get_cycle() + 100 *
- (u64)octeon_get_clock_rate / 1000000;
- union cvmx_usbcx_grstctl c;
-
- while (1) {
- c.u32 = cvmx_usb_read_csr32(usb, address);
- if (fflsh_type == 0 && c.s.txfflsh == 0) {
- result = 0;
- break;
- } else if (fflsh_type == 1 && c.s.rxfflsh == 0) {
- result = 0;
- break;
- } else if (cvmx_get_cycle() > done) {
- result = -1;
- break;
- }
-
- __delay(100);
- }
- return result;
-}
-
-static void cvmx_fifo_setup(struct octeon_hcd *usb)
-{
- union cvmx_usbcx_ghwcfg3 usbcx_ghwcfg3;
- union cvmx_usbcx_gnptxfsiz npsiz;
- union cvmx_usbcx_hptxfsiz psiz;
-
- usbcx_ghwcfg3.u32 = cvmx_usb_read_csr32(usb,
- CVMX_USBCX_GHWCFG3(usb->index));
-
- /*
- * Program the USBC_GRXFSIZ register to select the size of the receive
- * FIFO (25%).
- */
- USB_SET_FIELD32(CVMX_USBCX_GRXFSIZ(usb->index), cvmx_usbcx_grxfsiz,
- rxfdep, usbcx_ghwcfg3.s.dfifodepth / 4);
-
- /*
- * Program the USBC_GNPTXFSIZ register to select the size and the start
- * address of the non-periodic transmit FIFO for nonperiodic
- * transactions (50%).
- */
- npsiz.u32 = cvmx_usb_read_csr32(usb, CVMX_USBCX_GNPTXFSIZ(usb->index));
- npsiz.s.nptxfdep = usbcx_ghwcfg3.s.dfifodepth / 2;
- npsiz.s.nptxfstaddr = usbcx_ghwcfg3.s.dfifodepth / 4;
- cvmx_usb_write_csr32(usb, CVMX_USBCX_GNPTXFSIZ(usb->index), npsiz.u32);
-
- /*
- * Program the USBC_HPTXFSIZ register to select the size and start
- * address of the periodic transmit FIFO for periodic transactions
- * (25%).
- */
- psiz.u32 = cvmx_usb_read_csr32(usb, CVMX_USBCX_HPTXFSIZ(usb->index));
- psiz.s.ptxfsize = usbcx_ghwcfg3.s.dfifodepth / 4;
- psiz.s.ptxfstaddr = 3 * usbcx_ghwcfg3.s.dfifodepth / 4;
- cvmx_usb_write_csr32(usb, CVMX_USBCX_HPTXFSIZ(usb->index), psiz.u32);
-
- /* Flush all FIFOs */
- USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index),
- cvmx_usbcx_grstctl, txfnum, 0x10);
- USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index),
- cvmx_usbcx_grstctl, txfflsh, 1);
- cvmx_wait_tx_rx(usb, 0);
- USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index),
- cvmx_usbcx_grstctl, rxfflsh, 1);
- cvmx_wait_tx_rx(usb, 1);
-}
-
-/**
- * Shutdown a USB port after a call to cvmx_usb_initialize().
- * The port should be disabled with all pipes closed when this
- * function is called.
- *
- * @usb: USB device state populated by cvmx_usb_initialize().
- *
- * Returns: 0 or a negative error code.
- */
-static int cvmx_usb_shutdown(struct octeon_hcd *usb)
-{
- union cvmx_usbnx_clk_ctl usbn_clk_ctl;
-
- /* Make sure all pipes are closed */
- if (!list_empty(&usb->idle_pipes) ||
- !list_empty(&usb->active_pipes[CVMX_USB_TRANSFER_ISOCHRONOUS]) ||
- !list_empty(&usb->active_pipes[CVMX_USB_TRANSFER_INTERRUPT]) ||
- !list_empty(&usb->active_pipes[CVMX_USB_TRANSFER_CONTROL]) ||
- !list_empty(&usb->active_pipes[CVMX_USB_TRANSFER_BULK]))
- return -EBUSY;
-
- /* Disable the clocks and put them in power on reset */
- usbn_clk_ctl.u64 = cvmx_read64_uint64(CVMX_USBNX_CLK_CTL(usb->index));
- usbn_clk_ctl.s.enable = 1;
- usbn_clk_ctl.s.por = 1;
- usbn_clk_ctl.s.hclk_rst = 1;
- usbn_clk_ctl.s.prst = 0;
- usbn_clk_ctl.s.hrst = 0;
- cvmx_write64_uint64(CVMX_USBNX_CLK_CTL(usb->index), usbn_clk_ctl.u64);
- return 0;
-}
-
-/**
- * Initialize a USB port for use. This must be called before any
- * other access to the Octeon USB port is made. The port starts
- * off in the disabled state.
- *
- * @dev: Pointer to struct device for logging purposes.
- * @usb: Pointer to struct octeon_hcd.
- *
- * Returns: 0 or a negative error code.
- */
-static int cvmx_usb_initialize(struct device *dev,
- struct octeon_hcd *usb)
-{
- int channel;
- int divisor;
- int retries = 0;
- union cvmx_usbcx_hcfg usbcx_hcfg;
- union cvmx_usbnx_clk_ctl usbn_clk_ctl;
- union cvmx_usbcx_gintsts usbc_gintsts;
- union cvmx_usbcx_gahbcfg usbcx_gahbcfg;
- union cvmx_usbcx_gintmsk usbcx_gintmsk;
- union cvmx_usbcx_gusbcfg usbcx_gusbcfg;
- union cvmx_usbnx_usbp_ctl_status usbn_usbp_ctl_status;
-
-retry:
- /*
- * Power On Reset and PHY Initialization
- *
- * 1. Wait for DCOK to assert (nothing to do)
- *
- * 2a. Write USBN0/1_CLK_CTL[POR] = 1 and
- * USBN0/1_CLK_CTL[HRST,PRST,HCLK_RST] = 0
- */
- usbn_clk_ctl.u64 = cvmx_read64_uint64(CVMX_USBNX_CLK_CTL(usb->index));
- usbn_clk_ctl.s.por = 1;
- usbn_clk_ctl.s.hrst = 0;
- usbn_clk_ctl.s.prst = 0;
- usbn_clk_ctl.s.hclk_rst = 0;
- usbn_clk_ctl.s.enable = 0;
- /*
- * 2b. Select the USB reference clock/crystal parameters by writing
- * appropriate values to USBN0/1_CLK_CTL[P_C_SEL, P_RTYPE, P_COM_ON]
- */
- if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND) {
- /*
- * The USB port uses 12/24/48MHz 2.5V board clock
- * source at USB_XO. USB_XI should be tied to GND.
- * Most Octeon evaluation boards require this setting
- */
- if (OCTEON_IS_MODEL(OCTEON_CN3XXX) ||
- OCTEON_IS_MODEL(OCTEON_CN56XX) ||
- OCTEON_IS_MODEL(OCTEON_CN50XX))
- /* From CN56XX,CN50XX,CN31XX,CN30XX manuals */
- usbn_clk_ctl.s.p_rtype = 2; /* p_rclk=1 & p_xenbn=0 */
- else
- /* From CN52XX manual */
- usbn_clk_ctl.s.p_rtype = 1;
-
- switch (usb->init_flags &
- CVMX_USB_INITIALIZE_FLAGS_CLOCK_MHZ_MASK) {
- case CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ:
- usbn_clk_ctl.s.p_c_sel = 0;
- break;
- case CVMX_USB_INITIALIZE_FLAGS_CLOCK_24MHZ:
- usbn_clk_ctl.s.p_c_sel = 1;
- break;
- case CVMX_USB_INITIALIZE_FLAGS_CLOCK_48MHZ:
- usbn_clk_ctl.s.p_c_sel = 2;
- break;
- }
- } else {
- /*
- * The USB port uses a 12MHz crystal as clock source
- * at USB_XO and USB_XI
- */
- if (OCTEON_IS_MODEL(OCTEON_CN3XXX))
- /* From CN31XX,CN30XX manual */
- usbn_clk_ctl.s.p_rtype = 3; /* p_rclk=1 & p_xenbn=1 */
- else
- /* From CN56XX,CN52XX,CN50XX manuals. */
- usbn_clk_ctl.s.p_rtype = 0;
-
- usbn_clk_ctl.s.p_c_sel = 0;
- }
- /*
- * 2c. Select the HCLK via writing USBN0/1_CLK_CTL[DIVIDE, DIVIDE2] and
- * setting USBN0/1_CLK_CTL[ENABLE] = 1. Divide the core clock down
- * such that USB is as close as possible to 125Mhz
- */
- divisor = DIV_ROUND_UP(octeon_get_clock_rate(), 125000000);
- /* Lower than 4 doesn't seem to work properly */
- if (divisor < 4)
- divisor = 4;
- usbn_clk_ctl.s.divide = divisor;
- usbn_clk_ctl.s.divide2 = 0;
- cvmx_write64_uint64(CVMX_USBNX_CLK_CTL(usb->index), usbn_clk_ctl.u64);
-
- /* 2d. Write USBN0/1_CLK_CTL[HCLK_RST] = 1 */
- usbn_clk_ctl.s.hclk_rst = 1;
- cvmx_write64_uint64(CVMX_USBNX_CLK_CTL(usb->index), usbn_clk_ctl.u64);
- /* 2e. Wait 64 core-clock cycles for HCLK to stabilize */
- __delay(64);
- /*
- * 3. Program the power-on reset field in the USBN clock-control
- * register:
- * USBN_CLK_CTL[POR] = 0
- */
- usbn_clk_ctl.s.por = 0;
- cvmx_write64_uint64(CVMX_USBNX_CLK_CTL(usb->index), usbn_clk_ctl.u64);
- /* 4. Wait 1 ms for PHY clock to start */
- mdelay(1);
- /*
- * 5. Program the Reset input from automatic test equipment field in the
- * USBP control and status register:
- * USBN_USBP_CTL_STATUS[ATE_RESET] = 1
- */
- usbn_usbp_ctl_status.u64 =
- cvmx_read64_uint64(CVMX_USBNX_USBP_CTL_STATUS(usb->index));
- usbn_usbp_ctl_status.s.ate_reset = 1;
- cvmx_write64_uint64(CVMX_USBNX_USBP_CTL_STATUS(usb->index),
- usbn_usbp_ctl_status.u64);
- /* 6. Wait 10 cycles */
- __delay(10);
- /*
- * 7. Clear ATE_RESET field in the USBN clock-control register:
- * USBN_USBP_CTL_STATUS[ATE_RESET] = 0
- */
- usbn_usbp_ctl_status.s.ate_reset = 0;
- cvmx_write64_uint64(CVMX_USBNX_USBP_CTL_STATUS(usb->index),
- usbn_usbp_ctl_status.u64);
- /*
- * 8. Program the PHY reset field in the USBN clock-control register:
- * USBN_CLK_CTL[PRST] = 1
- */
- usbn_clk_ctl.s.prst = 1;
- cvmx_write64_uint64(CVMX_USBNX_CLK_CTL(usb->index), usbn_clk_ctl.u64);
- /*
- * 9. Program the USBP control and status register to select host or
- * device mode. USBN_USBP_CTL_STATUS[HST_MODE] = 0 for host, = 1 for
- * device
- */
- usbn_usbp_ctl_status.s.hst_mode = 0;
- cvmx_write64_uint64(CVMX_USBNX_USBP_CTL_STATUS(usb->index),
- usbn_usbp_ctl_status.u64);
- /* 10. Wait 1 us */
- udelay(1);
- /*
- * 11. Program the hreset_n field in the USBN clock-control register:
- * USBN_CLK_CTL[HRST] = 1
- */
- usbn_clk_ctl.s.hrst = 1;
- cvmx_write64_uint64(CVMX_USBNX_CLK_CTL(usb->index), usbn_clk_ctl.u64);
- /* 12. Proceed to USB core initialization */
- usbn_clk_ctl.s.enable = 1;
- cvmx_write64_uint64(CVMX_USBNX_CLK_CTL(usb->index), usbn_clk_ctl.u64);
- udelay(1);
-
- /*
- * USB Core Initialization
- *
- * 1. Read USBC_GHWCFG1, USBC_GHWCFG2, USBC_GHWCFG3, USBC_GHWCFG4 to
- * determine USB core configuration parameters.
- *
- * Nothing needed
- *
- * 2. Program the following fields in the global AHB configuration
- * register (USBC_GAHBCFG)
- * DMA mode, USBC_GAHBCFG[DMAEn]: 1 = DMA mode, 0 = slave mode
- * Burst length, USBC_GAHBCFG[HBSTLEN] = 0
- * Nonperiodic TxFIFO empty level (slave mode only),
- * USBC_GAHBCFG[NPTXFEMPLVL]
- * Periodic TxFIFO empty level (slave mode only),
- * USBC_GAHBCFG[PTXFEMPLVL]
- * Global interrupt mask, USBC_GAHBCFG[GLBLINTRMSK] = 1
- */
- usbcx_gahbcfg.u32 = 0;
- usbcx_gahbcfg.s.dmaen = !(usb->init_flags &
- CVMX_USB_INITIALIZE_FLAGS_NO_DMA);
- usbcx_gahbcfg.s.hbstlen = 0;
- usbcx_gahbcfg.s.nptxfemplvl = 1;
- usbcx_gahbcfg.s.ptxfemplvl = 1;
- usbcx_gahbcfg.s.glblintrmsk = 1;
- cvmx_usb_write_csr32(usb, CVMX_USBCX_GAHBCFG(usb->index),
- usbcx_gahbcfg.u32);
-
- /*
- * 3. Program the following fields in USBC_GUSBCFG register.
- * HS/FS timeout calibration, USBC_GUSBCFG[TOUTCAL] = 0
- * ULPI DDR select, USBC_GUSBCFG[DDRSEL] = 0
- * USB turnaround time, USBC_GUSBCFG[USBTRDTIM] = 0x5
- * PHY low-power clock select, USBC_GUSBCFG[PHYLPWRCLKSEL] = 0
- */
- usbcx_gusbcfg.u32 = cvmx_usb_read_csr32(usb,
- CVMX_USBCX_GUSBCFG(usb->index));
- usbcx_gusbcfg.s.toutcal = 0;
- usbcx_gusbcfg.s.ddrsel = 0;
- usbcx_gusbcfg.s.usbtrdtim = 0x5;
- usbcx_gusbcfg.s.phylpwrclksel = 0;
- cvmx_usb_write_csr32(usb, CVMX_USBCX_GUSBCFG(usb->index),
- usbcx_gusbcfg.u32);
-
- /*
- * 4. The software must unmask the following bits in the USBC_GINTMSK
- * register.
- * OTG interrupt mask, USBC_GINTMSK[OTGINTMSK] = 1
- * Mode mismatch interrupt mask, USBC_GINTMSK[MODEMISMSK] = 1
- */
- usbcx_gintmsk.u32 = cvmx_usb_read_csr32(usb,
- CVMX_USBCX_GINTMSK(usb->index));
- usbcx_gintmsk.s.otgintmsk = 1;
- usbcx_gintmsk.s.modemismsk = 1;
- usbcx_gintmsk.s.hchintmsk = 1;
- usbcx_gintmsk.s.sofmsk = 0;
- /* We need RX FIFO interrupts if we don't have DMA */
- if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
- usbcx_gintmsk.s.rxflvlmsk = 1;
- cvmx_usb_write_csr32(usb, CVMX_USBCX_GINTMSK(usb->index),
- usbcx_gintmsk.u32);
-
- /*
- * Disable all channel interrupts. We'll enable them per channel later.
- */
- for (channel = 0; channel < 8; channel++)
- cvmx_usb_write_csr32(usb,
- CVMX_USBCX_HCINTMSKX(channel, usb->index),
- 0);
-
- /*
- * Host Port Initialization
- *
- * 1. Program the host-port interrupt-mask field to unmask,
- * USBC_GINTMSK[PRTINT] = 1
- */
- USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index),
- cvmx_usbcx_gintmsk, prtintmsk, 1);
- USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index),
- cvmx_usbcx_gintmsk, disconnintmsk, 1);
-
- /*
- * 2. Program the USBC_HCFG register to select full-speed host
- * or high-speed host.
- */
- usbcx_hcfg.u32 = cvmx_usb_read_csr32(usb, CVMX_USBCX_HCFG(usb->index));
- usbcx_hcfg.s.fslssupp = 0;
- usbcx_hcfg.s.fslspclksel = 0;
- cvmx_usb_write_csr32(usb, CVMX_USBCX_HCFG(usb->index), usbcx_hcfg.u32);
-
- cvmx_fifo_setup(usb);
-
- /*
- * If the controller is getting port events right after the reset, it
- * means the initialization failed. Try resetting the controller again
- * in such case. This is seen to happen after cold boot on DSR-1000N.
- */
- usbc_gintsts.u32 = cvmx_usb_read_csr32(usb,
- CVMX_USBCX_GINTSTS(usb->index));
- cvmx_usb_write_csr32(usb, CVMX_USBCX_GINTSTS(usb->index),
- usbc_gintsts.u32);
- dev_dbg(dev, "gintsts after reset: 0x%x\n", (int)usbc_gintsts.u32);
- if (!usbc_gintsts.s.disconnint && !usbc_gintsts.s.prtint)
- return 0;
- if (retries++ >= 5)
- return -EAGAIN;
- dev_info(dev, "controller reset failed (gintsts=0x%x) - retrying\n",
- (int)usbc_gintsts.u32);
- msleep(50);
- cvmx_usb_shutdown(usb);
- msleep(50);
- goto retry;
-}
-
-/**
- * Reset a USB port. After this call succeeds, the USB port is
- * online and servicing requests.
- *
- * @usb: USB device state populated by cvmx_usb_initialize().
- */
-static void cvmx_usb_reset_port(struct octeon_hcd *usb)
-{
- usb->usbcx_hprt.u32 = cvmx_usb_read_csr32(usb,
- CVMX_USBCX_HPRT(usb->index));
-
- /* Program the port reset bit to start the reset process */
- USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), cvmx_usbcx_hprt,
- prtrst, 1);
-
- /*
- * Wait at least 50ms (high speed), or 10ms (full speed) for the reset
- * process to complete.
- */
- mdelay(50);
-
- /* Program the port reset bit to 0, USBC_HPRT[PRTRST] = 0 */
- USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), cvmx_usbcx_hprt,
- prtrst, 0);
-
- /*
- * Read the port speed field to get the enumerated speed,
- * USBC_HPRT[PRTSPD].
- */
- usb->usbcx_hprt.u32 = cvmx_usb_read_csr32(usb,
- CVMX_USBCX_HPRT(usb->index));
-}
-
-/**
- * Disable a USB port. After this call the USB port will not
- * generate data transfers and will not generate events.
- * Transactions in process will fail and call their
- * associated callbacks.
- *
- * @usb: USB device state populated by cvmx_usb_initialize().
- *
- * Returns: 0 or a negative error code.
- */
-static int cvmx_usb_disable(struct octeon_hcd *usb)
-{
- /* Disable the port */
- USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), cvmx_usbcx_hprt,
- prtena, 1);
- return 0;
-}
-
-/**
- * Get the current state of the USB port. Use this call to
- * determine if the usb port has anything connected, is enabled,
- * or has some sort of error condition. The return value of this
- * call has "changed" bits to signal of the value of some fields
- * have changed between calls.
- *
- * @usb: USB device state populated by cvmx_usb_initialize().
- *
- * Returns: Port status information
- */
-static struct cvmx_usb_port_status cvmx_usb_get_status(struct octeon_hcd *usb)
-{
- union cvmx_usbcx_hprt usbc_hprt;
- struct cvmx_usb_port_status result;
-
- memset(&result, 0, sizeof(result));
-
- usbc_hprt.u32 = cvmx_usb_read_csr32(usb, CVMX_USBCX_HPRT(usb->index));
- result.port_enabled = usbc_hprt.s.prtena;
- result.port_over_current = usbc_hprt.s.prtovrcurract;
- result.port_powered = usbc_hprt.s.prtpwr;
- result.port_speed = usbc_hprt.s.prtspd;
- result.connected = usbc_hprt.s.prtconnsts;
- result.connect_change =
- result.connected != usb->port_status.connected;
-
- return result;
-}
-
-/**
- * Open a virtual pipe between the host and a USB device. A pipe
- * must be opened before data can be transferred between a device
- * and Octeon.
- *
- * @usb: USB device state populated by cvmx_usb_initialize().
- * @device_addr:
- * USB device address to open the pipe to
- * (0-127).
- * @endpoint_num:
- * USB endpoint number to open the pipe to
- * (0-15).
- * @device_speed:
- * The speed of the device the pipe is going
- * to. This must match the device's speed,
- * which may be different than the port speed.
- * @max_packet: The maximum packet length the device can
- * transmit/receive (low speed=0-8, full
- * speed=0-1023, high speed=0-1024). This value
- * comes from the standard endpoint descriptor
- * field wMaxPacketSize bits <10:0>.
- * @transfer_type:
- * The type of transfer this pipe is for.
- * @transfer_dir:
- * The direction the pipe is in. This is not
- * used for control pipes.
- * @interval: For ISOCHRONOUS and INTERRUPT transfers,
- * this is how often the transfer is scheduled
- * for. All other transfers should specify
- * zero. The units are in frames (8000/sec at
- * high speed, 1000/sec for full speed).
- * @multi_count:
- * For high speed devices, this is the maximum
- * allowed number of packet per microframe.
- * Specify zero for non high speed devices. This
- * value comes from the standard endpoint descriptor
- * field wMaxPacketSize bits <12:11>.
- * @hub_device_addr:
- * Hub device address this device is connected
- * to. Devices connected directly to Octeon
- * use zero. This is only used when the device
- * is full/low speed behind a high speed hub.
- * The address will be of the high speed hub,
- * not and full speed hubs after it.
- * @hub_port: Which port on the hub the device is
- * connected. Use zero for devices connected
- * directly to Octeon. Like hub_device_addr,
- * this is only used for full/low speed
- * devices behind a high speed hub.
- *
- * Returns: A non-NULL value is a pipe. NULL means an error.
- */
-static struct cvmx_usb_pipe *cvmx_usb_open_pipe(struct octeon_hcd *usb,
- int device_addr,
- int endpoint_num,
- enum cvmx_usb_speed
- device_speed,
- int max_packet,
- enum cvmx_usb_transfer
- transfer_type,
- enum cvmx_usb_direction
- transfer_dir,
- int interval, int multi_count,
- int hub_device_addr,
- int hub_port)
-{
- struct cvmx_usb_pipe *pipe;
-
- pipe = kzalloc(sizeof(*pipe), GFP_ATOMIC);
- if (!pipe)
- return NULL;
- if ((device_speed == CVMX_USB_SPEED_HIGH) &&
- (transfer_dir == CVMX_USB_DIRECTION_OUT) &&
- (transfer_type == CVMX_USB_TRANSFER_BULK))
- pipe->flags |= CVMX_USB_PIPE_FLAGS_NEED_PING;
- pipe->device_addr = device_addr;
- pipe->endpoint_num = endpoint_num;
- pipe->device_speed = device_speed;
- pipe->max_packet = max_packet;
- pipe->transfer_type = transfer_type;
- pipe->transfer_dir = transfer_dir;
- INIT_LIST_HEAD(&pipe->transactions);
-
- /*
- * All pipes use interval to rate limit NAK processing. Force an
- * interval if one wasn't supplied
- */
- if (!interval)
- interval = 1;
- if (cvmx_usb_pipe_needs_split(usb, pipe)) {
- pipe->interval = interval * 8;
- /* Force start splits to be schedule on uFrame 0 */
- pipe->next_tx_frame = ((usb->frame_number + 7) & ~7) +
- pipe->interval;
- } else {
- pipe->interval = interval;
- pipe->next_tx_frame = usb->frame_number + pipe->interval;
- }
- pipe->multi_count = multi_count;
- pipe->hub_device_addr = hub_device_addr;
- pipe->hub_port = hub_port;
- pipe->pid_toggle = 0;
- pipe->split_sc_frame = -1;
- list_add_tail(&pipe->node, &usb->idle_pipes);
-
- /*
- * We don't need to tell the hardware about this pipe yet since
- * it doesn't have any submitted requests
- */
-
- return pipe;
-}
-
-/**
- * Poll the RX FIFOs and remove data as needed. This function is only used
- * in non DMA mode. It is very important that this function be called quickly
- * enough to prevent FIFO overflow.
- *
- * @usb: USB device state populated by cvmx_usb_initialize().
- */
-static void cvmx_usb_poll_rx_fifo(struct octeon_hcd *usb)
-{
- union cvmx_usbcx_grxstsph rx_status;
- int channel;
- int bytes;
- u64 address;
- u32 *ptr;
-
- rx_status.u32 = cvmx_usb_read_csr32(usb,
- CVMX_USBCX_GRXSTSPH(usb->index));
- /* Only read data if IN data is there */
- if (rx_status.s.pktsts != 2)
- return;
- /* Check if no data is available */
- if (!rx_status.s.bcnt)
- return;
-
- channel = rx_status.s.chnum;
- bytes = rx_status.s.bcnt;
- if (!bytes)
- return;
-
- /* Get where the DMA engine would have written this data */
- address = cvmx_read64_uint64(CVMX_USBNX_DMA0_INB_CHN0(usb->index) +
- channel * 8);
-
- ptr = cvmx_phys_to_ptr(address);
- cvmx_write64_uint64(CVMX_USBNX_DMA0_INB_CHN0(usb->index) + channel * 8,
- address + bytes);
-
- /* Loop writing the FIFO data for this packet into memory */
- while (bytes > 0) {
- *ptr++ = cvmx_usb_read_csr32(usb,
- USB_FIFO_ADDRESS(channel, usb->index));
- bytes -= 4;
- }
- CVMX_SYNCW;
-}
-
-/**
- * Fill the TX hardware fifo with data out of the software
- * fifos
- *
- * @usb: USB device state populated by cvmx_usb_initialize().
- * @fifo: Software fifo to use
- * @available: Amount of space in the hardware fifo
- *
- * Returns: Non zero if the hardware fifo was too small and needs
- * to be serviced again.
- */
-static int cvmx_usb_fill_tx_hw(struct octeon_hcd *usb,
- struct cvmx_usb_tx_fifo *fifo, int available)
-{
- /*
- * We're done either when there isn't anymore space or the software FIFO
- * is empty
- */
- while (available && (fifo->head != fifo->tail)) {
- int i = fifo->tail;
- const u32 *ptr = cvmx_phys_to_ptr(fifo->entry[i].address);
- u64 csr_address = USB_FIFO_ADDRESS(fifo->entry[i].channel,
- usb->index) ^ 4;
- int words = available;
-
- /* Limit the amount of data to what the SW fifo has */
- if (fifo->entry[i].size <= available) {
- words = fifo->entry[i].size;
- fifo->tail++;
- if (fifo->tail > MAX_CHANNELS)
- fifo->tail = 0;
- }
-
- /* Update the next locations and counts */
- available -= words;
- fifo->entry[i].address += words * 4;
- fifo->entry[i].size -= words;
-
- /*
- * Write the HW fifo data. The read every three writes is due
- * to an errata on CN3XXX chips
- */
- while (words > 3) {
- cvmx_write64_uint32(csr_address, *ptr++);
- cvmx_write64_uint32(csr_address, *ptr++);
- cvmx_write64_uint32(csr_address, *ptr++);
- cvmx_read64_uint64(
- CVMX_USBNX_DMA0_INB_CHN0(usb->index));
- words -= 3;
- }
- cvmx_write64_uint32(csr_address, *ptr++);
- if (--words) {
- cvmx_write64_uint32(csr_address, *ptr++);
- if (--words)
- cvmx_write64_uint32(csr_address, *ptr++);
- }
- cvmx_read64_uint64(CVMX_USBNX_DMA0_INB_CHN0(usb->index));
- }
- return fifo->head != fifo->tail;
-}
-
-/**
- * Check the hardware FIFOs and fill them as needed
- *
- * @usb: USB device state populated by cvmx_usb_initialize().
- */
-static void cvmx_usb_poll_tx_fifo(struct octeon_hcd *usb)
-{
- if (usb->periodic.head != usb->periodic.tail) {
- union cvmx_usbcx_hptxsts tx_status;
-
- tx_status.u32 = cvmx_usb_read_csr32(usb,
- CVMX_USBCX_HPTXSTS(usb->index));
- if (cvmx_usb_fill_tx_hw(usb, &usb->periodic,
- tx_status.s.ptxfspcavail))
- USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index),
- cvmx_usbcx_gintmsk, ptxfempmsk, 1);
- else
- USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index),
- cvmx_usbcx_gintmsk, ptxfempmsk, 0);
- }
-
- if (usb->nonperiodic.head != usb->nonperiodic.tail) {
- union cvmx_usbcx_gnptxsts tx_status;
-
- tx_status.u32 = cvmx_usb_read_csr32(usb,
- CVMX_USBCX_GNPTXSTS(usb->index));
- if (cvmx_usb_fill_tx_hw(usb, &usb->nonperiodic,
- tx_status.s.nptxfspcavail))
- USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index),
- cvmx_usbcx_gintmsk, nptxfempmsk, 1);
- else
- USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index),
- cvmx_usbcx_gintmsk, nptxfempmsk, 0);
- }
-}
-
-/**
- * Fill the TX FIFO with an outgoing packet
- *
- * @usb: USB device state populated by cvmx_usb_initialize().
- * @channel: Channel number to get packet from
- */
-static void cvmx_usb_fill_tx_fifo(struct octeon_hcd *usb, int channel)
-{
- union cvmx_usbcx_hccharx hcchar;
- union cvmx_usbcx_hcspltx usbc_hcsplt;
- union cvmx_usbcx_hctsizx usbc_hctsiz;
- struct cvmx_usb_tx_fifo *fifo;
-
- /* We only need to fill data on outbound channels */
- hcchar.u32 = cvmx_usb_read_csr32(usb,
- CVMX_USBCX_HCCHARX(channel, usb->index));
- if (hcchar.s.epdir != CVMX_USB_DIRECTION_OUT)
- return;
-
- /* OUT Splits only have data on the start and not the complete */
- usbc_hcsplt.u32 = cvmx_usb_read_csr32(usb,
- CVMX_USBCX_HCSPLTX(channel, usb->index));
- if (usbc_hcsplt.s.spltena && usbc_hcsplt.s.compsplt)
- return;
-
- /*
- * Find out how many bytes we need to fill and convert it into 32bit
- * words.
- */
- usbc_hctsiz.u32 = cvmx_usb_read_csr32(usb,
- CVMX_USBCX_HCTSIZX(channel, usb->index));
- if (!usbc_hctsiz.s.xfersize)
- return;
-
- if ((hcchar.s.eptype == CVMX_USB_TRANSFER_INTERRUPT) ||
- (hcchar.s.eptype == CVMX_USB_TRANSFER_ISOCHRONOUS))
- fifo = &usb->periodic;
- else
- fifo = &usb->nonperiodic;
-
- fifo->entry[fifo->head].channel = channel;
- fifo->entry[fifo->head].address =
- cvmx_read64_uint64(CVMX_USBNX_DMA0_OUTB_CHN0(usb->index) +
- channel * 8);
- fifo->entry[fifo->head].size = (usbc_hctsiz.s.xfersize + 3) >> 2;
- fifo->head++;
- if (fifo->head > MAX_CHANNELS)
- fifo->head = 0;
-
- cvmx_usb_poll_tx_fifo(usb);
-}
-
-/**
- * Perform channel specific setup for Control transactions. All
- * the generic stuff will already have been done in cvmx_usb_start_channel().
- *
- * @usb: USB device state populated by cvmx_usb_initialize().
- * @channel: Channel to setup
- * @pipe: Pipe for control transaction
- */
-static void cvmx_usb_start_channel_control(struct octeon_hcd *usb,
- int channel,
- struct cvmx_usb_pipe *pipe)
-{
- struct usb_hcd *hcd = octeon_to_hcd(usb);
- struct device *dev = hcd->self.controller;
- struct cvmx_usb_transaction *transaction =
- list_first_entry(&pipe->transactions, typeof(*transaction),
- node);
- struct usb_ctrlrequest *header =
- cvmx_phys_to_ptr(transaction->control_header);
- int bytes_to_transfer = transaction->buffer_length -
- transaction->actual_bytes;
- int packets_to_transfer;
- union cvmx_usbcx_hctsizx usbc_hctsiz;
-
- usbc_hctsiz.u32 = cvmx_usb_read_csr32(usb,
- CVMX_USBCX_HCTSIZX(channel, usb->index));
-
- switch (transaction->stage) {
- case CVMX_USB_STAGE_NON_CONTROL:
- case CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE:
- dev_err(dev, "%s: ERROR - Non control stage\n", __func__);
- break;
- case CVMX_USB_STAGE_SETUP:
- usbc_hctsiz.s.pid = 3; /* Setup */
- bytes_to_transfer = sizeof(*header);
- /* All Control operations start with a setup going OUT */
- USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index),
- cvmx_usbcx_hccharx, epdir,
- CVMX_USB_DIRECTION_OUT);
- /*
- * Setup send the control header instead of the buffer data. The
- * buffer data will be used in the next stage
- */
- cvmx_write64_uint64(CVMX_USBNX_DMA0_OUTB_CHN0(usb->index) +
- channel * 8,
- transaction->control_header);
- break;
- case CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE:
- usbc_hctsiz.s.pid = 3; /* Setup */
- bytes_to_transfer = 0;
- /* All Control operations start with a setup going OUT */
- USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index),
- cvmx_usbcx_hccharx, epdir,
- CVMX_USB_DIRECTION_OUT);
-
- USB_SET_FIELD32(CVMX_USBCX_HCSPLTX(channel, usb->index),
- cvmx_usbcx_hcspltx, compsplt, 1);
- break;
- case CVMX_USB_STAGE_DATA:
- usbc_hctsiz.s.pid = cvmx_usb_get_data_pid(pipe);
- if (cvmx_usb_pipe_needs_split(usb, pipe)) {
- if (header->bRequestType & USB_DIR_IN)
- bytes_to_transfer = 0;
- else if (bytes_to_transfer > pipe->max_packet)
- bytes_to_transfer = pipe->max_packet;
- }
- USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index),
- cvmx_usbcx_hccharx, epdir,
- ((header->bRequestType & USB_DIR_IN) ?
- CVMX_USB_DIRECTION_IN :
- CVMX_USB_DIRECTION_OUT));
- break;
- case CVMX_USB_STAGE_DATA_SPLIT_COMPLETE:
- usbc_hctsiz.s.pid = cvmx_usb_get_data_pid(pipe);
- if (!(header->bRequestType & USB_DIR_IN))
- bytes_to_transfer = 0;
- USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index),
- cvmx_usbcx_hccharx, epdir,
- ((header->bRequestType & USB_DIR_IN) ?
- CVMX_USB_DIRECTION_IN :
- CVMX_USB_DIRECTION_OUT));
- USB_SET_FIELD32(CVMX_USBCX_HCSPLTX(channel, usb->index),
- cvmx_usbcx_hcspltx, compsplt, 1);
- break;
- case CVMX_USB_STAGE_STATUS:
- usbc_hctsiz.s.pid = cvmx_usb_get_data_pid(pipe);
- bytes_to_transfer = 0;
- USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index),
- cvmx_usbcx_hccharx, epdir,
- ((header->bRequestType & USB_DIR_IN) ?
- CVMX_USB_DIRECTION_OUT :
- CVMX_USB_DIRECTION_IN));
- break;
- case CVMX_USB_STAGE_STATUS_SPLIT_COMPLETE:
- usbc_hctsiz.s.pid = cvmx_usb_get_data_pid(pipe);
- bytes_to_transfer = 0;
- USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index),
- cvmx_usbcx_hccharx, epdir,
- ((header->bRequestType & USB_DIR_IN) ?
- CVMX_USB_DIRECTION_OUT :
- CVMX_USB_DIRECTION_IN));
- USB_SET_FIELD32(CVMX_USBCX_HCSPLTX(channel, usb->index),
- cvmx_usbcx_hcspltx, compsplt, 1);
- break;
- }
-
- /*
- * Make sure the transfer never exceeds the byte limit of the hardware.
- * Further bytes will be sent as continued transactions
- */
- if (bytes_to_transfer > MAX_TRANSFER_BYTES) {
- /* Round MAX_TRANSFER_BYTES to a multiple of out packet size */
- bytes_to_transfer = MAX_TRANSFER_BYTES / pipe->max_packet;
- bytes_to_transfer *= pipe->max_packet;
- }
-
- /*
- * Calculate the number of packets to transfer. If the length is zero
- * we still need to transfer one packet
- */
- packets_to_transfer = DIV_ROUND_UP(bytes_to_transfer,
- pipe->max_packet);
- if (packets_to_transfer == 0) {
- packets_to_transfer = 1;
- } else if ((packets_to_transfer > 1) &&
- (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)) {
- /*
- * Limit to one packet when not using DMA. Channels must be
- * restarted between every packet for IN transactions, so there
- * is no reason to do multiple packets in a row
- */
- packets_to_transfer = 1;
- bytes_to_transfer = packets_to_transfer * pipe->max_packet;
- } else if (packets_to_transfer > MAX_TRANSFER_PACKETS) {
- /*
- * Limit the number of packet and data transferred to what the
- * hardware can handle
- */
- packets_to_transfer = MAX_TRANSFER_PACKETS;
- bytes_to_transfer = packets_to_transfer * pipe->max_packet;
- }
-
- usbc_hctsiz.s.xfersize = bytes_to_transfer;
- usbc_hctsiz.s.pktcnt = packets_to_transfer;
-
- cvmx_usb_write_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index),
- usbc_hctsiz.u32);
-}
-
-/**
- * Start a channel to perform the pipe's head transaction
- *
- * @usb: USB device state populated by cvmx_usb_initialize().
- * @channel: Channel to setup
- * @pipe: Pipe to start
- */
-static void cvmx_usb_start_channel(struct octeon_hcd *usb, int channel,
- struct cvmx_usb_pipe *pipe)
-{
- struct cvmx_usb_transaction *transaction =
- list_first_entry(&pipe->transactions, typeof(*transaction),
- node);
-
- /* Make sure all writes to the DMA region get flushed */
- CVMX_SYNCW;
-
- /* Attach the channel to the pipe */
- usb->pipe_for_channel[channel] = pipe;
- pipe->channel = channel;
- pipe->flags |= CVMX_USB_PIPE_FLAGS_SCHEDULED;
-
- /* Mark this channel as in use */
- usb->idle_hardware_channels &= ~(1 << channel);
-
- /* Enable the channel interrupt bits */
- {
- union cvmx_usbcx_hcintx usbc_hcint;
- union cvmx_usbcx_hcintmskx usbc_hcintmsk;
- union cvmx_usbcx_haintmsk usbc_haintmsk;
-
- /* Clear all channel status bits */
- usbc_hcint.u32 = cvmx_usb_read_csr32(usb,
- CVMX_USBCX_HCINTX(channel, usb->index));
-
- cvmx_usb_write_csr32(usb,
- CVMX_USBCX_HCINTX(channel, usb->index),
- usbc_hcint.u32);
-
- usbc_hcintmsk.u32 = 0;
- usbc_hcintmsk.s.chhltdmsk = 1;
- if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA) {
- /*
- * Channels need these extra interrupts when we aren't
- * in DMA mode.
- */
- usbc_hcintmsk.s.datatglerrmsk = 1;
- usbc_hcintmsk.s.frmovrunmsk = 1;
- usbc_hcintmsk.s.bblerrmsk = 1;
- usbc_hcintmsk.s.xacterrmsk = 1;
- if (cvmx_usb_pipe_needs_split(usb, pipe)) {
- /*
- * Splits don't generate xfercompl, so we need
- * ACK and NYET.
- */
- usbc_hcintmsk.s.nyetmsk = 1;
- usbc_hcintmsk.s.ackmsk = 1;
- }
- usbc_hcintmsk.s.nakmsk = 1;
- usbc_hcintmsk.s.stallmsk = 1;
- usbc_hcintmsk.s.xfercomplmsk = 1;
- }
- cvmx_usb_write_csr32(usb,
- CVMX_USBCX_HCINTMSKX(channel, usb->index),
- usbc_hcintmsk.u32);
-
- /* Enable the channel interrupt to propagate */
- usbc_haintmsk.u32 = cvmx_usb_read_csr32(usb,
- CVMX_USBCX_HAINTMSK(usb->index));
- usbc_haintmsk.s.haintmsk |= 1 << channel;
- cvmx_usb_write_csr32(usb, CVMX_USBCX_HAINTMSK(usb->index),
- usbc_haintmsk.u32);
- }
-
- /* Setup the location the DMA engine uses. */
- {
- u64 reg;
- u64 dma_address = transaction->buffer +
- transaction->actual_bytes;
-
- if (transaction->type == CVMX_USB_TRANSFER_ISOCHRONOUS)
- dma_address = transaction->buffer +
- transaction->iso_packets[0].offset +
- transaction->actual_bytes;
-
- if (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT)
- reg = CVMX_USBNX_DMA0_OUTB_CHN0(usb->index);
- else
- reg = CVMX_USBNX_DMA0_INB_CHN0(usb->index);
- cvmx_write64_uint64(reg + channel * 8, dma_address);
- }
-
- /* Setup both the size of the transfer and the SPLIT characteristics */
- {
- union cvmx_usbcx_hcspltx usbc_hcsplt = {.u32 = 0};
- union cvmx_usbcx_hctsizx usbc_hctsiz = {.u32 = 0};
- int packets_to_transfer;
- int bytes_to_transfer = transaction->buffer_length -
- transaction->actual_bytes;
-
- /*
- * ISOCHRONOUS transactions store each individual transfer size
- * in the packet structure, not the global buffer_length
- */
- if (transaction->type == CVMX_USB_TRANSFER_ISOCHRONOUS)
- bytes_to_transfer =
- transaction->iso_packets[0].length -
- transaction->actual_bytes;
-
- /*
- * We need to do split transactions when we are talking to non
- * high speed devices that are behind a high speed hub
- */
- if (cvmx_usb_pipe_needs_split(usb, pipe)) {
- /*
- * On the start split phase (stage is even) record the
- * frame number we will need to send the split complete.
- * We only store the lower two bits since the time ahead
- * can only be two frames
- */
- if ((transaction->stage & 1) == 0) {
- if (transaction->type == CVMX_USB_TRANSFER_BULK)
- pipe->split_sc_frame =
- (usb->frame_number + 1) & 0x7f;
- else
- pipe->split_sc_frame =
- (usb->frame_number + 2) & 0x7f;
- } else {
- pipe->split_sc_frame = -1;
- }
-
- usbc_hcsplt.s.spltena = 1;
- usbc_hcsplt.s.hubaddr = pipe->hub_device_addr;
- usbc_hcsplt.s.prtaddr = pipe->hub_port;
- usbc_hcsplt.s.compsplt = (transaction->stage ==
- CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE);
-
- /*
- * SPLIT transactions can only ever transmit one data
- * packet so limit the transfer size to the max packet
- * size
- */
- if (bytes_to_transfer > pipe->max_packet)
- bytes_to_transfer = pipe->max_packet;
-
- /*
- * ISOCHRONOUS OUT splits are unique in that they limit
- * data transfers to 188 byte chunks representing the
- * begin/middle/end of the data or all
- */
- if (!usbc_hcsplt.s.compsplt &&
- (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT) &&
- (pipe->transfer_type ==
- CVMX_USB_TRANSFER_ISOCHRONOUS)) {
- /*
- * Clear the split complete frame number as
- * there isn't going to be a split complete
- */
- pipe->split_sc_frame = -1;
- /*
- * See if we've started this transfer and sent
- * data
- */
- if (transaction->actual_bytes == 0) {
- /*
- * Nothing sent yet, this is either a
- * begin or the entire payload
- */
- if (bytes_to_transfer <= 188)
- /* Entire payload in one go */
- usbc_hcsplt.s.xactpos = 3;
- else
- /* First part of payload */
- usbc_hcsplt.s.xactpos = 2;
- } else {
- /*
- * Continuing the previous data, we must
- * either be in the middle or at the end
- */
- if (bytes_to_transfer <= 188)
- /* End of payload */
- usbc_hcsplt.s.xactpos = 1;
- else
- /* Middle of payload */
- usbc_hcsplt.s.xactpos = 0;
- }
- /*
- * Again, the transfer size is limited to 188
- * bytes
- */
- if (bytes_to_transfer > 188)
- bytes_to_transfer = 188;
- }
- }
-
- /*
- * Make sure the transfer never exceeds the byte limit of the
- * hardware. Further bytes will be sent as continued
- * transactions
- */
- if (bytes_to_transfer > MAX_TRANSFER_BYTES) {
- /*
- * Round MAX_TRANSFER_BYTES to a multiple of out packet
- * size
- */
- bytes_to_transfer = MAX_TRANSFER_BYTES /
- pipe->max_packet;
- bytes_to_transfer *= pipe->max_packet;
- }
-
- /*
- * Calculate the number of packets to transfer. If the length is
- * zero we still need to transfer one packet
- */
- packets_to_transfer =
- DIV_ROUND_UP(bytes_to_transfer, pipe->max_packet);
- if (packets_to_transfer == 0) {
- packets_to_transfer = 1;
- } else if ((packets_to_transfer > 1) &&
- (usb->init_flags &
- CVMX_USB_INITIALIZE_FLAGS_NO_DMA)) {
- /*
- * Limit to one packet when not using DMA. Channels must
- * be restarted between every packet for IN
- * transactions, so there is no reason to do multiple
- * packets in a row
- */
- packets_to_transfer = 1;
- bytes_to_transfer = packets_to_transfer *
- pipe->max_packet;
- } else if (packets_to_transfer > MAX_TRANSFER_PACKETS) {
- /*
- * Limit the number of packet and data transferred to
- * what the hardware can handle
- */
- packets_to_transfer = MAX_TRANSFER_PACKETS;
- bytes_to_transfer = packets_to_transfer *
- pipe->max_packet;
- }
-
- usbc_hctsiz.s.xfersize = bytes_to_transfer;
- usbc_hctsiz.s.pktcnt = packets_to_transfer;
-
- /* Update the DATA0/DATA1 toggle */
- usbc_hctsiz.s.pid = cvmx_usb_get_data_pid(pipe);
- /*
- * High speed pipes may need a hardware ping before they start
- */
- if (pipe->flags & CVMX_USB_PIPE_FLAGS_NEED_PING)
- usbc_hctsiz.s.dopng = 1;
-
- cvmx_usb_write_csr32(usb,
- CVMX_USBCX_HCSPLTX(channel, usb->index),
- usbc_hcsplt.u32);
- cvmx_usb_write_csr32(usb,
- CVMX_USBCX_HCTSIZX(channel, usb->index),
- usbc_hctsiz.u32);
- }
-
- /* Setup the Host Channel Characteristics Register */
- {
- union cvmx_usbcx_hccharx usbc_hcchar = {.u32 = 0};
-
- /*
- * Set the startframe odd/even properly. This is only used for
- * periodic
- */
- usbc_hcchar.s.oddfrm = usb->frame_number & 1;
-
- /*
- * Set the number of back to back packets allowed by this
- * endpoint. Split transactions interpret "ec" as the number of
- * immediate retries of failure. These retries happen too
- * quickly, so we disable these entirely for splits
- */
- if (cvmx_usb_pipe_needs_split(usb, pipe))
- usbc_hcchar.s.ec = 1;
- else if (pipe->multi_count < 1)
- usbc_hcchar.s.ec = 1;
- else if (pipe->multi_count > 3)
- usbc_hcchar.s.ec = 3;
- else
- usbc_hcchar.s.ec = pipe->multi_count;
-
- /* Set the rest of the endpoint specific settings */
- usbc_hcchar.s.devaddr = pipe->device_addr;
- usbc_hcchar.s.eptype = transaction->type;
- usbc_hcchar.s.lspddev =
- (pipe->device_speed == CVMX_USB_SPEED_LOW);
- usbc_hcchar.s.epdir = pipe->transfer_dir;
- usbc_hcchar.s.epnum = pipe->endpoint_num;
- usbc_hcchar.s.mps = pipe->max_packet;
- cvmx_usb_write_csr32(usb,
- CVMX_USBCX_HCCHARX(channel, usb->index),
- usbc_hcchar.u32);
- }
-
- /* Do transaction type specific fixups as needed */
- switch (transaction->type) {
- case CVMX_USB_TRANSFER_CONTROL:
- cvmx_usb_start_channel_control(usb, channel, pipe);
- break;
- case CVMX_USB_TRANSFER_BULK:
- case CVMX_USB_TRANSFER_INTERRUPT:
- break;
- case CVMX_USB_TRANSFER_ISOCHRONOUS:
- if (!cvmx_usb_pipe_needs_split(usb, pipe)) {
- /*
- * ISO transactions require different PIDs depending on
- * direction and how many packets are needed
- */
- if (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT) {
- if (pipe->multi_count < 2) /* Need DATA0 */
- USB_SET_FIELD32(
- CVMX_USBCX_HCTSIZX(channel,
- usb->index),
- cvmx_usbcx_hctsizx, pid, 0);
- else /* Need MDATA */
- USB_SET_FIELD32(
- CVMX_USBCX_HCTSIZX(channel,
- usb->index),
- cvmx_usbcx_hctsizx, pid, 3);
- }
- }
- break;
- }
- {
- union cvmx_usbcx_hctsizx usbc_hctsiz = { .u32 =
- cvmx_usb_read_csr32(usb,
- CVMX_USBCX_HCTSIZX(channel,
- usb->index))
- };
- transaction->xfersize = usbc_hctsiz.s.xfersize;
- transaction->pktcnt = usbc_hctsiz.s.pktcnt;
- }
- /* Remember when we start a split transaction */
- if (cvmx_usb_pipe_needs_split(usb, pipe))
- usb->active_split = transaction;
- USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index),
- cvmx_usbcx_hccharx, chena, 1);
- if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
- cvmx_usb_fill_tx_fifo(usb, channel);
-}
-
-/**
- * Find a pipe that is ready to be scheduled to hardware.
- * @usb: USB device state populated by cvmx_usb_initialize().
- * @xfer_type: Transfer type
- *
- * Returns: Pipe or NULL if none are ready
- */
-static struct cvmx_usb_pipe *cvmx_usb_find_ready_pipe(struct octeon_hcd *usb,
- enum cvmx_usb_transfer xfer_type)
-{
- struct list_head *list = usb->active_pipes + xfer_type;
- u64 current_frame = usb->frame_number;
- struct cvmx_usb_pipe *pipe;
-
- list_for_each_entry(pipe, list, node) {
- struct cvmx_usb_transaction *t =
- list_first_entry(&pipe->transactions, typeof(*t),
- node);
- if (!(pipe->flags & CVMX_USB_PIPE_FLAGS_SCHEDULED) && t &&
- (pipe->next_tx_frame <= current_frame) &&
- ((pipe->split_sc_frame == -1) ||
- ((((int)current_frame - pipe->split_sc_frame) & 0x7f) <
- 0x40)) &&
- (!usb->active_split || (usb->active_split == t))) {
- prefetch(t);
- return pipe;
- }
- }
- return NULL;
-}
-
-static struct cvmx_usb_pipe *cvmx_usb_next_pipe(struct octeon_hcd *usb,
- int is_sof)
-{
- struct cvmx_usb_pipe *pipe;
-
- /* Find a pipe needing service. */
- if (is_sof) {
- /*
- * Only process periodic pipes on SOF interrupts. This way we
- * are sure that the periodic data is sent in the beginning of
- * the frame.
- */
- pipe = cvmx_usb_find_ready_pipe(usb,
- CVMX_USB_TRANSFER_ISOCHRONOUS);
- if (pipe)
- return pipe;
- pipe = cvmx_usb_find_ready_pipe(usb,
- CVMX_USB_TRANSFER_INTERRUPT);
- if (pipe)
- return pipe;
- }
- pipe = cvmx_usb_find_ready_pipe(usb, CVMX_USB_TRANSFER_CONTROL);
- if (pipe)
- return pipe;
- return cvmx_usb_find_ready_pipe(usb, CVMX_USB_TRANSFER_BULK);
-}
-
-/**
- * Called whenever a pipe might need to be scheduled to the
- * hardware.
- *
- * @usb: USB device state populated by cvmx_usb_initialize().
- * @is_sof: True if this schedule was called on a SOF interrupt.
- */
-static void cvmx_usb_schedule(struct octeon_hcd *usb, int is_sof)
-{
- int channel;
- struct cvmx_usb_pipe *pipe;
- int need_sof;
- enum cvmx_usb_transfer ttype;
-
- if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA) {
- /*
- * Without DMA we need to be careful to not schedule something
- * at the end of a frame and cause an overrun.
- */
- union cvmx_usbcx_hfnum hfnum = {
- .u32 = cvmx_usb_read_csr32(usb,
- CVMX_USBCX_HFNUM(usb->index))
- };
-
- union cvmx_usbcx_hfir hfir = {
- .u32 = cvmx_usb_read_csr32(usb,
- CVMX_USBCX_HFIR(usb->index))
- };
-
- if (hfnum.s.frrem < hfir.s.frint / 4)
- goto done;
- }
-
- while (usb->idle_hardware_channels) {
- /* Find an idle channel */
- channel = __fls(usb->idle_hardware_channels);
- if (unlikely(channel > 7))
- break;
-
- pipe = cvmx_usb_next_pipe(usb, is_sof);
- if (!pipe)
- break;
-
- cvmx_usb_start_channel(usb, channel, pipe);
- }
-
-done:
- /*
- * Only enable SOF interrupts when we have transactions pending in the
- * future that might need to be scheduled
- */
- need_sof = 0;
- for (ttype = CVMX_USB_TRANSFER_CONTROL;
- ttype <= CVMX_USB_TRANSFER_INTERRUPT; ttype++) {
- list_for_each_entry(pipe, &usb->active_pipes[ttype], node) {
- if (pipe->next_tx_frame > usb->frame_number) {
- need_sof = 1;
- break;
- }
- }
- }
- USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index),
- cvmx_usbcx_gintmsk, sofmsk, need_sof);
-}
-
-static void octeon_usb_urb_complete_callback(struct octeon_hcd *usb,
- enum cvmx_usb_status status,
- struct cvmx_usb_pipe *pipe,
- struct cvmx_usb_transaction
- *transaction,
- int bytes_transferred,
- struct urb *urb)
-{
- struct usb_hcd *hcd = octeon_to_hcd(usb);
- struct device *dev = hcd->self.controller;
-
- if (likely(status == CVMX_USB_STATUS_OK))
- urb->actual_length = bytes_transferred;
- else
- urb->actual_length = 0;
-
- urb->hcpriv = NULL;
-
- /* For Isochronous transactions we need to update the URB packet status
- * list from data in our private copy
- */
- if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
- int i;
- /*
- * The pointer to the private list is stored in the setup_packet
- * field.
- */
- struct cvmx_usb_iso_packet *iso_packet =
- (struct cvmx_usb_iso_packet *)urb->setup_packet;
- /* Recalculate the transfer size by adding up each packet */
- urb->actual_length = 0;
- for (i = 0; i < urb->number_of_packets; i++) {
- if (iso_packet[i].status == CVMX_USB_STATUS_OK) {
- urb->iso_frame_desc[i].status = 0;
- urb->iso_frame_desc[i].actual_length =
- iso_packet[i].length;
- urb->actual_length +=
- urb->iso_frame_desc[i].actual_length;
- } else {
- dev_dbg(dev, "ISOCHRONOUS packet=%d of %d status=%d pipe=%p transaction=%p size=%d\n",
- i, urb->number_of_packets,
- iso_packet[i].status, pipe,
- transaction, iso_packet[i].length);
- urb->iso_frame_desc[i].status = -EREMOTEIO;
- }
- }
- /* Free the private list now that we don't need it anymore */
- kfree(iso_packet);
- urb->setup_packet = NULL;
- }
-
- switch (status) {
- case CVMX_USB_STATUS_OK:
- urb->status = 0;
- break;
- case CVMX_USB_STATUS_CANCEL:
- if (urb->status == 0)
- urb->status = -ENOENT;
- break;
- case CVMX_USB_STATUS_STALL:
- dev_dbg(dev, "status=stall pipe=%p transaction=%p size=%d\n",
- pipe, transaction, bytes_transferred);
- urb->status = -EPIPE;
- break;
- case CVMX_USB_STATUS_BABBLEERR:
- dev_dbg(dev, "status=babble pipe=%p transaction=%p size=%d\n",
- pipe, transaction, bytes_transferred);
- urb->status = -EPIPE;
- break;
- case CVMX_USB_STATUS_SHORT:
- dev_dbg(dev, "status=short pipe=%p transaction=%p size=%d\n",
- pipe, transaction, bytes_transferred);
- urb->status = -EREMOTEIO;
- break;
- case CVMX_USB_STATUS_ERROR:
- case CVMX_USB_STATUS_XACTERR:
- case CVMX_USB_STATUS_DATATGLERR:
- case CVMX_USB_STATUS_FRAMEERR:
- dev_dbg(dev, "status=%d pipe=%p transaction=%p size=%d\n",
- status, pipe, transaction, bytes_transferred);
- urb->status = -EPROTO;
- break;
- }
- usb_hcd_unlink_urb_from_ep(octeon_to_hcd(usb), urb);
- spin_unlock(&usb->lock);
- usb_hcd_giveback_urb(octeon_to_hcd(usb), urb, urb->status);
- spin_lock(&usb->lock);
-}
-
-/**
- * Signal the completion of a transaction and free it. The
- * transaction will be removed from the pipe transaction list.
- *
- * @usb: USB device state populated by cvmx_usb_initialize().
- * @pipe: Pipe the transaction is on
- * @transaction:
- * Transaction that completed
- * @complete_code:
- * Completion code
- */
-static void cvmx_usb_complete(struct octeon_hcd *usb,
- struct cvmx_usb_pipe *pipe,
- struct cvmx_usb_transaction *transaction,
- enum cvmx_usb_status complete_code)
-{
- /* If this was a split then clear our split in progress marker */
- if (usb->active_split == transaction)
- usb->active_split = NULL;
-
- /*
- * Isochronous transactions need extra processing as they might not be
- * done after a single data transfer
- */
- if (unlikely(transaction->type == CVMX_USB_TRANSFER_ISOCHRONOUS)) {
- /* Update the number of bytes transferred in this ISO packet */
- transaction->iso_packets[0].length = transaction->actual_bytes;
- transaction->iso_packets[0].status = complete_code;
-
- /*
- * If there are more ISOs pending and we succeeded, schedule the
- * next one
- */
- if ((transaction->iso_number_packets > 1) &&
- (complete_code == CVMX_USB_STATUS_OK)) {
- /* No bytes transferred for this packet as of yet */
- transaction->actual_bytes = 0;
- /* One less ISO waiting to transfer */
- transaction->iso_number_packets--;
- /* Increment to the next location in our packet array */
- transaction->iso_packets++;
- transaction->stage = CVMX_USB_STAGE_NON_CONTROL;
- return;
- }
- }
-
- /* Remove the transaction from the pipe list */
- list_del(&transaction->node);
- if (list_empty(&pipe->transactions))
- list_move_tail(&pipe->node, &usb->idle_pipes);
- octeon_usb_urb_complete_callback(usb, complete_code, pipe,
- transaction,
- transaction->actual_bytes,
- transaction->urb);
- kfree(transaction);
-}
-
-/**
- * Submit a usb transaction to a pipe. Called for all types
- * of transactions.
- *
- * @usb:
- * @pipe: Which pipe to submit to.
- * @type: Transaction type
- * @buffer: User buffer for the transaction
- * @buffer_length:
- * User buffer's length in bytes
- * @control_header:
- * For control transactions, the 8 byte standard header
- * @iso_start_frame:
- * For ISO transactions, the start frame
- * @iso_number_packets:
- * For ISO, the number of packet in the transaction.
- * @iso_packets:
- * A description of each ISO packet
- * @urb: URB for the callback
- *
- * Returns: Transaction or NULL on failure.
- */
-static struct cvmx_usb_transaction *cvmx_usb_submit_transaction(
- struct octeon_hcd *usb,
- struct cvmx_usb_pipe *pipe,
- enum cvmx_usb_transfer type,
- u64 buffer,
- int buffer_length,
- u64 control_header,
- int iso_start_frame,
- int iso_number_packets,
- struct cvmx_usb_iso_packet *iso_packets,
- struct urb *urb)
-{
- struct cvmx_usb_transaction *transaction;
-
- if (unlikely(pipe->transfer_type != type))
- return NULL;
-
- transaction = kzalloc(sizeof(*transaction), GFP_ATOMIC);
- if (unlikely(!transaction))
- return NULL;
-
- transaction->type = type;
- transaction->buffer = buffer;
- transaction->buffer_length = buffer_length;
- transaction->control_header = control_header;
- /* FIXME: This is not used, implement it. */
- transaction->iso_start_frame = iso_start_frame;
- transaction->iso_number_packets = iso_number_packets;
- transaction->iso_packets = iso_packets;
- transaction->urb = urb;
- if (transaction->type == CVMX_USB_TRANSFER_CONTROL)
- transaction->stage = CVMX_USB_STAGE_SETUP;
- else
- transaction->stage = CVMX_USB_STAGE_NON_CONTROL;
-
- if (!list_empty(&pipe->transactions)) {
- list_add_tail(&transaction->node, &pipe->transactions);
- } else {
- list_add_tail(&transaction->node, &pipe->transactions);
- list_move_tail(&pipe->node,
- &usb->active_pipes[pipe->transfer_type]);
-
- /*
- * We may need to schedule the pipe if this was the head of the
- * pipe.
- */
- cvmx_usb_schedule(usb, 0);
- }
-
- return transaction;
-}
-
-/**
- * Call to submit a USB Bulk transfer to a pipe.
- *
- * @usb: USB device state populated by cvmx_usb_initialize().
- * @pipe: Handle to the pipe for the transfer.
- * @urb: URB.
- *
- * Returns: A submitted transaction or NULL on failure.
- */
-static struct cvmx_usb_transaction *cvmx_usb_submit_bulk(
- struct octeon_hcd *usb,
- struct cvmx_usb_pipe *pipe,
- struct urb *urb)
-{
- return cvmx_usb_submit_transaction(usb, pipe, CVMX_USB_TRANSFER_BULK,
- urb->transfer_dma,
- urb->transfer_buffer_length,
- 0, /* control_header */
- 0, /* iso_start_frame */
- 0, /* iso_number_packets */
- NULL, /* iso_packets */
- urb);
-}
-
-/**
- * Call to submit a USB Interrupt transfer to a pipe.
- *
- * @usb: USB device state populated by cvmx_usb_initialize().
- * @pipe: Handle to the pipe for the transfer.
- * @urb: URB returned when the callback is called.
- *
- * Returns: A submitted transaction or NULL on failure.
- */
-static struct cvmx_usb_transaction *cvmx_usb_submit_interrupt(
- struct octeon_hcd *usb,
- struct cvmx_usb_pipe *pipe,
- struct urb *urb)
-{
- return cvmx_usb_submit_transaction(usb, pipe,
- CVMX_USB_TRANSFER_INTERRUPT,
- urb->transfer_dma,
- urb->transfer_buffer_length,
- 0, /* control_header */
- 0, /* iso_start_frame */
- 0, /* iso_number_packets */
- NULL, /* iso_packets */
- urb);
-}
-
-/**
- * Call to submit a USB Control transfer to a pipe.
- *
- * @usb: USB device state populated by cvmx_usb_initialize().
- * @pipe: Handle to the pipe for the transfer.
- * @urb: URB.
- *
- * Returns: A submitted transaction or NULL on failure.
- */
-static struct cvmx_usb_transaction *cvmx_usb_submit_control(
- struct octeon_hcd *usb,
- struct cvmx_usb_pipe *pipe,
- struct urb *urb)
-{
- int buffer_length = urb->transfer_buffer_length;
- u64 control_header = urb->setup_dma;
- struct usb_ctrlrequest *header = cvmx_phys_to_ptr(control_header);
-
- if ((header->bRequestType & USB_DIR_IN) == 0)
- buffer_length = le16_to_cpu(header->wLength);
-
- return cvmx_usb_submit_transaction(usb, pipe,
- CVMX_USB_TRANSFER_CONTROL,
- urb->transfer_dma, buffer_length,
- control_header,
- 0, /* iso_start_frame */
- 0, /* iso_number_packets */
- NULL, /* iso_packets */
- urb);
-}
-
-/**
- * Call to submit a USB Isochronous transfer to a pipe.
- *
- * @usb: USB device state populated by cvmx_usb_initialize().
- * @pipe: Handle to the pipe for the transfer.
- * @urb: URB returned when the callback is called.
- *
- * Returns: A submitted transaction or NULL on failure.
- */
-static struct cvmx_usb_transaction *cvmx_usb_submit_isochronous(
- struct octeon_hcd *usb,
- struct cvmx_usb_pipe *pipe,
- struct urb *urb)
-{
- struct cvmx_usb_iso_packet *packets;
-
- packets = (struct cvmx_usb_iso_packet *)urb->setup_packet;
- return cvmx_usb_submit_transaction(usb, pipe,
- CVMX_USB_TRANSFER_ISOCHRONOUS,
- urb->transfer_dma,
- urb->transfer_buffer_length,
- 0, /* control_header */
- urb->start_frame,
- urb->number_of_packets,
- packets, urb);
-}
-
-/**
- * Cancel one outstanding request in a pipe. Canceling a request
- * can fail if the transaction has already completed before cancel
- * is called. Even after a successful cancel call, it may take
- * a frame or two for the cvmx_usb_poll() function to call the
- * associated callback.
- *
- * @usb: USB device state populated by cvmx_usb_initialize().
- * @pipe: Pipe to cancel requests in.
- * @transaction: Transaction to cancel, returned by the submit function.
- *
- * Returns: 0 or a negative error code.
- */
-static int cvmx_usb_cancel(struct octeon_hcd *usb,
- struct cvmx_usb_pipe *pipe,
- struct cvmx_usb_transaction *transaction)
-{
- /*
- * If the transaction is the HEAD of the queue and scheduled. We need to
- * treat it special
- */
- if (list_first_entry(&pipe->transactions, typeof(*transaction), node) ==
- transaction && (pipe->flags & CVMX_USB_PIPE_FLAGS_SCHEDULED)) {
- union cvmx_usbcx_hccharx usbc_hcchar;
-
- usb->pipe_for_channel[pipe->channel] = NULL;
- pipe->flags &= ~CVMX_USB_PIPE_FLAGS_SCHEDULED;
-
- CVMX_SYNCW;
-
- usbc_hcchar.u32 = cvmx_usb_read_csr32(usb,
- CVMX_USBCX_HCCHARX(pipe->channel, usb->index));
- /*
- * If the channel isn't enabled then the transaction already
- * completed.
- */
- if (usbc_hcchar.s.chena) {
- usbc_hcchar.s.chdis = 1;
- cvmx_usb_write_csr32(usb,
- CVMX_USBCX_HCCHARX(pipe->channel,
- usb->index),
- usbc_hcchar.u32);
- }
- }
- cvmx_usb_complete(usb, pipe, transaction, CVMX_USB_STATUS_CANCEL);
- return 0;
-}
-
-/**
- * Cancel all outstanding requests in a pipe. Logically all this
- * does is call cvmx_usb_cancel() in a loop.
- *
- * @usb: USB device state populated by cvmx_usb_initialize().
- * @pipe: Pipe to cancel requests in.
- *
- * Returns: 0 or a negative error code.
- */
-static int cvmx_usb_cancel_all(struct octeon_hcd *usb,
- struct cvmx_usb_pipe *pipe)
-{
- struct cvmx_usb_transaction *transaction, *next;
-
- /* Simply loop through and attempt to cancel each transaction */
- list_for_each_entry_safe(transaction, next, &pipe->transactions, node) {
- int result = cvmx_usb_cancel(usb, pipe, transaction);
-
- if (unlikely(result != 0))
- return result;
- }
- return 0;
-}
-
-/**
- * Close a pipe created with cvmx_usb_open_pipe().
- *
- * @usb: USB device state populated by cvmx_usb_initialize().
- * @pipe: Pipe to close.
- *
- * Returns: 0 or a negative error code. EBUSY is returned if the pipe has
- * outstanding transfers.
- */
-static int cvmx_usb_close_pipe(struct octeon_hcd *usb,
- struct cvmx_usb_pipe *pipe)
-{
- /* Fail if the pipe has pending transactions */
- if (!list_empty(&pipe->transactions))
- return -EBUSY;
-
- list_del(&pipe->node);
- kfree(pipe);
-
- return 0;
-}
-
-/**
- * Get the current USB protocol level frame number. The frame
- * number is always in the range of 0-0x7ff.
- *
- * @usb: USB device state populated by cvmx_usb_initialize().
- *
- * Returns: USB frame number
- */
-static int cvmx_usb_get_frame_number(struct octeon_hcd *usb)
-{
- union cvmx_usbcx_hfnum usbc_hfnum;
-
- usbc_hfnum.u32 = cvmx_usb_read_csr32(usb, CVMX_USBCX_HFNUM(usb->index));
-
- return usbc_hfnum.s.frnum;
-}
-
-static void cvmx_usb_transfer_control(struct octeon_hcd *usb,
- struct cvmx_usb_pipe *pipe,
- struct cvmx_usb_transaction *transaction,
- union cvmx_usbcx_hccharx usbc_hcchar,
- int buffer_space_left,
- int bytes_in_last_packet)
-{
- switch (transaction->stage) {
- case CVMX_USB_STAGE_NON_CONTROL:
- case CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE:
- /* This should be impossible */
- cvmx_usb_complete(usb, pipe, transaction,
- CVMX_USB_STATUS_ERROR);
- break;
- case CVMX_USB_STAGE_SETUP:
- pipe->pid_toggle = 1;
- if (cvmx_usb_pipe_needs_split(usb, pipe)) {
- transaction->stage =
- CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE;
- } else {
- struct usb_ctrlrequest *header =
- cvmx_phys_to_ptr(transaction->control_header);
- if (header->wLength)
- transaction->stage = CVMX_USB_STAGE_DATA;
- else
- transaction->stage = CVMX_USB_STAGE_STATUS;
- }
- break;
- case CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE:
- {
- struct usb_ctrlrequest *header =
- cvmx_phys_to_ptr(transaction->control_header);
- if (header->wLength)
- transaction->stage = CVMX_USB_STAGE_DATA;
- else
- transaction->stage = CVMX_USB_STAGE_STATUS;
- }
- break;
- case CVMX_USB_STAGE_DATA:
- if (cvmx_usb_pipe_needs_split(usb, pipe)) {
- transaction->stage = CVMX_USB_STAGE_DATA_SPLIT_COMPLETE;
- /*
- * For setup OUT data that are splits,
- * the hardware doesn't appear to count
- * transferred data. Here we manually
- * update the data transferred
- */
- if (!usbc_hcchar.s.epdir) {
- if (buffer_space_left < pipe->max_packet)
- transaction->actual_bytes +=
- buffer_space_left;
- else
- transaction->actual_bytes +=
- pipe->max_packet;
- }
- } else if ((buffer_space_left == 0) ||
- (bytes_in_last_packet < pipe->max_packet)) {
- pipe->pid_toggle = 1;
- transaction->stage = CVMX_USB_STAGE_STATUS;
- }
- break;
- case CVMX_USB_STAGE_DATA_SPLIT_COMPLETE:
- if ((buffer_space_left == 0) ||
- (bytes_in_last_packet < pipe->max_packet)) {
- pipe->pid_toggle = 1;
- transaction->stage = CVMX_USB_STAGE_STATUS;
- } else {
- transaction->stage = CVMX_USB_STAGE_DATA;
- }
- break;
- case CVMX_USB_STAGE_STATUS:
- if (cvmx_usb_pipe_needs_split(usb, pipe))
- transaction->stage =
- CVMX_USB_STAGE_STATUS_SPLIT_COMPLETE;
- else
- cvmx_usb_complete(usb, pipe, transaction,
- CVMX_USB_STATUS_OK);
- break;
- case CVMX_USB_STAGE_STATUS_SPLIT_COMPLETE:
- cvmx_usb_complete(usb, pipe, transaction, CVMX_USB_STATUS_OK);
- break;
- }
-}
-
-static void cvmx_usb_transfer_bulk(struct octeon_hcd *usb,
- struct cvmx_usb_pipe *pipe,
- struct cvmx_usb_transaction *transaction,
- union cvmx_usbcx_hcintx usbc_hcint,
- int buffer_space_left,
- int bytes_in_last_packet)
-{
- /*
- * The only time a bulk transfer isn't complete when it finishes with
- * an ACK is during a split transaction. For splits we need to continue
- * the transfer if more data is needed.
- */
- if (cvmx_usb_pipe_needs_split(usb, pipe)) {
- if (transaction->stage == CVMX_USB_STAGE_NON_CONTROL)
- transaction->stage =
- CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE;
- else if (buffer_space_left &&
- (bytes_in_last_packet == pipe->max_packet))
- transaction->stage = CVMX_USB_STAGE_NON_CONTROL;
- else
- cvmx_usb_complete(usb, pipe, transaction,
- CVMX_USB_STATUS_OK);
- } else {
- if ((pipe->device_speed == CVMX_USB_SPEED_HIGH) &&
- (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT) &&
- (usbc_hcint.s.nak))
- pipe->flags |= CVMX_USB_PIPE_FLAGS_NEED_PING;
- if (!buffer_space_left ||
- (bytes_in_last_packet < pipe->max_packet))
- cvmx_usb_complete(usb, pipe, transaction,
- CVMX_USB_STATUS_OK);
- }
-}
-
-static void cvmx_usb_transfer_intr(struct octeon_hcd *usb,
- struct cvmx_usb_pipe *pipe,
- struct cvmx_usb_transaction *transaction,
- int buffer_space_left,
- int bytes_in_last_packet)
-{
- if (cvmx_usb_pipe_needs_split(usb, pipe)) {
- if (transaction->stage == CVMX_USB_STAGE_NON_CONTROL) {
- transaction->stage =
- CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE;
- } else if (buffer_space_left &&
- (bytes_in_last_packet == pipe->max_packet)) {
- transaction->stage = CVMX_USB_STAGE_NON_CONTROL;
- } else {
- pipe->next_tx_frame += pipe->interval;
- cvmx_usb_complete(usb, pipe, transaction,
- CVMX_USB_STATUS_OK);
- }
- } else if (!buffer_space_left ||
- (bytes_in_last_packet < pipe->max_packet)) {
- pipe->next_tx_frame += pipe->interval;
- cvmx_usb_complete(usb, pipe, transaction, CVMX_USB_STATUS_OK);
- }
-}
-
-static void cvmx_usb_transfer_isoc(struct octeon_hcd *usb,
- struct cvmx_usb_pipe *pipe,
- struct cvmx_usb_transaction *transaction,
- int buffer_space_left,
- int bytes_in_last_packet,
- int bytes_this_transfer)
-{
- if (cvmx_usb_pipe_needs_split(usb, pipe)) {
- /*
- * ISOCHRONOUS OUT splits don't require a complete split stage.
- * Instead they use a sequence of begin OUT splits to transfer
- * the data 188 bytes at a time. Once the transfer is complete,
- * the pipe sleeps until the next schedule interval.
- */
- if (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT) {
- /*
- * If no space left or this wasn't a max size packet
- * then this transfer is complete. Otherwise start it
- * again to send the next 188 bytes
- */
- if (!buffer_space_left || (bytes_this_transfer < 188)) {
- pipe->next_tx_frame += pipe->interval;
- cvmx_usb_complete(usb, pipe, transaction,
- CVMX_USB_STATUS_OK);
- }
- return;
- }
- if (transaction->stage ==
- CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE) {
- /*
- * We are in the incoming data phase. Keep getting data
- * until we run out of space or get a small packet
- */
- if ((buffer_space_left == 0) ||
- (bytes_in_last_packet < pipe->max_packet)) {
- pipe->next_tx_frame += pipe->interval;
- cvmx_usb_complete(usb, pipe, transaction,
- CVMX_USB_STATUS_OK);
- }
- } else {
- transaction->stage =
- CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE;
- }
- } else {
- pipe->next_tx_frame += pipe->interval;
- cvmx_usb_complete(usb, pipe, transaction, CVMX_USB_STATUS_OK);
- }
-}
-
-/**
- * Poll a channel for status
- *
- * @usb: USB device
- * @channel: Channel to poll
- *
- * Returns: Zero on success
- */
-static int cvmx_usb_poll_channel(struct octeon_hcd *usb, int channel)
-{
- struct usb_hcd *hcd = octeon_to_hcd(usb);
- struct device *dev = hcd->self.controller;
- union cvmx_usbcx_hcintx usbc_hcint;
- union cvmx_usbcx_hctsizx usbc_hctsiz;
- union cvmx_usbcx_hccharx usbc_hcchar;
- struct cvmx_usb_pipe *pipe;
- struct cvmx_usb_transaction *transaction;
- int bytes_this_transfer;
- int bytes_in_last_packet;
- int packets_processed;
- int buffer_space_left;
-
- /* Read the interrupt status bits for the channel */
- usbc_hcint.u32 = cvmx_usb_read_csr32(usb,
- CVMX_USBCX_HCINTX(channel, usb->index));
-
- if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA) {
- usbc_hcchar.u32 = cvmx_usb_read_csr32(usb,
- CVMX_USBCX_HCCHARX(channel, usb->index));
-
- if (usbc_hcchar.s.chena && usbc_hcchar.s.chdis) {
- /*
- * There seems to be a bug in CN31XX which can cause
- * interrupt IN transfers to get stuck until we do a
- * write of HCCHARX without changing things
- */
- cvmx_usb_write_csr32(usb,
- CVMX_USBCX_HCCHARX(channel,
- usb->index),
- usbc_hcchar.u32);
- return 0;
- }
-
- /*
- * In non DMA mode the channels don't halt themselves. We need
- * to manually disable channels that are left running
- */
- if (!usbc_hcint.s.chhltd) {
- if (usbc_hcchar.s.chena) {
- union cvmx_usbcx_hcintmskx hcintmsk;
- /* Disable all interrupts except CHHLTD */
- hcintmsk.u32 = 0;
- hcintmsk.s.chhltdmsk = 1;
- cvmx_usb_write_csr32(usb,
- CVMX_USBCX_HCINTMSKX(channel, usb->index),
- hcintmsk.u32);
- usbc_hcchar.s.chdis = 1;
- cvmx_usb_write_csr32(usb,
- CVMX_USBCX_HCCHARX(channel, usb->index),
- usbc_hcchar.u32);
- return 0;
- } else if (usbc_hcint.s.xfercompl) {
- /*
- * Successful IN/OUT with transfer complete.
- * Channel halt isn't needed.
- */
- } else {
- dev_err(dev, "USB%d: Channel %d interrupt without halt\n",
- usb->index, channel);
- return 0;
- }
- }
- } else {
- /*
- * There is are no interrupts that we need to process when the
- * channel is still running
- */
- if (!usbc_hcint.s.chhltd)
- return 0;
- }
-
- /* Disable the channel interrupts now that it is done */
- cvmx_usb_write_csr32(usb, CVMX_USBCX_HCINTMSKX(channel, usb->index), 0);
- usb->idle_hardware_channels |= (1 << channel);
-
- /* Make sure this channel is tied to a valid pipe */
- pipe = usb->pipe_for_channel[channel];
- prefetch(pipe);
- if (!pipe)
- return 0;
- transaction = list_first_entry(&pipe->transactions,
- typeof(*transaction),
- node);
- prefetch(transaction);
-
- /*
- * Disconnect this pipe from the HW channel. Later the schedule
- * function will figure out which pipe needs to go
- */
- usb->pipe_for_channel[channel] = NULL;
- pipe->flags &= ~CVMX_USB_PIPE_FLAGS_SCHEDULED;
-
- /*
- * Read the channel config info so we can figure out how much data
- * transferred
- */
- usbc_hcchar.u32 = cvmx_usb_read_csr32(usb,
- CVMX_USBCX_HCCHARX(channel, usb->index));
- usbc_hctsiz.u32 = cvmx_usb_read_csr32(usb,
- CVMX_USBCX_HCTSIZX(channel, usb->index));
-
- /*
- * Calculating the number of bytes successfully transferred is dependent
- * on the transfer direction
- */
- packets_processed = transaction->pktcnt - usbc_hctsiz.s.pktcnt;
- if (usbc_hcchar.s.epdir) {
- /*
- * IN transactions are easy. For every byte received the
- * hardware decrements xfersize. All we need to do is subtract
- * the current value of xfersize from its starting value and we
- * know how many bytes were written to the buffer
- */
- bytes_this_transfer = transaction->xfersize -
- usbc_hctsiz.s.xfersize;
- } else {
- /*
- * OUT transaction don't decrement xfersize. Instead pktcnt is
- * decremented on every successful packet send. The hardware
- * does this when it receives an ACK, or NYET. If it doesn't
- * receive one of these responses pktcnt doesn't change
- */
- bytes_this_transfer = packets_processed * usbc_hcchar.s.mps;
- /*
- * The last packet may not be a full transfer if we didn't have
- * enough data
- */
- if (bytes_this_transfer > transaction->xfersize)
- bytes_this_transfer = transaction->xfersize;
- }
- /* Figure out how many bytes were in the last packet of the transfer */
- if (packets_processed)
- bytes_in_last_packet = bytes_this_transfer -
- (packets_processed - 1) * usbc_hcchar.s.mps;
- else
- bytes_in_last_packet = bytes_this_transfer;
-
- /*
- * As a special case, setup transactions output the setup header, not
- * the user's data. For this reason we don't count setup data as bytes
- * transferred
- */
- if ((transaction->stage == CVMX_USB_STAGE_SETUP) ||
- (transaction->stage == CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE))
- bytes_this_transfer = 0;
-
- /*
- * Add the bytes transferred to the running total. It is important that
- * bytes_this_transfer doesn't count any data that needs to be
- * retransmitted
- */
- transaction->actual_bytes += bytes_this_transfer;
- if (transaction->type == CVMX_USB_TRANSFER_ISOCHRONOUS)
- buffer_space_left = transaction->iso_packets[0].length -
- transaction->actual_bytes;
- else
- buffer_space_left = transaction->buffer_length -
- transaction->actual_bytes;
-
- /*
- * We need to remember the PID toggle state for the next transaction.
- * The hardware already updated it for the next transaction
- */
- pipe->pid_toggle = !(usbc_hctsiz.s.pid == 0);
-
- /*
- * For high speed bulk out, assume the next transaction will need to do
- * a ping before proceeding. If this isn't true the ACK processing below
- * will clear this flag
- */
- if ((pipe->device_speed == CVMX_USB_SPEED_HIGH) &&
- (pipe->transfer_type == CVMX_USB_TRANSFER_BULK) &&
- (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT))
- pipe->flags |= CVMX_USB_PIPE_FLAGS_NEED_PING;
-
- if (WARN_ON_ONCE(bytes_this_transfer < 0)) {
- /*
- * In some rare cases the DMA engine seems to get stuck and
- * keeps substracting same byte count over and over again. In
- * such case we just need to fail every transaction.
- */
- cvmx_usb_complete(usb, pipe, transaction,
- CVMX_USB_STATUS_ERROR);
- return 0;
- }
-
- if (usbc_hcint.s.stall) {
- /*
- * STALL as a response means this transaction cannot be
- * completed because the device can't process transactions. Tell
- * the user. Any data that was transferred will be counted on
- * the actual bytes transferred
- */
- pipe->pid_toggle = 0;
- cvmx_usb_complete(usb, pipe, transaction,
- CVMX_USB_STATUS_STALL);
- } else if (usbc_hcint.s.xacterr) {
- /*
- * XactErr as a response means the device signaled
- * something wrong with the transfer. For example, PID
- * toggle errors cause these.
- */
- cvmx_usb_complete(usb, pipe, transaction,
- CVMX_USB_STATUS_XACTERR);
- } else if (usbc_hcint.s.bblerr) {
- /* Babble Error (BblErr) */
- cvmx_usb_complete(usb, pipe, transaction,
- CVMX_USB_STATUS_BABBLEERR);
- } else if (usbc_hcint.s.datatglerr) {
- /* Data toggle error */
- cvmx_usb_complete(usb, pipe, transaction,
- CVMX_USB_STATUS_DATATGLERR);
- } else if (usbc_hcint.s.nyet) {
- /*
- * NYET as a response is only allowed in three cases: as a
- * response to a ping, as a response to a split transaction, and
- * as a response to a bulk out. The ping case is handled by
- * hardware, so we only have splits and bulk out
- */
- if (!cvmx_usb_pipe_needs_split(usb, pipe)) {
- transaction->retries = 0;
- /*
- * If there is more data to go then we need to try
- * again. Otherwise this transaction is complete
- */
- if ((buffer_space_left == 0) ||
- (bytes_in_last_packet < pipe->max_packet))
- cvmx_usb_complete(usb, pipe,
- transaction,
- CVMX_USB_STATUS_OK);
- } else {
- /*
- * Split transactions retry the split complete 4 times
- * then rewind to the start split and do the entire
- * transactions again
- */
- transaction->retries++;
- if ((transaction->retries & 0x3) == 0) {
- /*
- * Rewind to the beginning of the transaction by
- * anding off the split complete bit
- */
- transaction->stage &= ~1;
- pipe->split_sc_frame = -1;
- }
- }
- } else if (usbc_hcint.s.ack) {
- transaction->retries = 0;
- /*
- * The ACK bit can only be checked after the other error bits.
- * This is because a multi packet transfer may succeed in a
- * number of packets and then get a different response on the
- * last packet. In this case both ACK and the last response bit
- * will be set. If none of the other response bits is set, then
- * the last packet must have been an ACK
- *
- * Since we got an ACK, we know we don't need to do a ping on
- * this pipe
- */
- pipe->flags &= ~CVMX_USB_PIPE_FLAGS_NEED_PING;
-
- switch (transaction->type) {
- case CVMX_USB_TRANSFER_CONTROL:
- cvmx_usb_transfer_control(usb, pipe, transaction,
- usbc_hcchar,
- buffer_space_left,
- bytes_in_last_packet);
- break;
- case CVMX_USB_TRANSFER_BULK:
- cvmx_usb_transfer_bulk(usb, pipe, transaction,
- usbc_hcint, buffer_space_left,
- bytes_in_last_packet);
- break;
- case CVMX_USB_TRANSFER_INTERRUPT:
- cvmx_usb_transfer_intr(usb, pipe, transaction,
- buffer_space_left,
- bytes_in_last_packet);
- break;
- case CVMX_USB_TRANSFER_ISOCHRONOUS:
- cvmx_usb_transfer_isoc(usb, pipe, transaction,
- buffer_space_left,
- bytes_in_last_packet,
- bytes_this_transfer);
- break;
- }
- } else if (usbc_hcint.s.nak) {
- /*
- * If this was a split then clear our split in progress marker.
- */
- if (usb->active_split == transaction)
- usb->active_split = NULL;
- /*
- * NAK as a response means the device couldn't accept the
- * transaction, but it should be retried in the future. Rewind
- * to the beginning of the transaction by anding off the split
- * complete bit. Retry in the next interval
- */
- transaction->retries = 0;
- transaction->stage &= ~1;
- pipe->next_tx_frame += pipe->interval;
- if (pipe->next_tx_frame < usb->frame_number)
- pipe->next_tx_frame = usb->frame_number +
- pipe->interval -
- (usb->frame_number - pipe->next_tx_frame) %
- pipe->interval;
- } else {
- struct cvmx_usb_port_status port;
-
- port = cvmx_usb_get_status(usb);
- if (port.port_enabled) {
- /* We'll retry the exact same transaction again */
- transaction->retries++;
- } else {
- /*
- * We get channel halted interrupts with no result bits
- * sets when the cable is unplugged
- */
- cvmx_usb_complete(usb, pipe, transaction,
- CVMX_USB_STATUS_ERROR);
- }
- }
- return 0;
-}
-
-static void octeon_usb_port_callback(struct octeon_hcd *usb)
-{
- spin_unlock(&usb->lock);
- usb_hcd_poll_rh_status(octeon_to_hcd(usb));
- spin_lock(&usb->lock);
-}
-
-/**
- * Poll the USB block for status and call all needed callback
- * handlers. This function is meant to be called in the interrupt
- * handler for the USB controller. It can also be called
- * periodically in a loop for non-interrupt based operation.
- *
- * @usb: USB device state populated by cvmx_usb_initialize().
- *
- * Returns: 0 or a negative error code.
- */
-static int cvmx_usb_poll(struct octeon_hcd *usb)
-{
- union cvmx_usbcx_hfnum usbc_hfnum;
- union cvmx_usbcx_gintsts usbc_gintsts;
-
- prefetch_range(usb, sizeof(*usb));
-
- /* Update the frame counter */
- usbc_hfnum.u32 = cvmx_usb_read_csr32(usb, CVMX_USBCX_HFNUM(usb->index));
- if ((usb->frame_number & 0x3fff) > usbc_hfnum.s.frnum)
- usb->frame_number += 0x4000;
- usb->frame_number &= ~0x3fffull;
- usb->frame_number |= usbc_hfnum.s.frnum;
-
- /* Read the pending interrupts */
- usbc_gintsts.u32 = cvmx_usb_read_csr32(usb,
- CVMX_USBCX_GINTSTS(usb->index));
-
- /* Clear the interrupts now that we know about them */
- cvmx_usb_write_csr32(usb, CVMX_USBCX_GINTSTS(usb->index),
- usbc_gintsts.u32);
-
- if (usbc_gintsts.s.rxflvl) {
- /*
- * RxFIFO Non-Empty (RxFLvl)
- * Indicates that there is at least one packet pending to be
- * read from the RxFIFO.
- *
- * In DMA mode this is handled by hardware
- */
- if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
- cvmx_usb_poll_rx_fifo(usb);
- }
- if (usbc_gintsts.s.ptxfemp || usbc_gintsts.s.nptxfemp) {
- /* Fill the Tx FIFOs when not in DMA mode */
- if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
- cvmx_usb_poll_tx_fifo(usb);
- }
- if (usbc_gintsts.s.disconnint || usbc_gintsts.s.prtint) {
- union cvmx_usbcx_hprt usbc_hprt;
- /*
- * Disconnect Detected Interrupt (DisconnInt)
- * Asserted when a device disconnect is detected.
- *
- * Host Port Interrupt (PrtInt)
- * The core sets this bit to indicate a change in port status of
- * one of the O2P USB core ports in Host mode. The application
- * must read the Host Port Control and Status (HPRT) register to
- * determine the exact event that caused this interrupt. The
- * application must clear the appropriate status bit in the Host
- * Port Control and Status register to clear this bit.
- *
- * Call the user's port callback
- */
- octeon_usb_port_callback(usb);
- /* Clear the port change bits */
- usbc_hprt.u32 =
- cvmx_usb_read_csr32(usb, CVMX_USBCX_HPRT(usb->index));
- usbc_hprt.s.prtena = 0;
- cvmx_usb_write_csr32(usb, CVMX_USBCX_HPRT(usb->index),
- usbc_hprt.u32);
- }
- if (usbc_gintsts.s.hchint) {
- /*
- * Host Channels Interrupt (HChInt)
- * The core sets this bit to indicate that an interrupt is
- * pending on one of the channels of the core (in Host mode).
- * The application must read the Host All Channels Interrupt
- * (HAINT) register to determine the exact number of the channel
- * on which the interrupt occurred, and then read the
- * corresponding Host Channel-n Interrupt (HCINTn) register to
- * determine the exact cause of the interrupt. The application
- * must clear the appropriate status bit in the HCINTn register
- * to clear this bit.
- */
- union cvmx_usbcx_haint usbc_haint;
-
- usbc_haint.u32 = cvmx_usb_read_csr32(usb,
- CVMX_USBCX_HAINT(usb->index));
- while (usbc_haint.u32) {
- int channel;
-
- channel = __fls(usbc_haint.u32);
- cvmx_usb_poll_channel(usb, channel);
- usbc_haint.u32 ^= 1 << channel;
- }
- }
-
- cvmx_usb_schedule(usb, usbc_gintsts.s.sof);
-
- return 0;
-}
-
-/* convert between an HCD pointer and the corresponding struct octeon_hcd */
-static inline struct octeon_hcd *hcd_to_octeon(struct usb_hcd *hcd)
-{
- return (struct octeon_hcd *)(hcd->hcd_priv);
-}
-
-static irqreturn_t octeon_usb_irq(struct usb_hcd *hcd)
-{
- struct octeon_hcd *usb = hcd_to_octeon(hcd);
- unsigned long flags;
-
- spin_lock_irqsave(&usb->lock, flags);
- cvmx_usb_poll(usb);
- spin_unlock_irqrestore(&usb->lock, flags);
- return IRQ_HANDLED;
-}
-
-static int octeon_usb_start(struct usb_hcd *hcd)
-{
- hcd->state = HC_STATE_RUNNING;
- return 0;
-}
-
-static void octeon_usb_stop(struct usb_hcd *hcd)
-{
- hcd->state = HC_STATE_HALT;
-}
-
-static int octeon_usb_get_frame_number(struct usb_hcd *hcd)
-{
- struct octeon_hcd *usb = hcd_to_octeon(hcd);
-
- return cvmx_usb_get_frame_number(usb);
-}
-
-static int octeon_usb_urb_enqueue(struct usb_hcd *hcd,
- struct urb *urb,
- gfp_t mem_flags)
-{
- struct octeon_hcd *usb = hcd_to_octeon(hcd);
- struct device *dev = hcd->self.controller;
- struct cvmx_usb_transaction *transaction = NULL;
- struct cvmx_usb_pipe *pipe;
- unsigned long flags;
- struct cvmx_usb_iso_packet *iso_packet;
- struct usb_host_endpoint *ep = urb->ep;
- int rc;
-
- urb->status = 0;
- spin_lock_irqsave(&usb->lock, flags);
-
- rc = usb_hcd_link_urb_to_ep(hcd, urb);
- if (rc) {
- spin_unlock_irqrestore(&usb->lock, flags);
- return rc;
- }
-
- if (!ep->hcpriv) {
- enum cvmx_usb_transfer transfer_type;
- enum cvmx_usb_speed speed;
- int split_device = 0;
- int split_port = 0;
-
- switch (usb_pipetype(urb->pipe)) {
- case PIPE_ISOCHRONOUS:
- transfer_type = CVMX_USB_TRANSFER_ISOCHRONOUS;
- break;
- case PIPE_INTERRUPT:
- transfer_type = CVMX_USB_TRANSFER_INTERRUPT;
- break;
- case PIPE_CONTROL:
- transfer_type = CVMX_USB_TRANSFER_CONTROL;
- break;
- default:
- transfer_type = CVMX_USB_TRANSFER_BULK;
- break;
- }
- switch (urb->dev->speed) {
- case USB_SPEED_LOW:
- speed = CVMX_USB_SPEED_LOW;
- break;
- case USB_SPEED_FULL:
- speed = CVMX_USB_SPEED_FULL;
- break;
- default:
- speed = CVMX_USB_SPEED_HIGH;
- break;
- }
- /*
- * For slow devices on high speed ports we need to find the hub
- * that does the speed translation so we know where to send the
- * split transactions.
- */
- if (speed != CVMX_USB_SPEED_HIGH) {
- /*
- * Start at this device and work our way up the usb
- * tree.
- */
- struct usb_device *dev = urb->dev;
-
- while (dev->parent) {
- /*
- * If our parent is high speed then he'll
- * receive the splits.
- */
- if (dev->parent->speed == USB_SPEED_HIGH) {
- split_device = dev->parent->devnum;
- split_port = dev->portnum;
- break;
- }
- /*
- * Move up the tree one level. If we make it all
- * the way up the tree, then the port must not
- * be in high speed mode and we don't need a
- * split.
- */
- dev = dev->parent;
- }
- }
- pipe = cvmx_usb_open_pipe(usb, usb_pipedevice(urb->pipe),
- usb_pipeendpoint(urb->pipe), speed,
- le16_to_cpu(ep->desc.wMaxPacketSize)
- & 0x7ff,
- transfer_type,
- usb_pipein(urb->pipe) ?
- CVMX_USB_DIRECTION_IN :
- CVMX_USB_DIRECTION_OUT,
- urb->interval,
- (le16_to_cpu(ep->desc.wMaxPacketSize)
- >> 11) & 0x3,
- split_device, split_port);
- if (!pipe) {
- usb_hcd_unlink_urb_from_ep(hcd, urb);
- spin_unlock_irqrestore(&usb->lock, flags);
- dev_dbg(dev, "Failed to create pipe\n");
- return -ENOMEM;
- }
- ep->hcpriv = pipe;
- } else {
- pipe = ep->hcpriv;
- }
-
- switch (usb_pipetype(urb->pipe)) {
- case PIPE_ISOCHRONOUS:
- dev_dbg(dev, "Submit isochronous to %d.%d\n",
- usb_pipedevice(urb->pipe),
- usb_pipeendpoint(urb->pipe));
- /*
- * Allocate a structure to use for our private list of
- * isochronous packets.
- */
- iso_packet = kmalloc_array(urb->number_of_packets,
- sizeof(struct cvmx_usb_iso_packet),
- GFP_ATOMIC);
- if (iso_packet) {
- int i;
- /* Fill the list with the data from the URB */
- for (i = 0; i < urb->number_of_packets; i++) {
- iso_packet[i].offset =
- urb->iso_frame_desc[i].offset;
- iso_packet[i].length =
- urb->iso_frame_desc[i].length;
- iso_packet[i].status = CVMX_USB_STATUS_ERROR;
- }
- /*
- * Store a pointer to the list in the URB setup_packet
- * field. We know this currently isn't being used and
- * this saves us a bunch of logic.
- */
- urb->setup_packet = (char *)iso_packet;
- transaction = cvmx_usb_submit_isochronous(usb,
- pipe, urb);
- /*
- * If submit failed we need to free our private packet
- * list.
- */
- if (!transaction) {
- urb->setup_packet = NULL;
- kfree(iso_packet);
- }
- }
- break;
- case PIPE_INTERRUPT:
- dev_dbg(dev, "Submit interrupt to %d.%d\n",
- usb_pipedevice(urb->pipe),
- usb_pipeendpoint(urb->pipe));
- transaction = cvmx_usb_submit_interrupt(usb, pipe, urb);
- break;
- case PIPE_CONTROL:
- dev_dbg(dev, "Submit control to %d.%d\n",
- usb_pipedevice(urb->pipe),
- usb_pipeendpoint(urb->pipe));
- transaction = cvmx_usb_submit_control(usb, pipe, urb);
- break;
- case PIPE_BULK:
- dev_dbg(dev, "Submit bulk to %d.%d\n",
- usb_pipedevice(urb->pipe),
- usb_pipeendpoint(urb->pipe));
- transaction = cvmx_usb_submit_bulk(usb, pipe, urb);
- break;
- }
- if (!transaction) {
- usb_hcd_unlink_urb_from_ep(hcd, urb);
- spin_unlock_irqrestore(&usb->lock, flags);
- dev_dbg(dev, "Failed to submit\n");
- return -ENOMEM;
- }
- urb->hcpriv = transaction;
- spin_unlock_irqrestore(&usb->lock, flags);
- return 0;
-}
-
-static int octeon_usb_urb_dequeue(struct usb_hcd *hcd,
- struct urb *urb,
- int status)
-{
- struct octeon_hcd *usb = hcd_to_octeon(hcd);
- unsigned long flags;
- int rc;
-
- if (!urb->dev)
- return -EINVAL;
-
- spin_lock_irqsave(&usb->lock, flags);
-
- rc = usb_hcd_check_unlink_urb(hcd, urb, status);
- if (rc)
- goto out;
-
- urb->status = status;
- cvmx_usb_cancel(usb, urb->ep->hcpriv, urb->hcpriv);
-
-out:
- spin_unlock_irqrestore(&usb->lock, flags);
-
- return rc;
-}
-
-static void octeon_usb_endpoint_disable(struct usb_hcd *hcd,
- struct usb_host_endpoint *ep)
-{
- struct device *dev = hcd->self.controller;
-
- if (ep->hcpriv) {
- struct octeon_hcd *usb = hcd_to_octeon(hcd);
- struct cvmx_usb_pipe *pipe = ep->hcpriv;
- unsigned long flags;
-
- spin_lock_irqsave(&usb->lock, flags);
- cvmx_usb_cancel_all(usb, pipe);
- if (cvmx_usb_close_pipe(usb, pipe))
- dev_dbg(dev, "Closing pipe %p failed\n", pipe);
- spin_unlock_irqrestore(&usb->lock, flags);
- ep->hcpriv = NULL;
- }
-}
-
-static int octeon_usb_hub_status_data(struct usb_hcd *hcd, char *buf)
-{
- struct octeon_hcd *usb = hcd_to_octeon(hcd);
- struct cvmx_usb_port_status port_status;
- unsigned long flags;
-
- spin_lock_irqsave(&usb->lock, flags);
- port_status = cvmx_usb_get_status(usb);
- spin_unlock_irqrestore(&usb->lock, flags);
- buf[0] = port_status.connect_change << 1;
-
- return buf[0] != 0;
-}
-
-static int octeon_usb_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
- u16 wIndex, char *buf, u16 wLength)
-{
- struct octeon_hcd *usb = hcd_to_octeon(hcd);
- struct device *dev = hcd->self.controller;
- struct cvmx_usb_port_status usb_port_status;
- int port_status;
- struct usb_hub_descriptor *desc;
- unsigned long flags;
-
- switch (typeReq) {
- case ClearHubFeature:
- dev_dbg(dev, "ClearHubFeature\n");
- switch (wValue) {
- case C_HUB_LOCAL_POWER:
- case C_HUB_OVER_CURRENT:
- /* Nothing required here */
- break;
- default:
- return -EINVAL;
- }
- break;
- case ClearPortFeature:
- dev_dbg(dev, "ClearPortFeature\n");
- if (wIndex != 1) {
- dev_dbg(dev, " INVALID\n");
- return -EINVAL;
- }
-
- switch (wValue) {
- case USB_PORT_FEAT_ENABLE:
- dev_dbg(dev, " ENABLE\n");
- spin_lock_irqsave(&usb->lock, flags);
- cvmx_usb_disable(usb);
- spin_unlock_irqrestore(&usb->lock, flags);
- break;
- case USB_PORT_FEAT_SUSPEND:
- dev_dbg(dev, " SUSPEND\n");
- /* Not supported on Octeon */
- break;
- case USB_PORT_FEAT_POWER:
- dev_dbg(dev, " POWER\n");
- /* Not supported on Octeon */
- break;
- case USB_PORT_FEAT_INDICATOR:
- dev_dbg(dev, " INDICATOR\n");
- /* Port inidicator not supported */
- break;
- case USB_PORT_FEAT_C_CONNECTION:
- dev_dbg(dev, " C_CONNECTION\n");
- /* Clears drivers internal connect status change flag */
- spin_lock_irqsave(&usb->lock, flags);
- usb->port_status = cvmx_usb_get_status(usb);
- spin_unlock_irqrestore(&usb->lock, flags);
- break;
- case USB_PORT_FEAT_C_RESET:
- dev_dbg(dev, " C_RESET\n");
- /*
- * Clears the driver's internal Port Reset Change flag.
- */
- spin_lock_irqsave(&usb->lock, flags);
- usb->port_status = cvmx_usb_get_status(usb);
- spin_unlock_irqrestore(&usb->lock, flags);
- break;
- case USB_PORT_FEAT_C_ENABLE:
- dev_dbg(dev, " C_ENABLE\n");
- /*
- * Clears the driver's internal Port Enable/Disable
- * Change flag.
- */
- spin_lock_irqsave(&usb->lock, flags);
- usb->port_status = cvmx_usb_get_status(usb);
- spin_unlock_irqrestore(&usb->lock, flags);
- break;
- case USB_PORT_FEAT_C_SUSPEND:
- dev_dbg(dev, " C_SUSPEND\n");
- /*
- * Clears the driver's internal Port Suspend Change
- * flag, which is set when resume signaling on the host
- * port is complete.
- */
- break;
- case USB_PORT_FEAT_C_OVER_CURRENT:
- dev_dbg(dev, " C_OVER_CURRENT\n");
- /* Clears the driver's overcurrent Change flag */
- spin_lock_irqsave(&usb->lock, flags);
- usb->port_status = cvmx_usb_get_status(usb);
- spin_unlock_irqrestore(&usb->lock, flags);
- break;
- default:
- dev_dbg(dev, " UNKNOWN\n");
- return -EINVAL;
- }
- break;
- case GetHubDescriptor:
- dev_dbg(dev, "GetHubDescriptor\n");
- desc = (struct usb_hub_descriptor *)buf;
- desc->bDescLength = 9;
- desc->bDescriptorType = 0x29;
- desc->bNbrPorts = 1;
- desc->wHubCharacteristics = cpu_to_le16(0x08);
- desc->bPwrOn2PwrGood = 1;
- desc->bHubContrCurrent = 0;
- desc->u.hs.DeviceRemovable[0] = 0;
- desc->u.hs.DeviceRemovable[1] = 0xff;
- break;
- case GetHubStatus:
- dev_dbg(dev, "GetHubStatus\n");
- *(__le32 *)buf = 0;
- break;
- case GetPortStatus:
- dev_dbg(dev, "GetPortStatus\n");
- if (wIndex != 1) {
- dev_dbg(dev, " INVALID\n");
- return -EINVAL;
- }
-
- spin_lock_irqsave(&usb->lock, flags);
- usb_port_status = cvmx_usb_get_status(usb);
- spin_unlock_irqrestore(&usb->lock, flags);
- port_status = 0;
-
- if (usb_port_status.connect_change) {
- port_status |= (1 << USB_PORT_FEAT_C_CONNECTION);
- dev_dbg(dev, " C_CONNECTION\n");
- }
-
- if (usb_port_status.port_enabled) {
- port_status |= (1 << USB_PORT_FEAT_C_ENABLE);
- dev_dbg(dev, " C_ENABLE\n");
- }
-
- if (usb_port_status.connected) {
- port_status |= (1 << USB_PORT_FEAT_CONNECTION);
- dev_dbg(dev, " CONNECTION\n");
- }
-
- if (usb_port_status.port_enabled) {
- port_status |= (1 << USB_PORT_FEAT_ENABLE);
- dev_dbg(dev, " ENABLE\n");
- }
-
- if (usb_port_status.port_over_current) {
- port_status |= (1 << USB_PORT_FEAT_OVER_CURRENT);
- dev_dbg(dev, " OVER_CURRENT\n");
- }
-
- if (usb_port_status.port_powered) {
- port_status |= (1 << USB_PORT_FEAT_POWER);
- dev_dbg(dev, " POWER\n");
- }
-
- if (usb_port_status.port_speed == CVMX_USB_SPEED_HIGH) {
- port_status |= USB_PORT_STAT_HIGH_SPEED;
- dev_dbg(dev, " HIGHSPEED\n");
- } else if (usb_port_status.port_speed == CVMX_USB_SPEED_LOW) {
- port_status |= (1 << USB_PORT_FEAT_LOWSPEED);
- dev_dbg(dev, " LOWSPEED\n");
- }
-
- *((__le32 *)buf) = cpu_to_le32(port_status);
- break;
- case SetHubFeature:
- dev_dbg(dev, "SetHubFeature\n");
- /* No HUB features supported */
- break;
- case SetPortFeature:
- dev_dbg(dev, "SetPortFeature\n");
- if (wIndex != 1) {
- dev_dbg(dev, " INVALID\n");
- return -EINVAL;
- }
-
- switch (wValue) {
- case USB_PORT_FEAT_SUSPEND:
- dev_dbg(dev, " SUSPEND\n");
- return -EINVAL;
- case USB_PORT_FEAT_POWER:
- dev_dbg(dev, " POWER\n");
- /*
- * Program the port power bit to drive VBUS on the USB.
- */
- spin_lock_irqsave(&usb->lock, flags);
- USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index),
- cvmx_usbcx_hprt, prtpwr, 1);
- spin_unlock_irqrestore(&usb->lock, flags);
- return 0;
- case USB_PORT_FEAT_RESET:
- dev_dbg(dev, " RESET\n");
- spin_lock_irqsave(&usb->lock, flags);
- cvmx_usb_reset_port(usb);
- spin_unlock_irqrestore(&usb->lock, flags);
- return 0;
- case USB_PORT_FEAT_INDICATOR:
- dev_dbg(dev, " INDICATOR\n");
- /* Not supported */
- break;
- default:
- dev_dbg(dev, " UNKNOWN\n");
- return -EINVAL;
- }
- break;
- default:
- dev_dbg(dev, "Unknown root hub request\n");
- return -EINVAL;
- }
- return 0;
-}
-
-static const struct hc_driver octeon_hc_driver = {
- .description = "Octeon USB",
- .product_desc = "Octeon Host Controller",
- .hcd_priv_size = sizeof(struct octeon_hcd),
- .irq = octeon_usb_irq,
- .flags = HCD_MEMORY | HCD_DMA | HCD_USB2,
- .start = octeon_usb_start,
- .stop = octeon_usb_stop,
- .urb_enqueue = octeon_usb_urb_enqueue,
- .urb_dequeue = octeon_usb_urb_dequeue,
- .endpoint_disable = octeon_usb_endpoint_disable,
- .get_frame_number = octeon_usb_get_frame_number,
- .hub_status_data = octeon_usb_hub_status_data,
- .hub_control = octeon_usb_hub_control,
- .map_urb_for_dma = octeon_map_urb_for_dma,
- .unmap_urb_for_dma = octeon_unmap_urb_for_dma,
-};
-
-static int octeon_usb_probe(struct platform_device *pdev)
-{
- int status;
- int initialize_flags;
- int usb_num;
- struct resource *res_mem;
- struct device_node *usbn_node;
- int irq = platform_get_irq(pdev, 0);
- struct device *dev = &pdev->dev;
- struct octeon_hcd *usb;
- struct usb_hcd *hcd;
- u32 clock_rate = 48000000;
- bool is_crystal_clock = false;
- const char *clock_type;
- int i;
-
- if (!dev->of_node) {
- dev_err(dev, "Error: empty of_node\n");
- return -ENXIO;
- }
- usbn_node = dev->of_node->parent;
-
- i = of_property_read_u32(usbn_node,
- "clock-frequency", &clock_rate);
- if (i)
- i = of_property_read_u32(usbn_node,
- "refclk-frequency", &clock_rate);
- if (i) {
- dev_err(dev, "No USBN \"clock-frequency\"\n");
- return -ENXIO;
- }
- switch (clock_rate) {
- case 12000000:
- initialize_flags = CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ;
- break;
- case 24000000:
- initialize_flags = CVMX_USB_INITIALIZE_FLAGS_CLOCK_24MHZ;
- break;
- case 48000000:
- initialize_flags = CVMX_USB_INITIALIZE_FLAGS_CLOCK_48MHZ;
- break;
- default:
- dev_err(dev, "Illegal USBN \"clock-frequency\" %u\n",
- clock_rate);
- return -ENXIO;
- }
-
- i = of_property_read_string(usbn_node,
- "cavium,refclk-type", &clock_type);
- if (i)
- i = of_property_read_string(usbn_node,
- "refclk-type", &clock_type);
-
- if (!i && strcmp("crystal", clock_type) == 0)
- is_crystal_clock = true;
-
- if (is_crystal_clock)
- initialize_flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_XI;
- else
- initialize_flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND;
-
- res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res_mem) {
- dev_err(dev, "found no memory resource\n");
- return -ENXIO;
- }
- usb_num = (res_mem->start >> 44) & 1;
-
- if (irq < 0) {
- /* Defective device tree, but we know how to fix it. */
- irq_hw_number_t hwirq = usb_num ? (1 << 6) + 17 : 56;
-
- irq = irq_create_mapping(NULL, hwirq);
- }
-
- /*
- * Set the DMA mask to 64bits so we get buffers already translated for
- * DMA.
- */
- i = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(64));
- if (i)
- return i;
-
- /*
- * Only cn52XX and cn56XX have DWC_OTG USB hardware and the
- * IOB priority registers. Under heavy network load USB
- * hardware can be starved by the IOB causing a crash. Give
- * it a priority boost if it has been waiting more than 400
- * cycles to avoid this situation.
- *
- * Testing indicates that a cnt_val of 8192 is not sufficient,
- * but no failures are seen with 4096. We choose a value of
- * 400 to give a safety factor of 10.
- */
- if (OCTEON_IS_MODEL(OCTEON_CN52XX) || OCTEON_IS_MODEL(OCTEON_CN56XX)) {
- union cvmx_iob_n2c_l2c_pri_cnt pri_cnt;
-
- pri_cnt.u64 = 0;
- pri_cnt.s.cnt_enb = 1;
- pri_cnt.s.cnt_val = 400;
- cvmx_write_csr(CVMX_IOB_N2C_L2C_PRI_CNT, pri_cnt.u64);
- }
-
- hcd = usb_create_hcd(&octeon_hc_driver, dev, dev_name(dev));
- if (!hcd) {
- dev_dbg(dev, "Failed to allocate memory for HCD\n");
- return -1;
- }
- hcd->uses_new_polling = 1;
- usb = (struct octeon_hcd *)hcd->hcd_priv;
-
- spin_lock_init(&usb->lock);
-
- usb->init_flags = initialize_flags;
-
- /* Initialize the USB state structure */
- usb->index = usb_num;
- INIT_LIST_HEAD(&usb->idle_pipes);
- for (i = 0; i < ARRAY_SIZE(usb->active_pipes); i++)
- INIT_LIST_HEAD(&usb->active_pipes[i]);
-
- /* Due to an errata, CN31XX doesn't support DMA */
- if (OCTEON_IS_MODEL(OCTEON_CN31XX)) {
- usb->init_flags |= CVMX_USB_INITIALIZE_FLAGS_NO_DMA;
- /* Only use one channel with non DMA */
- usb->idle_hardware_channels = 0x1;
- } else if (OCTEON_IS_MODEL(OCTEON_CN5XXX)) {
- /* CN5XXX have an errata with channel 3 */
- usb->idle_hardware_channels = 0xf7;
- } else {
- usb->idle_hardware_channels = 0xff;
- }
-
- status = cvmx_usb_initialize(dev, usb);
- if (status) {
- dev_dbg(dev, "USB initialization failed with %d\n", status);
- usb_put_hcd(hcd);
- return -1;
- }
-
- status = usb_add_hcd(hcd, irq, 0);
- if (status) {
- dev_dbg(dev, "USB add HCD failed with %d\n", status);
- usb_put_hcd(hcd);
- return -1;
- }
- device_wakeup_enable(hcd->self.controller);
-
- dev_info(dev, "Registered HCD for port %d on irq %d\n", usb_num, irq);
-
- return 0;
-}
-
-static int octeon_usb_remove(struct platform_device *pdev)
-{
- int status;
- struct device *dev = &pdev->dev;
- struct usb_hcd *hcd = dev_get_drvdata(dev);
- struct octeon_hcd *usb = hcd_to_octeon(hcd);
- unsigned long flags;
-
- usb_remove_hcd(hcd);
- spin_lock_irqsave(&usb->lock, flags);
- status = cvmx_usb_shutdown(usb);
- spin_unlock_irqrestore(&usb->lock, flags);
- if (status)
- dev_dbg(dev, "USB shutdown failed with %d\n", status);
-
- usb_put_hcd(hcd);
-
- return 0;
-}
-
-static const struct of_device_id octeon_usb_match[] = {
- {
- .compatible = "cavium,octeon-5750-usbc",
- },
- {},
-};
-MODULE_DEVICE_TABLE(of, octeon_usb_match);
-
-static struct platform_driver octeon_usb_driver = {
- .driver = {
- .name = "octeon-hcd",
- .of_match_table = octeon_usb_match,
- },
- .probe = octeon_usb_probe,
- .remove = octeon_usb_remove,
-};
-
-static int __init octeon_usb_driver_init(void)
-{
- if (usb_disabled())
- return 0;
-
- return platform_driver_register(&octeon_usb_driver);
-}
-module_init(octeon_usb_driver_init);
-
-static void __exit octeon_usb_driver_exit(void)
-{
- if (usb_disabled())
- return;
-
- platform_driver_unregister(&octeon_usb_driver);
-}
-module_exit(octeon_usb_driver_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Cavium, Inc. <support@cavium.com>");
-MODULE_DESCRIPTION("Cavium Inc. OCTEON USB Host driver.");
diff --git a/drivers/staging/octeon-usb/octeon-hcd.h b/drivers/staging/octeon-usb/octeon-hcd.h
deleted file mode 100644
index 9ed619c93a4e..000000000000
--- a/drivers/staging/octeon-usb/octeon-hcd.h
+++ /dev/null
@@ -1,1847 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Octeon HCD hardware register definitions.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Some parts of the code were originally released under BSD license:
- *
- * Copyright (c) 2003-2010 Cavium Networks (support@cavium.com). All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * * Neither the name of Cavium Networks nor the names of
- * its contributors may be used to endorse or promote products
- * derived from this software without specific prior written
- * permission.
- *
- * This Software, including technical data, may be subject to U.S. export
- * control laws, including the U.S. Export Administration Act and its associated
- * regulations, and may be subject to export or import regulations in other
- * countries.
- *
- * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
- * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS OR
- * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
- * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION
- * OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
- * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
- * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
- * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
- * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR
- * PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
- */
-
-#ifndef __OCTEON_HCD_H__
-#define __OCTEON_HCD_H__
-
-#include <asm/bitfield.h>
-
-#define CVMX_USBCXBASE 0x00016F0010000000ull
-#define CVMX_USBCXREG1(reg, bid) \
- (CVMX_ADD_IO_SEG(CVMX_USBCXBASE | reg) + \
- ((bid) & 1) * 0x100000000000ull)
-#define CVMX_USBCXREG2(reg, bid, off) \
- (CVMX_ADD_IO_SEG(CVMX_USBCXBASE | reg) + \
- (((off) & 7) + ((bid) & 1) * 0x8000000000ull) * 32)
-
-#define CVMX_USBCX_GAHBCFG(bid) CVMX_USBCXREG1(0x008, bid)
-#define CVMX_USBCX_GHWCFG3(bid) CVMX_USBCXREG1(0x04c, bid)
-#define CVMX_USBCX_GINTMSK(bid) CVMX_USBCXREG1(0x018, bid)
-#define CVMX_USBCX_GINTSTS(bid) CVMX_USBCXREG1(0x014, bid)
-#define CVMX_USBCX_GNPTXFSIZ(bid) CVMX_USBCXREG1(0x028, bid)
-#define CVMX_USBCX_GNPTXSTS(bid) CVMX_USBCXREG1(0x02c, bid)
-#define CVMX_USBCX_GOTGCTL(bid) CVMX_USBCXREG1(0x000, bid)
-#define CVMX_USBCX_GRSTCTL(bid) CVMX_USBCXREG1(0x010, bid)
-#define CVMX_USBCX_GRXFSIZ(bid) CVMX_USBCXREG1(0x024, bid)
-#define CVMX_USBCX_GRXSTSPH(bid) CVMX_USBCXREG1(0x020, bid)
-#define CVMX_USBCX_GUSBCFG(bid) CVMX_USBCXREG1(0x00c, bid)
-#define CVMX_USBCX_HAINT(bid) CVMX_USBCXREG1(0x414, bid)
-#define CVMX_USBCX_HAINTMSK(bid) CVMX_USBCXREG1(0x418, bid)
-#define CVMX_USBCX_HCCHARX(off, bid) CVMX_USBCXREG2(0x500, bid, off)
-#define CVMX_USBCX_HCFG(bid) CVMX_USBCXREG1(0x400, bid)
-#define CVMX_USBCX_HCINTMSKX(off, bid) CVMX_USBCXREG2(0x50c, bid, off)
-#define CVMX_USBCX_HCINTX(off, bid) CVMX_USBCXREG2(0x508, bid, off)
-#define CVMX_USBCX_HCSPLTX(off, bid) CVMX_USBCXREG2(0x504, bid, off)
-#define CVMX_USBCX_HCTSIZX(off, bid) CVMX_USBCXREG2(0x510, bid, off)
-#define CVMX_USBCX_HFIR(bid) CVMX_USBCXREG1(0x404, bid)
-#define CVMX_USBCX_HFNUM(bid) CVMX_USBCXREG1(0x408, bid)
-#define CVMX_USBCX_HPRT(bid) CVMX_USBCXREG1(0x440, bid)
-#define CVMX_USBCX_HPTXFSIZ(bid) CVMX_USBCXREG1(0x100, bid)
-#define CVMX_USBCX_HPTXSTS(bid) CVMX_USBCXREG1(0x410, bid)
-
-#define CVMX_USBNXBID1(bid) (((bid) & 1) * 0x10000000ull)
-#define CVMX_USBNXBID2(bid) (((bid) & 1) * 0x100000000000ull)
-
-#define CVMX_USBNXREG1(reg, bid) \
- (CVMX_ADD_IO_SEG(0x0001180068000000ull | reg) + CVMX_USBNXBID1(bid))
-#define CVMX_USBNXREG2(reg, bid) \
- (CVMX_ADD_IO_SEG(0x00016F0000000000ull | reg) + CVMX_USBNXBID2(bid))
-
-#define CVMX_USBNX_CLK_CTL(bid) CVMX_USBNXREG1(0x10, bid)
-#define CVMX_USBNX_DMA0_INB_CHN0(bid) CVMX_USBNXREG2(0x818, bid)
-#define CVMX_USBNX_DMA0_OUTB_CHN0(bid) CVMX_USBNXREG2(0x858, bid)
-#define CVMX_USBNX_USBP_CTL_STATUS(bid) CVMX_USBNXREG1(0x18, bid)
-
-/**
- * cvmx_usbc#_gahbcfg
- *
- * Core AHB Configuration Register (GAHBCFG)
- *
- * This register can be used to configure the core after power-on or a change in
- * mode of operation. This register mainly contains AHB system-related
- * configuration parameters. The AHB is the processor interface to the O2P USB
- * core. In general, software need not know about this interface except to
- * program the values as specified.
- *
- * The application must program this register as part of the O2P USB core
- * initialization. Do not change this register after the initial programming.
- */
-union cvmx_usbcx_gahbcfg {
- u32 u32;
- /**
- * struct cvmx_usbcx_gahbcfg_s
- * @ptxfemplvl: Periodic TxFIFO Empty Level (PTxFEmpLvl)
- * Software should set this bit to 0x1.
- * Indicates when the Periodic TxFIFO Empty Interrupt bit in the
- * Core Interrupt register (GINTSTS.PTxFEmp) is triggered. This
- * bit is used only in Slave mode.
- * * 1'b0: GINTSTS.PTxFEmp interrupt indicates that the Periodic
- * TxFIFO is half empty
- * * 1'b1: GINTSTS.PTxFEmp interrupt indicates that the Periodic
- * TxFIFO is completely empty
- * @nptxfemplvl: Non-Periodic TxFIFO Empty Level (NPTxFEmpLvl)
- * Software should set this bit to 0x1.
- * Indicates when the Non-Periodic TxFIFO Empty Interrupt bit in
- * the Core Interrupt register (GINTSTS.NPTxFEmp) is triggered.
- * This bit is used only in Slave mode.
- * * 1'b0: GINTSTS.NPTxFEmp interrupt indicates that the Non-
- * Periodic TxFIFO is half empty
- * * 1'b1: GINTSTS.NPTxFEmp interrupt indicates that the Non-
- * Periodic TxFIFO is completely empty
- * @dmaen: DMA Enable (DMAEn)
- * * 1'b0: Core operates in Slave mode
- * * 1'b1: Core operates in a DMA mode
- * @hbstlen: Burst Length/Type (HBstLen)
- * This field has not effect and should be left as 0x0.
- * @glblintrmsk: Global Interrupt Mask (GlblIntrMsk)
- * Software should set this field to 0x1.
- * The application uses this bit to mask or unmask the interrupt
- * line assertion to itself. Irrespective of this bit's setting,
- * the interrupt status registers are updated by the core.
- * * 1'b0: Mask the interrupt assertion to the application.
- * * 1'b1: Unmask the interrupt assertion to the application.
- */
- struct cvmx_usbcx_gahbcfg_s {
- __BITFIELD_FIELD(u32 reserved_9_31 : 23,
- __BITFIELD_FIELD(u32 ptxfemplvl : 1,
- __BITFIELD_FIELD(u32 nptxfemplvl : 1,
- __BITFIELD_FIELD(u32 reserved_6_6 : 1,
- __BITFIELD_FIELD(u32 dmaen : 1,
- __BITFIELD_FIELD(u32 hbstlen : 4,
- __BITFIELD_FIELD(u32 glblintrmsk : 1,
- ;)))))))
- } s;
-};
-
-/**
- * cvmx_usbc#_ghwcfg3
- *
- * User HW Config3 Register (GHWCFG3)
- *
- * This register contains the configuration options of the O2P USB core.
- */
-union cvmx_usbcx_ghwcfg3 {
- u32 u32;
- /**
- * struct cvmx_usbcx_ghwcfg3_s
- * @dfifodepth: DFIFO Depth (DfifoDepth)
- * This value is in terms of 32-bit words.
- * * Minimum value is 32
- * * Maximum value is 32768
- * @ahbphysync: AHB and PHY Synchronous (AhbPhySync)
- * Indicates whether AHB and PHY clocks are synchronous to
- * each other.
- * * 1'b0: No
- * * 1'b1: Yes
- * This bit is tied to 1.
- * @rsttype: Reset Style for Clocked always Blocks in RTL (RstType)
- * * 1'b0: Asynchronous reset is used in the core
- * * 1'b1: Synchronous reset is used in the core
- * @optfeature: Optional Features Removed (OptFeature)
- * Indicates whether the User ID register, GPIO interface ports,
- * and SOF toggle and counter ports were removed for gate count
- * optimization.
- * @vendor_control_interface_support: Vendor Control Interface Support
- * * 1'b0: Vendor Control Interface is not available on the core.
- * * 1'b1: Vendor Control Interface is available.
- * @i2c_selection: I2C Selection
- * * 1'b0: I2C Interface is not available on the core.
- * * 1'b1: I2C Interface is available on the core.
- * @otgen: OTG Function Enabled (OtgEn)
- * The application uses this bit to indicate the O2P USB core's
- * OTG capabilities.
- * * 1'b0: Not OTG capable
- * * 1'b1: OTG Capable
- * @pktsizewidth: Width of Packet Size Counters (PktSizeWidth)
- * * 3'b000: 4 bits
- * * 3'b001: 5 bits
- * * 3'b010: 6 bits
- * * 3'b011: 7 bits
- * * 3'b100: 8 bits
- * * 3'b101: 9 bits
- * * 3'b110: 10 bits
- * * Others: Reserved
- * @xfersizewidth: Width of Transfer Size Counters (XferSizeWidth)
- * * 4'b0000: 11 bits
- * * 4'b0001: 12 bits
- * - ...
- * * 4'b1000: 19 bits
- * * Others: Reserved
- */
- struct cvmx_usbcx_ghwcfg3_s {
- __BITFIELD_FIELD(u32 dfifodepth : 16,
- __BITFIELD_FIELD(u32 reserved_13_15 : 3,
- __BITFIELD_FIELD(u32 ahbphysync : 1,
- __BITFIELD_FIELD(u32 rsttype : 1,
- __BITFIELD_FIELD(u32 optfeature : 1,
- __BITFIELD_FIELD(u32 vendor_control_interface_support : 1,
- __BITFIELD_FIELD(u32 i2c_selection : 1,
- __BITFIELD_FIELD(u32 otgen : 1,
- __BITFIELD_FIELD(u32 pktsizewidth : 3,
- __BITFIELD_FIELD(u32 xfersizewidth : 4,
- ;))))))))))
- } s;
-};
-
-/**
- * cvmx_usbc#_gintmsk
- *
- * Core Interrupt Mask Register (GINTMSK)
- *
- * This register works with the Core Interrupt register to interrupt the
- * application. When an interrupt bit is masked, the interrupt associated with
- * that bit will not be generated. However, the Core Interrupt (GINTSTS)
- * register bit corresponding to that interrupt will still be set.
- * Mask interrupt: 1'b0, Unmask interrupt: 1'b1
- */
-union cvmx_usbcx_gintmsk {
- u32 u32;
- /**
- * struct cvmx_usbcx_gintmsk_s
- * @wkupintmsk: Resume/Remote Wakeup Detected Interrupt Mask
- * (WkUpIntMsk)
- * @sessreqintmsk: Session Request/New Session Detected Interrupt Mask
- * (SessReqIntMsk)
- * @disconnintmsk: Disconnect Detected Interrupt Mask (DisconnIntMsk)
- * @conidstschngmsk: Connector ID Status Change Mask (ConIDStsChngMsk)
- * @ptxfempmsk: Periodic TxFIFO Empty Mask (PTxFEmpMsk)
- * @hchintmsk: Host Channels Interrupt Mask (HChIntMsk)
- * @prtintmsk: Host Port Interrupt Mask (PrtIntMsk)
- * @fetsuspmsk: Data Fetch Suspended Mask (FetSuspMsk)
- * @incomplpmsk: Incomplete Periodic Transfer Mask (incomplPMsk)
- * Incomplete Isochronous OUT Transfer Mask
- * (incompISOOUTMsk)
- * @incompisoinmsk: Incomplete Isochronous IN Transfer Mask
- * (incompISOINMsk)
- * @oepintmsk: OUT Endpoints Interrupt Mask (OEPIntMsk)
- * @inepintmsk: IN Endpoints Interrupt Mask (INEPIntMsk)
- * @epmismsk: Endpoint Mismatch Interrupt Mask (EPMisMsk)
- * @eopfmsk: End of Periodic Frame Interrupt Mask (EOPFMsk)
- * @isooutdropmsk: Isochronous OUT Packet Dropped Interrupt Mask
- * (ISOOutDropMsk)
- * @enumdonemsk: Enumeration Done Mask (EnumDoneMsk)
- * @usbrstmsk: USB Reset Mask (USBRstMsk)
- * @usbsuspmsk: USB Suspend Mask (USBSuspMsk)
- * @erlysuspmsk: Early Suspend Mask (ErlySuspMsk)
- * @i2cint: I2C Interrupt Mask (I2CINT)
- * @ulpickintmsk: ULPI Carkit Interrupt Mask (ULPICKINTMsk)
- * I2C Carkit Interrupt Mask (I2CCKINTMsk)
- * @goutnakeffmsk: Global OUT NAK Effective Mask (GOUTNakEffMsk)
- * @ginnakeffmsk: Global Non-Periodic IN NAK Effective Mask
- * (GINNakEffMsk)
- * @nptxfempmsk: Non-Periodic TxFIFO Empty Mask (NPTxFEmpMsk)
- * @rxflvlmsk: Receive FIFO Non-Empty Mask (RxFLvlMsk)
- * @sofmsk: Start of (micro)Frame Mask (SofMsk)
- * @otgintmsk: OTG Interrupt Mask (OTGIntMsk)
- * @modemismsk: Mode Mismatch Interrupt Mask (ModeMisMsk)
- */
- struct cvmx_usbcx_gintmsk_s {
- __BITFIELD_FIELD(u32 wkupintmsk : 1,
- __BITFIELD_FIELD(u32 sessreqintmsk : 1,
- __BITFIELD_FIELD(u32 disconnintmsk : 1,
- __BITFIELD_FIELD(u32 conidstschngmsk : 1,
- __BITFIELD_FIELD(u32 reserved_27_27 : 1,
- __BITFIELD_FIELD(u32 ptxfempmsk : 1,
- __BITFIELD_FIELD(u32 hchintmsk : 1,
- __BITFIELD_FIELD(u32 prtintmsk : 1,
- __BITFIELD_FIELD(u32 reserved_23_23 : 1,
- __BITFIELD_FIELD(u32 fetsuspmsk : 1,
- __BITFIELD_FIELD(u32 incomplpmsk : 1,
- __BITFIELD_FIELD(u32 incompisoinmsk : 1,
- __BITFIELD_FIELD(u32 oepintmsk : 1,
- __BITFIELD_FIELD(u32 inepintmsk : 1,
- __BITFIELD_FIELD(u32 epmismsk : 1,
- __BITFIELD_FIELD(u32 reserved_16_16 : 1,
- __BITFIELD_FIELD(u32 eopfmsk : 1,
- __BITFIELD_FIELD(u32 isooutdropmsk : 1,
- __BITFIELD_FIELD(u32 enumdonemsk : 1,
- __BITFIELD_FIELD(u32 usbrstmsk : 1,
- __BITFIELD_FIELD(u32 usbsuspmsk : 1,
- __BITFIELD_FIELD(u32 erlysuspmsk : 1,
- __BITFIELD_FIELD(u32 i2cint : 1,
- __BITFIELD_FIELD(u32 ulpickintmsk : 1,
- __BITFIELD_FIELD(u32 goutnakeffmsk : 1,
- __BITFIELD_FIELD(u32 ginnakeffmsk : 1,
- __BITFIELD_FIELD(u32 nptxfempmsk : 1,
- __BITFIELD_FIELD(u32 rxflvlmsk : 1,
- __BITFIELD_FIELD(u32 sofmsk : 1,
- __BITFIELD_FIELD(u32 otgintmsk : 1,
- __BITFIELD_FIELD(u32 modemismsk : 1,
- __BITFIELD_FIELD(u32 reserved_0_0 : 1,
- ;))))))))))))))))))))))))))))))))
- } s;
-};
-
-/**
- * cvmx_usbc#_gintsts
- *
- * Core Interrupt Register (GINTSTS)
- *
- * This register interrupts the application for system-level events in the
- * current mode of operation (Device mode or Host mode). It is shown in
- * Interrupt. Some of the bits in this register are valid only in Host mode,
- * while others are valid in Device mode only. This register also indicates the
- * current mode of operation. In order to clear the interrupt status bits of
- * type R_SS_WC, the application must write 1'b1 into the bit. The FIFO status
- * interrupts are read only; once software reads from or writes to the FIFO
- * while servicing these interrupts, FIFO interrupt conditions are cleared
- * automatically.
- */
-union cvmx_usbcx_gintsts {
- u32 u32;
- /**
- * struct cvmx_usbcx_gintsts_s
- * @wkupint: Resume/Remote Wakeup Detected Interrupt (WkUpInt)
- * In Device mode, this interrupt is asserted when a resume is
- * detected on the USB. In Host mode, this interrupt is asserted
- * when a remote wakeup is detected on the USB.
- * For more information on how to use this interrupt, see "Partial
- * Power-Down and Clock Gating Programming Model" on
- * page 353.
- * @sessreqint: Session Request/New Session Detected Interrupt
- * (SessReqInt)
- * In Host mode, this interrupt is asserted when a session request
- * is detected from the device. In Device mode, this interrupt is
- * asserted when the utmiotg_bvalid signal goes high.
- * For more information on how to use this interrupt, see "Partial
- * Power-Down and Clock Gating Programming Model" on
- * page 353.
- * @disconnint: Disconnect Detected Interrupt (DisconnInt)
- * Asserted when a device disconnect is detected.
- * @conidstschng: Connector ID Status Change (ConIDStsChng)
- * The core sets this bit when there is a change in connector ID
- * status.
- * @ptxfemp: Periodic TxFIFO Empty (PTxFEmp)
- * Asserted when the Periodic Transmit FIFO is either half or
- * completely empty and there is space for at least one entry to be
- * written in the Periodic Request Queue. The half or completely
- * empty status is determined by the Periodic TxFIFO Empty Level
- * bit in the Core AHB Configuration register
- * (GAHBCFG.PTxFEmpLvl).
- * @hchint: Host Channels Interrupt (HChInt)
- * The core sets this bit to indicate that an interrupt is pending
- * on one of the channels of the core (in Host mode). The
- * application must read the Host All Channels Interrupt (HAINT)
- * register to determine the exact number of the channel on which
- * the interrupt occurred, and then read the corresponding Host
- * Channel-n Interrupt (HCINTn) register to determine the exact
- * cause of the interrupt. The application must clear the
- * appropriate status bit in the HCINTn register to clear this bit.
- * @prtint: Host Port Interrupt (PrtInt)
- * The core sets this bit to indicate a change in port status of
- * one of the O2P USB core ports in Host mode. The application must
- * read the Host Port Control and Status (HPRT) register to
- * determine the exact event that caused this interrupt. The
- * application must clear the appropriate status bit in the Host
- * Port Control and Status register to clear this bit.
- * @fetsusp: Data Fetch Suspended (FetSusp)
- * This interrupt is valid only in DMA mode. This interrupt
- * indicates that the core has stopped fetching data for IN
- * endpoints due to the unavailability of TxFIFO space or Request
- * Queue space. This interrupt is used by the application for an
- * endpoint mismatch algorithm.
- * @incomplp: Incomplete Periodic Transfer (incomplP)
- * In Host mode, the core sets this interrupt bit when there are
- * incomplete periodic transactions still pending which are
- * scheduled for the current microframe.
- * Incomplete Isochronous OUT Transfer (incompISOOUT)
- * The Device mode, the core sets this interrupt to indicate that
- * there is at least one isochronous OUT endpoint on which the
- * transfer is not completed in the current microframe. This
- * interrupt is asserted along with the End of Periodic Frame
- * Interrupt (EOPF) bit in this register.
- * @incompisoin: Incomplete Isochronous IN Transfer (incompISOIN)
- * The core sets this interrupt to indicate that there is at least
- * one isochronous IN endpoint on which the transfer is not
- * completed in the current microframe. This interrupt is asserted
- * along with the End of Periodic Frame Interrupt (EOPF) bit in
- * this register.
- * @oepint: OUT Endpoints Interrupt (OEPInt)
- * The core sets this bit to indicate that an interrupt is pending
- * on one of the OUT endpoints of the core (in Device mode). The
- * application must read the Device All Endpoints Interrupt
- * (DAINT) register to determine the exact number of the OUT
- * endpoint on which the interrupt occurred, and then read the
- * corresponding Device OUT Endpoint-n Interrupt (DOEPINTn)
- * register to determine the exact cause of the interrupt. The
- * application must clear the appropriate status bit in the
- * corresponding DOEPINTn register to clear this bit.
- * @iepint: IN Endpoints Interrupt (IEPInt)
- * The core sets this bit to indicate that an interrupt is pending
- * on one of the IN endpoints of the core (in Device mode). The
- * application must read the Device All Endpoints Interrupt
- * (DAINT) register to determine the exact number of the IN
- * endpoint on which the interrupt occurred, and then read the
- * corresponding Device IN Endpoint-n Interrupt (DIEPINTn)
- * register to determine the exact cause of the interrupt. The
- * application must clear the appropriate status bit in the
- * corresponding DIEPINTn register to clear this bit.
- * @epmis: Endpoint Mismatch Interrupt (EPMis)
- * Indicates that an IN token has been received for a non-periodic
- * endpoint, but the data for another endpoint is present in the
- * top of the Non-Periodic Transmit FIFO and the IN endpoint
- * mismatch count programmed by the application has expired.
- * @eopf: End of Periodic Frame Interrupt (EOPF)
- * Indicates that the period specified in the Periodic Frame
- * Interval field of the Device Configuration register
- * (DCFG.PerFrInt) has been reached in the current microframe.
- * @isooutdrop: Isochronous OUT Packet Dropped Interrupt (ISOOutDrop)
- * The core sets this bit when it fails to write an isochronous OUT
- * packet into the RxFIFO because the RxFIFO doesn't have
- * enough space to accommodate a maximum packet size packet
- * for the isochronous OUT endpoint.
- * @enumdone: Enumeration Done (EnumDone)
- * The core sets this bit to indicate that speed enumeration is
- * complete. The application must read the Device Status (DSTS)
- * register to obtain the enumerated speed.
- * @usbrst: USB Reset (USBRst)
- * The core sets this bit to indicate that a reset is detected on
- * the USB.
- * @usbsusp: USB Suspend (USBSusp)
- * The core sets this bit to indicate that a suspend was detected
- * on the USB. The core enters the Suspended state when there
- * is no activity on the phy_line_state_i signal for an extended
- * period of time.
- * @erlysusp: Early Suspend (ErlySusp)
- * The core sets this bit to indicate that an Idle state has been
- * detected on the USB for 3 ms.
- * @i2cint: I2C Interrupt (I2CINT)
- * This bit is always 0x0.
- * @ulpickint: ULPI Carkit Interrupt (ULPICKINT)
- * This bit is always 0x0.
- * @goutnakeff: Global OUT NAK Effective (GOUTNakEff)
- * Indicates that the Set Global OUT NAK bit in the Device Control
- * register (DCTL.SGOUTNak), set by the application, has taken
- * effect in the core. This bit can be cleared by writing the Clear
- * Global OUT NAK bit in the Device Control register
- * (DCTL.CGOUTNak).
- * @ginnakeff: Global IN Non-Periodic NAK Effective (GINNakEff)
- * Indicates that the Set Global Non-Periodic IN NAK bit in the
- * Device Control register (DCTL.SGNPInNak), set by the
- * application, has taken effect in the core. That is, the core has
- * sampled the Global IN NAK bit set by the application. This bit
- * can be cleared by clearing the Clear Global Non-Periodic IN
- * NAK bit in the Device Control register (DCTL.CGNPInNak).
- * This interrupt does not necessarily mean that a NAK handshake
- * is sent out on the USB. The STALL bit takes precedence over
- * the NAK bit.
- * @nptxfemp: Non-Periodic TxFIFO Empty (NPTxFEmp)
- * This interrupt is asserted when the Non-Periodic TxFIFO is
- * either half or completely empty, and there is space for at least
- * one entry to be written to the Non-Periodic Transmit Request
- * Queue. The half or completely empty status is determined by
- * the Non-Periodic TxFIFO Empty Level bit in the Core AHB
- * Configuration register (GAHBCFG.NPTxFEmpLvl).
- * @rxflvl: RxFIFO Non-Empty (RxFLvl)
- * Indicates that there is at least one packet pending to be read
- * from the RxFIFO.
- * @sof: Start of (micro)Frame (Sof)
- * In Host mode, the core sets this bit to indicate that an SOF
- * (FS), micro-SOF (HS), or Keep-Alive (LS) is transmitted on the
- * USB. The application must write a 1 to this bit to clear the
- * interrupt.
- * In Device mode, in the core sets this bit to indicate that an
- * SOF token has been received on the USB. The application can read
- * the Device Status register to get the current (micro)frame
- * number. This interrupt is seen only when the core is operating
- * at either HS or FS.
- * @otgint: OTG Interrupt (OTGInt)
- * The core sets this bit to indicate an OTG protocol event. The
- * application must read the OTG Interrupt Status (GOTGINT)
- * register to determine the exact event that caused this
- * interrupt. The application must clear the appropriate status bit
- * in the GOTGINT register to clear this bit.
- * @modemis: Mode Mismatch Interrupt (ModeMis)
- * The core sets this bit when the application is trying to access:
- * * A Host mode register, when the core is operating in Device
- * mode
- * * A Device mode register, when the core is operating in Host
- * mode
- * The register access is completed on the AHB with an OKAY
- * response, but is ignored by the core internally and doesn't
- * affect the operation of the core.
- * @curmod: Current Mode of Operation (CurMod)
- * Indicates the current mode of operation.
- * * 1'b0: Device mode
- * * 1'b1: Host mode
- */
- struct cvmx_usbcx_gintsts_s {
- __BITFIELD_FIELD(u32 wkupint : 1,
- __BITFIELD_FIELD(u32 sessreqint : 1,
- __BITFIELD_FIELD(u32 disconnint : 1,
- __BITFIELD_FIELD(u32 conidstschng : 1,
- __BITFIELD_FIELD(u32 reserved_27_27 : 1,
- __BITFIELD_FIELD(u32 ptxfemp : 1,
- __BITFIELD_FIELD(u32 hchint : 1,
- __BITFIELD_FIELD(u32 prtint : 1,
- __BITFIELD_FIELD(u32 reserved_23_23 : 1,
- __BITFIELD_FIELD(u32 fetsusp : 1,
- __BITFIELD_FIELD(u32 incomplp : 1,
- __BITFIELD_FIELD(u32 incompisoin : 1,
- __BITFIELD_FIELD(u32 oepint : 1,
- __BITFIELD_FIELD(u32 iepint : 1,
- __BITFIELD_FIELD(u32 epmis : 1,
- __BITFIELD_FIELD(u32 reserved_16_16 : 1,
- __BITFIELD_FIELD(u32 eopf : 1,
- __BITFIELD_FIELD(u32 isooutdrop : 1,
- __BITFIELD_FIELD(u32 enumdone : 1,
- __BITFIELD_FIELD(u32 usbrst : 1,
- __BITFIELD_FIELD(u32 usbsusp : 1,
- __BITFIELD_FIELD(u32 erlysusp : 1,
- __BITFIELD_FIELD(u32 i2cint : 1,
- __BITFIELD_FIELD(u32 ulpickint : 1,
- __BITFIELD_FIELD(u32 goutnakeff : 1,
- __BITFIELD_FIELD(u32 ginnakeff : 1,
- __BITFIELD_FIELD(u32 nptxfemp : 1,
- __BITFIELD_FIELD(u32 rxflvl : 1,
- __BITFIELD_FIELD(u32 sof : 1,
- __BITFIELD_FIELD(u32 otgint : 1,
- __BITFIELD_FIELD(u32 modemis : 1,
- __BITFIELD_FIELD(u32 curmod : 1,
- ;))))))))))))))))))))))))))))))))
- } s;
-};
-
-/**
- * cvmx_usbc#_gnptxfsiz
- *
- * Non-Periodic Transmit FIFO Size Register (GNPTXFSIZ)
- *
- * The application can program the RAM size and the memory start address for the
- * Non-Periodic TxFIFO.
- */
-union cvmx_usbcx_gnptxfsiz {
- u32 u32;
- /**
- * struct cvmx_usbcx_gnptxfsiz_s
- * @nptxfdep: Non-Periodic TxFIFO Depth (NPTxFDep)
- * This value is in terms of 32-bit words.
- * Minimum value is 16
- * Maximum value is 32768
- * @nptxfstaddr: Non-Periodic Transmit RAM Start Address (NPTxFStAddr)
- * This field contains the memory start address for Non-Periodic
- * Transmit FIFO RAM.
- */
- struct cvmx_usbcx_gnptxfsiz_s {
- __BITFIELD_FIELD(u32 nptxfdep : 16,
- __BITFIELD_FIELD(u32 nptxfstaddr : 16,
- ;))
- } s;
-};
-
-/**
- * cvmx_usbc#_gnptxsts
- *
- * Non-Periodic Transmit FIFO/Queue Status Register (GNPTXSTS)
- *
- * This read-only register contains the free space information for the
- * Non-Periodic TxFIFO and the Non-Periodic Transmit Request Queue.
- */
-union cvmx_usbcx_gnptxsts {
- u32 u32;
- /**
- * struct cvmx_usbcx_gnptxsts_s
- * @nptxqtop: Top of the Non-Periodic Transmit Request Queue (NPTxQTop)
- * Entry in the Non-Periodic Tx Request Queue that is currently
- * being processed by the MAC.
- * * Bits [30:27]: Channel/endpoint number
- * * Bits [26:25]:
- * - 2'b00: IN/OUT token
- * - 2'b01: Zero-length transmit packet (device IN/host OUT)
- * - 2'b10: PING/CSPLIT token
- * - 2'b11: Channel halt command
- * * Bit [24]: Terminate (last entry for selected channel/endpoint)
- * @nptxqspcavail: Non-Periodic Transmit Request Queue Space Available
- * (NPTxQSpcAvail)
- * Indicates the amount of free space available in the Non-
- * Periodic Transmit Request Queue. This queue holds both IN
- * and OUT requests in Host mode. Device mode has only IN
- * requests.
- * * 8'h0: Non-Periodic Transmit Request Queue is full
- * * 8'h1: 1 location available
- * * 8'h2: 2 locations available
- * * n: n locations available (0..8)
- * * Others: Reserved
- * @nptxfspcavail: Non-Periodic TxFIFO Space Avail (NPTxFSpcAvail)
- * Indicates the amount of free space available in the Non-
- * Periodic TxFIFO.
- * Values are in terms of 32-bit words.
- * * 16'h0: Non-Periodic TxFIFO is full
- * * 16'h1: 1 word available
- * * 16'h2: 2 words available
- * * 16'hn: n words available (where 0..32768)
- * * 16'h8000: 32768 words available
- * * Others: Reserved
- */
- struct cvmx_usbcx_gnptxsts_s {
- __BITFIELD_FIELD(u32 reserved_31_31 : 1,
- __BITFIELD_FIELD(u32 nptxqtop : 7,
- __BITFIELD_FIELD(u32 nptxqspcavail : 8,
- __BITFIELD_FIELD(u32 nptxfspcavail : 16,
- ;))))
- } s;
-};
-
-/**
- * cvmx_usbc#_grstctl
- *
- * Core Reset Register (GRSTCTL)
- *
- * The application uses this register to reset various hardware features inside
- * the core.
- */
-union cvmx_usbcx_grstctl {
- u32 u32;
- /**
- * struct cvmx_usbcx_grstctl_s
- * @ahbidle: AHB Master Idle (AHBIdle)
- * Indicates that the AHB Master State Machine is in the IDLE
- * condition.
- * @dmareq: DMA Request Signal (DMAReq)
- * Indicates that the DMA request is in progress. Used for debug.
- * @txfnum: TxFIFO Number (TxFNum)
- * This is the FIFO number that must be flushed using the TxFIFO
- * Flush bit. This field must not be changed until the core clears
- * the TxFIFO Flush bit.
- * * 5'h0: Non-Periodic TxFIFO flush
- * * 5'h1: Periodic TxFIFO 1 flush in Device mode or Periodic
- * TxFIFO flush in Host mode
- * * 5'h2: Periodic TxFIFO 2 flush in Device mode
- * - ...
- * * 5'hF: Periodic TxFIFO 15 flush in Device mode
- * * 5'h10: Flush all the Periodic and Non-Periodic TxFIFOs in the
- * core
- * @txfflsh: TxFIFO Flush (TxFFlsh)
- * This bit selectively flushes a single or all transmit FIFOs, but
- * cannot do so if the core is in the midst of a transaction.
- * The application must only write this bit after checking that the
- * core is neither writing to the TxFIFO nor reading from the
- * TxFIFO.
- * The application must wait until the core clears this bit before
- * performing any operations. This bit takes 8 clocks (of phy_clk
- * or hclk, whichever is slower) to clear.
- * @rxfflsh: RxFIFO Flush (RxFFlsh)
- * The application can flush the entire RxFIFO using this bit, but
- * must first ensure that the core is not in the middle of a
- * transaction.
- * The application must only write to this bit after checking that
- * the core is neither reading from the RxFIFO nor writing to the
- * RxFIFO.
- * The application must wait until the bit is cleared before
- * performing any other operations. This bit will take 8 clocks
- * (slowest of PHY or AHB clock) to clear.
- * @intknqflsh: IN Token Sequence Learning Queue Flush (INTknQFlsh)
- * The application writes this bit to flush the IN Token Sequence
- * Learning Queue.
- * @frmcntrrst: Host Frame Counter Reset (FrmCntrRst)
- * The application writes this bit to reset the (micro)frame number
- * counter inside the core. When the (micro)frame counter is reset,
- * the subsequent SOF sent out by the core will have a
- * (micro)frame number of 0.
- * @hsftrst: HClk Soft Reset (HSftRst)
- * The application uses this bit to flush the control logic in the
- * AHB Clock domain. Only AHB Clock Domain pipelines are reset.
- * * FIFOs are not flushed with this bit.
- * * All state machines in the AHB clock domain are reset to the
- * Idle state after terminating the transactions on the AHB,
- * following the protocol.
- * * CSR control bits used by the AHB clock domain state
- * machines are cleared.
- * * To clear this interrupt, status mask bits that control the
- * interrupt status and are generated by the AHB clock domain
- * state machine are cleared.
- * * Because interrupt status bits are not cleared, the application
- * can get the status of any core events that occurred after it set
- * this bit.
- * This is a self-clearing bit that the core clears after all
- * necessary logic is reset in the core. This may take several
- * clocks, depending on the core's current state.
- * @csftrst: Core Soft Reset (CSftRst)
- * Resets the hclk and phy_clock domains as follows:
- * * Clears the interrupts and all the CSR registers except the
- * following register bits:
- * - PCGCCTL.RstPdwnModule
- * - PCGCCTL.GateHclk
- * - PCGCCTL.PwrClmp
- * - PCGCCTL.StopPPhyLPwrClkSelclk
- * - GUSBCFG.PhyLPwrClkSel
- * - GUSBCFG.DDRSel
- * - GUSBCFG.PHYSel
- * - GUSBCFG.FSIntf
- * - GUSBCFG.ULPI_UTMI_Sel
- * - GUSBCFG.PHYIf
- * - HCFG.FSLSPclkSel
- * - DCFG.DevSpd
- * * All module state machines (except the AHB Slave Unit) are
- * reset to the IDLE state, and all the transmit FIFOs and the
- * receive FIFO are flushed.
- * * Any transactions on the AHB Master are terminated as soon
- * as possible, after gracefully completing the last data phase of
- * an AHB transfer. Any transactions on the USB are terminated
- * immediately.
- * The application can write to this bit any time it wants to reset
- * the core. This is a self-clearing bit and the core clears this
- * bit after all the necessary logic is reset in the core, which
- * may take several clocks, depending on the current state of the
- * core. Once this bit is cleared software should wait at least 3
- * PHY clocks before doing any access to the PHY domain
- * (synchronization delay). Software should also should check that
- * bit 31 of this register is 1 (AHB Master is IDLE) before
- * starting any operation.
- * Typically software reset is used during software development
- * and also when you dynamically change the PHY selection bits
- * in the USB configuration registers listed above. When you
- * change the PHY, the corresponding clock for the PHY is
- * selected and used in the PHY domain. Once a new clock is
- * selected, the PHY domain has to be reset for proper operation.
- */
- struct cvmx_usbcx_grstctl_s {
- __BITFIELD_FIELD(u32 ahbidle : 1,
- __BITFIELD_FIELD(u32 dmareq : 1,
- __BITFIELD_FIELD(u32 reserved_11_29 : 19,
- __BITFIELD_FIELD(u32 txfnum : 5,
- __BITFIELD_FIELD(u32 txfflsh : 1,
- __BITFIELD_FIELD(u32 rxfflsh : 1,
- __BITFIELD_FIELD(u32 intknqflsh : 1,
- __BITFIELD_FIELD(u32 frmcntrrst : 1,
- __BITFIELD_FIELD(u32 hsftrst : 1,
- __BITFIELD_FIELD(u32 csftrst : 1,
- ;))))))))))
- } s;
-};
-
-/**
- * cvmx_usbc#_grxfsiz
- *
- * Receive FIFO Size Register (GRXFSIZ)
- *
- * The application can program the RAM size that must be allocated to the
- * RxFIFO.
- */
-union cvmx_usbcx_grxfsiz {
- u32 u32;
- /**
- * struct cvmx_usbcx_grxfsiz_s
- * @rxfdep: RxFIFO Depth (RxFDep)
- * This value is in terms of 32-bit words.
- * * Minimum value is 16
- * * Maximum value is 32768
- */
- struct cvmx_usbcx_grxfsiz_s {
- __BITFIELD_FIELD(u32 reserved_16_31 : 16,
- __BITFIELD_FIELD(u32 rxfdep : 16,
- ;))
- } s;
-};
-
-/**
- * cvmx_usbc#_grxstsph
- *
- * Receive Status Read and Pop Register, Host Mode (GRXSTSPH)
- *
- * A read to the Receive Status Read and Pop register returns and additionally
- * pops the top data entry out of the RxFIFO.
- * This Description is only valid when the core is in Host Mode. For Device Mode
- * use USBC_GRXSTSPD instead.
- * NOTE: GRXSTSPH and GRXSTSPD are physically the same register and share the
- * same offset in the O2P USB core. The offset difference shown in this
- * document is for software clarity and is actually ignored by the
- * hardware.
- */
-union cvmx_usbcx_grxstsph {
- u32 u32;
- /**
- * struct cvmx_usbcx_grxstsph_s
- * @pktsts: Packet Status (PktSts)
- * Indicates the status of the received packet
- * * 4'b0010: IN data packet received
- * * 4'b0011: IN transfer completed (triggers an interrupt)
- * * 4'b0101: Data toggle error (triggers an interrupt)
- * * 4'b0111: Channel halted (triggers an interrupt)
- * * Others: Reserved
- * @dpid: Data PID (DPID)
- * * 2'b00: DATA0
- * * 2'b10: DATA1
- * * 2'b01: DATA2
- * * 2'b11: MDATA
- * @bcnt: Byte Count (BCnt)
- * Indicates the byte count of the received IN data packet
- * @chnum: Channel Number (ChNum)
- * Indicates the channel number to which the current received
- * packet belongs.
- */
- struct cvmx_usbcx_grxstsph_s {
- __BITFIELD_FIELD(u32 reserved_21_31 : 11,
- __BITFIELD_FIELD(u32 pktsts : 4,
- __BITFIELD_FIELD(u32 dpid : 2,
- __BITFIELD_FIELD(u32 bcnt : 11,
- __BITFIELD_FIELD(u32 chnum : 4,
- ;)))))
- } s;
-};
-
-/**
- * cvmx_usbc#_gusbcfg
- *
- * Core USB Configuration Register (GUSBCFG)
- *
- * This register can be used to configure the core after power-on or a changing
- * to Host mode or Device mode. It contains USB and USB-PHY related
- * configuration parameters. The application must program this register before
- * starting any transactions on either the AHB or the USB. Do not make changes
- * to this register after the initial programming.
- */
-union cvmx_usbcx_gusbcfg {
- u32 u32;
- /**
- * struct cvmx_usbcx_gusbcfg_s
- * @otgi2csel: UTMIFS or I2C Interface Select (OtgI2CSel)
- * This bit is always 0x0.
- * @phylpwrclksel: PHY Low-Power Clock Select (PhyLPwrClkSel)
- * Software should set this bit to 0x0.
- * Selects either 480-MHz or 48-MHz (low-power) PHY mode. In
- * FS and LS modes, the PHY can usually operate on a 48-MHz
- * clock to save power.
- * * 1'b0: 480-MHz Internal PLL clock
- * * 1'b1: 48-MHz External Clock
- * In 480 MHz mode, the UTMI interface operates at either 60 or
- * 30-MHz, depending upon whether 8- or 16-bit data width is
- * selected. In 48-MHz mode, the UTMI interface operates at 48
- * MHz in FS mode and at either 48 or 6 MHz in LS mode
- * (depending on the PHY vendor).
- * This bit drives the utmi_fsls_low_power core output signal, and
- * is valid only for UTMI+ PHYs.
- * @usbtrdtim: USB Turnaround Time (USBTrdTim)
- * Sets the turnaround time in PHY clocks.
- * Specifies the response time for a MAC request to the Packet
- * FIFO Controller (PFC) to fetch data from the DFIFO (SPRAM).
- * This must be programmed to 0x5.
- * @hnpcap: HNP-Capable (HNPCap)
- * This bit is always 0x0.
- * @srpcap: SRP-Capable (SRPCap)
- * This bit is always 0x0.
- * @ddrsel: ULPI DDR Select (DDRSel)
- * Software should set this bit to 0x0.
- * @physel: USB 2.0 High-Speed PHY or USB 1.1 Full-Speed Serial
- * Software should set this bit to 0x0.
- * @fsintf: Full-Speed Serial Interface Select (FSIntf)
- * Software should set this bit to 0x0.
- * @ulpi_utmi_sel: ULPI or UTMI+ Select (ULPI_UTMI_Sel)
- * This bit is always 0x0.
- * @phyif: PHY Interface (PHYIf)
- * This bit is always 0x1.
- * @toutcal: HS/FS Timeout Calibration (TOutCal)
- * The number of PHY clocks that the application programs in this
- * field is added to the high-speed/full-speed interpacket timeout
- * duration in the core to account for any additional delays
- * introduced by the PHY. This may be required, since the delay
- * introduced by the PHY in generating the linestate condition may
- * vary from one PHY to another.
- * The USB standard timeout value for high-speed operation is
- * 736 to 816 (inclusive) bit times. The USB standard timeout
- * value for full-speed operation is 16 to 18 (inclusive) bit
- * times. The application must program this field based on the
- * speed of enumeration. The number of bit times added per PHY
- * clock are:
- * High-speed operation:
- * * One 30-MHz PHY clock = 16 bit times
- * * One 60-MHz PHY clock = 8 bit times
- * Full-speed operation:
- * * One 30-MHz PHY clock = 0.4 bit times
- * * One 60-MHz PHY clock = 0.2 bit times
- * * One 48-MHz PHY clock = 0.25 bit times
- */
- struct cvmx_usbcx_gusbcfg_s {
- __BITFIELD_FIELD(u32 reserved_17_31 : 15,
- __BITFIELD_FIELD(u32 otgi2csel : 1,
- __BITFIELD_FIELD(u32 phylpwrclksel : 1,
- __BITFIELD_FIELD(u32 reserved_14_14 : 1,
- __BITFIELD_FIELD(u32 usbtrdtim : 4,
- __BITFIELD_FIELD(u32 hnpcap : 1,
- __BITFIELD_FIELD(u32 srpcap : 1,
- __BITFIELD_FIELD(u32 ddrsel : 1,
- __BITFIELD_FIELD(u32 physel : 1,
- __BITFIELD_FIELD(u32 fsintf : 1,
- __BITFIELD_FIELD(u32 ulpi_utmi_sel : 1,
- __BITFIELD_FIELD(u32 phyif : 1,
- __BITFIELD_FIELD(u32 toutcal : 3,
- ;)))))))))))))
- } s;
-};
-
-/**
- * cvmx_usbc#_haint
- *
- * Host All Channels Interrupt Register (HAINT)
- *
- * When a significant event occurs on a channel, the Host All Channels Interrupt
- * register interrupts the application using the Host Channels Interrupt bit of
- * the Core Interrupt register (GINTSTS.HChInt). This is shown in Interrupt.
- * There is one interrupt bit per channel, up to a maximum of 16 bits. Bits in
- * this register are set and cleared when the application sets and clears bits
- * in the corresponding Host Channel-n Interrupt register.
- */
-union cvmx_usbcx_haint {
- u32 u32;
- /**
- * struct cvmx_usbcx_haint_s
- * @haint: Channel Interrupts (HAINT)
- * One bit per channel: Bit 0 for Channel 0, bit 15 for Channel 15
- */
- struct cvmx_usbcx_haint_s {
- __BITFIELD_FIELD(u32 reserved_16_31 : 16,
- __BITFIELD_FIELD(u32 haint : 16,
- ;))
- } s;
-};
-
-/**
- * cvmx_usbc#_haintmsk
- *
- * Host All Channels Interrupt Mask Register (HAINTMSK)
- *
- * The Host All Channel Interrupt Mask register works with the Host All Channel
- * Interrupt register to interrupt the application when an event occurs on a
- * channel. There is one interrupt mask bit per channel, up to a maximum of 16
- * bits.
- * Mask interrupt: 1'b0 Unmask interrupt: 1'b1
- */
-union cvmx_usbcx_haintmsk {
- u32 u32;
- /**
- * struct cvmx_usbcx_haintmsk_s
- * @haintmsk: Channel Interrupt Mask (HAINTMsk)
- * One bit per channel: Bit 0 for channel 0, bit 15 for channel 15
- */
- struct cvmx_usbcx_haintmsk_s {
- __BITFIELD_FIELD(u32 reserved_16_31 : 16,
- __BITFIELD_FIELD(u32 haintmsk : 16,
- ;))
- } s;
-};
-
-/**
- * cvmx_usbc#_hcchar#
- *
- * Host Channel-n Characteristics Register (HCCHAR)
- *
- */
-union cvmx_usbcx_hccharx {
- u32 u32;
- /**
- * struct cvmx_usbcx_hccharx_s
- * @chena: Channel Enable (ChEna)
- * This field is set by the application and cleared by the OTG
- * host.
- * * 1'b0: Channel disabled
- * * 1'b1: Channel enabled
- * @chdis: Channel Disable (ChDis)
- * The application sets this bit to stop transmitting/receiving
- * data on a channel, even before the transfer for that channel is
- * complete. The application must wait for the Channel Disabled
- * interrupt before treating the channel as disabled.
- * @oddfrm: Odd Frame (OddFrm)
- * This field is set (reset) by the application to indicate that
- * the OTG host must perform a transfer in an odd (micro)frame.
- * This field is applicable for only periodic (isochronous and
- * interrupt) transactions.
- * * 1'b0: Even (micro)frame
- * * 1'b1: Odd (micro)frame
- * @devaddr: Device Address (DevAddr)
- * This field selects the specific device serving as the data
- * source or sink.
- * @ec: Multi Count (MC) / Error Count (EC)
- * When the Split Enable bit of the Host Channel-n Split Control
- * register (HCSPLTn.SpltEna) is reset (1'b0), this field indicates
- * to the host the number of transactions that should be executed
- * per microframe for this endpoint.
- * * 2'b00: Reserved. This field yields undefined results.
- * * 2'b01: 1 transaction
- * * 2'b10: 2 transactions to be issued for this endpoint per
- * microframe
- * * 2'b11: 3 transactions to be issued for this endpoint per
- * microframe
- * When HCSPLTn.SpltEna is set (1'b1), this field indicates the
- * number of immediate retries to be performed for a periodic split
- * transactions on transaction errors. This field must be set to at
- * least 2'b01.
- * @eptype: Endpoint Type (EPType)
- * Indicates the transfer type selected.
- * * 2'b00: Control
- * * 2'b01: Isochronous
- * * 2'b10: Bulk
- * * 2'b11: Interrupt
- * @lspddev: Low-Speed Device (LSpdDev)
- * This field is set by the application to indicate that this
- * channel is communicating to a low-speed device.
- * @epdir: Endpoint Direction (EPDir)
- * Indicates whether the transaction is IN or OUT.
- * * 1'b0: OUT
- * * 1'b1: IN
- * @epnum: Endpoint Number (EPNum)
- * Indicates the endpoint number on the device serving as the
- * data source or sink.
- * @mps: Maximum Packet Size (MPS)
- * Indicates the maximum packet size of the associated endpoint.
- */
- struct cvmx_usbcx_hccharx_s {
- __BITFIELD_FIELD(u32 chena : 1,
- __BITFIELD_FIELD(u32 chdis : 1,
- __BITFIELD_FIELD(u32 oddfrm : 1,
- __BITFIELD_FIELD(u32 devaddr : 7,
- __BITFIELD_FIELD(u32 ec : 2,
- __BITFIELD_FIELD(u32 eptype : 2,
- __BITFIELD_FIELD(u32 lspddev : 1,
- __BITFIELD_FIELD(u32 reserved_16_16 : 1,
- __BITFIELD_FIELD(u32 epdir : 1,
- __BITFIELD_FIELD(u32 epnum : 4,
- __BITFIELD_FIELD(u32 mps : 11,
- ;)))))))))))
- } s;
-};
-
-/**
- * cvmx_usbc#_hcfg
- *
- * Host Configuration Register (HCFG)
- *
- * This register configures the core after power-on. Do not make changes to this
- * register after initializing the host.
- */
-union cvmx_usbcx_hcfg {
- u32 u32;
- /**
- * struct cvmx_usbcx_hcfg_s
- * @fslssupp: FS- and LS-Only Support (FSLSSupp)
- * The application uses this bit to control the core's enumeration
- * speed. Using this bit, the application can make the core
- * enumerate as a FS host, even if the connected device supports
- * HS traffic. Do not make changes to this field after initial
- * programming.
- * * 1'b0: HS/FS/LS, based on the maximum speed supported by
- * the connected device
- * * 1'b1: FS/LS-only, even if the connected device can support HS
- * @fslspclksel: FS/LS PHY Clock Select (FSLSPclkSel)
- * When the core is in FS Host mode
- * * 2'b00: PHY clock is running at 30/60 MHz
- * * 2'b01: PHY clock is running at 48 MHz
- * * Others: Reserved
- * When the core is in LS Host mode
- * * 2'b00: PHY clock is running at 30/60 MHz. When the
- * UTMI+/ULPI PHY Low Power mode is not selected, use
- * 30/60 MHz.
- * * 2'b01: PHY clock is running at 48 MHz. When the UTMI+
- * PHY Low Power mode is selected, use 48MHz if the PHY
- * supplies a 48 MHz clock during LS mode.
- * * 2'b10: PHY clock is running at 6 MHz. In USB 1.1 FS mode,
- * use 6 MHz when the UTMI+ PHY Low Power mode is
- * selected and the PHY supplies a 6 MHz clock during LS
- * mode. If you select a 6 MHz clock during LS mode, you must
- * do a soft reset.
- * * 2'b11: Reserved
- */
- struct cvmx_usbcx_hcfg_s {
- __BITFIELD_FIELD(u32 reserved_3_31 : 29,
- __BITFIELD_FIELD(u32 fslssupp : 1,
- __BITFIELD_FIELD(u32 fslspclksel : 2,
- ;)))
- } s;
-};
-
-/**
- * cvmx_usbc#_hcint#
- *
- * Host Channel-n Interrupt Register (HCINT)
- *
- * This register indicates the status of a channel with respect to USB- and
- * AHB-related events. The application must read this register when the Host
- * Channels Interrupt bit of the Core Interrupt register (GINTSTS.HChInt) is
- * set. Before the application can read this register, it must first read
- * the Host All Channels Interrupt (HAINT) register to get the exact channel
- * number for the Host Channel-n Interrupt register. The application must clear
- * the appropriate bit in this register to clear the corresponding bits in the
- * HAINT and GINTSTS registers.
- */
-union cvmx_usbcx_hcintx {
- u32 u32;
- /**
- * struct cvmx_usbcx_hcintx_s
- * @datatglerr: Data Toggle Error (DataTglErr)
- * @frmovrun: Frame Overrun (FrmOvrun)
- * @bblerr: Babble Error (BblErr)
- * @xacterr: Transaction Error (XactErr)
- * @nyet: NYET Response Received Interrupt (NYET)
- * @ack: ACK Response Received Interrupt (ACK)
- * @nak: NAK Response Received Interrupt (NAK)
- * @stall: STALL Response Received Interrupt (STALL)
- * @ahberr: This bit is always 0x0.
- * @chhltd: Channel Halted (ChHltd)
- * Indicates the transfer completed abnormally either because of
- * any USB transaction error or in response to disable request by
- * the application.
- * @xfercompl: Transfer Completed (XferCompl)
- * Transfer completed normally without any errors.
- */
- struct cvmx_usbcx_hcintx_s {
- __BITFIELD_FIELD(u32 reserved_11_31 : 21,
- __BITFIELD_FIELD(u32 datatglerr : 1,
- __BITFIELD_FIELD(u32 frmovrun : 1,
- __BITFIELD_FIELD(u32 bblerr : 1,
- __BITFIELD_FIELD(u32 xacterr : 1,
- __BITFIELD_FIELD(u32 nyet : 1,
- __BITFIELD_FIELD(u32 ack : 1,
- __BITFIELD_FIELD(u32 nak : 1,
- __BITFIELD_FIELD(u32 stall : 1,
- __BITFIELD_FIELD(u32 ahberr : 1,
- __BITFIELD_FIELD(u32 chhltd : 1,
- __BITFIELD_FIELD(u32 xfercompl : 1,
- ;))))))))))))
- } s;
-};
-
-/**
- * cvmx_usbc#_hcintmsk#
- *
- * Host Channel-n Interrupt Mask Register (HCINTMSKn)
- *
- * This register reflects the mask for each channel status described in the
- * previous section.
- * Mask interrupt: 1'b0 Unmask interrupt: 1'b1
- */
-union cvmx_usbcx_hcintmskx {
- u32 u32;
- /**
- * struct cvmx_usbcx_hcintmskx_s
- * @datatglerrmsk: Data Toggle Error Mask (DataTglErrMsk)
- * @frmovrunmsk: Frame Overrun Mask (FrmOvrunMsk)
- * @bblerrmsk: Babble Error Mask (BblErrMsk)
- * @xacterrmsk: Transaction Error Mask (XactErrMsk)
- * @nyetmsk: NYET Response Received Interrupt Mask (NyetMsk)
- * @ackmsk: ACK Response Received Interrupt Mask (AckMsk)
- * @nakmsk: NAK Response Received Interrupt Mask (NakMsk)
- * @stallmsk: STALL Response Received Interrupt Mask (StallMsk)
- * @ahberrmsk: AHB Error Mask (AHBErrMsk)
- * @chhltdmsk: Channel Halted Mask (ChHltdMsk)
- * @xfercomplmsk: Transfer Completed Mask (XferComplMsk)
- */
- struct cvmx_usbcx_hcintmskx_s {
- __BITFIELD_FIELD(u32 reserved_11_31 : 21,
- __BITFIELD_FIELD(u32 datatglerrmsk : 1,
- __BITFIELD_FIELD(u32 frmovrunmsk : 1,
- __BITFIELD_FIELD(u32 bblerrmsk : 1,
- __BITFIELD_FIELD(u32 xacterrmsk : 1,
- __BITFIELD_FIELD(u32 nyetmsk : 1,
- __BITFIELD_FIELD(u32 ackmsk : 1,
- __BITFIELD_FIELD(u32 nakmsk : 1,
- __BITFIELD_FIELD(u32 stallmsk : 1,
- __BITFIELD_FIELD(u32 ahberrmsk : 1,
- __BITFIELD_FIELD(u32 chhltdmsk : 1,
- __BITFIELD_FIELD(u32 xfercomplmsk : 1,
- ;))))))))))))
- } s;
-};
-
-/**
- * cvmx_usbc#_hcsplt#
- *
- * Host Channel-n Split Control Register (HCSPLT)
- *
- */
-union cvmx_usbcx_hcspltx {
- u32 u32;
- /**
- * struct cvmx_usbcx_hcspltx_s
- * @spltena: Split Enable (SpltEna)
- * The application sets this field to indicate that this channel is
- * enabled to perform split transactions.
- * @compsplt: Do Complete Split (CompSplt)
- * The application sets this field to request the OTG host to
- * perform a complete split transaction.
- * @xactpos: Transaction Position (XactPos)
- * This field is used to determine whether to send all, first,
- * middle, or last payloads with each OUT transaction.
- * * 2'b11: All. This is the entire data payload is of this
- * transaction (which is less than or equal to 188 bytes).
- * * 2'b10: Begin. This is the first data payload of this
- * transaction (which is larger than 188 bytes).
- * * 2'b00: Mid. This is the middle payload of this transaction
- * (which is larger than 188 bytes).
- * * 2'b01: End. This is the last payload of this transaction
- * (which is larger than 188 bytes).
- * @hubaddr: Hub Address (HubAddr)
- * This field holds the device address of the transaction
- * translator's hub.
- * @prtaddr: Port Address (PrtAddr)
- * This field is the port number of the recipient transaction
- * translator.
- */
- struct cvmx_usbcx_hcspltx_s {
- __BITFIELD_FIELD(u32 spltena : 1,
- __BITFIELD_FIELD(u32 reserved_17_30 : 14,
- __BITFIELD_FIELD(u32 compsplt : 1,
- __BITFIELD_FIELD(u32 xactpos : 2,
- __BITFIELD_FIELD(u32 hubaddr : 7,
- __BITFIELD_FIELD(u32 prtaddr : 7,
- ;))))))
- } s;
-};
-
-/**
- * cvmx_usbc#_hctsiz#
- *
- * Host Channel-n Transfer Size Register (HCTSIZ)
- *
- */
-union cvmx_usbcx_hctsizx {
- u32 u32;
- /**
- * struct cvmx_usbcx_hctsizx_s
- * @dopng: Do Ping (DoPng)
- * Setting this field to 1 directs the host to do PING protocol.
- * @pid: PID (Pid)
- * The application programs this field with the type of PID to use
- * for the initial transaction. The host will maintain this field
- * for the rest of the transfer.
- * * 2'b00: DATA0
- * * 2'b01: DATA2
- * * 2'b10: DATA1
- * * 2'b11: MDATA (non-control)/SETUP (control)
- * @pktcnt: Packet Count (PktCnt)
- * This field is programmed by the application with the expected
- * number of packets to be transmitted (OUT) or received (IN).
- * The host decrements this count on every successful
- * transmission or reception of an OUT/IN packet. Once this count
- * reaches zero, the application is interrupted to indicate normal
- * completion.
- * @xfersize: Transfer Size (XferSize)
- * For an OUT, this field is the number of data bytes the host will
- * send during the transfer.
- * For an IN, this field is the buffer size that the application
- * has reserved for the transfer. The application is expected to
- * program this field as an integer multiple of the maximum packet
- * size for IN transactions (periodic and non-periodic).
- */
- struct cvmx_usbcx_hctsizx_s {
- __BITFIELD_FIELD(u32 dopng : 1,
- __BITFIELD_FIELD(u32 pid : 2,
- __BITFIELD_FIELD(u32 pktcnt : 10,
- __BITFIELD_FIELD(u32 xfersize : 19,
- ;))))
- } s;
-};
-
-/**
- * cvmx_usbc#_hfir
- *
- * Host Frame Interval Register (HFIR)
- *
- * This register stores the frame interval information for the current speed to
- * which the O2P USB core has enumerated.
- */
-union cvmx_usbcx_hfir {
- u32 u32;
- /**
- * struct cvmx_usbcx_hfir_s
- * @frint: Frame Interval (FrInt)
- * The value that the application programs to this field specifies
- * the interval between two consecutive SOFs (FS) or micro-
- * SOFs (HS) or Keep-Alive tokens (HS). This field contains the
- * number of PHY clocks that constitute the required frame
- * interval. The default value set in this field for a FS operation
- * when the PHY clock frequency is 60 MHz. The application can
- * write a value to this register only after the Port Enable bit of
- * the Host Port Control and Status register (HPRT.PrtEnaPort)
- * has been set. If no value is programmed, the core calculates
- * the value based on the PHY clock specified in the FS/LS PHY
- * Clock Select field of the Host Configuration register
- * (HCFG.FSLSPclkSel). Do not change the value of this field
- * after the initial configuration.
- * * 125 us (PHY clock frequency for HS)
- * * 1 ms (PHY clock frequency for FS/LS)
- */
- struct cvmx_usbcx_hfir_s {
- __BITFIELD_FIELD(u32 reserved_16_31 : 16,
- __BITFIELD_FIELD(u32 frint : 16,
- ;))
- } s;
-};
-
-/**
- * cvmx_usbc#_hfnum
- *
- * Host Frame Number/Frame Time Remaining Register (HFNUM)
- *
- * This register indicates the current frame number.
- * It also indicates the time remaining (in terms of the number of PHY clocks)
- * in the current (micro)frame.
- */
-union cvmx_usbcx_hfnum {
- u32 u32;
- /**
- * struct cvmx_usbcx_hfnum_s
- * @frrem: Frame Time Remaining (FrRem)
- * Indicates the amount of time remaining in the current
- * microframe (HS) or frame (FS/LS), in terms of PHY clocks.
- * This field decrements on each PHY clock. When it reaches
- * zero, this field is reloaded with the value in the Frame
- * Interval register and a new SOF is transmitted on the USB.
- * @frnum: Frame Number (FrNum)
- * This field increments when a new SOF is transmitted on the
- * USB, and is reset to 0 when it reaches 16'h3FFF.
- */
- struct cvmx_usbcx_hfnum_s {
- __BITFIELD_FIELD(u32 frrem : 16,
- __BITFIELD_FIELD(u32 frnum : 16,
- ;))
- } s;
-};
-
-/**
- * cvmx_usbc#_hprt
- *
- * Host Port Control and Status Register (HPRT)
- *
- * This register is available in both Host and Device modes.
- * Currently, the OTG Host supports only one port.
- * A single register holds USB port-related information such as USB reset,
- * enable, suspend, resume, connect status, and test mode for each port. The
- * R_SS_WC bits in this register can trigger an interrupt to the application
- * through the Host Port Interrupt bit of the Core Interrupt register
- * (GINTSTS.PrtInt). On a Port Interrupt, the application must read this
- * register and clear the bit that caused the interrupt. For the R_SS_WC bits,
- * the application must write a 1 to the bit to clear the interrupt.
- */
-union cvmx_usbcx_hprt {
- u32 u32;
- /**
- * struct cvmx_usbcx_hprt_s
- * @prtspd: Port Speed (PrtSpd)
- * Indicates the speed of the device attached to this port.
- * * 2'b00: High speed
- * * 2'b01: Full speed
- * * 2'b10: Low speed
- * * 2'b11: Reserved
- * @prttstctl: Port Test Control (PrtTstCtl)
- * The application writes a nonzero value to this field to put
- * the port into a Test mode, and the corresponding pattern is
- * signaled on the port.
- * * 4'b0000: Test mode disabled
- * * 4'b0001: Test_J mode
- * * 4'b0010: Test_K mode
- * * 4'b0011: Test_SE0_NAK mode
- * * 4'b0100: Test_Packet mode
- * * 4'b0101: Test_Force_Enable
- * * Others: Reserved
- * PrtSpd must be zero (i.e. the interface must be in high-speed
- * mode) to use the PrtTstCtl test modes.
- * @prtpwr: Port Power (PrtPwr)
- * The application uses this field to control power to this port,
- * and the core clears this bit on an overcurrent condition.
- * * 1'b0: Power off
- * * 1'b1: Power on
- * @prtlnsts: Port Line Status (PrtLnSts)
- * Indicates the current logic level USB data lines
- * * Bit [10]: Logic level of D-
- * * Bit [11]: Logic level of D+
- * @prtrst: Port Reset (PrtRst)
- * When the application sets this bit, a reset sequence is
- * started on this port. The application must time the reset
- * period and clear this bit after the reset sequence is
- * complete.
- * * 1'b0: Port not in reset
- * * 1'b1: Port in reset
- * The application must leave this bit set for at least a
- * minimum duration mentioned below to start a reset on the
- * port. The application can leave it set for another 10 ms in
- * addition to the required minimum duration, before clearing
- * the bit, even though there is no maximum limit set by the
- * USB standard.
- * * High speed: 50 ms
- * * Full speed/Low speed: 10 ms
- * @prtsusp: Port Suspend (PrtSusp)
- * The application sets this bit to put this port in Suspend
- * mode. The core only stops sending SOFs when this is set.
- * To stop the PHY clock, the application must set the Port
- * Clock Stop bit, which will assert the suspend input pin of
- * the PHY.
- * The read value of this bit reflects the current suspend
- * status of the port. This bit is cleared by the core after a
- * remote wakeup signal is detected or the application sets
- * the Port Reset bit or Port Resume bit in this register or the
- * Resume/Remote Wakeup Detected Interrupt bit or
- * Disconnect Detected Interrupt bit in the Core Interrupt
- * register (GINTSTS.WkUpInt or GINTSTS.DisconnInt,
- * respectively).
- * * 1'b0: Port not in Suspend mode
- * * 1'b1: Port in Suspend mode
- * @prtres: Port Resume (PrtRes)
- * The application sets this bit to drive resume signaling on
- * the port. The core continues to drive the resume signal
- * until the application clears this bit.
- * If the core detects a USB remote wakeup sequence, as
- * indicated by the Port Resume/Remote Wakeup Detected
- * Interrupt bit of the Core Interrupt register
- * (GINTSTS.WkUpInt), the core starts driving resume
- * signaling without application intervention and clears this bit
- * when it detects a disconnect condition. The read value of
- * this bit indicates whether the core is currently driving
- * resume signaling.
- * * 1'b0: No resume driven
- * * 1'b1: Resume driven
- * @prtovrcurrchng: Port Overcurrent Change (PrtOvrCurrChng)
- * The core sets this bit when the status of the Port
- * Overcurrent Active bit (bit 4) in this register changes.
- * @prtovrcurract: Port Overcurrent Active (PrtOvrCurrAct)
- * Indicates the overcurrent condition of the port.
- * * 1'b0: No overcurrent condition
- * * 1'b1: Overcurrent condition
- * @prtenchng: Port Enable/Disable Change (PrtEnChng)
- * The core sets this bit when the status of the Port Enable bit
- * [2] of this register changes.
- * @prtena: Port Enable (PrtEna)
- * A port is enabled only by the core after a reset sequence,
- * and is disabled by an overcurrent condition, a disconnect
- * condition, or by the application clearing this bit. The
- * application cannot set this bit by a register write. It can only
- * clear it to disable the port. This bit does not trigger any
- * interrupt to the application.
- * * 1'b0: Port disabled
- * * 1'b1: Port enabled
- * @prtconndet: Port Connect Detected (PrtConnDet)
- * The core sets this bit when a device connection is detected
- * to trigger an interrupt to the application using the Host Port
- * Interrupt bit of the Core Interrupt register (GINTSTS.PrtInt).
- * The application must write a 1 to this bit to clear the
- * interrupt.
- * @prtconnsts: Port Connect Status (PrtConnSts)
- * * 0: No device is attached to the port.
- * * 1: A device is attached to the port.
- */
- struct cvmx_usbcx_hprt_s {
- __BITFIELD_FIELD(u32 reserved_19_31 : 13,
- __BITFIELD_FIELD(u32 prtspd : 2,
- __BITFIELD_FIELD(u32 prttstctl : 4,
- __BITFIELD_FIELD(u32 prtpwr : 1,
- __BITFIELD_FIELD(u32 prtlnsts : 2,
- __BITFIELD_FIELD(u32 reserved_9_9 : 1,
- __BITFIELD_FIELD(u32 prtrst : 1,
- __BITFIELD_FIELD(u32 prtsusp : 1,
- __BITFIELD_FIELD(u32 prtres : 1,
- __BITFIELD_FIELD(u32 prtovrcurrchng : 1,
- __BITFIELD_FIELD(u32 prtovrcurract : 1,
- __BITFIELD_FIELD(u32 prtenchng : 1,
- __BITFIELD_FIELD(u32 prtena : 1,
- __BITFIELD_FIELD(u32 prtconndet : 1,
- __BITFIELD_FIELD(u32 prtconnsts : 1,
- ;)))))))))))))))
- } s;
-};
-
-/**
- * cvmx_usbc#_hptxfsiz
- *
- * Host Periodic Transmit FIFO Size Register (HPTXFSIZ)
- *
- * This register holds the size and the memory start address of the Periodic
- * TxFIFO, as shown in Figures 310 and 311.
- */
-union cvmx_usbcx_hptxfsiz {
- u32 u32;
- /**
- * struct cvmx_usbcx_hptxfsiz_s
- * @ptxfsize: Host Periodic TxFIFO Depth (PTxFSize)
- * This value is in terms of 32-bit words.
- * * Minimum value is 16
- * * Maximum value is 32768
- * @ptxfstaddr: Host Periodic TxFIFO Start Address (PTxFStAddr)
- */
- struct cvmx_usbcx_hptxfsiz_s {
- __BITFIELD_FIELD(u32 ptxfsize : 16,
- __BITFIELD_FIELD(u32 ptxfstaddr : 16,
- ;))
- } s;
-};
-
-/**
- * cvmx_usbc#_hptxsts
- *
- * Host Periodic Transmit FIFO/Queue Status Register (HPTXSTS)
- *
- * This read-only register contains the free space information for the Periodic
- * TxFIFO and the Periodic Transmit Request Queue
- */
-union cvmx_usbcx_hptxsts {
- u32 u32;
- /**
- * struct cvmx_usbcx_hptxsts_s
- * @ptxqtop: Top of the Periodic Transmit Request Queue (PTxQTop)
- * This indicates the entry in the Periodic Tx Request Queue that
- * is currently being processes by the MAC.
- * This register is used for debugging.
- * * Bit [31]: Odd/Even (micro)frame
- * - 1'b0: send in even (micro)frame
- * - 1'b1: send in odd (micro)frame
- * * Bits [30:27]: Channel/endpoint number
- * * Bits [26:25]: Type
- * - 2'b00: IN/OUT
- * - 2'b01: Zero-length packet
- * - 2'b10: CSPLIT
- * - 2'b11: Disable channel command
- * * Bit [24]: Terminate (last entry for the selected
- * channel/endpoint)
- * @ptxqspcavail: Periodic Transmit Request Queue Space Available
- * (PTxQSpcAvail)
- * Indicates the number of free locations available to be written
- * in the Periodic Transmit Request Queue. This queue holds both
- * IN and OUT requests.
- * * 8'h0: Periodic Transmit Request Queue is full
- * * 8'h1: 1 location available
- * * 8'h2: 2 locations available
- * * n: n locations available (0..8)
- * * Others: Reserved
- * @ptxfspcavail: Periodic Transmit Data FIFO Space Available
- * (PTxFSpcAvail)
- * Indicates the number of free locations available to be written
- * to in the Periodic TxFIFO.
- * Values are in terms of 32-bit words
- * * 16'h0: Periodic TxFIFO is full
- * * 16'h1: 1 word available
- * * 16'h2: 2 words available
- * * 16'hn: n words available (where 0..32768)
- * * 16'h8000: 32768 words available
- * * Others: Reserved
- */
- struct cvmx_usbcx_hptxsts_s {
- __BITFIELD_FIELD(u32 ptxqtop : 8,
- __BITFIELD_FIELD(u32 ptxqspcavail : 8,
- __BITFIELD_FIELD(u32 ptxfspcavail : 16,
- ;)))
- } s;
-};
-
-/**
- * cvmx_usbn#_clk_ctl
- *
- * USBN_CLK_CTL = USBN's Clock Control
- *
- * This register is used to control the frequency of the hclk and the
- * hreset and phy_rst signals.
- */
-union cvmx_usbnx_clk_ctl {
- u64 u64;
- /**
- * struct cvmx_usbnx_clk_ctl_s
- * @divide2: The 'hclk' used by the USB subsystem is derived
- * from the eclk.
- * Also see the field DIVIDE. DIVIDE2<1> must currently
- * be zero because it is not implemented, so the maximum
- * ratio of eclk/hclk is currently 16.
- * The actual divide number for hclk is:
- * (DIVIDE2 + 1) * (DIVIDE + 1)
- * @hclk_rst: When this field is '0' the HCLK-DIVIDER used to
- * generate the hclk in the USB Subsystem is held
- * in reset. This bit must be set to '0' before
- * changing the value os DIVIDE in this register.
- * The reset to the HCLK_DIVIDERis also asserted
- * when core reset is asserted.
- * @p_x_on: Force USB-PHY on during suspend.
- * '1' USB-PHY XO block is powered-down during
- * suspend.
- * '0' USB-PHY XO block is powered-up during
- * suspend.
- * The value of this field must be set while POR is
- * active.
- * @p_rtype: PHY reference clock type
- * On CN50XX/CN52XX/CN56XX the values are:
- * '0' The USB-PHY uses a 12MHz crystal as a clock source
- * at the USB_XO and USB_XI pins.
- * '1' Reserved.
- * '2' The USB_PHY uses 12/24/48MHz 2.5V board clock at the
- * USB_XO pin. USB_XI should be tied to ground in this
- * case.
- * '3' Reserved.
- * On CN3xxx bits 14 and 15 are p_xenbn and p_rclk and values are:
- * '0' Reserved.
- * '1' Reserved.
- * '2' The PHY PLL uses the XO block output as a reference.
- * The XO block uses an external clock supplied on the
- * XO pin. USB_XI should be tied to ground for this
- * usage.
- * '3' The XO block uses the clock from a crystal.
- * @p_com_on: '0' Force USB-PHY XO Bias, Bandgap and PLL to
- * remain powered in Suspend Mode.
- * '1' The USB-PHY XO Bias, Bandgap and PLL are
- * powered down in suspend mode.
- * The value of this field must be set while POR is
- * active.
- * @p_c_sel: Phy clock speed select.
- * Selects the reference clock / crystal frequency.
- * '11': Reserved
- * '10': 48 MHz (reserved when a crystal is used)
- * '01': 24 MHz (reserved when a crystal is used)
- * '00': 12 MHz
- * The value of this field must be set while POR is
- * active.
- * NOTE: if a crystal is used as a reference clock,
- * this field must be set to 12 MHz.
- * @cdiv_byp: Used to enable the bypass input to the USB_CLK_DIV.
- * @sd_mode: Scaledown mode for the USBC. Control timing events
- * in the USBC, for normal operation this must be '0'.
- * @s_bist: Starts bist on the hclk memories, during the '0'
- * to '1' transition.
- * @por: Power On Reset for the PHY.
- * Resets all the PHYS registers and state machines.
- * @enable: When '1' allows the generation of the hclk. When
- * '0' the hclk will not be generated. SEE DIVIDE
- * field of this register.
- * @prst: When this field is '0' the reset associated with
- * the phy_clk functionality in the USB Subsystem is
- * help in reset. This bit should not be set to '1'
- * until the time it takes 6 clocks (hclk or phy_clk,
- * whichever is slower) has passed. Under normal
- * operation once this bit is set to '1' it should not
- * be set to '0'.
- * @hrst: When this field is '0' the reset associated with
- * the hclk functioanlity in the USB Subsystem is
- * held in reset.This bit should not be set to '1'
- * until 12ms after phy_clk is stable. Under normal
- * operation, once this bit is set to '1' it should
- * not be set to '0'.
- * @divide: The frequency of 'hclk' used by the USB subsystem
- * is the eclk frequency divided by the value of
- * (DIVIDE2 + 1) * (DIVIDE + 1), also see the field
- * DIVIDE2 of this register.
- * The hclk frequency should be less than 125Mhz.
- * After writing a value to this field the SW should
- * read the field for the value written.
- * The ENABLE field of this register should not be set
- * until AFTER this field is set and then read.
- */
- struct cvmx_usbnx_clk_ctl_s {
- __BITFIELD_FIELD(u64 reserved_20_63 : 44,
- __BITFIELD_FIELD(u64 divide2 : 2,
- __BITFIELD_FIELD(u64 hclk_rst : 1,
- __BITFIELD_FIELD(u64 p_x_on : 1,
- __BITFIELD_FIELD(u64 p_rtype : 2,
- __BITFIELD_FIELD(u64 p_com_on : 1,
- __BITFIELD_FIELD(u64 p_c_sel : 2,
- __BITFIELD_FIELD(u64 cdiv_byp : 1,
- __BITFIELD_FIELD(u64 sd_mode : 2,
- __BITFIELD_FIELD(u64 s_bist : 1,
- __BITFIELD_FIELD(u64 por : 1,
- __BITFIELD_FIELD(u64 enable : 1,
- __BITFIELD_FIELD(u64 prst : 1,
- __BITFIELD_FIELD(u64 hrst : 1,
- __BITFIELD_FIELD(u64 divide : 3,
- ;)))))))))))))))
- } s;
-};
-
-/**
- * cvmx_usbn#_usbp_ctl_status
- *
- * USBN_USBP_CTL_STATUS = USBP Control And Status Register
- *
- * Contains general control and status information for the USBN block.
- */
-union cvmx_usbnx_usbp_ctl_status {
- u64 u64;
- /**
- * struct cvmx_usbnx_usbp_ctl_status_s
- * @txrisetune: HS Transmitter Rise/Fall Time Adjustment
- * @txvreftune: HS DC Voltage Level Adjustment
- * @txfslstune: FS/LS Source Impedance Adjustment
- * @txhsxvtune: Transmitter High-Speed Crossover Adjustment
- * @sqrxtune: Squelch Threshold Adjustment
- * @compdistune: Disconnect Threshold Adjustment
- * @otgtune: VBUS Valid Threshold Adjustment
- * @otgdisable: OTG Block Disable
- * @portreset: Per_Port Reset
- * @drvvbus: Drive VBUS
- * @lsbist: Low-Speed BIST Enable.
- * @fsbist: Full-Speed BIST Enable.
- * @hsbist: High-Speed BIST Enable.
- * @bist_done: PHY Bist Done.
- * Asserted at the end of the PHY BIST sequence.
- * @bist_err: PHY Bist Error.
- * Indicates an internal error was detected during
- * the BIST sequence.
- * @tdata_out: PHY Test Data Out.
- * Presents either internally generated signals or
- * test register contents, based upon the value of
- * test_data_out_sel.
- * @siddq: Drives the USBP (USB-PHY) SIDDQ input.
- * Normally should be set to zero.
- * When customers have no intent to use USB PHY
- * interface, they should:
- * - still provide 3.3V to USB_VDD33, and
- * - tie USB_REXT to 3.3V supply, and
- * - set USBN*_USBP_CTL_STATUS[SIDDQ]=1
- * @txpreemphasistune: HS Transmitter Pre-Emphasis Enable
- * @dma_bmode: When set to 1 the L2C DMA address will be updated
- * with byte-counts between packets. When set to 0
- * the L2C DMA address is incremented to the next
- * 4-byte aligned address after adding byte-count.
- * @usbc_end: Bigendian input to the USB Core. This should be
- * set to '0' for operation.
- * @usbp_bist: PHY, This is cleared '0' to run BIST on the USBP.
- * @tclk: PHY Test Clock, used to load TDATA_IN to the USBP.
- * @dp_pulld: PHY DP_PULLDOWN input to the USB-PHY.
- * This signal enables the pull-down resistance on
- * the D+ line. '1' pull down-resistance is connected
- * to D+/ '0' pull down resistance is not connected
- * to D+. When an A/B device is acting as a host
- * (downstream-facing port), dp_pulldown and
- * dm_pulldown are enabled. This must not toggle
- * during normal operation.
- * @dm_pulld: PHY DM_PULLDOWN input to the USB-PHY.
- * This signal enables the pull-down resistance on
- * the D- line. '1' pull down-resistance is connected
- * to D-. '0' pull down resistance is not connected
- * to D-. When an A/B device is acting as a host
- * (downstream-facing port), dp_pulldown and
- * dm_pulldown are enabled. This must not toggle
- * during normal operation.
- * @hst_mode: When '0' the USB is acting as HOST, when '1'
- * USB is acting as device. This field needs to be
- * set while the USB is in reset.
- * @tuning: Transmitter Tuning for High-Speed Operation.
- * Tunes the current supply and rise/fall output
- * times for high-speed operation.
- * [20:19] == 11: Current supply increased
- * approximately 9%
- * [20:19] == 10: Current supply increased
- * approximately 4.5%
- * [20:19] == 01: Design default.
- * [20:19] == 00: Current supply decreased
- * approximately 4.5%
- * [22:21] == 11: Rise and fall times are increased.
- * [22:21] == 10: Design default.
- * [22:21] == 01: Rise and fall times are decreased.
- * [22:21] == 00: Rise and fall times are decreased
- * further as compared to the 01 setting.
- * @tx_bs_enh: Transmit Bit Stuffing on [15:8].
- * Enables or disables bit stuffing on data[15:8]
- * when bit-stuffing is enabled.
- * @tx_bs_en: Transmit Bit Stuffing on [7:0].
- * Enables or disables bit stuffing on data[7:0]
- * when bit-stuffing is enabled.
- * @loop_enb: PHY Loopback Test Enable.
- * '1': During data transmission the receive is
- * enabled.
- * '0': During data transmission the receive is
- * disabled.
- * Must be '0' for normal operation.
- * @vtest_enb: Analog Test Pin Enable.
- * '1' The PHY's analog_test pin is enabled for the
- * input and output of applicable analog test signals.
- * '0' THe analog_test pin is disabled.
- * @bist_enb: Built-In Self Test Enable.
- * Used to activate BIST in the PHY.
- * @tdata_sel: Test Data Out Select.
- * '1' test_data_out[3:0] (PHY) register contents
- * are output. '0' internally generated signals are
- * output.
- * @taddr_in: Mode Address for Test Interface.
- * Specifies the register address for writing to or
- * reading from the PHY test interface register.
- * @tdata_in: Internal Testing Register Input Data and Select
- * This is a test bus. Data is present on [3:0],
- * and its corresponding select (enable) is present
- * on bits [7:4].
- * @ate_reset: Reset input from automatic test equipment.
- * This is a test signal. When the USB Core is
- * powered up (not in Susned Mode), an automatic
- * tester can use this to disable phy_clock and
- * free_clk, then re-enable them with an aligned
- * phase.
- * '1': The phy_clk and free_clk outputs are
- * disabled. "0": The phy_clock and free_clk outputs
- * are available within a specific period after the
- * de-assertion.
- */
- struct cvmx_usbnx_usbp_ctl_status_s {
- __BITFIELD_FIELD(u64 txrisetune : 1,
- __BITFIELD_FIELD(u64 txvreftune : 4,
- __BITFIELD_FIELD(u64 txfslstune : 4,
- __BITFIELD_FIELD(u64 txhsxvtune : 2,
- __BITFIELD_FIELD(u64 sqrxtune : 3,
- __BITFIELD_FIELD(u64 compdistune : 3,
- __BITFIELD_FIELD(u64 otgtune : 3,
- __BITFIELD_FIELD(u64 otgdisable : 1,
- __BITFIELD_FIELD(u64 portreset : 1,
- __BITFIELD_FIELD(u64 drvvbus : 1,
- __BITFIELD_FIELD(u64 lsbist : 1,
- __BITFIELD_FIELD(u64 fsbist : 1,
- __BITFIELD_FIELD(u64 hsbist : 1,
- __BITFIELD_FIELD(u64 bist_done : 1,
- __BITFIELD_FIELD(u64 bist_err : 1,
- __BITFIELD_FIELD(u64 tdata_out : 4,
- __BITFIELD_FIELD(u64 siddq : 1,
- __BITFIELD_FIELD(u64 txpreemphasistune : 1,
- __BITFIELD_FIELD(u64 dma_bmode : 1,
- __BITFIELD_FIELD(u64 usbc_end : 1,
- __BITFIELD_FIELD(u64 usbp_bist : 1,
- __BITFIELD_FIELD(u64 tclk : 1,
- __BITFIELD_FIELD(u64 dp_pulld : 1,
- __BITFIELD_FIELD(u64 dm_pulld : 1,
- __BITFIELD_FIELD(u64 hst_mode : 1,
- __BITFIELD_FIELD(u64 tuning : 4,
- __BITFIELD_FIELD(u64 tx_bs_enh : 1,
- __BITFIELD_FIELD(u64 tx_bs_en : 1,
- __BITFIELD_FIELD(u64 loop_enb : 1,
- __BITFIELD_FIELD(u64 vtest_enb : 1,
- __BITFIELD_FIELD(u64 bist_enb : 1,
- __BITFIELD_FIELD(u64 tdata_sel : 1,
- __BITFIELD_FIELD(u64 taddr_in : 4,
- __BITFIELD_FIELD(u64 tdata_in : 8,
- __BITFIELD_FIELD(u64 ate_reset : 1,
- ;)))))))))))))))))))))))))))))))))))
- } s;
-};
-
-#endif /* __OCTEON_HCD_H__ */
diff --git a/drivers/staging/octeon/Kconfig b/drivers/staging/octeon/Kconfig
deleted file mode 100644
index e7f4ddcc1361..000000000000
--- a/drivers/staging/octeon/Kconfig
+++ /dev/null
@@ -1,16 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-config OCTEON_ETHERNET
- tristate "Cavium Networks Octeon Ethernet support"
- depends on CAVIUM_OCTEON_SOC || COMPILE_TEST
- depends on NETDEVICES
- depends on BROKEN
- select PHYLIB
- select MDIO_OCTEON
- help
- This driver supports the builtin ethernet ports on Cavium
- Networks' products in the Octeon family. This driver supports the
- CN3XXX and CN5XXX Octeon processors.
-
- To compile this driver as a module, choose M here. The module
- will be called octeon-ethernet.
-
diff --git a/drivers/staging/octeon/Makefile b/drivers/staging/octeon/Makefile
deleted file mode 100644
index 3887cf5f1e84..000000000000
--- a/drivers/staging/octeon/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-#
-# Copyright (C) 2005-2009 Cavium Networks
-#
-
-#
-# Makefile for Cavium OCTEON on-board ethernet driver
-#
-
-obj-${CONFIG_OCTEON_ETHERNET} := octeon-ethernet.o
-
-octeon-ethernet-y := ethernet.o
-octeon-ethernet-y += ethernet-mdio.o
-octeon-ethernet-y += ethernet-mem.o
-octeon-ethernet-y += ethernet-rgmii.o
-octeon-ethernet-y += ethernet-rx.o
-octeon-ethernet-y += ethernet-sgmii.o
-octeon-ethernet-y += ethernet-spi.o
-octeon-ethernet-y += ethernet-tx.o
diff --git a/drivers/staging/octeon/TODO b/drivers/staging/octeon/TODO
deleted file mode 100644
index 67a0a1f6b922..000000000000
--- a/drivers/staging/octeon/TODO
+++ /dev/null
@@ -1,9 +0,0 @@
-This driver is functional and supports Ethernet on OCTEON+/OCTEON2/OCTEON3
-chips at least up to CN7030.
-
-TODO:
- - general code review and clean up
- - make driver self-contained instead of being split between staging and
- arch/mips/cavium-octeon.
-
-Contact: Aaro Koskinen <aaro.koskinen@iki.fi>
diff --git a/drivers/staging/octeon/ethernet-defines.h b/drivers/staging/octeon/ethernet-defines.h
deleted file mode 100644
index ef9e767b0e2e..000000000000
--- a/drivers/staging/octeon/ethernet-defines.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * This file is based on code from OCTEON SDK by Cavium Networks.
- *
- * Copyright (c) 2003-2007 Cavium Networks
- */
-
-/*
- * A few defines are used to control the operation of this driver:
- * USE_ASYNC_IOBDMA
- * Use asynchronous IO access to hardware. This uses Octeon's asynchronous
- * IOBDMAs to issue IO accesses without stalling. Set this to zero
- * to disable this. Note that IOBDMAs require CVMSEG.
- * REUSE_SKBUFFS_WITHOUT_FREE
- * Allows the TX path to free an skbuff into the FPA hardware pool. This
- * can significantly improve performance for forwarding and bridging, but
- * may be somewhat dangerous. Checks are made, but if any buffer is reused
- * without the proper Linux cleanup, the networking stack may have very
- * bizarre bugs.
- */
-#ifndef __ETHERNET_DEFINES_H__
-#define __ETHERNET_DEFINES_H__
-
-#ifdef CONFIG_NETFILTER
-#define REUSE_SKBUFFS_WITHOUT_FREE 0
-#else
-#define REUSE_SKBUFFS_WITHOUT_FREE 1
-#endif
-
-#define USE_ASYNC_IOBDMA (CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0)
-
-/* Maximum number of SKBs to try to free per xmit packet. */
-#define MAX_OUT_QUEUE_DEPTH 1000
-
-#define FAU_TOTAL_TX_TO_CLEAN (CVMX_FAU_REG_END - sizeof(u32))
-#define FAU_NUM_PACKET_BUFFERS_TO_FREE (FAU_TOTAL_TX_TO_CLEAN - sizeof(u32))
-
-#define TOTAL_NUMBER_OF_PORTS (CVMX_PIP_NUM_INPUT_PORTS + 1)
-
-#endif /* __ETHERNET_DEFINES_H__ */
diff --git a/drivers/staging/octeon/ethernet-mdio.c b/drivers/staging/octeon/ethernet-mdio.c
deleted file mode 100644
index c798672d61b2..000000000000
--- a/drivers/staging/octeon/ethernet-mdio.c
+++ /dev/null
@@ -1,178 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * This file is based on code from OCTEON SDK by Cavium Networks.
- *
- * Copyright (c) 2003-2007 Cavium Networks
- */
-
-#include <linux/kernel.h>
-#include <linux/ethtool.h>
-#include <linux/phy.h>
-#include <linux/ratelimit.h>
-#include <linux/of_mdio.h>
-#include <generated/utsrelease.h>
-#include <net/dst.h>
-
-#include "octeon-ethernet.h"
-#include "ethernet-defines.h"
-#include "ethernet-mdio.h"
-#include "ethernet-util.h"
-
-static void cvm_oct_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
- strlcpy(info->version, UTS_RELEASE, sizeof(info->version));
- strlcpy(info->bus_info, "Builtin", sizeof(info->bus_info));
-}
-
-static int cvm_oct_nway_reset(struct net_device *dev)
-{
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
-
- if (dev->phydev)
- return phy_start_aneg(dev->phydev);
-
- return -EINVAL;
-}
-
-const struct ethtool_ops cvm_oct_ethtool_ops = {
- .get_drvinfo = cvm_oct_get_drvinfo,
- .nway_reset = cvm_oct_nway_reset,
- .get_link = ethtool_op_get_link,
- .get_link_ksettings = phy_ethtool_get_link_ksettings,
- .set_link_ksettings = phy_ethtool_set_link_ksettings,
-};
-
-/**
- * cvm_oct_ioctl - IOCTL support for PHY control
- * @dev: Device to change
- * @rq: the request
- * @cmd: the command
- *
- * Returns Zero on success
- */
-int cvm_oct_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-{
- if (!netif_running(dev))
- return -EINVAL;
-
- if (!dev->phydev)
- return -EINVAL;
-
- return phy_mii_ioctl(dev->phydev, rq, cmd);
-}
-
-void cvm_oct_note_carrier(struct octeon_ethernet *priv,
- union cvmx_helper_link_info li)
-{
- if (li.s.link_up) {
- pr_notice_ratelimited("%s: %u Mbps %s duplex, port %d, queue %d\n",
- netdev_name(priv->netdev), li.s.speed,
- (li.s.full_duplex) ? "Full" : "Half",
- priv->port, priv->queue);
- } else {
- pr_notice_ratelimited("%s: Link down\n",
- netdev_name(priv->netdev));
- }
-}
-
-void cvm_oct_adjust_link(struct net_device *dev)
-{
- struct octeon_ethernet *priv = netdev_priv(dev);
- union cvmx_helper_link_info link_info;
-
- link_info.u64 = 0;
- link_info.s.link_up = dev->phydev->link ? 1 : 0;
- link_info.s.full_duplex = dev->phydev->duplex ? 1 : 0;
- link_info.s.speed = dev->phydev->speed;
- priv->link_info = link_info.u64;
-
- /*
- * The polling task need to know about link status changes.
- */
- if (priv->poll)
- priv->poll(dev);
-
- if (priv->last_link != dev->phydev->link) {
- priv->last_link = dev->phydev->link;
- cvmx_helper_link_set(priv->port, link_info);
- cvm_oct_note_carrier(priv, link_info);
- }
-}
-
-int cvm_oct_common_stop(struct net_device *dev)
-{
- struct octeon_ethernet *priv = netdev_priv(dev);
- int interface = INTERFACE(priv->port);
- union cvmx_helper_link_info link_info;
- union cvmx_gmxx_prtx_cfg gmx_cfg;
- int index = INDEX(priv->port);
-
- gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
- gmx_cfg.s.en = 0;
- cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
-
- priv->poll = NULL;
-
- if (dev->phydev)
- phy_disconnect(dev->phydev);
-
- if (priv->last_link) {
- link_info.u64 = 0;
- priv->last_link = 0;
-
- cvmx_helper_link_set(priv->port, link_info);
- cvm_oct_note_carrier(priv, link_info);
- }
- return 0;
-}
-
-/**
- * cvm_oct_phy_setup_device - setup the PHY
- *
- * @dev: Device to setup
- *
- * Returns Zero on success, negative on failure
- */
-int cvm_oct_phy_setup_device(struct net_device *dev)
-{
- struct octeon_ethernet *priv = netdev_priv(dev);
- struct device_node *phy_node;
- struct phy_device *phydev = NULL;
-
- if (!priv->of_node)
- goto no_phy;
-
- phy_node = of_parse_phandle(priv->of_node, "phy-handle", 0);
- if (!phy_node && of_phy_is_fixed_link(priv->of_node)) {
- int rc;
-
- rc = of_phy_register_fixed_link(priv->of_node);
- if (rc)
- return rc;
-
- phy_node = of_node_get(priv->of_node);
- }
- if (!phy_node)
- goto no_phy;
-
- phydev = of_phy_connect(dev, phy_node, cvm_oct_adjust_link, 0,
- priv->phy_mode);
- of_node_put(phy_node);
-
- if (!phydev)
- return -ENODEV;
-
- priv->last_link = 0;
- phy_start(phydev);
-
- return 0;
-no_phy:
- /* If there is no phy, assume a direct MAC connection and that
- * the link is up.
- */
- netif_carrier_on(dev);
- return 0;
-}
diff --git a/drivers/staging/octeon/ethernet-mdio.h b/drivers/staging/octeon/ethernet-mdio.h
deleted file mode 100644
index e3771d48c49b..000000000000
--- a/drivers/staging/octeon/ethernet-mdio.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * This file is based on code from OCTEON SDK by Cavium Networks.
- *
- * Copyright (c) 2003-2007 Cavium Networks
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/ip.h>
-#include <linux/string.h>
-#include <linux/ethtool.h>
-#include <linux/seq_file.h>
-#include <linux/proc_fs.h>
-#include <net/dst.h>
-#ifdef CONFIG_XFRM
-#include <linux/xfrm.h>
-#include <net/xfrm.h>
-#endif /* CONFIG_XFRM */
-
-extern const struct ethtool_ops cvm_oct_ethtool_ops;
-
-void octeon_mdiobus_force_mod_depencency(void);
-
-int cvm_oct_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-int cvm_oct_phy_setup_device(struct net_device *dev);
diff --git a/drivers/staging/octeon/ethernet-mem.c b/drivers/staging/octeon/ethernet-mem.c
deleted file mode 100644
index 532594957ebc..000000000000
--- a/drivers/staging/octeon/ethernet-mem.c
+++ /dev/null
@@ -1,154 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * This file is based on code from OCTEON SDK by Cavium Networks.
- *
- * Copyright (c) 2003-2010 Cavium Networks
- */
-
-#include <linux/kernel.h>
-#include <linux/netdevice.h>
-#include <linux/slab.h>
-
-#include "octeon-ethernet.h"
-#include "ethernet-mem.h"
-#include "ethernet-defines.h"
-
-/**
- * cvm_oct_fill_hw_skbuff - fill the supplied hardware pool with skbuffs
- * @pool: Pool to allocate an skbuff for
- * @size: Size of the buffer needed for the pool
- * @elements: Number of buffers to allocate
- *
- * Returns the actual number of buffers allocated.
- */
-static int cvm_oct_fill_hw_skbuff(int pool, int size, int elements)
-{
- int freed = elements;
-
- while (freed) {
- struct sk_buff *skb = dev_alloc_skb(size + 256);
-
- if (unlikely(!skb))
- break;
- skb_reserve(skb, 256 - (((unsigned long)skb->data) & 0x7f));
- *(struct sk_buff **)(skb->data - sizeof(void *)) = skb;
- cvmx_fpa_free(skb->data, pool, size / 128);
- freed--;
- }
- return elements - freed;
-}
-
-/**
- * cvm_oct_free_hw_skbuff- free hardware pool skbuffs
- * @pool: Pool to allocate an skbuff for
- * @size: Size of the buffer needed for the pool
- * @elements: Number of buffers to allocate
- */
-static void cvm_oct_free_hw_skbuff(int pool, int size, int elements)
-{
- char *memory;
-
- do {
- memory = cvmx_fpa_alloc(pool);
- if (memory) {
- struct sk_buff *skb =
- *(struct sk_buff **)(memory - sizeof(void *));
- elements--;
- dev_kfree_skb(skb);
- }
- } while (memory);
-
- if (elements < 0)
- pr_warn("Freeing of pool %u had too many skbuffs (%d)\n",
- pool, elements);
- else if (elements > 0)
- pr_warn("Freeing of pool %u is missing %d skbuffs\n",
- pool, elements);
-}
-
-/**
- * cvm_oct_fill_hw_memory - fill a hardware pool with memory.
- * @pool: Pool to populate
- * @size: Size of each buffer in the pool
- * @elements: Number of buffers to allocate
- *
- * Returns the actual number of buffers allocated.
- */
-static int cvm_oct_fill_hw_memory(int pool, int size, int elements)
-{
- char *memory;
- char *fpa;
- int freed = elements;
-
- while (freed) {
- /*
- * FPA memory must be 128 byte aligned. Since we are
- * aligning we need to save the original pointer so we
- * can feed it to kfree when the memory is returned to
- * the kernel.
- *
- * We allocate an extra 256 bytes to allow for
- * alignment and space for the original pointer saved
- * just before the block.
- */
- memory = kmalloc(size + 256, GFP_ATOMIC);
- if (unlikely(!memory)) {
- pr_warn("Unable to allocate %u bytes for FPA pool %d\n",
- elements * size, pool);
- break;
- }
- fpa = (char *)(((unsigned long)memory + 256) & ~0x7fUL);
- *((char **)fpa - 1) = memory;
- cvmx_fpa_free(fpa, pool, 0);
- freed--;
- }
- return elements - freed;
-}
-
-/**
- * cvm_oct_free_hw_memory - Free memory allocated by cvm_oct_fill_hw_memory
- * @pool: FPA pool to free
- * @size: Size of each buffer in the pool
- * @elements: Number of buffers that should be in the pool
- */
-static void cvm_oct_free_hw_memory(int pool, int size, int elements)
-{
- char *memory;
- char *fpa;
-
- do {
- fpa = cvmx_fpa_alloc(pool);
- if (fpa) {
- elements--;
- fpa = (char *)phys_to_virt(cvmx_ptr_to_phys(fpa));
- memory = *((char **)fpa - 1);
- kfree(memory);
- }
- } while (fpa);
-
- if (elements < 0)
- pr_warn("Freeing of pool %u had too many buffers (%d)\n",
- pool, elements);
- else if (elements > 0)
- pr_warn("Warning: Freeing of pool %u is missing %d buffers\n",
- pool, elements);
-}
-
-int cvm_oct_mem_fill_fpa(int pool, int size, int elements)
-{
- int freed;
-
- if (pool == CVMX_FPA_PACKET_POOL)
- freed = cvm_oct_fill_hw_skbuff(pool, size, elements);
- else
- freed = cvm_oct_fill_hw_memory(pool, size, elements);
- return freed;
-}
-
-void cvm_oct_mem_empty_fpa(int pool, int size, int elements)
-{
- if (pool == CVMX_FPA_PACKET_POOL)
- cvm_oct_free_hw_skbuff(pool, size, elements);
- else
- cvm_oct_free_hw_memory(pool, size, elements);
-}
diff --git a/drivers/staging/octeon/ethernet-mem.h b/drivers/staging/octeon/ethernet-mem.h
deleted file mode 100644
index 692dcdb7154d..000000000000
--- a/drivers/staging/octeon/ethernet-mem.h
+++ /dev/null
@@ -1,9 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * This file is based on code from OCTEON SDK by Cavium Networks.
- *
- * Copyright (c) 2003-2007 Cavium Networks
- */
-
-int cvm_oct_mem_fill_fpa(int pool, int size, int elements);
-void cvm_oct_mem_empty_fpa(int pool, int size, int elements);
diff --git a/drivers/staging/octeon/ethernet-rgmii.c b/drivers/staging/octeon/ethernet-rgmii.c
deleted file mode 100644
index 0c4fac31540a..000000000000
--- a/drivers/staging/octeon/ethernet-rgmii.c
+++ /dev/null
@@ -1,158 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * This file is based on code from OCTEON SDK by Cavium Networks.
- *
- * Copyright (c) 2003-2007 Cavium Networks
- */
-
-#include <linux/kernel.h>
-#include <linux/netdevice.h>
-#include <linux/interrupt.h>
-#include <linux/phy.h>
-#include <linux/ratelimit.h>
-#include <net/dst.h>
-
-#include "octeon-ethernet.h"
-#include "ethernet-defines.h"
-#include "ethernet-util.h"
-#include "ethernet-mdio.h"
-
-static DEFINE_SPINLOCK(global_register_lock);
-
-static void cvm_oct_set_hw_preamble(struct octeon_ethernet *priv, bool enable)
-{
- union cvmx_gmxx_rxx_frm_ctl gmxx_rxx_frm_ctl;
- union cvmx_ipd_sub_port_fcs ipd_sub_port_fcs;
- union cvmx_gmxx_rxx_int_reg gmxx_rxx_int_reg;
- int interface = INTERFACE(priv->port);
- int index = INDEX(priv->port);
-
- /* Set preamble checking. */
- gmxx_rxx_frm_ctl.u64 = cvmx_read_csr(CVMX_GMXX_RXX_FRM_CTL(index,
- interface));
- gmxx_rxx_frm_ctl.s.pre_chk = enable;
- cvmx_write_csr(CVMX_GMXX_RXX_FRM_CTL(index, interface),
- gmxx_rxx_frm_ctl.u64);
-
- /* Set FCS stripping. */
- ipd_sub_port_fcs.u64 = cvmx_read_csr(CVMX_IPD_SUB_PORT_FCS);
- if (enable)
- ipd_sub_port_fcs.s.port_bit |= 1ull << priv->port;
- else
- ipd_sub_port_fcs.s.port_bit &=
- 0xffffffffull ^ (1ull << priv->port);
- cvmx_write_csr(CVMX_IPD_SUB_PORT_FCS, ipd_sub_port_fcs.u64);
-
- /* Clear any error bits. */
- gmxx_rxx_int_reg.u64 = cvmx_read_csr(CVMX_GMXX_RXX_INT_REG(index,
- interface));
- cvmx_write_csr(CVMX_GMXX_RXX_INT_REG(index, interface),
- gmxx_rxx_int_reg.u64);
-}
-
-static void cvm_oct_check_preamble_errors(struct net_device *dev)
-{
- struct octeon_ethernet *priv = netdev_priv(dev);
- union cvmx_helper_link_info link_info;
- unsigned long flags;
-
- link_info.u64 = priv->link_info;
-
- /*
- * Take the global register lock since we are going to
- * touch registers that affect more than one port.
- */
- spin_lock_irqsave(&global_register_lock, flags);
-
- if (link_info.s.speed == 10 && priv->last_speed == 10) {
- /*
- * Read the GMXX_RXX_INT_REG[PCTERR] bit and see if we are
- * getting preamble errors.
- */
- int interface = INTERFACE(priv->port);
- int index = INDEX(priv->port);
- union cvmx_gmxx_rxx_int_reg gmxx_rxx_int_reg;
-
- gmxx_rxx_int_reg.u64 = cvmx_read_csr(CVMX_GMXX_RXX_INT_REG
- (index, interface));
- if (gmxx_rxx_int_reg.s.pcterr) {
- /*
- * We are getting preamble errors at 10Mbps. Most
- * likely the PHY is giving us packets with misaligned
- * preambles. In order to get these packets we need to
- * disable preamble checking and do it in software.
- */
- cvm_oct_set_hw_preamble(priv, false);
- printk_ratelimited("%s: Using 10Mbps with software preamble removal\n",
- dev->name);
- }
- } else {
- /*
- * Since the 10Mbps preamble workaround is allowed we need to
- * enable preamble checking, FCS stripping, and clear error
- * bits on every speed change. If errors occur during 10Mbps
- * operation the above code will change this stuff
- */
- if (priv->last_speed != link_info.s.speed)
- cvm_oct_set_hw_preamble(priv, true);
- priv->last_speed = link_info.s.speed;
- }
- spin_unlock_irqrestore(&global_register_lock, flags);
-}
-
-static void cvm_oct_rgmii_poll(struct net_device *dev)
-{
- struct octeon_ethernet *priv = netdev_priv(dev);
- union cvmx_helper_link_info link_info;
- bool status_change;
-
- link_info = cvmx_helper_link_get(priv->port);
- if (priv->link_info != link_info.u64 &&
- cvmx_helper_link_set(priv->port, link_info))
- link_info.u64 = priv->link_info;
- status_change = priv->link_info != link_info.u64;
- priv->link_info = link_info.u64;
-
- cvm_oct_check_preamble_errors(dev);
-
- if (likely(!status_change))
- return;
-
- /* Tell core. */
- if (link_info.s.link_up) {
- if (!netif_carrier_ok(dev))
- netif_carrier_on(dev);
- } else if (netif_carrier_ok(dev)) {
- netif_carrier_off(dev);
- }
- cvm_oct_note_carrier(priv, link_info);
-}
-
-int cvm_oct_rgmii_open(struct net_device *dev)
-{
- struct octeon_ethernet *priv = netdev_priv(dev);
- int ret;
-
- ret = cvm_oct_common_open(dev, cvm_oct_rgmii_poll);
- if (ret)
- return ret;
-
- if (dev->phydev) {
- /*
- * In phydev mode, we need still periodic polling for the
- * preamble error checking, and we also need to call this
- * function on every link state change.
- *
- * Only true RGMII ports need to be polled. In GMII mode, port
- * 0 is really a RGMII port.
- */
- if ((priv->imode == CVMX_HELPER_INTERFACE_MODE_GMII &&
- priv->port == 0) ||
- (priv->imode == CVMX_HELPER_INTERFACE_MODE_RGMII)) {
- priv->poll = cvm_oct_check_preamble_errors;
- cvm_oct_check_preamble_errors(dev);
- }
- }
-
- return 0;
-}
diff --git a/drivers/staging/octeon/ethernet-rx.c b/drivers/staging/octeon/ethernet-rx.c
deleted file mode 100644
index 2c16230f993c..000000000000
--- a/drivers/staging/octeon/ethernet-rx.c
+++ /dev/null
@@ -1,538 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * This file is based on code from OCTEON SDK by Cavium Networks.
- *
- * Copyright (c) 2003-2010 Cavium Networks
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/cache.h>
-#include <linux/cpumask.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/ip.h>
-#include <linux/string.h>
-#include <linux/prefetch.h>
-#include <linux/ratelimit.h>
-#include <linux/smp.h>
-#include <linux/interrupt.h>
-#include <net/dst.h>
-#ifdef CONFIG_XFRM
-#include <linux/xfrm.h>
-#include <net/xfrm.h>
-#endif /* CONFIG_XFRM */
-
-#include "octeon-ethernet.h"
-#include "ethernet-defines.h"
-#include "ethernet-mem.h"
-#include "ethernet-rx.h"
-#include "ethernet-util.h"
-
-static atomic_t oct_rx_ready = ATOMIC_INIT(0);
-
-static struct oct_rx_group {
- int irq;
- int group;
- struct napi_struct napi;
-} oct_rx_group[16];
-
-/**
- * cvm_oct_do_interrupt - interrupt handler.
- * @irq: Interrupt number.
- * @napi_id: Cookie to identify the NAPI instance.
- *
- * The interrupt occurs whenever the POW has packets in our group.
- *
- */
-static irqreturn_t cvm_oct_do_interrupt(int irq, void *napi_id)
-{
- /* Disable the IRQ and start napi_poll. */
- disable_irq_nosync(irq);
- napi_schedule(napi_id);
-
- return IRQ_HANDLED;
-}
-
-/**
- * cvm_oct_check_rcv_error - process receive errors
- * @work: Work queue entry pointing to the packet.
- *
- * Returns Non-zero if the packet can be dropped, zero otherwise.
- */
-static inline int cvm_oct_check_rcv_error(struct cvmx_wqe *work)
-{
- int port;
-
- if (octeon_has_feature(OCTEON_FEATURE_PKND))
- port = work->word0.pip.cn68xx.pknd;
- else
- port = work->word1.cn38xx.ipprt;
-
- if ((work->word2.snoip.err_code == 10) && (work->word1.len <= 64)) {
- /*
- * Ignore length errors on min size packets. Some
- * equipment incorrectly pads packets to 64+4FCS
- * instead of 60+4FCS. Note these packets still get
- * counted as frame errors.
- */
- } else if (work->word2.snoip.err_code == 5 ||
- work->word2.snoip.err_code == 7) {
- /*
- * We received a packet with either an alignment error
- * or a FCS error. This may be signalling that we are
- * running 10Mbps with GMXX_RXX_FRM_CTL[PRE_CHK]
- * off. If this is the case we need to parse the
- * packet to determine if we can remove a non spec
- * preamble and generate a correct packet.
- */
- int interface = cvmx_helper_get_interface_num(port);
- int index = cvmx_helper_get_interface_index_num(port);
- union cvmx_gmxx_rxx_frm_ctl gmxx_rxx_frm_ctl;
-
- gmxx_rxx_frm_ctl.u64 =
- cvmx_read_csr(CVMX_GMXX_RXX_FRM_CTL(index, interface));
- if (gmxx_rxx_frm_ctl.s.pre_chk == 0) {
- u8 *ptr =
- cvmx_phys_to_ptr(work->packet_ptr.s.addr);
- int i = 0;
-
- while (i < work->word1.len - 1) {
- if (*ptr != 0x55)
- break;
- ptr++;
- i++;
- }
-
- if (*ptr == 0xd5) {
- /* Port received 0xd5 preamble */
- work->packet_ptr.s.addr += i + 1;
- work->word1.len -= i + 5;
- } else if ((*ptr & 0xf) == 0xd) {
- /* Port received 0xd preamble */
- work->packet_ptr.s.addr += i;
- work->word1.len -= i + 4;
- for (i = 0; i < work->word1.len; i++) {
- *ptr =
- ((*ptr & 0xf0) >> 4) |
- ((*(ptr + 1) & 0xf) << 4);
- ptr++;
- }
- } else {
- printk_ratelimited("Port %d unknown preamble, packet dropped\n",
- port);
- cvm_oct_free_work(work);
- return 1;
- }
- }
- } else {
- printk_ratelimited("Port %d receive error code %d, packet dropped\n",
- port, work->word2.snoip.err_code);
- cvm_oct_free_work(work);
- return 1;
- }
-
- return 0;
-}
-
-static void copy_segments_to_skb(struct cvmx_wqe *work, struct sk_buff *skb)
-{
- int segments = work->word2.s.bufs;
- union cvmx_buf_ptr segment_ptr = work->packet_ptr;
- int len = work->word1.len;
- int segment_size;
-
- while (segments--) {
- union cvmx_buf_ptr next_ptr;
-
- next_ptr = *(union cvmx_buf_ptr *)
- cvmx_phys_to_ptr(segment_ptr.s.addr - 8);
-
- /*
- * Octeon Errata PKI-100: The segment size is wrong.
- *
- * Until it is fixed, calculate the segment size based on
- * the packet pool buffer size.
- * When it is fixed, the following line should be replaced
- * with this one:
- * int segment_size = segment_ptr.s.size;
- */
- segment_size =
- CVMX_FPA_PACKET_POOL_SIZE -
- (segment_ptr.s.addr -
- (((segment_ptr.s.addr >> 7) -
- segment_ptr.s.back) << 7));
-
- /* Don't copy more than what is left in the packet */
- if (segment_size > len)
- segment_size = len;
-
- /* Copy the data into the packet */
- skb_put_data(skb, cvmx_phys_to_ptr(segment_ptr.s.addr),
- segment_size);
- len -= segment_size;
- segment_ptr = next_ptr;
- }
-}
-
-static int cvm_oct_poll(struct oct_rx_group *rx_group, int budget)
-{
- const int coreid = cvmx_get_core_num();
- u64 old_group_mask;
- u64 old_scratch;
- int rx_count = 0;
- int did_work_request = 0;
- int packet_not_copied;
-
- /* Prefetch cvm_oct_device since we know we need it soon */
- prefetch(cvm_oct_device);
-
- if (USE_ASYNC_IOBDMA) {
- /* Save scratch in case userspace is using it */
- CVMX_SYNCIOBDMA;
- old_scratch = cvmx_scratch_read64(CVMX_SCR_SCRATCH);
- }
-
- /* Only allow work for our group (and preserve priorities) */
- if (OCTEON_IS_MODEL(OCTEON_CN68XX)) {
- old_group_mask = cvmx_read_csr(CVMX_SSO_PPX_GRP_MSK(coreid));
- cvmx_write_csr(CVMX_SSO_PPX_GRP_MSK(coreid),
- BIT(rx_group->group));
- cvmx_read_csr(CVMX_SSO_PPX_GRP_MSK(coreid)); /* Flush */
- } else {
- old_group_mask = cvmx_read_csr(CVMX_POW_PP_GRP_MSKX(coreid));
- cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(coreid),
- (old_group_mask & ~0xFFFFull) |
- BIT(rx_group->group));
- }
-
- if (USE_ASYNC_IOBDMA) {
- cvmx_pow_work_request_async(CVMX_SCR_SCRATCH, CVMX_POW_NO_WAIT);
- did_work_request = 1;
- }
-
- while (rx_count < budget) {
- struct sk_buff *skb = NULL;
- struct sk_buff **pskb = NULL;
- int skb_in_hw;
- struct cvmx_wqe *work;
- int port;
-
- if (USE_ASYNC_IOBDMA && did_work_request)
- work = cvmx_pow_work_response_async(CVMX_SCR_SCRATCH);
- else
- work = cvmx_pow_work_request_sync(CVMX_POW_NO_WAIT);
-
- prefetch(work);
- did_work_request = 0;
- if (!work) {
- if (OCTEON_IS_MODEL(OCTEON_CN68XX)) {
- cvmx_write_csr(CVMX_SSO_WQ_IQ_DIS,
- BIT(rx_group->group));
- cvmx_write_csr(CVMX_SSO_WQ_INT,
- BIT(rx_group->group));
- } else {
- union cvmx_pow_wq_int wq_int;
-
- wq_int.u64 = 0;
- wq_int.s.iq_dis = BIT(rx_group->group);
- wq_int.s.wq_int = BIT(rx_group->group);
- cvmx_write_csr(CVMX_POW_WQ_INT, wq_int.u64);
- }
- break;
- }
- pskb = (struct sk_buff **)
- (cvm_oct_get_buffer_ptr(work->packet_ptr) -
- sizeof(void *));
- prefetch(pskb);
-
- if (USE_ASYNC_IOBDMA && rx_count < (budget - 1)) {
- cvmx_pow_work_request_async_nocheck(CVMX_SCR_SCRATCH,
- CVMX_POW_NO_WAIT);
- did_work_request = 1;
- }
- rx_count++;
-
- skb_in_hw = work->word2.s.bufs == 1;
- if (likely(skb_in_hw)) {
- skb = *pskb;
- prefetch(&skb->head);
- prefetch(&skb->len);
- }
-
- if (octeon_has_feature(OCTEON_FEATURE_PKND))
- port = work->word0.pip.cn68xx.pknd;
- else
- port = work->word1.cn38xx.ipprt;
-
- prefetch(cvm_oct_device[port]);
-
- /* Immediately throw away all packets with receive errors */
- if (unlikely(work->word2.snoip.rcv_error)) {
- if (cvm_oct_check_rcv_error(work))
- continue;
- }
-
- /*
- * We can only use the zero copy path if skbuffs are
- * in the FPA pool and the packet fits in a single
- * buffer.
- */
- if (likely(skb_in_hw)) {
- skb->data = skb->head + work->packet_ptr.s.addr -
- cvmx_ptr_to_phys(skb->head);
- prefetch(skb->data);
- skb->len = work->word1.len;
- skb_set_tail_pointer(skb, skb->len);
- packet_not_copied = 1;
- } else {
- /*
- * We have to copy the packet. First allocate
- * an skbuff for it.
- */
- skb = dev_alloc_skb(work->word1.len);
- if (!skb) {
- cvm_oct_free_work(work);
- continue;
- }
-
- /*
- * Check if we've received a packet that was
- * entirely stored in the work entry.
- */
- if (unlikely(work->word2.s.bufs == 0)) {
- u8 *ptr = work->packet_data;
-
- if (likely(!work->word2.s.not_IP)) {
- /*
- * The beginning of the packet
- * moves for IP packets.
- */
- if (work->word2.s.is_v6)
- ptr += 2;
- else
- ptr += 6;
- }
- skb_put_data(skb, ptr, work->word1.len);
- /* No packet buffers to free */
- } else {
- copy_segments_to_skb(work, skb);
- }
- packet_not_copied = 0;
- }
- if (likely((port < TOTAL_NUMBER_OF_PORTS) &&
- cvm_oct_device[port])) {
- struct net_device *dev = cvm_oct_device[port];
-
- /*
- * Only accept packets for devices that are
- * currently up.
- */
- if (likely(dev->flags & IFF_UP)) {
- skb->protocol = eth_type_trans(skb, dev);
- skb->dev = dev;
-
- if (unlikely(work->word2.s.not_IP ||
- work->word2.s.IP_exc ||
- work->word2.s.L4_error ||
- !work->word2.s.tcp_or_udp))
- skb->ip_summed = CHECKSUM_NONE;
- else
- skb->ip_summed = CHECKSUM_UNNECESSARY;
-
- /* Increment RX stats for virtual ports */
- if (port >= CVMX_PIP_NUM_INPUT_PORTS) {
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += skb->len;
- }
- netif_receive_skb(skb);
- } else {
- /*
- * Drop any packet received for a device that
- * isn't up.
- */
- dev->stats.rx_dropped++;
- dev_kfree_skb_irq(skb);
- }
- } else {
- /*
- * Drop any packet received for a device that
- * doesn't exist.
- */
- printk_ratelimited("Port %d not controlled by Linux, packet dropped\n",
- port);
- dev_kfree_skb_irq(skb);
- }
- /*
- * Check to see if the skbuff and work share the same
- * packet buffer.
- */
- if (likely(packet_not_copied)) {
- /*
- * This buffer needs to be replaced, increment
- * the number of buffers we need to free by
- * one.
- */
- cvmx_fau_atomic_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE,
- 1);
-
- cvmx_fpa_free(work, CVMX_FPA_WQE_POOL, 1);
- } else {
- cvm_oct_free_work(work);
- }
- }
- /* Restore the original POW group mask */
- if (OCTEON_IS_MODEL(OCTEON_CN68XX)) {
- cvmx_write_csr(CVMX_SSO_PPX_GRP_MSK(coreid), old_group_mask);
- cvmx_read_csr(CVMX_SSO_PPX_GRP_MSK(coreid)); /* Flush */
- } else {
- cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(coreid), old_group_mask);
- }
-
- if (USE_ASYNC_IOBDMA) {
- /* Restore the scratch area */
- cvmx_scratch_write64(CVMX_SCR_SCRATCH, old_scratch);
- }
- cvm_oct_rx_refill_pool(0);
-
- return rx_count;
-}
-
-/**
- * cvm_oct_napi_poll - the NAPI poll function.
- * @napi: The NAPI instance.
- * @budget: Maximum number of packets to receive.
- *
- * Returns the number of packets processed.
- */
-static int cvm_oct_napi_poll(struct napi_struct *napi, int budget)
-{
- struct oct_rx_group *rx_group = container_of(napi, struct oct_rx_group,
- napi);
- int rx_count;
-
- rx_count = cvm_oct_poll(rx_group, budget);
-
- if (rx_count < budget) {
- /* No more work */
- napi_complete_done(napi, rx_count);
- enable_irq(rx_group->irq);
- }
- return rx_count;
-}
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-/**
- * cvm_oct_poll_controller - poll for receive packets
- * device.
- *
- * @dev: Device to poll. Unused
- */
-void cvm_oct_poll_controller(struct net_device *dev)
-{
- int i;
-
- if (!atomic_read(&oct_rx_ready))
- return;
-
- for (i = 0; i < ARRAY_SIZE(oct_rx_group); i++) {
- if (!(pow_receive_groups & BIT(i)))
- continue;
-
- cvm_oct_poll(&oct_rx_group[i], 16);
- }
-}
-#endif
-
-void cvm_oct_rx_initialize(void)
-{
- int i;
- struct net_device *dev_for_napi = NULL;
-
- for (i = 0; i < TOTAL_NUMBER_OF_PORTS; i++) {
- if (cvm_oct_device[i]) {
- dev_for_napi = cvm_oct_device[i];
- break;
- }
- }
-
- if (!dev_for_napi)
- panic("No net_devices were allocated.");
-
- for (i = 0; i < ARRAY_SIZE(oct_rx_group); i++) {
- int ret;
-
- if (!(pow_receive_groups & BIT(i)))
- continue;
-
- netif_napi_add(dev_for_napi, &oct_rx_group[i].napi,
- cvm_oct_napi_poll, rx_napi_weight);
- napi_enable(&oct_rx_group[i].napi);
-
- oct_rx_group[i].irq = OCTEON_IRQ_WORKQ0 + i;
- oct_rx_group[i].group = i;
-
- /* Register an IRQ handler to receive POW interrupts */
- ret = request_irq(oct_rx_group[i].irq, cvm_oct_do_interrupt, 0,
- "Ethernet", &oct_rx_group[i].napi);
- if (ret)
- panic("Could not acquire Ethernet IRQ %d\n",
- oct_rx_group[i].irq);
-
- disable_irq_nosync(oct_rx_group[i].irq);
-
- /* Enable POW interrupt when our port has at least one packet */
- if (OCTEON_IS_MODEL(OCTEON_CN68XX)) {
- union cvmx_sso_wq_int_thrx int_thr;
- union cvmx_pow_wq_int_pc int_pc;
-
- int_thr.u64 = 0;
- int_thr.s.tc_en = 1;
- int_thr.s.tc_thr = 1;
- cvmx_write_csr(CVMX_SSO_WQ_INT_THRX(i), int_thr.u64);
-
- int_pc.u64 = 0;
- int_pc.s.pc_thr = 5;
- cvmx_write_csr(CVMX_SSO_WQ_INT_PC, int_pc.u64);
- } else {
- union cvmx_pow_wq_int_thrx int_thr;
- union cvmx_pow_wq_int_pc int_pc;
-
- int_thr.u64 = 0;
- int_thr.s.tc_en = 1;
- int_thr.s.tc_thr = 1;
- cvmx_write_csr(CVMX_POW_WQ_INT_THRX(i), int_thr.u64);
-
- int_pc.u64 = 0;
- int_pc.s.pc_thr = 5;
- cvmx_write_csr(CVMX_POW_WQ_INT_PC, int_pc.u64);
- }
-
- /* Schedule NAPI now. This will indirectly enable the
- * interrupt.
- */
- napi_schedule(&oct_rx_group[i].napi);
- }
- atomic_inc(&oct_rx_ready);
-}
-
-void cvm_oct_rx_shutdown(void)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(oct_rx_group); i++) {
- if (!(pow_receive_groups & BIT(i)))
- continue;
-
- /* Disable POW interrupt */
- if (OCTEON_IS_MODEL(OCTEON_CN68XX))
- cvmx_write_csr(CVMX_SSO_WQ_INT_THRX(i), 0);
- else
- cvmx_write_csr(CVMX_POW_WQ_INT_THRX(i), 0);
-
- /* Free the interrupt handler */
- free_irq(oct_rx_group[i].irq, cvm_oct_device);
-
- netif_napi_del(&oct_rx_group[i].napi);
- }
-}
diff --git a/drivers/staging/octeon/ethernet-rx.h b/drivers/staging/octeon/ethernet-rx.h
deleted file mode 100644
index ff6482fa20d6..000000000000
--- a/drivers/staging/octeon/ethernet-rx.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * This file is based on code from OCTEON SDK by Cavium Networks.
- *
- * Copyright (c) 2003-2007 Cavium Networks
- */
-
-void cvm_oct_poll_controller(struct net_device *dev);
-void cvm_oct_rx_initialize(void);
-void cvm_oct_rx_shutdown(void);
-
-static inline void cvm_oct_rx_refill_pool(int fill_threshold)
-{
- int number_to_free;
- int num_freed;
- /* Refill the packet buffer pool */
- number_to_free =
- cvmx_fau_fetch_and_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE, 0);
-
- if (number_to_free > fill_threshold) {
- cvmx_fau_atomic_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE,
- -number_to_free);
- num_freed = cvm_oct_mem_fill_fpa(CVMX_FPA_PACKET_POOL,
- CVMX_FPA_PACKET_POOL_SIZE,
- number_to_free);
- if (num_freed != number_to_free) {
- cvmx_fau_atomic_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE,
- number_to_free - num_freed);
- }
- }
-}
diff --git a/drivers/staging/octeon/ethernet-sgmii.c b/drivers/staging/octeon/ethernet-sgmii.c
deleted file mode 100644
index d7fbd9159302..000000000000
--- a/drivers/staging/octeon/ethernet-sgmii.c
+++ /dev/null
@@ -1,30 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * This file is based on code from OCTEON SDK by Cavium Networks.
- *
- * Copyright (c) 2003-2007 Cavium Networks
- */
-
-#include <linux/phy.h>
-#include <linux/kernel.h>
-#include <linux/netdevice.h>
-#include <linux/ratelimit.h>
-#include <net/dst.h>
-
-#include "octeon-ethernet.h"
-#include "ethernet-defines.h"
-#include "ethernet-util.h"
-#include "ethernet-mdio.h"
-
-int cvm_oct_sgmii_open(struct net_device *dev)
-{
- return cvm_oct_common_open(dev, cvm_oct_link_poll);
-}
-
-int cvm_oct_sgmii_init(struct net_device *dev)
-{
- cvm_oct_common_init(dev);
-
- /* FIXME: Need autoneg logic */
- return 0;
-}
diff --git a/drivers/staging/octeon/ethernet-spi.c b/drivers/staging/octeon/ethernet-spi.c
deleted file mode 100644
index c582403e6a1f..000000000000
--- a/drivers/staging/octeon/ethernet-spi.c
+++ /dev/null
@@ -1,226 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * This file is based on code from OCTEON SDK by Cavium Networks.
- *
- * Copyright (c) 2003-2007 Cavium Networks
- */
-
-#include <linux/kernel.h>
-#include <linux/netdevice.h>
-#include <linux/interrupt.h>
-#include <net/dst.h>
-
-#include "octeon-ethernet.h"
-#include "ethernet-defines.h"
-#include "ethernet-util.h"
-
-static int number_spi_ports;
-static int need_retrain[2] = { 0, 0 };
-
-static void cvm_oct_spxx_int_pr(union cvmx_spxx_int_reg spx_int_reg, int index)
-{
- if (spx_int_reg.s.spf)
- pr_err("SPI%d: SRX Spi4 interface down\n", index);
- if (spx_int_reg.s.calerr)
- pr_err("SPI%d: SRX Spi4 Calendar table parity error\n", index);
- if (spx_int_reg.s.syncerr)
- pr_err("SPI%d: SRX Consecutive Spi4 DIP4 errors have exceeded SPX_ERR_CTL[ERRCNT]\n",
- index);
- if (spx_int_reg.s.diperr)
- pr_err("SPI%d: SRX Spi4 DIP4 error\n", index);
- if (spx_int_reg.s.tpaovr)
- pr_err("SPI%d: SRX Selected port has hit TPA overflow\n",
- index);
- if (spx_int_reg.s.rsverr)
- pr_err("SPI%d: SRX Spi4 reserved control word detected\n",
- index);
- if (spx_int_reg.s.drwnng)
- pr_err("SPI%d: SRX Spi4 receive FIFO drowning/overflow\n",
- index);
- if (spx_int_reg.s.clserr)
- pr_err("SPI%d: SRX Spi4 packet closed on non-16B alignment without EOP\n",
- index);
- if (spx_int_reg.s.spiovr)
- pr_err("SPI%d: SRX Spi4 async FIFO overflow\n", index);
- if (spx_int_reg.s.abnorm)
- pr_err("SPI%d: SRX Abnormal packet termination (ERR bit)\n",
- index);
- if (spx_int_reg.s.prtnxa)
- pr_err("SPI%d: SRX Port out of range\n", index);
-}
-
-static void cvm_oct_stxx_int_pr(union cvmx_stxx_int_reg stx_int_reg, int index)
-{
- if (stx_int_reg.s.syncerr)
- pr_err("SPI%d: STX Interface encountered a fatal error\n",
- index);
- if (stx_int_reg.s.frmerr)
- pr_err("SPI%d: STX FRMCNT has exceeded STX_DIP_CNT[MAXFRM]\n",
- index);
- if (stx_int_reg.s.unxfrm)
- pr_err("SPI%d: STX Unexpected framing sequence\n", index);
- if (stx_int_reg.s.nosync)
- pr_err("SPI%d: STX ERRCNT has exceeded STX_DIP_CNT[MAXDIP]\n",
- index);
- if (stx_int_reg.s.diperr)
- pr_err("SPI%d: STX DIP2 error on the Spi4 Status channel\n",
- index);
- if (stx_int_reg.s.datovr)
- pr_err("SPI%d: STX Spi4 FIFO overflow error\n", index);
- if (stx_int_reg.s.ovrbst)
- pr_err("SPI%d: STX Transmit packet burst too big\n", index);
- if (stx_int_reg.s.calpar1)
- pr_err("SPI%d: STX Calendar Table Parity Error Bank%d\n",
- index, 1);
- if (stx_int_reg.s.calpar0)
- pr_err("SPI%d: STX Calendar Table Parity Error Bank%d\n",
- index, 0);
-}
-
-static irqreturn_t cvm_oct_spi_spx_int(int index)
-{
- union cvmx_spxx_int_reg spx_int_reg;
- union cvmx_stxx_int_reg stx_int_reg;
-
- spx_int_reg.u64 = cvmx_read_csr(CVMX_SPXX_INT_REG(index));
- cvmx_write_csr(CVMX_SPXX_INT_REG(index), spx_int_reg.u64);
- if (!need_retrain[index]) {
- spx_int_reg.u64 &= cvmx_read_csr(CVMX_SPXX_INT_MSK(index));
- cvm_oct_spxx_int_pr(spx_int_reg, index);
- }
-
- stx_int_reg.u64 = cvmx_read_csr(CVMX_STXX_INT_REG(index));
- cvmx_write_csr(CVMX_STXX_INT_REG(index), stx_int_reg.u64);
- if (!need_retrain[index]) {
- stx_int_reg.u64 &= cvmx_read_csr(CVMX_STXX_INT_MSK(index));
- cvm_oct_stxx_int_pr(stx_int_reg, index);
- }
-
- cvmx_write_csr(CVMX_SPXX_INT_MSK(index), 0);
- cvmx_write_csr(CVMX_STXX_INT_MSK(index), 0);
- need_retrain[index] = 1;
-
- return IRQ_HANDLED;
-}
-
-static irqreturn_t cvm_oct_spi_rml_interrupt(int cpl, void *dev_id)
-{
- irqreturn_t return_status = IRQ_NONE;
- union cvmx_npi_rsl_int_blocks rsl_int_blocks;
-
- /* Check and see if this interrupt was caused by the GMX block */
- rsl_int_blocks.u64 = cvmx_read_csr(CVMX_NPI_RSL_INT_BLOCKS);
- if (rsl_int_blocks.s.spx1) /* 19 - SPX1_INT_REG & STX1_INT_REG */
- return_status = cvm_oct_spi_spx_int(1);
-
- if (rsl_int_blocks.s.spx0) /* 18 - SPX0_INT_REG & STX0_INT_REG */
- return_status = cvm_oct_spi_spx_int(0);
-
- return return_status;
-}
-
-static void cvm_oct_spi_enable_error_reporting(int interface)
-{
- union cvmx_spxx_int_msk spxx_int_msk;
- union cvmx_stxx_int_msk stxx_int_msk;
-
- spxx_int_msk.u64 = cvmx_read_csr(CVMX_SPXX_INT_MSK(interface));
- spxx_int_msk.s.calerr = 1;
- spxx_int_msk.s.syncerr = 1;
- spxx_int_msk.s.diperr = 1;
- spxx_int_msk.s.tpaovr = 1;
- spxx_int_msk.s.rsverr = 1;
- spxx_int_msk.s.drwnng = 1;
- spxx_int_msk.s.clserr = 1;
- spxx_int_msk.s.spiovr = 1;
- spxx_int_msk.s.abnorm = 1;
- spxx_int_msk.s.prtnxa = 1;
- cvmx_write_csr(CVMX_SPXX_INT_MSK(interface), spxx_int_msk.u64);
-
- stxx_int_msk.u64 = cvmx_read_csr(CVMX_STXX_INT_MSK(interface));
- stxx_int_msk.s.frmerr = 1;
- stxx_int_msk.s.unxfrm = 1;
- stxx_int_msk.s.nosync = 1;
- stxx_int_msk.s.diperr = 1;
- stxx_int_msk.s.datovr = 1;
- stxx_int_msk.s.ovrbst = 1;
- stxx_int_msk.s.calpar1 = 1;
- stxx_int_msk.s.calpar0 = 1;
- cvmx_write_csr(CVMX_STXX_INT_MSK(interface), stxx_int_msk.u64);
-}
-
-static void cvm_oct_spi_poll(struct net_device *dev)
-{
- static int spi4000_port;
- struct octeon_ethernet *priv = netdev_priv(dev);
- int interface;
-
- for (interface = 0; interface < 2; interface++) {
- if ((priv->port == interface * 16) && need_retrain[interface]) {
- if (cvmx_spi_restart_interface
- (interface, CVMX_SPI_MODE_DUPLEX, 10) == 0) {
- need_retrain[interface] = 0;
- cvm_oct_spi_enable_error_reporting(interface);
- }
- }
-
- /*
- * The SPI4000 TWSI interface is very slow. In order
- * not to bring the system to a crawl, we only poll a
- * single port every second. This means negotiation
- * speed changes take up to 10 seconds, but at least
- * we don't waste absurd amounts of time waiting for
- * TWSI.
- */
- if (priv->port == spi4000_port) {
- /*
- * This function does nothing if it is called on an
- * interface without a SPI4000.
- */
- cvmx_spi4000_check_speed(interface, priv->port);
- /*
- * Normal ordering increments. By decrementing
- * we only match once per iteration.
- */
- spi4000_port--;
- if (spi4000_port < 0)
- spi4000_port = 10;
- }
- }
-}
-
-int cvm_oct_spi_init(struct net_device *dev)
-{
- int r;
- struct octeon_ethernet *priv = netdev_priv(dev);
-
- if (number_spi_ports == 0) {
- r = request_irq(OCTEON_IRQ_RML, cvm_oct_spi_rml_interrupt,
- IRQF_SHARED, "SPI", &number_spi_ports);
- if (r)
- return r;
- }
- number_spi_ports++;
-
- if ((priv->port == 0) || (priv->port == 16)) {
- cvm_oct_spi_enable_error_reporting(INTERFACE(priv->port));
- priv->poll = cvm_oct_spi_poll;
- }
- cvm_oct_common_init(dev);
- return 0;
-}
-
-void cvm_oct_spi_uninit(struct net_device *dev)
-{
- int interface;
-
- cvm_oct_common_uninit(dev);
- number_spi_ports--;
- if (number_spi_ports == 0) {
- for (interface = 0; interface < 2; interface++) {
- cvmx_write_csr(CVMX_SPXX_INT_MSK(interface), 0);
- cvmx_write_csr(CVMX_STXX_INT_MSK(interface), 0);
- }
- free_irq(OCTEON_IRQ_RML, &number_spi_ports);
- }
-}
diff --git a/drivers/staging/octeon/ethernet-tx.c b/drivers/staging/octeon/ethernet-tx.c
deleted file mode 100644
index b334cf89794e..000000000000
--- a/drivers/staging/octeon/ethernet-tx.c
+++ /dev/null
@@ -1,717 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * This file is based on code from OCTEON SDK by Cavium Networks.
- *
- * Copyright (c) 2003-2010 Cavium Networks
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/ip.h>
-#include <linux/ratelimit.h>
-#include <linux/string.h>
-#include <linux/interrupt.h>
-#include <net/dst.h>
-#ifdef CONFIG_XFRM
-#include <linux/xfrm.h>
-#include <net/xfrm.h>
-#endif /* CONFIG_XFRM */
-
-#include <linux/atomic.h>
-#include <net/sch_generic.h>
-
-#include "octeon-ethernet.h"
-#include "ethernet-defines.h"
-#include "ethernet-tx.h"
-#include "ethernet-util.h"
-
-#define CVM_OCT_SKB_CB(skb) ((u64 *)((skb)->cb))
-
-/*
- * You can define GET_SKBUFF_QOS() to override how the skbuff output
- * function determines which output queue is used. The default
- * implementation always uses the base queue for the port. If, for
- * example, you wanted to use the skb->priority field, define
- * GET_SKBUFF_QOS as: #define GET_SKBUFF_QOS(skb) ((skb)->priority)
- */
-#ifndef GET_SKBUFF_QOS
-#define GET_SKBUFF_QOS(skb) 0
-#endif
-
-static void cvm_oct_tx_do_cleanup(unsigned long arg);
-static DECLARE_TASKLET(cvm_oct_tx_cleanup_tasklet, cvm_oct_tx_do_cleanup, 0);
-
-/* Maximum number of SKBs to try to free per xmit packet. */
-#define MAX_SKB_TO_FREE (MAX_OUT_QUEUE_DEPTH * 2)
-
-static inline int cvm_oct_adjust_skb_to_free(int skb_to_free, int fau)
-{
- int undo;
-
- undo = skb_to_free > 0 ? MAX_SKB_TO_FREE : skb_to_free +
- MAX_SKB_TO_FREE;
- if (undo > 0)
- cvmx_fau_atomic_add32(fau, -undo);
- skb_to_free = -skb_to_free > MAX_SKB_TO_FREE ? MAX_SKB_TO_FREE :
- -skb_to_free;
- return skb_to_free;
-}
-
-static void cvm_oct_kick_tx_poll_watchdog(void)
-{
- union cvmx_ciu_timx ciu_timx;
-
- ciu_timx.u64 = 0;
- ciu_timx.s.one_shot = 1;
- ciu_timx.s.len = cvm_oct_tx_poll_interval;
- cvmx_write_csr(CVMX_CIU_TIMX(1), ciu_timx.u64);
-}
-
-static void cvm_oct_free_tx_skbs(struct net_device *dev)
-{
- int skb_to_free;
- int qos, queues_per_port;
- int total_freed = 0;
- int total_remaining = 0;
- unsigned long flags;
- struct octeon_ethernet *priv = netdev_priv(dev);
-
- queues_per_port = cvmx_pko_get_num_queues(priv->port);
- /* Drain any pending packets in the free list */
- for (qos = 0; qos < queues_per_port; qos++) {
- if (skb_queue_len(&priv->tx_free_list[qos]) == 0)
- continue;
- skb_to_free = cvmx_fau_fetch_and_add32(priv->fau + qos * 4,
- MAX_SKB_TO_FREE);
- skb_to_free = cvm_oct_adjust_skb_to_free(skb_to_free,
- priv->fau + qos * 4);
- total_freed += skb_to_free;
- if (skb_to_free > 0) {
- struct sk_buff *to_free_list = NULL;
-
- spin_lock_irqsave(&priv->tx_free_list[qos].lock, flags);
- while (skb_to_free > 0) {
- struct sk_buff *t;
-
- t = __skb_dequeue(&priv->tx_free_list[qos]);
- t->next = to_free_list;
- to_free_list = t;
- skb_to_free--;
- }
- spin_unlock_irqrestore(&priv->tx_free_list[qos].lock,
- flags);
- /* Do the actual freeing outside of the lock. */
- while (to_free_list) {
- struct sk_buff *t = to_free_list;
-
- to_free_list = to_free_list->next;
- dev_kfree_skb_any(t);
- }
- }
- total_remaining += skb_queue_len(&priv->tx_free_list[qos]);
- }
- if (total_remaining < MAX_OUT_QUEUE_DEPTH && netif_queue_stopped(dev))
- netif_wake_queue(dev);
- if (total_remaining)
- cvm_oct_kick_tx_poll_watchdog();
-}
-
-/**
- * cvm_oct_xmit - transmit a packet
- * @skb: Packet to send
- * @dev: Device info structure
- *
- * Returns Always returns NETDEV_TX_OK
- */
-int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- union cvmx_pko_command_word0 pko_command;
- union cvmx_buf_ptr hw_buffer;
- u64 old_scratch;
- u64 old_scratch2;
- int qos;
- int i;
- enum {QUEUE_CORE, QUEUE_HW, QUEUE_DROP} queue_type;
- struct octeon_ethernet *priv = netdev_priv(dev);
- struct sk_buff *to_free_list;
- int skb_to_free;
- int buffers_to_free;
- u32 total_to_clean;
- unsigned long flags;
-#if REUSE_SKBUFFS_WITHOUT_FREE
- unsigned char *fpa_head;
-#endif
-
- /*
- * Prefetch the private data structure. It is larger than the
- * one cache line.
- */
- prefetch(priv);
-
- /*
- * The check on CVMX_PKO_QUEUES_PER_PORT_* is designed to
- * completely remove "qos" in the event neither interface
- * supports multiple queues per port.
- */
- if ((CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 > 1) ||
- (CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 > 1)) {
- qos = GET_SKBUFF_QOS(skb);
- if (qos <= 0)
- qos = 0;
- else if (qos >= cvmx_pko_get_num_queues(priv->port))
- qos = 0;
- } else {
- qos = 0;
- }
-
- if (USE_ASYNC_IOBDMA) {
- /* Save scratch in case userspace is using it */
- CVMX_SYNCIOBDMA;
- old_scratch = cvmx_scratch_read64(CVMX_SCR_SCRATCH);
- old_scratch2 = cvmx_scratch_read64(CVMX_SCR_SCRATCH + 8);
-
- /*
- * Fetch and increment the number of packets to be
- * freed.
- */
- cvmx_fau_async_fetch_and_add32(CVMX_SCR_SCRATCH + 8,
- FAU_NUM_PACKET_BUFFERS_TO_FREE,
- 0);
- cvmx_fau_async_fetch_and_add32(CVMX_SCR_SCRATCH,
- priv->fau + qos * 4,
- MAX_SKB_TO_FREE);
- }
-
- /*
- * We have space for 6 segment pointers, If there will be more
- * than that, we must linearize.
- */
- if (unlikely(skb_shinfo(skb)->nr_frags > 5)) {
- if (unlikely(__skb_linearize(skb))) {
- queue_type = QUEUE_DROP;
- if (USE_ASYNC_IOBDMA) {
- /*
- * Get the number of skbuffs in use
- * by the hardware
- */
- CVMX_SYNCIOBDMA;
- skb_to_free =
- cvmx_scratch_read64(CVMX_SCR_SCRATCH);
- } else {
- /*
- * Get the number of skbuffs in use
- * by the hardware
- */
- skb_to_free =
- cvmx_fau_fetch_and_add32(priv->fau +
- qos * 4,
- MAX_SKB_TO_FREE);
- }
- skb_to_free = cvm_oct_adjust_skb_to_free(skb_to_free,
- priv->fau +
- qos * 4);
- spin_lock_irqsave(&priv->tx_free_list[qos].lock, flags);
- goto skip_xmit;
- }
- }
-
- /*
- * The CN3XXX series of parts has an errata (GMX-401) which
- * causes the GMX block to hang if a collision occurs towards
- * the end of a <68 byte packet. As a workaround for this, we
- * pad packets to be 68 bytes whenever we are in half duplex
- * mode. We don't handle the case of having a small packet but
- * no room to add the padding. The kernel should always give
- * us at least a cache line
- */
- if ((skb->len < 64) && OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
- union cvmx_gmxx_prtx_cfg gmx_prt_cfg;
- int interface = INTERFACE(priv->port);
- int index = INDEX(priv->port);
-
- if (interface < 2) {
- /* We only need to pad packet in half duplex mode */
- gmx_prt_cfg.u64 =
- cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
- if (gmx_prt_cfg.s.duplex == 0) {
- int add_bytes = 64 - skb->len;
-
- if ((skb_tail_pointer(skb) + add_bytes) <=
- skb_end_pointer(skb))
- __skb_put_zero(skb, add_bytes);
- }
- }
- }
-
- /* Build the PKO command */
- pko_command.u64 = 0;
-#ifdef __LITTLE_ENDIAN
- pko_command.s.le = 1;
-#endif
- pko_command.s.n2 = 1; /* Don't pollute L2 with the outgoing packet */
- pko_command.s.segs = 1;
- pko_command.s.total_bytes = skb->len;
- pko_command.s.size0 = CVMX_FAU_OP_SIZE_32;
- pko_command.s.subone0 = 1;
-
- pko_command.s.dontfree = 1;
-
- /* Build the PKO buffer pointer */
- hw_buffer.u64 = 0;
- if (skb_shinfo(skb)->nr_frags == 0) {
- hw_buffer.s.addr = XKPHYS_TO_PHYS((uintptr_t)skb->data);
- hw_buffer.s.pool = 0;
- hw_buffer.s.size = skb->len;
- } else {
- hw_buffer.s.addr = XKPHYS_TO_PHYS((uintptr_t)skb->data);
- hw_buffer.s.pool = 0;
- hw_buffer.s.size = skb_headlen(skb);
- CVM_OCT_SKB_CB(skb)[0] = hw_buffer.u64;
- for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
- skb_frag_t *fs = skb_shinfo(skb)->frags + i;
-
- hw_buffer.s.addr =
- XKPHYS_TO_PHYS((uintptr_t)skb_frag_address(fs));
- hw_buffer.s.size = skb_frag_size(fs);
- CVM_OCT_SKB_CB(skb)[i + 1] = hw_buffer.u64;
- }
- hw_buffer.s.addr =
- XKPHYS_TO_PHYS((uintptr_t)CVM_OCT_SKB_CB(skb));
- hw_buffer.s.size = skb_shinfo(skb)->nr_frags + 1;
- pko_command.s.segs = skb_shinfo(skb)->nr_frags + 1;
- pko_command.s.gather = 1;
- goto dont_put_skbuff_in_hw;
- }
-
- /*
- * See if we can put this skb in the FPA pool. Any strange
- * behavior from the Linux networking stack will most likely
- * be caused by a bug in the following code. If some field is
- * in use by the network stack and gets carried over when a
- * buffer is reused, bad things may happen. If in doubt and
- * you dont need the absolute best performance, disable the
- * define REUSE_SKBUFFS_WITHOUT_FREE. The reuse of buffers has
- * shown a 25% increase in performance under some loads.
- */
-#if REUSE_SKBUFFS_WITHOUT_FREE
- fpa_head = skb->head + 256 - ((unsigned long)skb->head & 0x7f);
- if (unlikely(skb->data < fpa_head)) {
- /* TX buffer beginning can't meet FPA alignment constraints */
- goto dont_put_skbuff_in_hw;
- }
- if (unlikely
- ((skb_end_pointer(skb) - fpa_head) < CVMX_FPA_PACKET_POOL_SIZE)) {
- /* TX buffer isn't large enough for the FPA */
- goto dont_put_skbuff_in_hw;
- }
- if (unlikely(skb_shared(skb))) {
- /* TX buffer sharing data with someone else */
- goto dont_put_skbuff_in_hw;
- }
- if (unlikely(skb_cloned(skb))) {
- /* TX buffer has been cloned */
- goto dont_put_skbuff_in_hw;
- }
- if (unlikely(skb_header_cloned(skb))) {
- /* TX buffer header has been cloned */
- goto dont_put_skbuff_in_hw;
- }
- if (unlikely(skb->destructor)) {
- /* TX buffer has a destructor */
- goto dont_put_skbuff_in_hw;
- }
- if (unlikely(skb_shinfo(skb)->nr_frags)) {
- /* TX buffer has fragments */
- goto dont_put_skbuff_in_hw;
- }
- if (unlikely
- (skb->truesize !=
- sizeof(*skb) + skb_end_offset(skb))) {
- /* TX buffer truesize has been changed */
- goto dont_put_skbuff_in_hw;
- }
-
- /*
- * We can use this buffer in the FPA. We don't need the FAU
- * update anymore
- */
- pko_command.s.dontfree = 0;
-
- hw_buffer.s.back = ((unsigned long)skb->data >> 7) -
- ((unsigned long)fpa_head >> 7);
-
- *(struct sk_buff **)(fpa_head - sizeof(void *)) = skb;
-
- /*
- * The skbuff will be reused without ever being freed. We must
- * cleanup a bunch of core things.
- */
- dst_release(skb_dst(skb));
- skb_dst_set(skb, NULL);
- skb_ext_reset(skb);
- nf_reset_ct(skb);
-
-#ifdef CONFIG_NET_SCHED
- skb->tc_index = 0;
- skb_reset_tc(skb);
-#endif /* CONFIG_NET_SCHED */
-#endif /* REUSE_SKBUFFS_WITHOUT_FREE */
-
-dont_put_skbuff_in_hw:
-
- /* Check if we can use the hardware checksumming */
- if ((skb->protocol == htons(ETH_P_IP)) &&
- (ip_hdr(skb)->version == 4) &&
- (ip_hdr(skb)->ihl == 5) &&
- ((ip_hdr(skb)->frag_off == 0) ||
- (ip_hdr(skb)->frag_off == htons(1 << 14))) &&
- ((ip_hdr(skb)->protocol == IPPROTO_TCP) ||
- (ip_hdr(skb)->protocol == IPPROTO_UDP))) {
- /* Use hardware checksum calc */
- pko_command.s.ipoffp1 = skb_network_offset(skb) + 1;
- }
-
- if (USE_ASYNC_IOBDMA) {
- /* Get the number of skbuffs in use by the hardware */
- CVMX_SYNCIOBDMA;
- skb_to_free = cvmx_scratch_read64(CVMX_SCR_SCRATCH);
- buffers_to_free = cvmx_scratch_read64(CVMX_SCR_SCRATCH + 8);
- } else {
- /* Get the number of skbuffs in use by the hardware */
- skb_to_free = cvmx_fau_fetch_and_add32(priv->fau + qos * 4,
- MAX_SKB_TO_FREE);
- buffers_to_free =
- cvmx_fau_fetch_and_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE, 0);
- }
-
- skb_to_free = cvm_oct_adjust_skb_to_free(skb_to_free,
- priv->fau + qos * 4);
-
- /*
- * If we're sending faster than the receive can free them then
- * don't do the HW free.
- */
- if ((buffers_to_free < -100) && !pko_command.s.dontfree)
- pko_command.s.dontfree = 1;
-
- if (pko_command.s.dontfree) {
- queue_type = QUEUE_CORE;
- pko_command.s.reg0 = priv->fau + qos * 4;
- } else {
- queue_type = QUEUE_HW;
- }
- if (USE_ASYNC_IOBDMA)
- cvmx_fau_async_fetch_and_add32(CVMX_SCR_SCRATCH,
- FAU_TOTAL_TX_TO_CLEAN, 1);
-
- spin_lock_irqsave(&priv->tx_free_list[qos].lock, flags);
-
- /* Drop this packet if we have too many already queued to the HW */
- if (unlikely(skb_queue_len(&priv->tx_free_list[qos]) >=
- MAX_OUT_QUEUE_DEPTH)) {
- if (dev->tx_queue_len != 0) {
- /* Drop the lock when notifying the core. */
- spin_unlock_irqrestore(&priv->tx_free_list[qos].lock,
- flags);
- netif_stop_queue(dev);
- spin_lock_irqsave(&priv->tx_free_list[qos].lock,
- flags);
- } else {
- /* If not using normal queueing. */
- queue_type = QUEUE_DROP;
- goto skip_xmit;
- }
- }
-
- cvmx_pko_send_packet_prepare(priv->port, priv->queue + qos,
- CVMX_PKO_LOCK_NONE);
-
- /* Send the packet to the output queue */
- if (unlikely(cvmx_pko_send_packet_finish(priv->port,
- priv->queue + qos,
- pko_command, hw_buffer,
- CVMX_PKO_LOCK_NONE))) {
- printk_ratelimited("%s: Failed to send the packet\n",
- dev->name);
- queue_type = QUEUE_DROP;
- }
-skip_xmit:
- to_free_list = NULL;
-
- switch (queue_type) {
- case QUEUE_DROP:
- skb->next = to_free_list;
- to_free_list = skb;
- dev->stats.tx_dropped++;
- break;
- case QUEUE_HW:
- cvmx_fau_atomic_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE, -1);
- break;
- case QUEUE_CORE:
- __skb_queue_tail(&priv->tx_free_list[qos], skb);
- break;
- default:
- BUG();
- }
-
- while (skb_to_free > 0) {
- struct sk_buff *t = __skb_dequeue(&priv->tx_free_list[qos]);
-
- t->next = to_free_list;
- to_free_list = t;
- skb_to_free--;
- }
-
- spin_unlock_irqrestore(&priv->tx_free_list[qos].lock, flags);
-
- /* Do the actual freeing outside of the lock. */
- while (to_free_list) {
- struct sk_buff *t = to_free_list;
-
- to_free_list = to_free_list->next;
- dev_kfree_skb_any(t);
- }
-
- if (USE_ASYNC_IOBDMA) {
- CVMX_SYNCIOBDMA;
- total_to_clean = cvmx_scratch_read64(CVMX_SCR_SCRATCH);
- /* Restore the scratch area */
- cvmx_scratch_write64(CVMX_SCR_SCRATCH, old_scratch);
- cvmx_scratch_write64(CVMX_SCR_SCRATCH + 8, old_scratch2);
- } else {
- total_to_clean =
- cvmx_fau_fetch_and_add32(FAU_TOTAL_TX_TO_CLEAN, 1);
- }
-
- if (total_to_clean & 0x3ff) {
- /*
- * Schedule the cleanup tasklet every 1024 packets for
- * the pathological case of high traffic on one port
- * delaying clean up of packets on a different port
- * that is blocked waiting for the cleanup.
- */
- tasklet_schedule(&cvm_oct_tx_cleanup_tasklet);
- }
-
- cvm_oct_kick_tx_poll_watchdog();
-
- return NETDEV_TX_OK;
-}
-
-/**
- * cvm_oct_xmit_pow - transmit a packet to the POW
- * @skb: Packet to send
- * @dev: Device info structure
-
- * Returns Always returns zero
- */
-int cvm_oct_xmit_pow(struct sk_buff *skb, struct net_device *dev)
-{
- struct octeon_ethernet *priv = netdev_priv(dev);
- void *packet_buffer;
- void *copy_location;
-
- /* Get a work queue entry */
- struct cvmx_wqe *work = cvmx_fpa_alloc(CVMX_FPA_WQE_POOL);
-
- if (unlikely(!work)) {
- printk_ratelimited("%s: Failed to allocate a work queue entry\n",
- dev->name);
- dev->stats.tx_dropped++;
- dev_kfree_skb_any(skb);
- return 0;
- }
-
- /* Get a packet buffer */
- packet_buffer = cvmx_fpa_alloc(CVMX_FPA_PACKET_POOL);
- if (unlikely(!packet_buffer)) {
- printk_ratelimited("%s: Failed to allocate a packet buffer\n",
- dev->name);
- cvmx_fpa_free(work, CVMX_FPA_WQE_POOL, 1);
- dev->stats.tx_dropped++;
- dev_kfree_skb_any(skb);
- return 0;
- }
-
- /*
- * Calculate where we need to copy the data to. We need to
- * leave 8 bytes for a next pointer (unused). We also need to
- * include any configure skip. Then we need to align the IP
- * packet src and dest into the same 64bit word. The below
- * calculation may add a little extra, but that doesn't
- * hurt.
- */
- copy_location = packet_buffer + sizeof(u64);
- copy_location += ((CVMX_HELPER_FIRST_MBUFF_SKIP + 7) & 0xfff8) + 6;
-
- /*
- * We have to copy the packet since whoever processes this
- * packet will free it to a hardware pool. We can't use the
- * trick of counting outstanding packets like in
- * cvm_oct_xmit.
- */
- memcpy(copy_location, skb->data, skb->len);
-
- /*
- * Fill in some of the work queue fields. We may need to add
- * more if the software at the other end needs them.
- */
- if (!OCTEON_IS_MODEL(OCTEON_CN68XX))
- work->word0.pip.cn38xx.hw_chksum = skb->csum;
- work->word1.len = skb->len;
- cvmx_wqe_set_port(work, priv->port);
- cvmx_wqe_set_qos(work, priv->port & 0x7);
- cvmx_wqe_set_grp(work, pow_send_group);
- work->word1.tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
- work->word1.tag = pow_send_group; /* FIXME */
- /* Default to zero. Sets of zero later are commented out */
- work->word2.u64 = 0;
- work->word2.s.bufs = 1;
- work->packet_ptr.u64 = 0;
- work->packet_ptr.s.addr = cvmx_ptr_to_phys(copy_location);
- work->packet_ptr.s.pool = CVMX_FPA_PACKET_POOL;
- work->packet_ptr.s.size = CVMX_FPA_PACKET_POOL_SIZE;
- work->packet_ptr.s.back = (copy_location - packet_buffer) >> 7;
-
- if (skb->protocol == htons(ETH_P_IP)) {
- work->word2.s.ip_offset = 14;
-#if 0
- work->word2.s.vlan_valid = 0; /* FIXME */
- work->word2.s.vlan_cfi = 0; /* FIXME */
- work->word2.s.vlan_id = 0; /* FIXME */
- work->word2.s.dec_ipcomp = 0; /* FIXME */
-#endif
- work->word2.s.tcp_or_udp =
- (ip_hdr(skb)->protocol == IPPROTO_TCP) ||
- (ip_hdr(skb)->protocol == IPPROTO_UDP);
-#if 0
- /* FIXME */
- work->word2.s.dec_ipsec = 0;
- /* We only support IPv4 right now */
- work->word2.s.is_v6 = 0;
- /* Hardware would set to zero */
- work->word2.s.software = 0;
- /* No error, packet is internal */
- work->word2.s.L4_error = 0;
-#endif
- work->word2.s.is_frag = !((ip_hdr(skb)->frag_off == 0) ||
- (ip_hdr(skb)->frag_off ==
- cpu_to_be16(1 << 14)));
-#if 0
- /* Assume Linux is sending a good packet */
- work->word2.s.IP_exc = 0;
-#endif
- work->word2.s.is_bcast = (skb->pkt_type == PACKET_BROADCAST);
- work->word2.s.is_mcast = (skb->pkt_type == PACKET_MULTICAST);
-#if 0
- /* This is an IP packet */
- work->word2.s.not_IP = 0;
- /* No error, packet is internal */
- work->word2.s.rcv_error = 0;
- /* No error, packet is internal */
- work->word2.s.err_code = 0;
-#endif
-
- /*
- * When copying the data, include 4 bytes of the
- * ethernet header to align the same way hardware
- * does.
- */
- memcpy(work->packet_data, skb->data + 10,
- sizeof(work->packet_data));
- } else {
-#if 0
- work->word2.snoip.vlan_valid = 0; /* FIXME */
- work->word2.snoip.vlan_cfi = 0; /* FIXME */
- work->word2.snoip.vlan_id = 0; /* FIXME */
- work->word2.snoip.software = 0; /* Hardware would set to zero */
-#endif
- work->word2.snoip.is_rarp = skb->protocol == htons(ETH_P_RARP);
- work->word2.snoip.is_arp = skb->protocol == htons(ETH_P_ARP);
- work->word2.snoip.is_bcast =
- (skb->pkt_type == PACKET_BROADCAST);
- work->word2.snoip.is_mcast =
- (skb->pkt_type == PACKET_MULTICAST);
- work->word2.snoip.not_IP = 1; /* IP was done up above */
-#if 0
- /* No error, packet is internal */
- work->word2.snoip.rcv_error = 0;
- /* No error, packet is internal */
- work->word2.snoip.err_code = 0;
-#endif
- memcpy(work->packet_data, skb->data, sizeof(work->packet_data));
- }
-
- /* Submit the packet to the POW */
- cvmx_pow_work_submit(work, work->word1.tag, work->word1.tag_type,
- cvmx_wqe_get_qos(work), cvmx_wqe_get_grp(work));
- dev->stats.tx_packets++;
- dev->stats.tx_bytes += skb->len;
- dev_consume_skb_any(skb);
- return 0;
-}
-
-/**
- * cvm_oct_tx_shutdown_dev - free all skb that are currently queued for TX.
- * @dev: Device being shutdown
- *
- */
-void cvm_oct_tx_shutdown_dev(struct net_device *dev)
-{
- struct octeon_ethernet *priv = netdev_priv(dev);
- unsigned long flags;
- int qos;
-
- for (qos = 0; qos < 16; qos++) {
- spin_lock_irqsave(&priv->tx_free_list[qos].lock, flags);
- while (skb_queue_len(&priv->tx_free_list[qos]))
- dev_kfree_skb_any(__skb_dequeue
- (&priv->tx_free_list[qos]));
- spin_unlock_irqrestore(&priv->tx_free_list[qos].lock, flags);
- }
-}
-
-static void cvm_oct_tx_do_cleanup(unsigned long arg)
-{
- int port;
-
- for (port = 0; port < TOTAL_NUMBER_OF_PORTS; port++) {
- if (cvm_oct_device[port]) {
- struct net_device *dev = cvm_oct_device[port];
-
- cvm_oct_free_tx_skbs(dev);
- }
- }
-}
-
-static irqreturn_t cvm_oct_tx_cleanup_watchdog(int cpl, void *dev_id)
-{
- /* Disable the interrupt. */
- cvmx_write_csr(CVMX_CIU_TIMX(1), 0);
- /* Do the work in the tasklet. */
- tasklet_schedule(&cvm_oct_tx_cleanup_tasklet);
- return IRQ_HANDLED;
-}
-
-void cvm_oct_tx_initialize(void)
-{
- int i;
-
- /* Disable the interrupt. */
- cvmx_write_csr(CVMX_CIU_TIMX(1), 0);
- /* Register an IRQ handler to receive CIU_TIMX(1) interrupts */
- i = request_irq(OCTEON_IRQ_TIMER1,
- cvm_oct_tx_cleanup_watchdog, 0,
- "Ethernet", cvm_oct_device);
-
- if (i)
- panic("Could not acquire Ethernet IRQ %d\n", OCTEON_IRQ_TIMER1);
-}
-
-void cvm_oct_tx_shutdown(void)
-{
- /* Free the interrupt handler */
- free_irq(OCTEON_IRQ_TIMER1, cvm_oct_device);
-}
diff --git a/drivers/staging/octeon/ethernet-tx.h b/drivers/staging/octeon/ethernet-tx.h
deleted file mode 100644
index 78936e9b33b0..000000000000
--- a/drivers/staging/octeon/ethernet-tx.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * This file is based on code from OCTEON SDK by Cavium Networks.
- *
- * Copyright (c) 2003-2007 Cavium Networks
- */
-
-int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev);
-int cvm_oct_xmit_pow(struct sk_buff *skb, struct net_device *dev);
-int cvm_oct_transmit_qos(struct net_device *dev, void *work_queue_entry,
- int do_free, int qos);
-void cvm_oct_tx_initialize(void);
-void cvm_oct_tx_shutdown(void);
-void cvm_oct_tx_shutdown_dev(struct net_device *dev);
diff --git a/drivers/staging/octeon/ethernet-util.h b/drivers/staging/octeon/ethernet-util.h
deleted file mode 100644
index 2af83a12ca78..000000000000
--- a/drivers/staging/octeon/ethernet-util.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * This file is based on code from OCTEON SDK by Cavium Networks.
- *
- * Copyright (c) 2003-2007 Cavium Networks
- */
-
-/**
- * cvm_oct_get_buffer_ptr - convert packet data address to pointer
- * @packet_ptr: Packet data hardware address
- *
- * Returns Packet buffer pointer
- */
-static inline void *cvm_oct_get_buffer_ptr(union cvmx_buf_ptr packet_ptr)
-{
- return cvmx_phys_to_ptr(((packet_ptr.s.addr >> 7) - packet_ptr.s.back)
- << 7);
-}
-
-/**
- * INTERFACE - convert IPD port to logical interface
- * @ipd_port: Port to check
- *
- * Returns Logical interface
- */
-static inline int INTERFACE(int ipd_port)
-{
- int interface;
-
- if (ipd_port == CVMX_PIP_NUM_INPUT_PORTS)
- return 10;
- interface = cvmx_helper_get_interface_num(ipd_port);
- if (interface >= 0)
- return interface;
- panic("Illegal ipd_port %d passed to %s\n", ipd_port, __func__);
-}
-
-/**
- * INDEX - convert IPD/PKO port number to the port's interface index
- * @ipd_port: Port to check
- *
- * Returns Index into interface port list
- */
-static inline int INDEX(int ipd_port)
-{
- return cvmx_helper_get_interface_index_num(ipd_port);
-}
diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c
deleted file mode 100644
index f42c3816ce49..000000000000
--- a/drivers/staging/octeon/ethernet.c
+++ /dev/null
@@ -1,992 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * This file is based on code from OCTEON SDK by Cavium Networks.
- *
- * Copyright (c) 2003-2007 Cavium Networks
- */
-
-#include <linux/platform_device.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/phy.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/of_net.h>
-#include <linux/if_ether.h>
-#include <linux/if_vlan.h>
-
-#include <net/dst.h>
-
-#include "octeon-ethernet.h"
-#include "ethernet-defines.h"
-#include "ethernet-mem.h"
-#include "ethernet-rx.h"
-#include "ethernet-tx.h"
-#include "ethernet-mdio.h"
-#include "ethernet-util.h"
-
-#define OCTEON_MAX_MTU 65392
-
-static int num_packet_buffers = 1024;
-module_param(num_packet_buffers, int, 0444);
-MODULE_PARM_DESC(num_packet_buffers, "\n"
- "\tNumber of packet buffers to allocate and store in the\n"
- "\tFPA. By default, 1024 packet buffers are used.\n");
-
-static int pow_receive_group = 15;
-module_param(pow_receive_group, int, 0444);
-MODULE_PARM_DESC(pow_receive_group, "\n"
- "\tPOW group to receive packets from. All ethernet hardware\n"
- "\twill be configured to send incoming packets to this POW\n"
- "\tgroup. Also any other software can submit packets to this\n"
- "\tgroup for the kernel to process.");
-
-static int receive_group_order;
-module_param(receive_group_order, int, 0444);
-MODULE_PARM_DESC(receive_group_order, "\n"
- "\tOrder (0..4) of receive groups to take into use. Ethernet hardware\n"
- "\twill be configured to send incoming packets to multiple POW\n"
- "\tgroups. pow_receive_group parameter is ignored when multiple\n"
- "\tgroups are taken into use and groups are allocated starting\n"
- "\tfrom 0. By default, a single group is used.\n");
-
-int pow_send_group = -1;
-module_param(pow_send_group, int, 0644);
-MODULE_PARM_DESC(pow_send_group, "\n"
- "\tPOW group to send packets to other software on. This\n"
- "\tcontrols the creation of the virtual device pow0.\n"
- "\talways_use_pow also depends on this value.");
-
-int always_use_pow;
-module_param(always_use_pow, int, 0444);
-MODULE_PARM_DESC(always_use_pow, "\n"
- "\tWhen set, always send to the pow group. This will cause\n"
- "\tpackets sent to real ethernet devices to be sent to the\n"
- "\tPOW group instead of the hardware. Unless some other\n"
- "\tapplication changes the config, packets will still be\n"
- "\treceived from the low level hardware. Use this option\n"
- "\tto allow a CVMX app to intercept all packets from the\n"
- "\tlinux kernel. You must specify pow_send_group along with\n"
- "\tthis option.");
-
-char pow_send_list[128] = "";
-module_param_string(pow_send_list, pow_send_list, sizeof(pow_send_list), 0444);
-MODULE_PARM_DESC(pow_send_list, "\n"
- "\tComma separated list of ethernet devices that should use the\n"
- "\tPOW for transmit instead of the actual ethernet hardware. This\n"
- "\tis a per port version of always_use_pow. always_use_pow takes\n"
- "\tprecedence over this list. For example, setting this to\n"
- "\t\"eth2,spi3,spi7\" would cause these three devices to transmit\n"
- "\tusing the pow_send_group.");
-
-int rx_napi_weight = 32;
-module_param(rx_napi_weight, int, 0444);
-MODULE_PARM_DESC(rx_napi_weight, "The NAPI WEIGHT parameter.");
-
-/* Mask indicating which receive groups are in use. */
-int pow_receive_groups;
-
-/*
- * cvm_oct_poll_queue_stopping - flag to indicate polling should stop.
- *
- * Set to one right before cvm_oct_poll_queue is destroyed.
- */
-atomic_t cvm_oct_poll_queue_stopping = ATOMIC_INIT(0);
-
-/*
- * Array of every ethernet device owned by this driver indexed by
- * the ipd input port number.
- */
-struct net_device *cvm_oct_device[TOTAL_NUMBER_OF_PORTS];
-
-u64 cvm_oct_tx_poll_interval;
-
-static void cvm_oct_rx_refill_worker(struct work_struct *work);
-static DECLARE_DELAYED_WORK(cvm_oct_rx_refill_work, cvm_oct_rx_refill_worker);
-
-static void cvm_oct_rx_refill_worker(struct work_struct *work)
-{
- /*
- * FPA 0 may have been drained, try to refill it if we need
- * more than num_packet_buffers / 2, otherwise normal receive
- * processing will refill it. If it were drained, no packets
- * could be received so cvm_oct_napi_poll would never be
- * invoked to do the refill.
- */
- cvm_oct_rx_refill_pool(num_packet_buffers / 2);
-
- if (!atomic_read(&cvm_oct_poll_queue_stopping))
- schedule_delayed_work(&cvm_oct_rx_refill_work, HZ);
-}
-
-static void cvm_oct_periodic_worker(struct work_struct *work)
-{
- struct octeon_ethernet *priv = container_of(work,
- struct octeon_ethernet,
- port_periodic_work.work);
-
- if (priv->poll)
- priv->poll(cvm_oct_device[priv->port]);
-
- cvm_oct_device[priv->port]->netdev_ops->ndo_get_stats
- (cvm_oct_device[priv->port]);
-
- if (!atomic_read(&cvm_oct_poll_queue_stopping))
- schedule_delayed_work(&priv->port_periodic_work, HZ);
-}
-
-static void cvm_oct_configure_common_hw(void)
-{
- /* Setup the FPA */
- cvmx_fpa_enable();
- cvm_oct_mem_fill_fpa(CVMX_FPA_PACKET_POOL, CVMX_FPA_PACKET_POOL_SIZE,
- num_packet_buffers);
- cvm_oct_mem_fill_fpa(CVMX_FPA_WQE_POOL, CVMX_FPA_WQE_POOL_SIZE,
- num_packet_buffers);
- if (CVMX_FPA_OUTPUT_BUFFER_POOL != CVMX_FPA_PACKET_POOL)
- cvm_oct_mem_fill_fpa(CVMX_FPA_OUTPUT_BUFFER_POOL,
- CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE, 1024);
-
-#ifdef __LITTLE_ENDIAN
- {
- union cvmx_ipd_ctl_status ipd_ctl_status;
-
- ipd_ctl_status.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS);
- ipd_ctl_status.s.pkt_lend = 1;
- ipd_ctl_status.s.wqe_lend = 1;
- cvmx_write_csr(CVMX_IPD_CTL_STATUS, ipd_ctl_status.u64);
- }
-#endif
-
- cvmx_helper_setup_red(num_packet_buffers / 4, num_packet_buffers / 8);
-}
-
-/**
- * cvm_oct_free_work- Free a work queue entry
- *
- * @work_queue_entry: Work queue entry to free
- *
- * Returns Zero on success, Negative on failure.
- */
-int cvm_oct_free_work(void *work_queue_entry)
-{
- struct cvmx_wqe *work = work_queue_entry;
-
- int segments = work->word2.s.bufs;
- union cvmx_buf_ptr segment_ptr = work->packet_ptr;
-
- while (segments--) {
- union cvmx_buf_ptr next_ptr = *(union cvmx_buf_ptr *)
- cvmx_phys_to_ptr(segment_ptr.s.addr - 8);
- if (unlikely(!segment_ptr.s.i))
- cvmx_fpa_free(cvm_oct_get_buffer_ptr(segment_ptr),
- segment_ptr.s.pool,
- CVMX_FPA_PACKET_POOL_SIZE / 128);
- segment_ptr = next_ptr;
- }
- cvmx_fpa_free(work, CVMX_FPA_WQE_POOL, 1);
-
- return 0;
-}
-EXPORT_SYMBOL(cvm_oct_free_work);
-
-/**
- * cvm_oct_common_get_stats - get the low level ethernet statistics
- * @dev: Device to get the statistics from
- *
- * Returns Pointer to the statistics
- */
-static struct net_device_stats *cvm_oct_common_get_stats(struct net_device *dev)
-{
- cvmx_pip_port_status_t rx_status;
- cvmx_pko_port_status_t tx_status;
- struct octeon_ethernet *priv = netdev_priv(dev);
-
- if (priv->port < CVMX_PIP_NUM_INPUT_PORTS) {
- if (octeon_is_simulation()) {
- /* The simulator doesn't support statistics */
- memset(&rx_status, 0, sizeof(rx_status));
- memset(&tx_status, 0, sizeof(tx_status));
- } else {
- cvmx_pip_get_port_status(priv->port, 1, &rx_status);
- cvmx_pko_get_port_status(priv->port, 1, &tx_status);
- }
-
- dev->stats.rx_packets += rx_status.inb_packets;
- dev->stats.tx_packets += tx_status.packets;
- dev->stats.rx_bytes += rx_status.inb_octets;
- dev->stats.tx_bytes += tx_status.octets;
- dev->stats.multicast += rx_status.multicast_packets;
- dev->stats.rx_crc_errors += rx_status.inb_errors;
- dev->stats.rx_frame_errors += rx_status.fcs_align_err_packets;
- dev->stats.rx_dropped += rx_status.dropped_packets;
- }
-
- return &dev->stats;
-}
-
-/**
- * cvm_oct_common_change_mtu - change the link MTU
- * @dev: Device to change
- * @new_mtu: The new MTU
- *
- * Returns Zero on success
- */
-static int cvm_oct_common_change_mtu(struct net_device *dev, int new_mtu)
-{
- struct octeon_ethernet *priv = netdev_priv(dev);
- int interface = INTERFACE(priv->port);
-#if IS_ENABLED(CONFIG_VLAN_8021Q)
- int vlan_bytes = VLAN_HLEN;
-#else
- int vlan_bytes = 0;
-#endif
- int mtu_overhead = ETH_HLEN + ETH_FCS_LEN + vlan_bytes;
-
- dev->mtu = new_mtu;
-
- if ((interface < 2) &&
- (cvmx_helper_interface_get_mode(interface) !=
- CVMX_HELPER_INTERFACE_MODE_SPI)) {
- int index = INDEX(priv->port);
- /* Add ethernet header and FCS, and VLAN if configured. */
- int max_packet = new_mtu + mtu_overhead;
-
- if (OCTEON_IS_MODEL(OCTEON_CN3XXX) ||
- OCTEON_IS_MODEL(OCTEON_CN58XX)) {
- /* Signal errors on packets larger than the MTU */
- cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX(index, interface),
- max_packet);
- } else {
- /*
- * Set the hardware to truncate packets larger
- * than the MTU and smaller the 64 bytes.
- */
- union cvmx_pip_frm_len_chkx frm_len_chk;
-
- frm_len_chk.u64 = 0;
- frm_len_chk.s.minlen = VLAN_ETH_ZLEN;
- frm_len_chk.s.maxlen = max_packet;
- cvmx_write_csr(CVMX_PIP_FRM_LEN_CHKX(interface),
- frm_len_chk.u64);
- }
- /*
- * Set the hardware to truncate packets larger than
- * the MTU. The jabber register must be set to a
- * multiple of 8 bytes, so round up.
- */
- cvmx_write_csr(CVMX_GMXX_RXX_JABBER(index, interface),
- (max_packet + 7) & ~7u);
- }
- return 0;
-}
-
-/**
- * cvm_oct_common_set_multicast_list - set the multicast list
- * @dev: Device to work on
- */
-static void cvm_oct_common_set_multicast_list(struct net_device *dev)
-{
- union cvmx_gmxx_prtx_cfg gmx_cfg;
- struct octeon_ethernet *priv = netdev_priv(dev);
- int interface = INTERFACE(priv->port);
-
- if ((interface < 2) &&
- (cvmx_helper_interface_get_mode(interface) !=
- CVMX_HELPER_INTERFACE_MODE_SPI)) {
- union cvmx_gmxx_rxx_adr_ctl control;
- int index = INDEX(priv->port);
-
- control.u64 = 0;
- control.s.bcst = 1; /* Allow broadcast MAC addresses */
-
- if (!netdev_mc_empty(dev) || (dev->flags & IFF_ALLMULTI) ||
- (dev->flags & IFF_PROMISC))
- /* Force accept multicast packets */
- control.s.mcst = 2;
- else
- /* Force reject multicast packets */
- control.s.mcst = 1;
-
- if (dev->flags & IFF_PROMISC)
- /*
- * Reject matches if promisc. Since CAM is
- * shut off, should accept everything.
- */
- control.s.cam_mode = 0;
- else
- /* Filter packets based on the CAM */
- control.s.cam_mode = 1;
-
- gmx_cfg.u64 =
- cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
- cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
- gmx_cfg.u64 & ~1ull);
-
- cvmx_write_csr(CVMX_GMXX_RXX_ADR_CTL(index, interface),
- control.u64);
- if (dev->flags & IFF_PROMISC)
- cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM_EN
- (index, interface), 0);
- else
- cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM_EN
- (index, interface), 1);
-
- cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
- gmx_cfg.u64);
- }
-}
-
-static int cvm_oct_set_mac_filter(struct net_device *dev)
-{
- struct octeon_ethernet *priv = netdev_priv(dev);
- union cvmx_gmxx_prtx_cfg gmx_cfg;
- int interface = INTERFACE(priv->port);
-
- if ((interface < 2) &&
- (cvmx_helper_interface_get_mode(interface) !=
- CVMX_HELPER_INTERFACE_MODE_SPI)) {
- int i;
- u8 *ptr = dev->dev_addr;
- u64 mac = 0;
- int index = INDEX(priv->port);
-
- for (i = 0; i < 6; i++)
- mac = (mac << 8) | (u64)ptr[i];
-
- gmx_cfg.u64 =
- cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
- cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
- gmx_cfg.u64 & ~1ull);
-
- cvmx_write_csr(CVMX_GMXX_SMACX(index, interface), mac);
- cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM0(index, interface),
- ptr[0]);
- cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM1(index, interface),
- ptr[1]);
- cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM2(index, interface),
- ptr[2]);
- cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM3(index, interface),
- ptr[3]);
- cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM4(index, interface),
- ptr[4]);
- cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM5(index, interface),
- ptr[5]);
- cvm_oct_common_set_multicast_list(dev);
- cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
- gmx_cfg.u64);
- }
- return 0;
-}
-
-/**
- * cvm_oct_common_set_mac_address - set the hardware MAC address for a device
- * @dev: The device in question.
- * @addr: Socket address.
- *
- * Returns Zero on success
- */
-static int cvm_oct_common_set_mac_address(struct net_device *dev, void *addr)
-{
- int r = eth_mac_addr(dev, addr);
-
- if (r)
- return r;
- return cvm_oct_set_mac_filter(dev);
-}
-
-/**
- * cvm_oct_common_init - per network device initialization
- * @dev: Device to initialize
- *
- * Returns Zero on success
- */
-int cvm_oct_common_init(struct net_device *dev)
-{
- struct octeon_ethernet *priv = netdev_priv(dev);
- const u8 *mac = NULL;
-
- if (priv->of_node)
- mac = of_get_mac_address(priv->of_node);
-
- if (!IS_ERR_OR_NULL(mac))
- ether_addr_copy(dev->dev_addr, mac);
- else
- eth_hw_addr_random(dev);
-
- /*
- * Force the interface to use the POW send if always_use_pow
- * was specified or it is in the pow send list.
- */
- if ((pow_send_group != -1) &&
- (always_use_pow || strstr(pow_send_list, dev->name)))
- priv->queue = -1;
-
- if (priv->queue != -1)
- dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
-
- /* We do our own locking, Linux doesn't need to */
- dev->features |= NETIF_F_LLTX;
- dev->ethtool_ops = &cvm_oct_ethtool_ops;
-
- cvm_oct_set_mac_filter(dev);
- dev_set_mtu(dev, dev->mtu);
-
- /*
- * Zero out stats for port so we won't mistakenly show
- * counters from the bootloader.
- */
- memset(dev->netdev_ops->ndo_get_stats(dev), 0,
- sizeof(struct net_device_stats));
-
- if (dev->netdev_ops->ndo_stop)
- dev->netdev_ops->ndo_stop(dev);
-
- return 0;
-}
-
-void cvm_oct_common_uninit(struct net_device *dev)
-{
- if (dev->phydev)
- phy_disconnect(dev->phydev);
-}
-
-int cvm_oct_common_open(struct net_device *dev,
- void (*link_poll)(struct net_device *))
-{
- union cvmx_gmxx_prtx_cfg gmx_cfg;
- struct octeon_ethernet *priv = netdev_priv(dev);
- int interface = INTERFACE(priv->port);
- int index = INDEX(priv->port);
- union cvmx_helper_link_info link_info;
- int rv;
-
- rv = cvm_oct_phy_setup_device(dev);
- if (rv)
- return rv;
-
- gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
- gmx_cfg.s.en = 1;
- if (octeon_has_feature(OCTEON_FEATURE_PKND))
- gmx_cfg.s.pknd = priv->port;
- cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
-
- if (octeon_is_simulation())
- return 0;
-
- if (dev->phydev) {
- int r = phy_read_status(dev->phydev);
-
- if (r == 0 && dev->phydev->link == 0)
- netif_carrier_off(dev);
- cvm_oct_adjust_link(dev);
- } else {
- link_info = cvmx_helper_link_get(priv->port);
- if (!link_info.s.link_up)
- netif_carrier_off(dev);
- priv->poll = link_poll;
- link_poll(dev);
- }
-
- return 0;
-}
-
-void cvm_oct_link_poll(struct net_device *dev)
-{
- struct octeon_ethernet *priv = netdev_priv(dev);
- union cvmx_helper_link_info link_info;
-
- link_info = cvmx_helper_link_get(priv->port);
- if (link_info.u64 == priv->link_info)
- return;
-
- if (cvmx_helper_link_set(priv->port, link_info))
- link_info.u64 = priv->link_info;
- else
- priv->link_info = link_info.u64;
-
- if (link_info.s.link_up) {
- if (!netif_carrier_ok(dev))
- netif_carrier_on(dev);
- } else if (netif_carrier_ok(dev)) {
- netif_carrier_off(dev);
- }
- cvm_oct_note_carrier(priv, link_info);
-}
-
-static int cvm_oct_xaui_open(struct net_device *dev)
-{
- return cvm_oct_common_open(dev, cvm_oct_link_poll);
-}
-
-static const struct net_device_ops cvm_oct_npi_netdev_ops = {
- .ndo_init = cvm_oct_common_init,
- .ndo_uninit = cvm_oct_common_uninit,
- .ndo_start_xmit = cvm_oct_xmit,
- .ndo_set_rx_mode = cvm_oct_common_set_multicast_list,
- .ndo_set_mac_address = cvm_oct_common_set_mac_address,
- .ndo_do_ioctl = cvm_oct_ioctl,
- .ndo_change_mtu = cvm_oct_common_change_mtu,
- .ndo_get_stats = cvm_oct_common_get_stats,
-#ifdef CONFIG_NET_POLL_CONTROLLER
- .ndo_poll_controller = cvm_oct_poll_controller,
-#endif
-};
-
-static const struct net_device_ops cvm_oct_xaui_netdev_ops = {
- .ndo_init = cvm_oct_common_init,
- .ndo_uninit = cvm_oct_common_uninit,
- .ndo_open = cvm_oct_xaui_open,
- .ndo_stop = cvm_oct_common_stop,
- .ndo_start_xmit = cvm_oct_xmit,
- .ndo_set_rx_mode = cvm_oct_common_set_multicast_list,
- .ndo_set_mac_address = cvm_oct_common_set_mac_address,
- .ndo_do_ioctl = cvm_oct_ioctl,
- .ndo_change_mtu = cvm_oct_common_change_mtu,
- .ndo_get_stats = cvm_oct_common_get_stats,
-#ifdef CONFIG_NET_POLL_CONTROLLER
- .ndo_poll_controller = cvm_oct_poll_controller,
-#endif
-};
-
-static const struct net_device_ops cvm_oct_sgmii_netdev_ops = {
- .ndo_init = cvm_oct_sgmii_init,
- .ndo_uninit = cvm_oct_common_uninit,
- .ndo_open = cvm_oct_sgmii_open,
- .ndo_stop = cvm_oct_common_stop,
- .ndo_start_xmit = cvm_oct_xmit,
- .ndo_set_rx_mode = cvm_oct_common_set_multicast_list,
- .ndo_set_mac_address = cvm_oct_common_set_mac_address,
- .ndo_do_ioctl = cvm_oct_ioctl,
- .ndo_change_mtu = cvm_oct_common_change_mtu,
- .ndo_get_stats = cvm_oct_common_get_stats,
-#ifdef CONFIG_NET_POLL_CONTROLLER
- .ndo_poll_controller = cvm_oct_poll_controller,
-#endif
-};
-
-static const struct net_device_ops cvm_oct_spi_netdev_ops = {
- .ndo_init = cvm_oct_spi_init,
- .ndo_uninit = cvm_oct_spi_uninit,
- .ndo_start_xmit = cvm_oct_xmit,
- .ndo_set_rx_mode = cvm_oct_common_set_multicast_list,
- .ndo_set_mac_address = cvm_oct_common_set_mac_address,
- .ndo_do_ioctl = cvm_oct_ioctl,
- .ndo_change_mtu = cvm_oct_common_change_mtu,
- .ndo_get_stats = cvm_oct_common_get_stats,
-#ifdef CONFIG_NET_POLL_CONTROLLER
- .ndo_poll_controller = cvm_oct_poll_controller,
-#endif
-};
-
-static const struct net_device_ops cvm_oct_rgmii_netdev_ops = {
- .ndo_init = cvm_oct_common_init,
- .ndo_uninit = cvm_oct_common_uninit,
- .ndo_open = cvm_oct_rgmii_open,
- .ndo_stop = cvm_oct_common_stop,
- .ndo_start_xmit = cvm_oct_xmit,
- .ndo_set_rx_mode = cvm_oct_common_set_multicast_list,
- .ndo_set_mac_address = cvm_oct_common_set_mac_address,
- .ndo_do_ioctl = cvm_oct_ioctl,
- .ndo_change_mtu = cvm_oct_common_change_mtu,
- .ndo_get_stats = cvm_oct_common_get_stats,
-#ifdef CONFIG_NET_POLL_CONTROLLER
- .ndo_poll_controller = cvm_oct_poll_controller,
-#endif
-};
-
-static const struct net_device_ops cvm_oct_pow_netdev_ops = {
- .ndo_init = cvm_oct_common_init,
- .ndo_start_xmit = cvm_oct_xmit_pow,
- .ndo_set_rx_mode = cvm_oct_common_set_multicast_list,
- .ndo_set_mac_address = cvm_oct_common_set_mac_address,
- .ndo_do_ioctl = cvm_oct_ioctl,
- .ndo_change_mtu = cvm_oct_common_change_mtu,
- .ndo_get_stats = cvm_oct_common_get_stats,
-#ifdef CONFIG_NET_POLL_CONTROLLER
- .ndo_poll_controller = cvm_oct_poll_controller,
-#endif
-};
-
-static struct device_node *cvm_oct_of_get_child
- (const struct device_node *parent, int reg_val)
-{
- struct device_node *node = NULL;
- int size;
- const __be32 *addr;
-
- for (;;) {
- node = of_get_next_child(parent, node);
- if (!node)
- break;
- addr = of_get_property(node, "reg", &size);
- if (addr && (be32_to_cpu(*addr) == reg_val))
- break;
- }
- return node;
-}
-
-static struct device_node *cvm_oct_node_for_port(struct device_node *pip,
- int interface, int port)
-{
- struct device_node *ni, *np;
-
- ni = cvm_oct_of_get_child(pip, interface);
- if (!ni)
- return NULL;
-
- np = cvm_oct_of_get_child(ni, port);
- of_node_put(ni);
-
- return np;
-}
-
-static void cvm_set_rgmii_delay(struct octeon_ethernet *priv, int iface,
- int port)
-{
- struct device_node *np = priv->of_node;
- u32 delay_value;
- bool rx_delay;
- bool tx_delay;
-
- /* By default, both RX/TX delay is enabled in
- * __cvmx_helper_rgmii_enable().
- */
- rx_delay = true;
- tx_delay = true;
-
- if (!of_property_read_u32(np, "rx-delay", &delay_value)) {
- cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(port, iface), delay_value);
- rx_delay = delay_value > 0;
- }
- if (!of_property_read_u32(np, "tx-delay", &delay_value)) {
- cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(port, iface), delay_value);
- tx_delay = delay_value > 0;
- }
-
- if (!rx_delay && !tx_delay)
- priv->phy_mode = PHY_INTERFACE_MODE_RGMII_ID;
- else if (!rx_delay)
- priv->phy_mode = PHY_INTERFACE_MODE_RGMII_RXID;
- else if (!tx_delay)
- priv->phy_mode = PHY_INTERFACE_MODE_RGMII_TXID;
- else
- priv->phy_mode = PHY_INTERFACE_MODE_RGMII;
-}
-
-static int cvm_oct_probe(struct platform_device *pdev)
-{
- int num_interfaces;
- int interface;
- int fau = FAU_NUM_PACKET_BUFFERS_TO_FREE;
- int qos;
- struct device_node *pip;
- int mtu_overhead = ETH_HLEN + ETH_FCS_LEN;
-
-#if IS_ENABLED(CONFIG_VLAN_8021Q)
- mtu_overhead += VLAN_HLEN;
-#endif
-
- octeon_mdiobus_force_mod_depencency();
-
- pip = pdev->dev.of_node;
- if (!pip) {
- pr_err("Error: No 'pip' in /aliases\n");
- return -EINVAL;
- }
-
- cvm_oct_configure_common_hw();
-
- cvmx_helper_initialize_packet_io_global();
-
- if (receive_group_order) {
- if (receive_group_order > 4)
- receive_group_order = 4;
- pow_receive_groups = (1 << (1 << receive_group_order)) - 1;
- } else {
- pow_receive_groups = BIT(pow_receive_group);
- }
-
- /* Change the input group for all ports before input is enabled */
- num_interfaces = cvmx_helper_get_number_of_interfaces();
- for (interface = 0; interface < num_interfaces; interface++) {
- int num_ports = cvmx_helper_ports_on_interface(interface);
- int port;
-
- for (port = cvmx_helper_get_ipd_port(interface, 0);
- port < cvmx_helper_get_ipd_port(interface, num_ports);
- port++) {
- union cvmx_pip_prt_tagx pip_prt_tagx;
-
- pip_prt_tagx.u64 =
- cvmx_read_csr(CVMX_PIP_PRT_TAGX(port));
-
- if (receive_group_order) {
- int tag_mask;
-
- /* We support only 16 groups at the moment, so
- * always disable the two additional "hidden"
- * tag_mask bits on CN68XX.
- */
- if (OCTEON_IS_MODEL(OCTEON_CN68XX))
- pip_prt_tagx.u64 |= 0x3ull << 44;
-
- tag_mask = ~((1 << receive_group_order) - 1);
- pip_prt_tagx.s.grptagbase = 0;
- pip_prt_tagx.s.grptagmask = tag_mask;
- pip_prt_tagx.s.grptag = 1;
- pip_prt_tagx.s.tag_mode = 0;
- pip_prt_tagx.s.inc_prt_flag = 1;
- pip_prt_tagx.s.ip6_dprt_flag = 1;
- pip_prt_tagx.s.ip4_dprt_flag = 1;
- pip_prt_tagx.s.ip6_sprt_flag = 1;
- pip_prt_tagx.s.ip4_sprt_flag = 1;
- pip_prt_tagx.s.ip6_dst_flag = 1;
- pip_prt_tagx.s.ip4_dst_flag = 1;
- pip_prt_tagx.s.ip6_src_flag = 1;
- pip_prt_tagx.s.ip4_src_flag = 1;
- pip_prt_tagx.s.grp = 0;
- } else {
- pip_prt_tagx.s.grptag = 0;
- pip_prt_tagx.s.grp = pow_receive_group;
- }
-
- cvmx_write_csr(CVMX_PIP_PRT_TAGX(port),
- pip_prt_tagx.u64);
- }
- }
-
- cvmx_helper_ipd_and_packet_input_enable();
-
- memset(cvm_oct_device, 0, sizeof(cvm_oct_device));
-
- /*
- * Initialize the FAU used for counting packet buffers that
- * need to be freed.
- */
- cvmx_fau_atomic_write32(FAU_NUM_PACKET_BUFFERS_TO_FREE, 0);
-
- /* Initialize the FAU used for counting tx SKBs that need to be freed */
- cvmx_fau_atomic_write32(FAU_TOTAL_TX_TO_CLEAN, 0);
-
- if ((pow_send_group != -1)) {
- struct net_device *dev;
-
- dev = alloc_etherdev(sizeof(struct octeon_ethernet));
- if (dev) {
- /* Initialize the device private structure. */
- struct octeon_ethernet *priv = netdev_priv(dev);
-
- SET_NETDEV_DEV(dev, &pdev->dev);
- dev->netdev_ops = &cvm_oct_pow_netdev_ops;
- priv->imode = CVMX_HELPER_INTERFACE_MODE_DISABLED;
- priv->port = CVMX_PIP_NUM_INPUT_PORTS;
- priv->queue = -1;
- strscpy(dev->name, "pow%d", sizeof(dev->name));
- for (qos = 0; qos < 16; qos++)
- skb_queue_head_init(&priv->tx_free_list[qos]);
- dev->min_mtu = VLAN_ETH_ZLEN - mtu_overhead;
- dev->max_mtu = OCTEON_MAX_MTU - mtu_overhead;
-
- if (register_netdev(dev) < 0) {
- pr_err("Failed to register ethernet device for POW\n");
- free_netdev(dev);
- } else {
- cvm_oct_device[CVMX_PIP_NUM_INPUT_PORTS] = dev;
- pr_info("%s: POW send group %d, receive group %d\n",
- dev->name, pow_send_group,
- pow_receive_group);
- }
- } else {
- pr_err("Failed to allocate ethernet device for POW\n");
- }
- }
-
- num_interfaces = cvmx_helper_get_number_of_interfaces();
- for (interface = 0; interface < num_interfaces; interface++) {
- cvmx_helper_interface_mode_t imode =
- cvmx_helper_interface_get_mode(interface);
- int num_ports = cvmx_helper_ports_on_interface(interface);
- int port;
- int port_index;
-
- for (port_index = 0,
- port = cvmx_helper_get_ipd_port(interface, 0);
- port < cvmx_helper_get_ipd_port(interface, num_ports);
- port_index++, port++) {
- struct octeon_ethernet *priv;
- struct net_device *dev =
- alloc_etherdev(sizeof(struct octeon_ethernet));
- if (!dev) {
- pr_err("Failed to allocate ethernet device for port %d\n",
- port);
- continue;
- }
-
- /* Initialize the device private structure. */
- SET_NETDEV_DEV(dev, &pdev->dev);
- priv = netdev_priv(dev);
- priv->netdev = dev;
- priv->of_node = cvm_oct_node_for_port(pip, interface,
- port_index);
-
- INIT_DELAYED_WORK(&priv->port_periodic_work,
- cvm_oct_periodic_worker);
- priv->imode = imode;
- priv->port = port;
- priv->queue = cvmx_pko_get_base_queue(priv->port);
- priv->fau = fau - cvmx_pko_get_num_queues(port) * 4;
- priv->phy_mode = PHY_INTERFACE_MODE_NA;
- for (qos = 0; qos < 16; qos++)
- skb_queue_head_init(&priv->tx_free_list[qos]);
- for (qos = 0; qos < cvmx_pko_get_num_queues(port);
- qos++)
- cvmx_fau_atomic_write32(priv->fau + qos * 4, 0);
- dev->min_mtu = VLAN_ETH_ZLEN - mtu_overhead;
- dev->max_mtu = OCTEON_MAX_MTU - mtu_overhead;
-
- switch (priv->imode) {
- /* These types don't support ports to IPD/PKO */
- case CVMX_HELPER_INTERFACE_MODE_DISABLED:
- case CVMX_HELPER_INTERFACE_MODE_PCIE:
- case CVMX_HELPER_INTERFACE_MODE_PICMG:
- break;
-
- case CVMX_HELPER_INTERFACE_MODE_NPI:
- dev->netdev_ops = &cvm_oct_npi_netdev_ops;
- strscpy(dev->name, "npi%d", sizeof(dev->name));
- break;
-
- case CVMX_HELPER_INTERFACE_MODE_XAUI:
- dev->netdev_ops = &cvm_oct_xaui_netdev_ops;
- strscpy(dev->name, "xaui%d", sizeof(dev->name));
- break;
-
- case CVMX_HELPER_INTERFACE_MODE_LOOP:
- dev->netdev_ops = &cvm_oct_npi_netdev_ops;
- strscpy(dev->name, "loop%d", sizeof(dev->name));
- break;
-
- case CVMX_HELPER_INTERFACE_MODE_SGMII:
- priv->phy_mode = PHY_INTERFACE_MODE_SGMII;
- dev->netdev_ops = &cvm_oct_sgmii_netdev_ops;
- strscpy(dev->name, "eth%d", sizeof(dev->name));
- break;
-
- case CVMX_HELPER_INTERFACE_MODE_SPI:
- dev->netdev_ops = &cvm_oct_spi_netdev_ops;
- strscpy(dev->name, "spi%d", sizeof(dev->name));
- break;
-
- case CVMX_HELPER_INTERFACE_MODE_GMII:
- priv->phy_mode = PHY_INTERFACE_MODE_GMII;
- dev->netdev_ops = &cvm_oct_rgmii_netdev_ops;
- strscpy(dev->name, "eth%d", sizeof(dev->name));
- break;
-
- case CVMX_HELPER_INTERFACE_MODE_RGMII:
- dev->netdev_ops = &cvm_oct_rgmii_netdev_ops;
- strscpy(dev->name, "eth%d", sizeof(dev->name));
- cvm_set_rgmii_delay(priv, interface,
- port_index);
- break;
- }
-
- if (!dev->netdev_ops) {
- free_netdev(dev);
- } else if (register_netdev(dev) < 0) {
- pr_err("Failed to register ethernet device for interface %d, port %d\n",
- interface, priv->port);
- free_netdev(dev);
- } else {
- cvm_oct_device[priv->port] = dev;
- fau -=
- cvmx_pko_get_num_queues(priv->port) *
- sizeof(u32);
- schedule_delayed_work(&priv->port_periodic_work,
- HZ);
- }
- }
- }
-
- cvm_oct_tx_initialize();
- cvm_oct_rx_initialize();
-
- /*
- * 150 uS: about 10 1500-byte packets at 1GE.
- */
- cvm_oct_tx_poll_interval = 150 * (octeon_get_clock_rate() / 1000000);
-
- schedule_delayed_work(&cvm_oct_rx_refill_work, HZ);
-
- return 0;
-}
-
-static int cvm_oct_remove(struct platform_device *pdev)
-{
- int port;
-
- cvmx_ipd_disable();
-
- atomic_inc_return(&cvm_oct_poll_queue_stopping);
- cancel_delayed_work_sync(&cvm_oct_rx_refill_work);
-
- cvm_oct_rx_shutdown();
- cvm_oct_tx_shutdown();
-
- cvmx_pko_disable();
-
- /* Free the ethernet devices */
- for (port = 0; port < TOTAL_NUMBER_OF_PORTS; port++) {
- if (cvm_oct_device[port]) {
- struct net_device *dev = cvm_oct_device[port];
- struct octeon_ethernet *priv = netdev_priv(dev);
-
- cancel_delayed_work_sync(&priv->port_periodic_work);
-
- cvm_oct_tx_shutdown_dev(dev);
- unregister_netdev(dev);
- free_netdev(dev);
- cvm_oct_device[port] = NULL;
- }
- }
-
- cvmx_pko_shutdown();
-
- cvmx_ipd_free_ptr();
-
- /* Free the HW pools */
- cvm_oct_mem_empty_fpa(CVMX_FPA_PACKET_POOL, CVMX_FPA_PACKET_POOL_SIZE,
- num_packet_buffers);
- cvm_oct_mem_empty_fpa(CVMX_FPA_WQE_POOL, CVMX_FPA_WQE_POOL_SIZE,
- num_packet_buffers);
- if (CVMX_FPA_OUTPUT_BUFFER_POOL != CVMX_FPA_PACKET_POOL)
- cvm_oct_mem_empty_fpa(CVMX_FPA_OUTPUT_BUFFER_POOL,
- CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE, 128);
- return 0;
-}
-
-static const struct of_device_id cvm_oct_match[] = {
- {
- .compatible = "cavium,octeon-3860-pip",
- },
- {},
-};
-MODULE_DEVICE_TABLE(of, cvm_oct_match);
-
-static struct platform_driver cvm_oct_driver = {
- .probe = cvm_oct_probe,
- .remove = cvm_oct_remove,
- .driver = {
- .name = KBUILD_MODNAME,
- .of_match_table = cvm_oct_match,
- },
-};
-
-module_platform_driver(cvm_oct_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Cavium Networks <support@caviumnetworks.com>");
-MODULE_DESCRIPTION("Cavium Networks Octeon ethernet driver.");
diff --git a/drivers/staging/octeon/octeon-ethernet.h b/drivers/staging/octeon/octeon-ethernet.h
deleted file mode 100644
index a6140705706f..000000000000
--- a/drivers/staging/octeon/octeon-ethernet.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * This file is based on code from OCTEON SDK by Cavium Networks.
- *
- * Copyright (c) 2003-2010 Cavium Networks
- */
-
-/*
- * External interface for the Cavium Octeon ethernet driver.
- */
-#ifndef OCTEON_ETHERNET_H
-#define OCTEON_ETHERNET_H
-
-#include <linux/of.h>
-#include <linux/phy.h>
-
-#ifdef CONFIG_CAVIUM_OCTEON_SOC
-
-#include <asm/octeon/octeon.h>
-
-#include <asm/octeon/cvmx-asxx-defs.h>
-#include <asm/octeon/cvmx-config.h>
-#include <asm/octeon/cvmx-fau.h>
-#include <asm/octeon/cvmx-gmxx-defs.h>
-#include <asm/octeon/cvmx-helper.h>
-#include <asm/octeon/cvmx-helper-util.h>
-#include <asm/octeon/cvmx-ipd.h>
-#include <asm/octeon/cvmx-ipd-defs.h>
-#include <asm/octeon/cvmx-npi-defs.h>
-#include <asm/octeon/cvmx-pip.h>
-#include <asm/octeon/cvmx-pko.h>
-#include <asm/octeon/cvmx-pow.h>
-#include <asm/octeon/cvmx-scratch.h>
-#include <asm/octeon/cvmx-spi.h>
-#include <asm/octeon/cvmx-spxx-defs.h>
-#include <asm/octeon/cvmx-stxx-defs.h>
-#include <asm/octeon/cvmx-wqe.h>
-
-#else
-
-#include "octeon-stubs.h"
-
-#endif
-
-/**
- * This is the definition of the Ethernet driver's private
- * driver state stored in netdev_priv(dev).
- */
-struct octeon_ethernet {
- /* PKO hardware output port */
- int port;
- /* PKO hardware queue for the port */
- int queue;
- /* Hardware fetch and add to count outstanding tx buffers */
- int fau;
- /* My netdev. */
- struct net_device *netdev;
- /*
- * Type of port. This is one of the enums in
- * cvmx_helper_interface_mode_t
- */
- int imode;
- /* PHY mode */
- phy_interface_t phy_mode;
- /* List of outstanding tx buffers per queue */
- struct sk_buff_head tx_free_list[16];
- unsigned int last_speed;
- unsigned int last_link;
- /* Last negotiated link state */
- u64 link_info;
- /* Called periodically to check link status */
- void (*poll)(struct net_device *dev);
- struct delayed_work port_periodic_work;
- struct device_node *of_node;
-};
-
-int cvm_oct_free_work(void *work_queue_entry);
-
-int cvm_oct_rgmii_open(struct net_device *dev);
-
-int cvm_oct_sgmii_init(struct net_device *dev);
-int cvm_oct_sgmii_open(struct net_device *dev);
-
-int cvm_oct_spi_init(struct net_device *dev);
-void cvm_oct_spi_uninit(struct net_device *dev);
-
-int cvm_oct_common_init(struct net_device *dev);
-void cvm_oct_common_uninit(struct net_device *dev);
-void cvm_oct_adjust_link(struct net_device *dev);
-int cvm_oct_common_stop(struct net_device *dev);
-int cvm_oct_common_open(struct net_device *dev,
- void (*link_poll)(struct net_device *));
-void cvm_oct_note_carrier(struct octeon_ethernet *priv,
- union cvmx_helper_link_info li);
-void cvm_oct_link_poll(struct net_device *dev);
-
-extern int always_use_pow;
-extern int pow_send_group;
-extern int pow_receive_groups;
-extern char pow_send_list[];
-extern struct net_device *cvm_oct_device[];
-extern atomic_t cvm_oct_poll_queue_stopping;
-extern u64 cvm_oct_tx_poll_interval;
-
-extern int rx_napi_weight;
-
-#endif
diff --git a/drivers/staging/octeon/octeon-stubs.h b/drivers/staging/octeon/octeon-stubs.h
deleted file mode 100644
index 79213c045504..000000000000
--- a/drivers/staging/octeon/octeon-stubs.h
+++ /dev/null
@@ -1,1433 +0,0 @@
-#define CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE 512
-
-#ifndef XKPHYS_TO_PHYS
-# define XKPHYS_TO_PHYS(p) (p)
-#endif
-
-#define OCTEON_IRQ_WORKQ0 0
-#define OCTEON_IRQ_RML 0
-#define OCTEON_IRQ_TIMER1 0
-#define OCTEON_IS_MODEL(x) 0
-#define octeon_has_feature(x) 0
-#define octeon_get_clock_rate() 0
-
-#define CVMX_SYNCIOBDMA do { } while(0)
-
-#define CVMX_HELPER_INPUT_TAG_TYPE 0
-#define CVMX_HELPER_FIRST_MBUFF_SKIP 7
-#define CVMX_FAU_REG_END (2048)
-#define CVMX_FPA_OUTPUT_BUFFER_POOL (2)
-#define CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE 16
-#define CVMX_FPA_PACKET_POOL (0)
-#define CVMX_FPA_PACKET_POOL_SIZE 16
-#define CVMX_FPA_WQE_POOL (1)
-#define CVMX_FPA_WQE_POOL_SIZE 16
-#define CVMX_GMXX_RXX_ADR_CAM_EN(a, b) ((a)+(b))
-#define CVMX_GMXX_RXX_ADR_CTL(a, b) ((a)+(b))
-#define CVMX_GMXX_PRTX_CFG(a, b) ((a)+(b))
-#define CVMX_GMXX_RXX_FRM_MAX(a, b) ((a)+(b))
-#define CVMX_GMXX_RXX_JABBER(a, b) ((a)+(b))
-#define CVMX_IPD_CTL_STATUS 0
-#define CVMX_PIP_FRM_LEN_CHKX(a) (a)
-#define CVMX_PIP_NUM_INPUT_PORTS 1
-#define CVMX_SCR_SCRATCH 0
-#define CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 2
-#define CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 2
-#define CVMX_IPD_SUB_PORT_FCS 0
-#define CVMX_SSO_WQ_IQ_DIS 0
-#define CVMX_SSO_WQ_INT 0
-#define CVMX_POW_WQ_INT 0
-#define CVMX_SSO_WQ_INT_PC 0
-#define CVMX_NPI_RSL_INT_BLOCKS 0
-#define CVMX_POW_WQ_INT_PC 0
-
-union cvmx_pip_wqe_word2 {
- uint64_t u64;
- struct {
- uint64_t bufs:8;
- uint64_t ip_offset:8;
- uint64_t vlan_valid:1;
- uint64_t vlan_stacked:1;
- uint64_t unassigned:1;
- uint64_t vlan_cfi:1;
- uint64_t vlan_id:12;
- uint64_t pr:4;
- uint64_t unassigned2:8;
- uint64_t dec_ipcomp:1;
- uint64_t tcp_or_udp:1;
- uint64_t dec_ipsec:1;
- uint64_t is_v6:1;
- uint64_t software:1;
- uint64_t L4_error:1;
- uint64_t is_frag:1;
- uint64_t IP_exc:1;
- uint64_t is_bcast:1;
- uint64_t is_mcast:1;
- uint64_t not_IP:1;
- uint64_t rcv_error:1;
- uint64_t err_code:8;
- } s;
- struct {
- uint64_t bufs:8;
- uint64_t ip_offset:8;
- uint64_t vlan_valid:1;
- uint64_t vlan_stacked:1;
- uint64_t unassigned:1;
- uint64_t vlan_cfi:1;
- uint64_t vlan_id:12;
- uint64_t port:12;
- uint64_t dec_ipcomp:1;
- uint64_t tcp_or_udp:1;
- uint64_t dec_ipsec:1;
- uint64_t is_v6:1;
- uint64_t software:1;
- uint64_t L4_error:1;
- uint64_t is_frag:1;
- uint64_t IP_exc:1;
- uint64_t is_bcast:1;
- uint64_t is_mcast:1;
- uint64_t not_IP:1;
- uint64_t rcv_error:1;
- uint64_t err_code:8;
- } s_cn68xx;
-
- struct {
- uint64_t unused1:16;
- uint64_t vlan:16;
- uint64_t unused2:32;
- } svlan;
- struct {
- uint64_t bufs:8;
- uint64_t unused:8;
- uint64_t vlan_valid:1;
- uint64_t vlan_stacked:1;
- uint64_t unassigned:1;
- uint64_t vlan_cfi:1;
- uint64_t vlan_id:12;
- uint64_t pr:4;
- uint64_t unassigned2:12;
- uint64_t software:1;
- uint64_t unassigned3:1;
- uint64_t is_rarp:1;
- uint64_t is_arp:1;
- uint64_t is_bcast:1;
- uint64_t is_mcast:1;
- uint64_t not_IP:1;
- uint64_t rcv_error:1;
- uint64_t err_code:8;
- } snoip;
-
-};
-
-union cvmx_pip_wqe_word0 {
- struct {
- uint64_t next_ptr:40;
- uint8_t unused;
- __wsum hw_chksum;
- } cn38xx;
- struct {
- uint64_t pknd:6; /* 0..5 */
- uint64_t unused2:2; /* 6..7 */
- uint64_t bpid:6; /* 8..13 */
- uint64_t unused1:18; /* 14..31 */
- uint64_t l2ptr:8; /* 32..39 */
- uint64_t l3ptr:8; /* 40..47 */
- uint64_t unused0:8; /* 48..55 */
- uint64_t l4ptr:8; /* 56..63 */
- } cn68xx;
-};
-
-union cvmx_wqe_word0 {
- uint64_t u64;
- union cvmx_pip_wqe_word0 pip;
-};
-
-union cvmx_wqe_word1 {
- uint64_t u64;
- struct {
- uint64_t tag:32;
- uint64_t tag_type:2;
- uint64_t varies:14;
- uint64_t len:16;
- };
- struct {
- uint64_t tag:32;
- uint64_t tag_type:2;
- uint64_t zero_2:3;
- uint64_t grp:6;
- uint64_t zero_1:1;
- uint64_t qos:3;
- uint64_t zero_0:1;
- uint64_t len:16;
- } cn68xx;
- struct {
- uint64_t tag:32;
- uint64_t tag_type:2;
- uint64_t zero_2:1;
- uint64_t grp:4;
- uint64_t qos:3;
- uint64_t ipprt:6;
- uint64_t len:16;
- } cn38xx;
-};
-
-union cvmx_buf_ptr {
- void *ptr;
- uint64_t u64;
- struct {
- uint64_t i:1;
- uint64_t back:4;
- uint64_t pool:3;
- uint64_t size:16;
- uint64_t addr:40;
- } s;
-};
-
-struct cvmx_wqe {
- union cvmx_wqe_word0 word0;
- union cvmx_wqe_word1 word1;
- union cvmx_pip_wqe_word2 word2;
- union cvmx_buf_ptr packet_ptr;
- uint8_t packet_data[96];
-};
-
-union cvmx_helper_link_info {
- uint64_t u64;
- struct {
- uint64_t reserved_20_63:44;
- uint64_t link_up:1; /**< Is the physical link up? */
- uint64_t full_duplex:1; /**< 1 if the link is full duplex */
- uint64_t speed:18; /**< Speed of the link in Mbps */
- } s;
-};
-
-enum cvmx_fau_reg_32 {
- CVMX_FAU_REG_32_START = 0,
-};
-
-enum cvmx_fau_op_size {
- CVMX_FAU_OP_SIZE_8 = 0,
- CVMX_FAU_OP_SIZE_16 = 1,
- CVMX_FAU_OP_SIZE_32 = 2,
- CVMX_FAU_OP_SIZE_64 = 3
-};
-
-typedef enum {
- CVMX_SPI_MODE_UNKNOWN = 0,
- CVMX_SPI_MODE_TX_HALFPLEX = 1,
- CVMX_SPI_MODE_RX_HALFPLEX = 2,
- CVMX_SPI_MODE_DUPLEX = 3
-} cvmx_spi_mode_t;
-
-typedef enum {
- CVMX_HELPER_INTERFACE_MODE_DISABLED,
- CVMX_HELPER_INTERFACE_MODE_RGMII,
- CVMX_HELPER_INTERFACE_MODE_GMII,
- CVMX_HELPER_INTERFACE_MODE_SPI,
- CVMX_HELPER_INTERFACE_MODE_PCIE,
- CVMX_HELPER_INTERFACE_MODE_XAUI,
- CVMX_HELPER_INTERFACE_MODE_SGMII,
- CVMX_HELPER_INTERFACE_MODE_PICMG,
- CVMX_HELPER_INTERFACE_MODE_NPI,
- CVMX_HELPER_INTERFACE_MODE_LOOP,
-} cvmx_helper_interface_mode_t;
-
-typedef enum {
- CVMX_POW_WAIT = 1,
- CVMX_POW_NO_WAIT = 0,
-} cvmx_pow_wait_t;
-
-typedef enum {
- CVMX_PKO_LOCK_NONE = 0,
- CVMX_PKO_LOCK_ATOMIC_TAG = 1,
- CVMX_PKO_LOCK_CMD_QUEUE = 2,
-} cvmx_pko_lock_t;
-
-typedef enum {
- CVMX_PKO_SUCCESS,
- CVMX_PKO_INVALID_PORT,
- CVMX_PKO_INVALID_QUEUE,
- CVMX_PKO_INVALID_PRIORITY,
- CVMX_PKO_NO_MEMORY,
- CVMX_PKO_PORT_ALREADY_SETUP,
- CVMX_PKO_CMD_QUEUE_INIT_ERROR
-} cvmx_pko_status_t;
-
-enum cvmx_pow_tag_type {
- CVMX_POW_TAG_TYPE_ORDERED = 0L,
- CVMX_POW_TAG_TYPE_ATOMIC = 1L,
- CVMX_POW_TAG_TYPE_NULL = 2L,
- CVMX_POW_TAG_TYPE_NULL_NULL = 3L
-};
-
-union cvmx_ipd_ctl_status {
- uint64_t u64;
- struct cvmx_ipd_ctl_status_s {
- uint64_t reserved_18_63:46;
- uint64_t use_sop:1;
- uint64_t rst_done:1;
- uint64_t clken:1;
- uint64_t no_wptr:1;
- uint64_t pq_apkt:1;
- uint64_t pq_nabuf:1;
- uint64_t ipd_full:1;
- uint64_t pkt_off:1;
- uint64_t len_m8:1;
- uint64_t reset:1;
- uint64_t addpkt:1;
- uint64_t naddbuf:1;
- uint64_t pkt_lend:1;
- uint64_t wqe_lend:1;
- uint64_t pbp_en:1;
- uint64_t opc_mode:2;
- uint64_t ipd_en:1;
- } s;
- struct cvmx_ipd_ctl_status_cn30xx {
- uint64_t reserved_10_63:54;
- uint64_t len_m8:1;
- uint64_t reset:1;
- uint64_t addpkt:1;
- uint64_t naddbuf:1;
- uint64_t pkt_lend:1;
- uint64_t wqe_lend:1;
- uint64_t pbp_en:1;
- uint64_t opc_mode:2;
- uint64_t ipd_en:1;
- } cn30xx;
- struct cvmx_ipd_ctl_status_cn38xxp2 {
- uint64_t reserved_9_63:55;
- uint64_t reset:1;
- uint64_t addpkt:1;
- uint64_t naddbuf:1;
- uint64_t pkt_lend:1;
- uint64_t wqe_lend:1;
- uint64_t pbp_en:1;
- uint64_t opc_mode:2;
- uint64_t ipd_en:1;
- } cn38xxp2;
- struct cvmx_ipd_ctl_status_cn50xx {
- uint64_t reserved_15_63:49;
- uint64_t no_wptr:1;
- uint64_t pq_apkt:1;
- uint64_t pq_nabuf:1;
- uint64_t ipd_full:1;
- uint64_t pkt_off:1;
- uint64_t len_m8:1;
- uint64_t reset:1;
- uint64_t addpkt:1;
- uint64_t naddbuf:1;
- uint64_t pkt_lend:1;
- uint64_t wqe_lend:1;
- uint64_t pbp_en:1;
- uint64_t opc_mode:2;
- uint64_t ipd_en:1;
- } cn50xx;
- struct cvmx_ipd_ctl_status_cn58xx {
- uint64_t reserved_12_63:52;
- uint64_t ipd_full:1;
- uint64_t pkt_off:1;
- uint64_t len_m8:1;
- uint64_t reset:1;
- uint64_t addpkt:1;
- uint64_t naddbuf:1;
- uint64_t pkt_lend:1;
- uint64_t wqe_lend:1;
- uint64_t pbp_en:1;
- uint64_t opc_mode:2;
- uint64_t ipd_en:1;
- } cn58xx;
- struct cvmx_ipd_ctl_status_cn63xxp1 {
- uint64_t reserved_16_63:48;
- uint64_t clken:1;
- uint64_t no_wptr:1;
- uint64_t pq_apkt:1;
- uint64_t pq_nabuf:1;
- uint64_t ipd_full:1;
- uint64_t pkt_off:1;
- uint64_t len_m8:1;
- uint64_t reset:1;
- uint64_t addpkt:1;
- uint64_t naddbuf:1;
- uint64_t pkt_lend:1;
- uint64_t wqe_lend:1;
- uint64_t pbp_en:1;
- uint64_t opc_mode:2;
- uint64_t ipd_en:1;
- } cn63xxp1;
-};
-
-union cvmx_ipd_sub_port_fcs {
- uint64_t u64;
- struct cvmx_ipd_sub_port_fcs_s {
- uint64_t port_bit:32;
- uint64_t reserved_32_35:4;
- uint64_t port_bit2:4;
- uint64_t reserved_40_63:24;
- } s;
- struct cvmx_ipd_sub_port_fcs_cn30xx {
- uint64_t port_bit:3;
- uint64_t reserved_3_63:61;
- } cn30xx;
- struct cvmx_ipd_sub_port_fcs_cn38xx {
- uint64_t port_bit:32;
- uint64_t reserved_32_63:32;
- } cn38xx;
-};
-
-union cvmx_ipd_sub_port_qos_cnt {
- uint64_t u64;
- struct cvmx_ipd_sub_port_qos_cnt_s {
- uint64_t cnt:32;
- uint64_t port_qos:9;
- uint64_t reserved_41_63:23;
- } s;
-};
-typedef struct {
- uint32_t dropped_octets;
- uint32_t dropped_packets;
- uint32_t pci_raw_packets;
- uint32_t octets;
- uint32_t packets;
- uint32_t multicast_packets;
- uint32_t broadcast_packets;
- uint32_t len_64_packets;
- uint32_t len_65_127_packets;
- uint32_t len_128_255_packets;
- uint32_t len_256_511_packets;
- uint32_t len_512_1023_packets;
- uint32_t len_1024_1518_packets;
- uint32_t len_1519_max_packets;
- uint32_t fcs_align_err_packets;
- uint32_t runt_packets;
- uint32_t runt_crc_packets;
- uint32_t oversize_packets;
- uint32_t oversize_crc_packets;
- uint32_t inb_packets;
- uint64_t inb_octets;
- uint16_t inb_errors;
-} cvmx_pip_port_status_t;
-
-typedef struct {
- uint32_t packets;
- uint64_t octets;
- uint64_t doorbell;
-} cvmx_pko_port_status_t;
-
-union cvmx_pip_frm_len_chkx {
- uint64_t u64;
- struct cvmx_pip_frm_len_chkx_s {
- uint64_t reserved_32_63:32;
- uint64_t maxlen:16;
- uint64_t minlen:16;
- } s;
-};
-
-union cvmx_gmxx_rxx_frm_ctl {
- uint64_t u64;
- struct cvmx_gmxx_rxx_frm_ctl_s {
- uint64_t pre_chk:1;
- uint64_t pre_strp:1;
- uint64_t ctl_drp:1;
- uint64_t ctl_bck:1;
- uint64_t ctl_mcst:1;
- uint64_t ctl_smac:1;
- uint64_t pre_free:1;
- uint64_t vlan_len:1;
- uint64_t pad_len:1;
- uint64_t pre_align:1;
- uint64_t null_dis:1;
- uint64_t reserved_11_11:1;
- uint64_t ptp_mode:1;
- uint64_t reserved_13_63:51;
- } s;
- struct cvmx_gmxx_rxx_frm_ctl_cn30xx {
- uint64_t pre_chk:1;
- uint64_t pre_strp:1;
- uint64_t ctl_drp:1;
- uint64_t ctl_bck:1;
- uint64_t ctl_mcst:1;
- uint64_t ctl_smac:1;
- uint64_t pre_free:1;
- uint64_t vlan_len:1;
- uint64_t pad_len:1;
- uint64_t reserved_9_63:55;
- } cn30xx;
- struct cvmx_gmxx_rxx_frm_ctl_cn31xx {
- uint64_t pre_chk:1;
- uint64_t pre_strp:1;
- uint64_t ctl_drp:1;
- uint64_t ctl_bck:1;
- uint64_t ctl_mcst:1;
- uint64_t ctl_smac:1;
- uint64_t pre_free:1;
- uint64_t vlan_len:1;
- uint64_t reserved_8_63:56;
- } cn31xx;
- struct cvmx_gmxx_rxx_frm_ctl_cn50xx {
- uint64_t pre_chk:1;
- uint64_t pre_strp:1;
- uint64_t ctl_drp:1;
- uint64_t ctl_bck:1;
- uint64_t ctl_mcst:1;
- uint64_t ctl_smac:1;
- uint64_t pre_free:1;
- uint64_t reserved_7_8:2;
- uint64_t pre_align:1;
- uint64_t null_dis:1;
- uint64_t reserved_11_63:53;
- } cn50xx;
- struct cvmx_gmxx_rxx_frm_ctl_cn56xxp1 {
- uint64_t pre_chk:1;
- uint64_t pre_strp:1;
- uint64_t ctl_drp:1;
- uint64_t ctl_bck:1;
- uint64_t ctl_mcst:1;
- uint64_t ctl_smac:1;
- uint64_t pre_free:1;
- uint64_t reserved_7_8:2;
- uint64_t pre_align:1;
- uint64_t reserved_10_63:54;
- } cn56xxp1;
- struct cvmx_gmxx_rxx_frm_ctl_cn58xx {
- uint64_t pre_chk:1;
- uint64_t pre_strp:1;
- uint64_t ctl_drp:1;
- uint64_t ctl_bck:1;
- uint64_t ctl_mcst:1;
- uint64_t ctl_smac:1;
- uint64_t pre_free:1;
- uint64_t vlan_len:1;
- uint64_t pad_len:1;
- uint64_t pre_align:1;
- uint64_t null_dis:1;
- uint64_t reserved_11_63:53;
- } cn58xx;
- struct cvmx_gmxx_rxx_frm_ctl_cn61xx {
- uint64_t pre_chk:1;
- uint64_t pre_strp:1;
- uint64_t ctl_drp:1;
- uint64_t ctl_bck:1;
- uint64_t ctl_mcst:1;
- uint64_t ctl_smac:1;
- uint64_t pre_free:1;
- uint64_t reserved_7_8:2;
- uint64_t pre_align:1;
- uint64_t null_dis:1;
- uint64_t reserved_11_11:1;
- uint64_t ptp_mode:1;
- uint64_t reserved_13_63:51;
- } cn61xx;
-};
-
-union cvmx_gmxx_rxx_int_reg {
- uint64_t u64;
- struct cvmx_gmxx_rxx_int_reg_s {
- uint64_t minerr:1;
- uint64_t carext:1;
- uint64_t maxerr:1;
- uint64_t jabber:1;
- uint64_t fcserr:1;
- uint64_t alnerr:1;
- uint64_t lenerr:1;
- uint64_t rcverr:1;
- uint64_t skperr:1;
- uint64_t niberr:1;
- uint64_t ovrerr:1;
- uint64_t pcterr:1;
- uint64_t rsverr:1;
- uint64_t falerr:1;
- uint64_t coldet:1;
- uint64_t ifgerr:1;
- uint64_t phy_link:1;
- uint64_t phy_spd:1;
- uint64_t phy_dupx:1;
- uint64_t pause_drp:1;
- uint64_t loc_fault:1;
- uint64_t rem_fault:1;
- uint64_t bad_seq:1;
- uint64_t bad_term:1;
- uint64_t unsop:1;
- uint64_t uneop:1;
- uint64_t undat:1;
- uint64_t hg2fld:1;
- uint64_t hg2cc:1;
- uint64_t reserved_29_63:35;
- } s;
- struct cvmx_gmxx_rxx_int_reg_cn30xx {
- uint64_t minerr:1;
- uint64_t carext:1;
- uint64_t maxerr:1;
- uint64_t jabber:1;
- uint64_t fcserr:1;
- uint64_t alnerr:1;
- uint64_t lenerr:1;
- uint64_t rcverr:1;
- uint64_t skperr:1;
- uint64_t niberr:1;
- uint64_t ovrerr:1;
- uint64_t pcterr:1;
- uint64_t rsverr:1;
- uint64_t falerr:1;
- uint64_t coldet:1;
- uint64_t ifgerr:1;
- uint64_t phy_link:1;
- uint64_t phy_spd:1;
- uint64_t phy_dupx:1;
- uint64_t reserved_19_63:45;
- } cn30xx;
- struct cvmx_gmxx_rxx_int_reg_cn50xx {
- uint64_t reserved_0_0:1;
- uint64_t carext:1;
- uint64_t reserved_2_2:1;
- uint64_t jabber:1;
- uint64_t fcserr:1;
- uint64_t alnerr:1;
- uint64_t reserved_6_6:1;
- uint64_t rcverr:1;
- uint64_t skperr:1;
- uint64_t niberr:1;
- uint64_t ovrerr:1;
- uint64_t pcterr:1;
- uint64_t rsverr:1;
- uint64_t falerr:1;
- uint64_t coldet:1;
- uint64_t ifgerr:1;
- uint64_t phy_link:1;
- uint64_t phy_spd:1;
- uint64_t phy_dupx:1;
- uint64_t pause_drp:1;
- uint64_t reserved_20_63:44;
- } cn50xx;
- struct cvmx_gmxx_rxx_int_reg_cn52xx {
- uint64_t reserved_0_0:1;
- uint64_t carext:1;
- uint64_t reserved_2_2:1;
- uint64_t jabber:1;
- uint64_t fcserr:1;
- uint64_t reserved_5_6:2;
- uint64_t rcverr:1;
- uint64_t skperr:1;
- uint64_t reserved_9_9:1;
- uint64_t ovrerr:1;
- uint64_t pcterr:1;
- uint64_t rsverr:1;
- uint64_t falerr:1;
- uint64_t coldet:1;
- uint64_t ifgerr:1;
- uint64_t reserved_16_18:3;
- uint64_t pause_drp:1;
- uint64_t loc_fault:1;
- uint64_t rem_fault:1;
- uint64_t bad_seq:1;
- uint64_t bad_term:1;
- uint64_t unsop:1;
- uint64_t uneop:1;
- uint64_t undat:1;
- uint64_t hg2fld:1;
- uint64_t hg2cc:1;
- uint64_t reserved_29_63:35;
- } cn52xx;
- struct cvmx_gmxx_rxx_int_reg_cn56xxp1 {
- uint64_t reserved_0_0:1;
- uint64_t carext:1;
- uint64_t reserved_2_2:1;
- uint64_t jabber:1;
- uint64_t fcserr:1;
- uint64_t reserved_5_6:2;
- uint64_t rcverr:1;
- uint64_t skperr:1;
- uint64_t reserved_9_9:1;
- uint64_t ovrerr:1;
- uint64_t pcterr:1;
- uint64_t rsverr:1;
- uint64_t falerr:1;
- uint64_t coldet:1;
- uint64_t ifgerr:1;
- uint64_t reserved_16_18:3;
- uint64_t pause_drp:1;
- uint64_t loc_fault:1;
- uint64_t rem_fault:1;
- uint64_t bad_seq:1;
- uint64_t bad_term:1;
- uint64_t unsop:1;
- uint64_t uneop:1;
- uint64_t undat:1;
- uint64_t reserved_27_63:37;
- } cn56xxp1;
- struct cvmx_gmxx_rxx_int_reg_cn58xx {
- uint64_t minerr:1;
- uint64_t carext:1;
- uint64_t maxerr:1;
- uint64_t jabber:1;
- uint64_t fcserr:1;
- uint64_t alnerr:1;
- uint64_t lenerr:1;
- uint64_t rcverr:1;
- uint64_t skperr:1;
- uint64_t niberr:1;
- uint64_t ovrerr:1;
- uint64_t pcterr:1;
- uint64_t rsverr:1;
- uint64_t falerr:1;
- uint64_t coldet:1;
- uint64_t ifgerr:1;
- uint64_t phy_link:1;
- uint64_t phy_spd:1;
- uint64_t phy_dupx:1;
- uint64_t pause_drp:1;
- uint64_t reserved_20_63:44;
- } cn58xx;
- struct cvmx_gmxx_rxx_int_reg_cn61xx {
- uint64_t minerr:1;
- uint64_t carext:1;
- uint64_t reserved_2_2:1;
- uint64_t jabber:1;
- uint64_t fcserr:1;
- uint64_t reserved_5_6:2;
- uint64_t rcverr:1;
- uint64_t skperr:1;
- uint64_t reserved_9_9:1;
- uint64_t ovrerr:1;
- uint64_t pcterr:1;
- uint64_t rsverr:1;
- uint64_t falerr:1;
- uint64_t coldet:1;
- uint64_t ifgerr:1;
- uint64_t reserved_16_18:3;
- uint64_t pause_drp:1;
- uint64_t loc_fault:1;
- uint64_t rem_fault:1;
- uint64_t bad_seq:1;
- uint64_t bad_term:1;
- uint64_t unsop:1;
- uint64_t uneop:1;
- uint64_t undat:1;
- uint64_t hg2fld:1;
- uint64_t hg2cc:1;
- uint64_t reserved_29_63:35;
- } cn61xx;
-};
-
-union cvmx_gmxx_prtx_cfg {
- uint64_t u64;
- struct cvmx_gmxx_prtx_cfg_s {
- uint64_t reserved_22_63:42;
- uint64_t pknd:6;
- uint64_t reserved_14_15:2;
- uint64_t tx_idle:1;
- uint64_t rx_idle:1;
- uint64_t reserved_9_11:3;
- uint64_t speed_msb:1;
- uint64_t reserved_4_7:4;
- uint64_t slottime:1;
- uint64_t duplex:1;
- uint64_t speed:1;
- uint64_t en:1;
- } s;
- struct cvmx_gmxx_prtx_cfg_cn30xx {
- uint64_t reserved_4_63:60;
- uint64_t slottime:1;
- uint64_t duplex:1;
- uint64_t speed:1;
- uint64_t en:1;
- } cn30xx;
- struct cvmx_gmxx_prtx_cfg_cn52xx {
- uint64_t reserved_14_63:50;
- uint64_t tx_idle:1;
- uint64_t rx_idle:1;
- uint64_t reserved_9_11:3;
- uint64_t speed_msb:1;
- uint64_t reserved_4_7:4;
- uint64_t slottime:1;
- uint64_t duplex:1;
- uint64_t speed:1;
- uint64_t en:1;
- } cn52xx;
-};
-
-union cvmx_gmxx_rxx_adr_ctl {
- uint64_t u64;
- struct cvmx_gmxx_rxx_adr_ctl_s {
- uint64_t reserved_4_63:60;
- uint64_t cam_mode:1;
- uint64_t mcst:2;
- uint64_t bcst:1;
- } s;
-};
-
-union cvmx_pip_prt_tagx {
- uint64_t u64;
- struct cvmx_pip_prt_tagx_s {
- uint64_t reserved_54_63:10;
- uint64_t portadd_en:1;
- uint64_t inc_hwchk:1;
- uint64_t reserved_50_51:2;
- uint64_t grptagbase_msb:2;
- uint64_t reserved_46_47:2;
- uint64_t grptagmask_msb:2;
- uint64_t reserved_42_43:2;
- uint64_t grp_msb:2;
- uint64_t grptagbase:4;
- uint64_t grptagmask:4;
- uint64_t grptag:1;
- uint64_t grptag_mskip:1;
- uint64_t tag_mode:2;
- uint64_t inc_vs:2;
- uint64_t inc_vlan:1;
- uint64_t inc_prt_flag:1;
- uint64_t ip6_dprt_flag:1;
- uint64_t ip4_dprt_flag:1;
- uint64_t ip6_sprt_flag:1;
- uint64_t ip4_sprt_flag:1;
- uint64_t ip6_nxth_flag:1;
- uint64_t ip4_pctl_flag:1;
- uint64_t ip6_dst_flag:1;
- uint64_t ip4_dst_flag:1;
- uint64_t ip6_src_flag:1;
- uint64_t ip4_src_flag:1;
- uint64_t tcp6_tag_type:2;
- uint64_t tcp4_tag_type:2;
- uint64_t ip6_tag_type:2;
- uint64_t ip4_tag_type:2;
- uint64_t non_tag_type:2;
- uint64_t grp:4;
- } s;
- struct cvmx_pip_prt_tagx_cn30xx {
- uint64_t reserved_40_63:24;
- uint64_t grptagbase:4;
- uint64_t grptagmask:4;
- uint64_t grptag:1;
- uint64_t reserved_30_30:1;
- uint64_t tag_mode:2;
- uint64_t inc_vs:2;
- uint64_t inc_vlan:1;
- uint64_t inc_prt_flag:1;
- uint64_t ip6_dprt_flag:1;
- uint64_t ip4_dprt_flag:1;
- uint64_t ip6_sprt_flag:1;
- uint64_t ip4_sprt_flag:1;
- uint64_t ip6_nxth_flag:1;
- uint64_t ip4_pctl_flag:1;
- uint64_t ip6_dst_flag:1;
- uint64_t ip4_dst_flag:1;
- uint64_t ip6_src_flag:1;
- uint64_t ip4_src_flag:1;
- uint64_t tcp6_tag_type:2;
- uint64_t tcp4_tag_type:2;
- uint64_t ip6_tag_type:2;
- uint64_t ip4_tag_type:2;
- uint64_t non_tag_type:2;
- uint64_t grp:4;
- } cn30xx;
- struct cvmx_pip_prt_tagx_cn50xx {
- uint64_t reserved_40_63:24;
- uint64_t grptagbase:4;
- uint64_t grptagmask:4;
- uint64_t grptag:1;
- uint64_t grptag_mskip:1;
- uint64_t tag_mode:2;
- uint64_t inc_vs:2;
- uint64_t inc_vlan:1;
- uint64_t inc_prt_flag:1;
- uint64_t ip6_dprt_flag:1;
- uint64_t ip4_dprt_flag:1;
- uint64_t ip6_sprt_flag:1;
- uint64_t ip4_sprt_flag:1;
- uint64_t ip6_nxth_flag:1;
- uint64_t ip4_pctl_flag:1;
- uint64_t ip6_dst_flag:1;
- uint64_t ip4_dst_flag:1;
- uint64_t ip6_src_flag:1;
- uint64_t ip4_src_flag:1;
- uint64_t tcp6_tag_type:2;
- uint64_t tcp4_tag_type:2;
- uint64_t ip6_tag_type:2;
- uint64_t ip4_tag_type:2;
- uint64_t non_tag_type:2;
- uint64_t grp:4;
- } cn50xx;
-};
-
-union cvmx_spxx_int_reg {
- uint64_t u64;
- struct cvmx_spxx_int_reg_s {
- uint64_t reserved_32_63:32;
- uint64_t spf:1;
- uint64_t reserved_12_30:19;
- uint64_t calerr:1;
- uint64_t syncerr:1;
- uint64_t diperr:1;
- uint64_t tpaovr:1;
- uint64_t rsverr:1;
- uint64_t drwnng:1;
- uint64_t clserr:1;
- uint64_t spiovr:1;
- uint64_t reserved_2_3:2;
- uint64_t abnorm:1;
- uint64_t prtnxa:1;
- } s;
-};
-
-union cvmx_spxx_int_msk {
- uint64_t u64;
- struct cvmx_spxx_int_msk_s {
- uint64_t reserved_12_63:52;
- uint64_t calerr:1;
- uint64_t syncerr:1;
- uint64_t diperr:1;
- uint64_t tpaovr:1;
- uint64_t rsverr:1;
- uint64_t drwnng:1;
- uint64_t clserr:1;
- uint64_t spiovr:1;
- uint64_t reserved_2_3:2;
- uint64_t abnorm:1;
- uint64_t prtnxa:1;
- } s;
-};
-
-union cvmx_pow_wq_int {
- uint64_t u64;
- struct cvmx_pow_wq_int_s {
- uint64_t wq_int:16;
- uint64_t iq_dis:16;
- uint64_t reserved_32_63:32;
- } s;
-};
-
-union cvmx_sso_wq_int_thrx {
- uint64_t u64;
- struct {
- uint64_t iq_thr:12;
- uint64_t reserved_12_13:2;
- uint64_t ds_thr:12;
- uint64_t reserved_26_27:2;
- uint64_t tc_thr:4;
- uint64_t tc_en:1;
- uint64_t reserved_33_63:31;
- } s;
-};
-
-union cvmx_stxx_int_reg {
- uint64_t u64;
- struct cvmx_stxx_int_reg_s {
- uint64_t reserved_9_63:55;
- uint64_t syncerr:1;
- uint64_t frmerr:1;
- uint64_t unxfrm:1;
- uint64_t nosync:1;
- uint64_t diperr:1;
- uint64_t datovr:1;
- uint64_t ovrbst:1;
- uint64_t calpar1:1;
- uint64_t calpar0:1;
- } s;
-};
-
-union cvmx_stxx_int_msk {
- uint64_t u64;
- struct cvmx_stxx_int_msk_s {
- uint64_t reserved_8_63:56;
- uint64_t frmerr:1;
- uint64_t unxfrm:1;
- uint64_t nosync:1;
- uint64_t diperr:1;
- uint64_t datovr:1;
- uint64_t ovrbst:1;
- uint64_t calpar1:1;
- uint64_t calpar0:1;
- } s;
-};
-
-union cvmx_pow_wq_int_pc {
- uint64_t u64;
- struct cvmx_pow_wq_int_pc_s {
- uint64_t reserved_0_7:8;
- uint64_t pc_thr:20;
- uint64_t reserved_28_31:4;
- uint64_t pc:28;
- uint64_t reserved_60_63:4;
- } s;
-};
-
-union cvmx_pow_wq_int_thrx {
- uint64_t u64;
- struct cvmx_pow_wq_int_thrx_s {
- uint64_t reserved_29_63:35;
- uint64_t tc_en:1;
- uint64_t tc_thr:4;
- uint64_t reserved_23_23:1;
- uint64_t ds_thr:11;
- uint64_t reserved_11_11:1;
- uint64_t iq_thr:11;
- } s;
- struct cvmx_pow_wq_int_thrx_cn30xx {
- uint64_t reserved_29_63:35;
- uint64_t tc_en:1;
- uint64_t tc_thr:4;
- uint64_t reserved_18_23:6;
- uint64_t ds_thr:6;
- uint64_t reserved_6_11:6;
- uint64_t iq_thr:6;
- } cn30xx;
- struct cvmx_pow_wq_int_thrx_cn31xx {
- uint64_t reserved_29_63:35;
- uint64_t tc_en:1;
- uint64_t tc_thr:4;
- uint64_t reserved_20_23:4;
- uint64_t ds_thr:8;
- uint64_t reserved_8_11:4;
- uint64_t iq_thr:8;
- } cn31xx;
- struct cvmx_pow_wq_int_thrx_cn52xx {
- uint64_t reserved_29_63:35;
- uint64_t tc_en:1;
- uint64_t tc_thr:4;
- uint64_t reserved_21_23:3;
- uint64_t ds_thr:9;
- uint64_t reserved_9_11:3;
- uint64_t iq_thr:9;
- } cn52xx;
- struct cvmx_pow_wq_int_thrx_cn63xx {
- uint64_t reserved_29_63:35;
- uint64_t tc_en:1;
- uint64_t tc_thr:4;
- uint64_t reserved_22_23:2;
- uint64_t ds_thr:10;
- uint64_t reserved_10_11:2;
- uint64_t iq_thr:10;
- } cn63xx;
-};
-
-union cvmx_npi_rsl_int_blocks {
- uint64_t u64;
- struct cvmx_npi_rsl_int_blocks_s {
- uint64_t reserved_32_63:32;
- uint64_t rint_31:1;
- uint64_t iob:1;
- uint64_t reserved_28_29:2;
- uint64_t rint_27:1;
- uint64_t rint_26:1;
- uint64_t rint_25:1;
- uint64_t rint_24:1;
- uint64_t asx1:1;
- uint64_t asx0:1;
- uint64_t rint_21:1;
- uint64_t pip:1;
- uint64_t spx1:1;
- uint64_t spx0:1;
- uint64_t lmc:1;
- uint64_t l2c:1;
- uint64_t rint_15:1;
- uint64_t reserved_13_14:2;
- uint64_t pow:1;
- uint64_t tim:1;
- uint64_t pko:1;
- uint64_t ipd:1;
- uint64_t rint_8:1;
- uint64_t zip:1;
- uint64_t dfa:1;
- uint64_t fpa:1;
- uint64_t key:1;
- uint64_t npi:1;
- uint64_t gmx1:1;
- uint64_t gmx0:1;
- uint64_t mio:1;
- } s;
- struct cvmx_npi_rsl_int_blocks_cn30xx {
- uint64_t reserved_32_63:32;
- uint64_t rint_31:1;
- uint64_t iob:1;
- uint64_t rint_29:1;
- uint64_t rint_28:1;
- uint64_t rint_27:1;
- uint64_t rint_26:1;
- uint64_t rint_25:1;
- uint64_t rint_24:1;
- uint64_t asx1:1;
- uint64_t asx0:1;
- uint64_t rint_21:1;
- uint64_t pip:1;
- uint64_t spx1:1;
- uint64_t spx0:1;
- uint64_t lmc:1;
- uint64_t l2c:1;
- uint64_t rint_15:1;
- uint64_t rint_14:1;
- uint64_t usb:1;
- uint64_t pow:1;
- uint64_t tim:1;
- uint64_t pko:1;
- uint64_t ipd:1;
- uint64_t rint_8:1;
- uint64_t zip:1;
- uint64_t dfa:1;
- uint64_t fpa:1;
- uint64_t key:1;
- uint64_t npi:1;
- uint64_t gmx1:1;
- uint64_t gmx0:1;
- uint64_t mio:1;
- } cn30xx;
- struct cvmx_npi_rsl_int_blocks_cn38xx {
- uint64_t reserved_32_63:32;
- uint64_t rint_31:1;
- uint64_t iob:1;
- uint64_t rint_29:1;
- uint64_t rint_28:1;
- uint64_t rint_27:1;
- uint64_t rint_26:1;
- uint64_t rint_25:1;
- uint64_t rint_24:1;
- uint64_t asx1:1;
- uint64_t asx0:1;
- uint64_t rint_21:1;
- uint64_t pip:1;
- uint64_t spx1:1;
- uint64_t spx0:1;
- uint64_t lmc:1;
- uint64_t l2c:1;
- uint64_t rint_15:1;
- uint64_t rint_14:1;
- uint64_t rint_13:1;
- uint64_t pow:1;
- uint64_t tim:1;
- uint64_t pko:1;
- uint64_t ipd:1;
- uint64_t rint_8:1;
- uint64_t zip:1;
- uint64_t dfa:1;
- uint64_t fpa:1;
- uint64_t key:1;
- uint64_t npi:1;
- uint64_t gmx1:1;
- uint64_t gmx0:1;
- uint64_t mio:1;
- } cn38xx;
- struct cvmx_npi_rsl_int_blocks_cn50xx {
- uint64_t reserved_31_63:33;
- uint64_t iob:1;
- uint64_t lmc1:1;
- uint64_t agl:1;
- uint64_t reserved_24_27:4;
- uint64_t asx1:1;
- uint64_t asx0:1;
- uint64_t reserved_21_21:1;
- uint64_t pip:1;
- uint64_t spx1:1;
- uint64_t spx0:1;
- uint64_t lmc:1;
- uint64_t l2c:1;
- uint64_t reserved_15_15:1;
- uint64_t rad:1;
- uint64_t usb:1;
- uint64_t pow:1;
- uint64_t tim:1;
- uint64_t pko:1;
- uint64_t ipd:1;
- uint64_t reserved_8_8:1;
- uint64_t zip:1;
- uint64_t dfa:1;
- uint64_t fpa:1;
- uint64_t key:1;
- uint64_t npi:1;
- uint64_t gmx1:1;
- uint64_t gmx0:1;
- uint64_t mio:1;
- } cn50xx;
-};
-
-union cvmx_pko_command_word0 {
- uint64_t u64;
- struct {
- uint64_t total_bytes:16;
- uint64_t segs:6;
- uint64_t dontfree:1;
- uint64_t ignore_i:1;
- uint64_t ipoffp1:7;
- uint64_t gather:1;
- uint64_t rsp:1;
- uint64_t wqp:1;
- uint64_t n2:1;
- uint64_t le:1;
- uint64_t reg0:11;
- uint64_t subone0:1;
- uint64_t reg1:11;
- uint64_t subone1:1;
- uint64_t size0:2;
- uint64_t size1:2;
- } s;
-};
-
-union cvmx_ciu_timx {
- uint64_t u64;
- struct cvmx_ciu_timx_s {
- uint64_t reserved_37_63:27;
- uint64_t one_shot:1;
- uint64_t len:36;
- } s;
-};
-
-union cvmx_gmxx_rxx_rx_inbnd {
- uint64_t u64;
- struct cvmx_gmxx_rxx_rx_inbnd_s {
- uint64_t status:1;
- uint64_t speed:2;
- uint64_t duplex:1;
- uint64_t reserved_4_63:60;
- } s;
-};
-
-static inline int32_t cvmx_fau_fetch_and_add32(enum cvmx_fau_reg_32 reg,
- int32_t value)
-{
- return value;
-}
-
-static inline void cvmx_fau_atomic_add32(enum cvmx_fau_reg_32 reg,
- int32_t value)
-{ }
-
-static inline void cvmx_fau_atomic_write32(enum cvmx_fau_reg_32 reg,
- int32_t value)
-{ }
-
-static inline uint64_t cvmx_scratch_read64(uint64_t address)
-{
- return 0;
-}
-
-static inline void cvmx_scratch_write64(uint64_t address, uint64_t value)
-{ }
-
-static inline int cvmx_wqe_get_grp(struct cvmx_wqe *work)
-{
- return 0;
-}
-
-static inline void *cvmx_phys_to_ptr(uint64_t physical_address)
-{
- return (void *)(uintptr_t)(physical_address);
-}
-
-static inline uint64_t cvmx_ptr_to_phys(void *ptr)
-{
- return (unsigned long)ptr;
-}
-
-static inline int cvmx_helper_get_interface_num(int ipd_port)
-{
- return ipd_port;
-}
-
-static inline int cvmx_helper_get_interface_index_num(int ipd_port)
-{
- return ipd_port;
-}
-
-static inline void cvmx_fpa_enable(void)
-{ }
-
-static inline uint64_t cvmx_read_csr(uint64_t csr_addr)
-{
- return 0;
-}
-
-static inline void cvmx_write_csr(uint64_t csr_addr, uint64_t val)
-{ }
-
-static inline int cvmx_helper_setup_red(int pass_thresh, int drop_thresh)
-{
- return 0;
-}
-
-static inline void *cvmx_fpa_alloc(uint64_t pool)
-{
- return NULL;
-}
-
-static inline void cvmx_fpa_free(void *ptr, uint64_t pool,
- uint64_t num_cache_lines)
-{ }
-
-static inline int octeon_is_simulation(void)
-{
- return 1;
-}
-
-static inline void cvmx_pip_get_port_status(uint64_t port_num, uint64_t clear,
- cvmx_pip_port_status_t *status)
-{ }
-
-static inline void cvmx_pko_get_port_status(uint64_t port_num, uint64_t clear,
- cvmx_pko_port_status_t *status)
-{ }
-
-static inline cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int
- interface)
-{
- return 0;
-}
-
-static inline union cvmx_helper_link_info cvmx_helper_link_get(int ipd_port)
-{
- union cvmx_helper_link_info ret = { .u64 = 0 };
-
- return ret;
-}
-
-static inline int cvmx_helper_link_set(int ipd_port,
- union cvmx_helper_link_info link_info)
-{
- return 0;
-}
-
-static inline int cvmx_helper_initialize_packet_io_global(void)
-{
- return 0;
-}
-
-static inline int cvmx_helper_get_number_of_interfaces(void)
-{
- return 2;
-}
-
-static inline int cvmx_helper_ports_on_interface(int interface)
-{
- return 1;
-}
-
-static inline int cvmx_helper_get_ipd_port(int interface, int port)
-{
- return 0;
-}
-
-static inline int cvmx_helper_ipd_and_packet_input_enable(void)
-{
- return 0;
-}
-
-static inline void cvmx_ipd_disable(void)
-{ }
-
-static inline void cvmx_ipd_free_ptr(void)
-{ }
-
-static inline void cvmx_pko_disable(void)
-{ }
-
-static inline void cvmx_pko_shutdown(void)
-{ }
-
-static inline int cvmx_pko_get_base_queue_per_core(int port, int core)
-{
- return port;
-}
-
-static inline int cvmx_pko_get_base_queue(int port)
-{
- return port;
-}
-
-static inline int cvmx_pko_get_num_queues(int port)
-{
- return port;
-}
-
-static inline unsigned int cvmx_get_core_num(void)
-{
- return 0;
-}
-
-static inline void cvmx_pow_work_request_async_nocheck(int scr_addr,
- cvmx_pow_wait_t wait)
-{ }
-
-static inline void cvmx_pow_work_request_async(int scr_addr,
- cvmx_pow_wait_t wait)
-{ }
-
-static inline struct cvmx_wqe *cvmx_pow_work_response_async(int scr_addr)
-{
- struct cvmx_wqe *wqe = (void *)(unsigned long)scr_addr;
-
- return wqe;
-}
-
-static inline struct cvmx_wqe *cvmx_pow_work_request_sync(cvmx_pow_wait_t wait)
-{
- return (void *)(unsigned long)wait;
-}
-
-static inline int cvmx_spi_restart_interface(int interface,
- cvmx_spi_mode_t mode, int timeout)
-{
- return 0;
-}
-
-static inline void cvmx_fau_async_fetch_and_add32(uint64_t scraddr,
- enum cvmx_fau_reg_32 reg,
- int32_t value)
-{ }
-
-static inline union cvmx_gmxx_rxx_rx_inbnd cvmx_spi4000_check_speed(
- int interface,
- int port)
-{
- union cvmx_gmxx_rxx_rx_inbnd r;
-
- r.u64 = 0;
- return r;
-}
-
-static inline void cvmx_pko_send_packet_prepare(uint64_t port, uint64_t queue,
- cvmx_pko_lock_t use_locking)
-{ }
-
-static inline cvmx_pko_status_t cvmx_pko_send_packet_finish(uint64_t port,
- uint64_t queue, union cvmx_pko_command_word0 pko_command,
- union cvmx_buf_ptr packet, cvmx_pko_lock_t use_locking)
-{
- return 0;
-}
-
-static inline void cvmx_wqe_set_port(struct cvmx_wqe *work, int port)
-{ }
-
-static inline void cvmx_wqe_set_qos(struct cvmx_wqe *work, int qos)
-{ }
-
-static inline int cvmx_wqe_get_qos(struct cvmx_wqe *work)
-{
- return 0;
-}
-
-static inline void cvmx_wqe_set_grp(struct cvmx_wqe *work, int grp)
-{ }
-
-static inline void cvmx_pow_work_submit(struct cvmx_wqe *wqp, uint32_t tag,
- enum cvmx_pow_tag_type tag_type,
- uint64_t qos, uint64_t grp)
-{ }
-
-#define CVMX_ASXX_RX_CLK_SETX(a, b) ((a)+(b))
-#define CVMX_ASXX_TX_CLK_SETX(a, b) ((a)+(b))
-#define CVMX_CIU_TIMX(a) (a)
-#define CVMX_GMXX_RXX_ADR_CAM0(a, b) ((a)+(b))
-#define CVMX_GMXX_RXX_ADR_CAM1(a, b) ((a)+(b))
-#define CVMX_GMXX_RXX_ADR_CAM2(a, b) ((a)+(b))
-#define CVMX_GMXX_RXX_ADR_CAM3(a, b) ((a)+(b))
-#define CVMX_GMXX_RXX_ADR_CAM4(a, b) ((a)+(b))
-#define CVMX_GMXX_RXX_ADR_CAM5(a, b) ((a)+(b))
-#define CVMX_GMXX_RXX_FRM_CTL(a, b) ((a)+(b))
-#define CVMX_GMXX_RXX_INT_REG(a, b) ((a)+(b))
-#define CVMX_GMXX_SMACX(a, b) ((a)+(b))
-#define CVMX_PIP_PRT_TAGX(a) (a)
-#define CVMX_POW_PP_GRP_MSKX(a) (a)
-#define CVMX_POW_WQ_INT_THRX(a) (a)
-#define CVMX_SPXX_INT_MSK(a) (a)
-#define CVMX_SPXX_INT_REG(a) (a)
-#define CVMX_SSO_PPX_GRP_MSK(a) (a)
-#define CVMX_SSO_WQ_INT_THRX(a) (a)
-#define CVMX_STXX_INT_MSK(a) (a)
-#define CVMX_STXX_INT_REG(a) (a)
diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h
index 6ec7e3ce3863..4bc5d5fce9bf 100644
--- a/drivers/staging/qlge/qlge.h
+++ b/drivers/staging/qlge/qlge.h
@@ -63,7 +63,6 @@
#define UDELAY_COUNT 3
#define UDELAY_DELAY 100
-
#define TX_DESC_PER_IOCB 8
#if ((MAX_SKB_FRAGS - TX_DESC_PER_IOCB) + 2) > 0
@@ -1627,18 +1626,18 @@ enum {
#define MPI_COREDUMP_COOKIE 0x5555aaaa
struct mpi_coredump_global_header {
u32 cookie;
- u8 idString[16];
- u32 timeLo;
- u32 timeHi;
- u32 imageSize;
- u32 headerSize;
+ u8 id_string[16];
+ u32 time_lo;
+ u32 time_hi;
+ u32 image_size;
+ u32 header_size;
u8 info[220];
};
struct mpi_coredump_segment_header {
u32 cookie;
- u32 segNum;
- u32 segSize;
+ u32 seg_num;
+ u32 seg_size;
u32 extra;
u8 description[16];
};
diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c
index 83f34ca43aa4..8cf39615c520 100644
--- a/drivers/staging/qlge/qlge_dbg.c
+++ b/drivers/staging/qlge/qlge_dbg.c
@@ -142,10 +142,10 @@ static int ql_get_serdes_regs(struct ql_adapter *qdev,
u32 *direct_ptr, temp;
u32 *indirect_ptr;
-
/* The XAUI needs to be read out per port */
status = ql_read_other_func_serdes_reg(qdev,
- XG_SERDES_XAUI_HSS_PCS_START, &temp);
+ XG_SERDES_XAUI_HSS_PCS_START,
+ &temp);
if (status)
temp = XG_SERDES_ADDR_XAUI_PWR_DOWN;
@@ -297,7 +297,6 @@ static int ql_get_serdes_regs(struct ql_adapter *qdev,
ql_get_both_serdes(qdev, i, direct_ptr, indirect_ptr,
xfi_direct_valid, xfi_indirect_valid);
-
/* Get XAUI_XFI_HSS_PLL register block. */
if (qdev->func & 1) {
direct_ptr =
@@ -482,7 +481,8 @@ static int ql_get_mpi_shadow_regs(struct ql_adapter *qdev, u32 *buf)
int status;
for (i = 0; i < MPI_CORE_SH_REGS_CNT; i++, buf++) {
- status = ql_write_mpi_reg(qdev, RISC_124,
+ status = ql_write_mpi_reg(qdev,
+ RISC_124,
(SHADOW_OFFSET | i << SHADOW_REG_SHIFT));
if (status)
goto end;
@@ -702,8 +702,8 @@ static void ql_build_coredump_seg_header(
{
memset(seg_hdr, 0, sizeof(struct mpi_coredump_segment_header));
seg_hdr->cookie = MPI_COREDUMP_COOKIE;
- seg_hdr->segNum = seg_number;
- seg_hdr->segSize = seg_size;
+ seg_hdr->seg_num = seg_number;
+ seg_hdr->seg_size = seg_size;
strncpy(seg_hdr->description, desc, (sizeof(seg_hdr->description)) - 1);
}
@@ -741,12 +741,12 @@ int ql_core_dump(struct ql_adapter *qdev, struct ql_mpi_coredump *mpi_coredump)
memset(&(mpi_coredump->mpi_global_header), 0,
sizeof(struct mpi_coredump_global_header));
mpi_coredump->mpi_global_header.cookie = MPI_COREDUMP_COOKIE;
- mpi_coredump->mpi_global_header.headerSize =
+ mpi_coredump->mpi_global_header.header_size =
sizeof(struct mpi_coredump_global_header);
- mpi_coredump->mpi_global_header.imageSize =
+ mpi_coredump->mpi_global_header.image_size =
sizeof(struct ql_mpi_coredump);
- strncpy(mpi_coredump->mpi_global_header.idString, "MPI Coredump",
- sizeof(mpi_coredump->mpi_global_header.idString));
+ strncpy(mpi_coredump->mpi_global_header.id_string, "MPI Coredump",
+ sizeof(mpi_coredump->mpi_global_header.id_string));
/* Get generic NIC reg dump */
ql_build_coredump_seg_header(&mpi_coredump->nic_regs_seg_hdr,
@@ -1108,7 +1108,7 @@ int ql_core_dump(struct ql_adapter *qdev, struct ql_mpi_coredump *mpi_coredump)
+ sizeof(mpi_coredump->nic_routing_words),
"Routing Words");
status = ql_get_routing_entries(qdev,
- &mpi_coredump->nic_routing_words[0]);
+ &mpi_coredump->nic_routing_words[0]);
if (status)
goto err;
@@ -1227,17 +1227,15 @@ static void ql_gen_reg_dump(struct ql_adapter *qdev,
{
int i, status;
-
memset(&(mpi_coredump->mpi_global_header), 0,
sizeof(struct mpi_coredump_global_header));
mpi_coredump->mpi_global_header.cookie = MPI_COREDUMP_COOKIE;
- mpi_coredump->mpi_global_header.headerSize =
+ mpi_coredump->mpi_global_header.header_size =
sizeof(struct mpi_coredump_global_header);
- mpi_coredump->mpi_global_header.imageSize =
+ mpi_coredump->mpi_global_header.image_size =
sizeof(struct ql_reg_dump);
- strncpy(mpi_coredump->mpi_global_header.idString, "MPI Coredump",
- sizeof(mpi_coredump->mpi_global_header.idString));
-
+ strncpy(mpi_coredump->mpi_global_header.id_string, "MPI Coredump",
+ sizeof(mpi_coredump->mpi_global_header.id_string));
/* segment 16 */
ql_build_coredump_seg_header(&mpi_coredump->misc_nic_seg_hdr,
diff --git a/drivers/staging/qlge/qlge_ethtool.c b/drivers/staging/qlge/qlge_ethtool.c
index 56d116d79e56..790997aff995 100644
--- a/drivers/staging/qlge/qlge_ethtool.c
+++ b/drivers/staging/qlge/qlge_ethtool.c
@@ -32,7 +32,6 @@
#include <linux/mm.h>
#include <linux/vmalloc.h>
-
#include "qlge.h"
struct ql_stats {
@@ -197,8 +196,7 @@ static int ql_update_ring_coalescing(struct ql_adapter *qdev)
*/
cqicb = (struct cqicb *)&qdev->rx_ring[qdev->rss_ring_count];
if (le16_to_cpu(cqicb->irq_delay) != qdev->tx_coalesce_usecs ||
- le16_to_cpu(cqicb->pkt_delay) !=
- qdev->tx_max_coalesced_frames) {
+ le16_to_cpu(cqicb->pkt_delay) != qdev->tx_max_coalesced_frames) {
for (i = qdev->rss_ring_count; i < qdev->rx_ring_count; i++) {
rx_ring = &qdev->rx_ring[i];
cqicb = (struct cqicb *)rx_ring;
@@ -207,7 +205,7 @@ static int ql_update_ring_coalescing(struct ql_adapter *qdev)
cpu_to_le16(qdev->tx_max_coalesced_frames);
cqicb->flags = FLAGS_LI;
status = ql_write_cfg(qdev, cqicb, sizeof(*cqicb),
- CFG_LCQ, rx_ring->cq_id);
+ CFG_LCQ, rx_ring->cq_id);
if (status) {
netif_err(qdev, ifup, qdev->ndev,
"Failed to load CQICB.\n");
@@ -219,8 +217,7 @@ static int ql_update_ring_coalescing(struct ql_adapter *qdev)
/* Update the inbound (RSS) handler queues if they changed. */
cqicb = (struct cqicb *)&qdev->rx_ring[0];
if (le16_to_cpu(cqicb->irq_delay) != qdev->rx_coalesce_usecs ||
- le16_to_cpu(cqicb->pkt_delay) !=
- qdev->rx_max_coalesced_frames) {
+ le16_to_cpu(cqicb->pkt_delay) != qdev->rx_max_coalesced_frames) {
for (i = 0; i < qdev->rss_ring_count; i++, rx_ring++) {
rx_ring = &qdev->rx_ring[i];
cqicb = (struct cqicb *)rx_ring;
@@ -229,7 +226,7 @@ static int ql_update_ring_coalescing(struct ql_adapter *qdev)
cpu_to_le16(qdev->rx_max_coalesced_frames);
cqicb->flags = FLAGS_LI;
status = ql_write_cfg(qdev, cqicb, sizeof(*cqicb),
- CFG_LCQ, rx_ring->cq_id);
+ CFG_LCQ, rx_ring->cq_id);
if (status) {
netif_err(qdev, ifup, qdev->ndev,
"Failed to load CQICB.\n");
@@ -332,6 +329,7 @@ quit:
static void ql_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
{
int index;
+
switch (stringset) {
case ETH_SS_TEST:
memcpy(buf, *ql_gstrings_test, QLGE_TEST_LEN * ETH_GSTRING_LEN);
@@ -339,8 +337,8 @@ static void ql_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
case ETH_SS_STATS:
for (index = 0; index < QLGE_STATS_LEN; index++) {
memcpy(buf + index * ETH_GSTRING_LEN,
- ql_gstrings_stats[index].stat_string,
- ETH_GSTRING_LEN);
+ ql_gstrings_stats[index].stat_string,
+ ETH_GSTRING_LEN);
}
break;
}
@@ -412,6 +410,7 @@ static void ql_get_drvinfo(struct net_device *ndev,
struct ethtool_drvinfo *drvinfo)
{
struct ql_adapter *qdev = netdev_priv(ndev);
+
strlcpy(drvinfo->driver, qlge_driver_name, sizeof(drvinfo->driver));
strlcpy(drvinfo->version, qlge_driver_version,
sizeof(drvinfo->version));
@@ -431,7 +430,7 @@ static void ql_get_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
/* WOL is only supported for mezz card. */
if (ssys_dev == QLGE_MEZZ_SSYS_ID_068 ||
- ssys_dev == QLGE_MEZZ_SSYS_ID_180) {
+ ssys_dev == QLGE_MEZZ_SSYS_ID_180) {
wol->supported = WAKE_MAGIC;
wol->wolopts = qdev->wol;
}
@@ -444,9 +443,9 @@ static int ql_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
/* WOL is only supported for mezz card. */
if (ssys_dev != QLGE_MEZZ_SSYS_ID_068 &&
- ssys_dev != QLGE_MEZZ_SSYS_ID_180) {
+ ssys_dev != QLGE_MEZZ_SSYS_ID_180) {
netif_info(qdev, drv, qdev->ndev,
- "WOL is only supported for mezz card\n");
+ "WOL is only supported for mezz card\n");
return -EOPNOTSUPP;
}
if (wol->wolopts & ~WAKE_MAGIC)
@@ -506,7 +505,7 @@ static void ql_stop_loopback(struct ql_adapter *qdev)
}
static void ql_create_lb_frame(struct sk_buff *skb,
- unsigned int frame_size)
+ unsigned int frame_size)
{
memset(skb->data, 0xFF, frame_size);
frame_size &= ~1;
@@ -516,13 +515,13 @@ static void ql_create_lb_frame(struct sk_buff *skb,
}
void ql_check_lb_frame(struct ql_adapter *qdev,
- struct sk_buff *skb)
+ struct sk_buff *skb)
{
unsigned int frame_size = skb->len;
if ((*(skb->data + 3) == 0xFF) &&
- (*(skb->data + frame_size / 2 + 10) == 0xBE) &&
- (*(skb->data + frame_size / 2 + 12) == 0xAF)) {
+ (*(skb->data + frame_size / 2 + 10) == 0xBE) &&
+ (*(skb->data + frame_size / 2 + 12) == 0xAF)) {
atomic_dec(&qdev->lb_count);
return;
}
@@ -566,7 +565,7 @@ out:
}
static void ql_self_test(struct net_device *ndev,
- struct ethtool_test *eth_test, u64 *data)
+ struct ethtool_test *eth_test, u64 *data)
{
struct ql_adapter *qdev = netdev_priv(ndev);
@@ -672,7 +671,7 @@ static int ql_set_coalesce(struct net_device *ndev, struct ethtool_coalesce *c)
}
static void ql_get_pauseparam(struct net_device *netdev,
- struct ethtool_pauseparam *pause)
+ struct ethtool_pauseparam *pause)
{
struct ql_adapter *qdev = netdev_priv(netdev);
@@ -684,7 +683,7 @@ static void ql_get_pauseparam(struct net_device *netdev,
}
static int ql_set_pauseparam(struct net_device *netdev,
- struct ethtool_pauseparam *pause)
+ struct ethtool_pauseparam *pause)
{
struct ql_adapter *qdev = netdev_priv(netdev);
int status = 0;
@@ -703,12 +702,14 @@ static int ql_set_pauseparam(struct net_device *netdev,
static u32 ql_get_msglevel(struct net_device *ndev)
{
struct ql_adapter *qdev = netdev_priv(ndev);
+
return qdev->msg_enable;
}
static void ql_set_msglevel(struct net_device *ndev, u32 value)
{
struct ql_adapter *qdev = netdev_priv(ndev);
+
qdev->msg_enable = value;
}
diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c
index 24d20f000435..fd3b9f6d7dce 100644
--- a/drivers/staging/qlge/qlge_main.c
+++ b/drivers/staging/qlge/qlge_main.c
@@ -77,14 +77,12 @@ MODULE_PARM_DESC(qlge_irq_type, "0 = MSI-X, 1 = MSI, 2 = Legacy.");
static int qlge_mpi_coredump;
module_param(qlge_mpi_coredump, int, 0);
MODULE_PARM_DESC(qlge_mpi_coredump,
- "Option to enable MPI firmware dump. "
- "Default is OFF - Do Not allocate memory. ");
+ "Option to enable MPI firmware dump. Default is OFF - Do Not allocate memory. ");
static int qlge_force_coredump;
module_param(qlge_force_coredump, int, 0);
MODULE_PARM_DESC(qlge_force_coredump,
- "Option to allow force of firmware core dump. "
- "Default is OFF - Do not allow.");
+ "Option to allow force of firmware core dump. Default is OFF - Do not allow.");
static const struct pci_device_id qlge_pci_tbl[] = {
{PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, QLGE_DEVICE_ID_8012)},
@@ -178,8 +176,9 @@ int ql_wait_reg_rdy(struct ql_adapter *qdev, u32 reg, u32 bit, u32 err_bit)
"register 0x%.08x access error, value = 0x%.08x!.\n",
reg, temp);
return -EIO;
- } else if (temp & bit)
+ } else if (temp & bit) {
return 0;
+ }
udelay(UDELAY_DELAY);
}
netif_alert(qdev, probe, qdev->ndev,
@@ -206,7 +205,6 @@ static int ql_wait_cfg(struct ql_adapter *qdev, u32 bit)
return -ETIMEDOUT;
}
-
/* Used to issue init control blocks to hw. Maps control block,
* sets address, triggers download, waits for completion.
*/
@@ -270,36 +268,34 @@ int ql_get_mac_addr_reg(struct ql_adapter *qdev, u32 type, u16 index,
{
status =
ql_wait_reg_rdy(qdev,
- MAC_ADDR_IDX, MAC_ADDR_MW, 0);
+ MAC_ADDR_IDX, MAC_ADDR_MW, 0);
if (status)
goto exit;
ql_write32(qdev, MAC_ADDR_IDX, (offset++) | /* offset */
(index << MAC_ADDR_IDX_SHIFT) | /* index */
MAC_ADDR_ADR | MAC_ADDR_RS | type); /* type */
status =
- ql_wait_reg_rdy(qdev,
- MAC_ADDR_IDX, MAC_ADDR_MR, 0);
+ ql_wait_reg_rdy(qdev, MAC_ADDR_IDX, MAC_ADDR_MR, 0);
if (status)
goto exit;
*value++ = ql_read32(qdev, MAC_ADDR_DATA);
status =
- ql_wait_reg_rdy(qdev,
- MAC_ADDR_IDX, MAC_ADDR_MW, 0);
+ ql_wait_reg_rdy(qdev, MAC_ADDR_IDX, MAC_ADDR_MW, 0);
if (status)
goto exit;
ql_write32(qdev, MAC_ADDR_IDX, (offset++) | /* offset */
(index << MAC_ADDR_IDX_SHIFT) | /* index */
MAC_ADDR_ADR | MAC_ADDR_RS | type); /* type */
status =
- ql_wait_reg_rdy(qdev,
- MAC_ADDR_IDX, MAC_ADDR_MR, 0);
+ ql_wait_reg_rdy(qdev, MAC_ADDR_IDX, MAC_ADDR_MR, 0);
if (status)
goto exit;
*value++ = ql_read32(qdev, MAC_ADDR_DATA);
if (type == MAC_ADDR_TYPE_CAM_MAC) {
status =
ql_wait_reg_rdy(qdev,
- MAC_ADDR_IDX, MAC_ADDR_MW, 0);
+ MAC_ADDR_IDX, MAC_ADDR_MW,
+ 0);
if (status)
goto exit;
ql_write32(qdev, MAC_ADDR_IDX, (offset++) | /* offset */
@@ -343,7 +339,7 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type,
status =
ql_wait_reg_rdy(qdev,
- MAC_ADDR_IDX, MAC_ADDR_MW, 0);
+ MAC_ADDR_IDX, MAC_ADDR_MW, 0);
if (status)
goto exit;
ql_write32(qdev, MAC_ADDR_IDX, (offset++) |
@@ -352,7 +348,7 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type,
ql_write32(qdev, MAC_ADDR_DATA, lower);
status =
ql_wait_reg_rdy(qdev,
- MAC_ADDR_IDX, MAC_ADDR_MW, 0);
+ MAC_ADDR_IDX, MAC_ADDR_MW, 0);
if (status)
goto exit;
ql_write32(qdev, MAC_ADDR_IDX, (offset++) |
@@ -362,7 +358,7 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type,
ql_write32(qdev, MAC_ADDR_DATA, upper);
status =
ql_wait_reg_rdy(qdev,
- MAC_ADDR_IDX, MAC_ADDR_MW, 0);
+ MAC_ADDR_IDX, MAC_ADDR_MW, 0);
if (status)
goto exit;
break;
@@ -375,8 +371,7 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type,
(addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) |
(addr[5]);
status =
- ql_wait_reg_rdy(qdev,
- MAC_ADDR_IDX, MAC_ADDR_MW, 0);
+ ql_wait_reg_rdy(qdev, MAC_ADDR_IDX, MAC_ADDR_MW, 0);
if (status)
goto exit;
ql_write32(qdev, MAC_ADDR_IDX, (offset++) | /* offset */
@@ -384,8 +379,7 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type,
type); /* type */
ql_write32(qdev, MAC_ADDR_DATA, lower);
status =
- ql_wait_reg_rdy(qdev,
- MAC_ADDR_IDX, MAC_ADDR_MW, 0);
+ ql_wait_reg_rdy(qdev, MAC_ADDR_IDX, MAC_ADDR_MW, 0);
if (status)
goto exit;
ql_write32(qdev, MAC_ADDR_IDX, (offset++) | /* offset */
@@ -393,16 +387,15 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type,
type); /* type */
ql_write32(qdev, MAC_ADDR_DATA, upper);
status =
- ql_wait_reg_rdy(qdev,
- MAC_ADDR_IDX, MAC_ADDR_MW, 0);
+ ql_wait_reg_rdy(qdev, MAC_ADDR_IDX, MAC_ADDR_MW, 0);
if (status)
goto exit;
ql_write32(qdev, MAC_ADDR_IDX, (offset) | /* offset */
(index << MAC_ADDR_IDX_SHIFT) | /* index */
type); /* type */
/* This field should also include the queue id
- and possibly the function id. Right now we hardcode
- the route field to NIC core.
+ * and possibly the function id. Right now we hardcode
+ * the route field to NIC core.
*/
cam_output = (CAM_OUT_ROUTE_NIC |
(qdev->
@@ -423,8 +416,7 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type,
* That's bit-27 we're talking about.
*/
status =
- ql_wait_reg_rdy(qdev,
- MAC_ADDR_IDX, MAC_ADDR_MW, 0);
+ ql_wait_reg_rdy(qdev, MAC_ADDR_IDX, MAC_ADDR_MW, 0);
if (status)
goto exit;
ql_write32(qdev, MAC_ADDR_IDX, offset | /* offset */
@@ -467,7 +459,8 @@ static int ql_set_mac_addr(struct ql_adapter *qdev, int set)
if (status)
return status;
status = ql_set_mac_addr_reg(qdev, (u8 *) addr,
- MAC_ADDR_TYPE_CAM_MAC, qdev->func * MAX_CQ);
+ MAC_ADDR_TYPE_CAM_MAC,
+ qdev->func * MAX_CQ);
ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
if (status)
netif_err(qdev, ifup, qdev->ndev,
@@ -672,17 +665,17 @@ static int ql_read_flash_word(struct ql_adapter *qdev, int offset, __le32 *data)
int status = 0;
/* wait for reg to come ready */
status = ql_wait_reg_rdy(qdev,
- FLASH_ADDR, FLASH_ADDR_RDY, FLASH_ADDR_ERR);
+ FLASH_ADDR, FLASH_ADDR_RDY, FLASH_ADDR_ERR);
if (status)
goto exit;
/* set up for reg read */
ql_write32(qdev, FLASH_ADDR, FLASH_ADDR_R | offset);
/* wait for reg to come ready */
status = ql_wait_reg_rdy(qdev,
- FLASH_ADDR, FLASH_ADDR_RDY, FLASH_ADDR_ERR);
+ FLASH_ADDR, FLASH_ADDR_RDY, FLASH_ADDR_ERR);
if (status)
goto exit;
- /* This data is stored on flash as an array of
+ /* This data is stored on flash as an array of
* __le32. Since ql_read32() returns cpu endian
* we need to swap it back.
*/
@@ -721,8 +714,9 @@ static int ql_get_8000_flash_params(struct ql_adapter *qdev)
}
status = ql_validate_flash(qdev,
- sizeof(struct flash_params_8000) / sizeof(u16),
- "8000");
+ sizeof(struct flash_params_8000) /
+ sizeof(u16),
+ "8000");
if (status) {
netif_err(qdev, ifup, qdev->ndev, "Invalid flash.\n");
status = -EINVAL;
@@ -734,12 +728,12 @@ static int ql_get_8000_flash_params(struct ql_adapter *qdev)
*/
if (qdev->flash.flash_params_8000.data_type1 == 2)
memcpy(mac_addr,
- qdev->flash.flash_params_8000.mac_addr1,
- qdev->ndev->addr_len);
+ qdev->flash.flash_params_8000.mac_addr1,
+ qdev->ndev->addr_len);
else
memcpy(mac_addr,
- qdev->flash.flash_params_8000.mac_addr,
- qdev->ndev->addr_len);
+ qdev->flash.flash_params_8000.mac_addr,
+ qdev->ndev->addr_len);
if (!is_valid_ether_addr(mac_addr)) {
netif_err(qdev, ifup, qdev->ndev, "Invalid MAC address.\n");
@@ -748,8 +742,8 @@ static int ql_get_8000_flash_params(struct ql_adapter *qdev)
}
memcpy(qdev->ndev->dev_addr,
- mac_addr,
- qdev->ndev->addr_len);
+ mac_addr,
+ qdev->ndev->addr_len);
exit:
ql_sem_unlock(qdev, SEM_FLASH_MASK);
@@ -784,8 +778,9 @@ static int ql_get_8012_flash_params(struct ql_adapter *qdev)
}
status = ql_validate_flash(qdev,
- sizeof(struct flash_params_8012) / sizeof(u16),
- "8012");
+ sizeof(struct flash_params_8012) /
+ sizeof(u16),
+ "8012");
if (status) {
netif_err(qdev, ifup, qdev->ndev, "Invalid flash.\n");
status = -EINVAL;
@@ -798,8 +793,8 @@ static int ql_get_8012_flash_params(struct ql_adapter *qdev)
}
memcpy(qdev->ndev->dev_addr,
- qdev->flash.flash_params_8012.mac_addr,
- qdev->ndev->addr_len);
+ qdev->flash.flash_params_8012.mac_addr,
+ qdev->ndev->addr_len);
exit:
ql_sem_unlock(qdev, SEM_FLASH_MASK);
@@ -815,7 +810,7 @@ static int ql_write_xgmac_reg(struct ql_adapter *qdev, u32 reg, u32 data)
int status;
/* wait for reg to come ready */
status = ql_wait_reg_rdy(qdev,
- XGMAC_ADDR, XGMAC_ADDR_RDY, XGMAC_ADDR_XME);
+ XGMAC_ADDR, XGMAC_ADDR_RDY, XGMAC_ADDR_XME);
if (status)
return status;
/* write the data to the data reg */
@@ -834,14 +829,14 @@ int ql_read_xgmac_reg(struct ql_adapter *qdev, u32 reg, u32 *data)
int status = 0;
/* wait for reg to come ready */
status = ql_wait_reg_rdy(qdev,
- XGMAC_ADDR, XGMAC_ADDR_RDY, XGMAC_ADDR_XME);
+ XGMAC_ADDR, XGMAC_ADDR_RDY, XGMAC_ADDR_XME);
if (status)
goto exit;
/* set up for reg read */
ql_write32(qdev, XGMAC_ADDR, reg | XGMAC_ADDR_R);
/* wait for reg to come ready */
status = ql_wait_reg_rdy(qdev,
- XGMAC_ADDR, XGMAC_ADDR_RDY, XGMAC_ADDR_XME);
+ XGMAC_ADDR, XGMAC_ADDR_RDY, XGMAC_ADDR_XME);
if (status)
goto exit;
/* get the data */
@@ -1436,10 +1431,9 @@ static void ql_update_mac_hdr_len(struct ql_adapter *qdev,
/* Process an inbound completion from an rx ring. */
static void ql_process_mac_rx_gro_page(struct ql_adapter *qdev,
- struct rx_ring *rx_ring,
- struct ib_mac_iocb_rsp *ib_mac_rsp,
- u32 length,
- u16 vlan_id)
+ struct rx_ring *rx_ring,
+ struct ib_mac_iocb_rsp *ib_mac_rsp,
+ u32 length, u16 vlan_id)
{
struct sk_buff *skb;
struct qlge_bq_desc *lbq_desc = ql_get_curr_lchunk(qdev, rx_ring);
@@ -1483,10 +1477,9 @@ static void ql_process_mac_rx_gro_page(struct ql_adapter *qdev,
/* Process an inbound completion from an rx ring. */
static void ql_process_mac_rx_page(struct ql_adapter *qdev,
- struct rx_ring *rx_ring,
- struct ib_mac_iocb_rsp *ib_mac_rsp,
- u32 length,
- u16 vlan_id)
+ struct rx_ring *rx_ring,
+ struct ib_mac_iocb_rsp *ib_mac_rsp,
+ u32 length, u16 vlan_id)
{
struct net_device *ndev = qdev->ndev;
struct sk_buff *skb = NULL;
@@ -1528,8 +1521,7 @@ static void ql_process_mac_rx_page(struct ql_adapter *qdev,
"%d bytes of headers and data in large. Chain page to new skb and pull tail.\n",
length);
skb_fill_page_desc(skb, 0, lbq_desc->p.pg_chunk.page,
- lbq_desc->p.pg_chunk.offset + hlen,
- length - hlen);
+ lbq_desc->p.pg_chunk.offset + hlen, length - hlen);
skb->len += length - hlen;
skb->data_len += length - hlen;
skb->truesize += length - hlen;
@@ -1540,7 +1532,7 @@ static void ql_process_mac_rx_page(struct ql_adapter *qdev,
skb_checksum_none_assert(skb);
if ((ndev->features & NETIF_F_RXCSUM) &&
- !(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) {
+ !(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) {
/* TCP frame. */
if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) {
netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
@@ -1576,10 +1568,9 @@ err_out:
/* Process an inbound completion from an rx ring. */
static void ql_process_mac_rx_skb(struct ql_adapter *qdev,
- struct rx_ring *rx_ring,
- struct ib_mac_iocb_rsp *ib_mac_rsp,
- u32 length,
- u16 vlan_id)
+ struct rx_ring *rx_ring,
+ struct ib_mac_iocb_rsp *ib_mac_rsp,
+ u32 length, u16 vlan_id)
{
struct qlge_bq_desc *sbq_desc = qlge_get_curr_buf(&rx_ring->sbq);
struct net_device *ndev = qdev->ndev;
@@ -1648,7 +1639,7 @@ static void ql_process_mac_rx_skb(struct ql_adapter *qdev,
* csum or frame errors.
*/
if ((ndev->features & NETIF_F_RXCSUM) &&
- !(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) {
+ !(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) {
/* TCP frame. */
if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) {
netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
@@ -1779,8 +1770,7 @@ static struct sk_buff *ql_build_rx_skb(struct ql_adapter *qdev,
"Chaining page at offset = %d, for %d bytes to skb.\n",
lbq_desc->p.pg_chunk.offset, length);
skb_fill_page_desc(skb, 0, lbq_desc->p.pg_chunk.page,
- lbq_desc->p.pg_chunk.offset,
- length);
+ lbq_desc->p.pg_chunk.offset, length);
skb->len += length;
skb->data_len += length;
skb->truesize += length;
@@ -1804,10 +1794,9 @@ static struct sk_buff *ql_build_rx_skb(struct ql_adapter *qdev,
netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
"%d bytes of headers and data in large. Chain page to new skb and pull tail.\n",
length);
- skb_fill_page_desc(skb, 0,
- lbq_desc->p.pg_chunk.page,
- lbq_desc->p.pg_chunk.offset,
- length);
+ skb_fill_page_desc(skb, 0, lbq_desc->p.pg_chunk.page,
+ lbq_desc->p.pg_chunk.offset,
+ length);
skb->len += length;
skb->data_len += length;
skb->truesize += length;
@@ -1857,9 +1846,8 @@ static struct sk_buff *ql_build_rx_skb(struct ql_adapter *qdev,
"Adding page %d to skb for %d bytes.\n",
i, size);
skb_fill_page_desc(skb, i,
- lbq_desc->p.pg_chunk.page,
- lbq_desc->p.pg_chunk.offset,
- size);
+ lbq_desc->p.pg_chunk.page,
+ lbq_desc->p.pg_chunk.offset, size);
skb->len += size;
skb->data_len += size;
skb->truesize += size;
@@ -1875,9 +1863,9 @@ static struct sk_buff *ql_build_rx_skb(struct ql_adapter *qdev,
/* Process an inbound completion from an rx ring. */
static void ql_process_mac_split_rx_intr(struct ql_adapter *qdev,
- struct rx_ring *rx_ring,
- struct ib_mac_iocb_rsp *ib_mac_rsp,
- u16 vlan_id)
+ struct rx_ring *rx_ring,
+ struct ib_mac_iocb_rsp *ib_mac_rsp,
+ u16 vlan_id)
{
struct net_device *ndev = qdev->ndev;
struct sk_buff *skb = NULL;
@@ -1938,7 +1926,7 @@ static void ql_process_mac_split_rx_intr(struct ql_adapter *qdev,
* csum or frame errors.
*/
if ((ndev->features & NETIF_F_RXCSUM) &&
- !(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) {
+ !(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) {
/* TCP frame. */
if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) {
netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
@@ -1970,8 +1958,8 @@ static void ql_process_mac_split_rx_intr(struct ql_adapter *qdev,
/* Process an inbound completion from an rx ring. */
static unsigned long ql_process_mac_rx_intr(struct ql_adapter *qdev,
- struct rx_ring *rx_ring,
- struct ib_mac_iocb_rsp *ib_mac_rsp)
+ struct rx_ring *rx_ring,
+ struct ib_mac_iocb_rsp *ib_mac_rsp)
{
u32 length = le32_to_cpu(ib_mac_rsp->data_len);
u16 vlan_id = ((ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_V) &&
@@ -1986,34 +1974,34 @@ static unsigned long ql_process_mac_rx_intr(struct ql_adapter *qdev,
* separate buffers.
*/
ql_process_mac_split_rx_intr(qdev, rx_ring, ib_mac_rsp,
- vlan_id);
+ vlan_id);
} else if (ib_mac_rsp->flags3 & IB_MAC_IOCB_RSP_DS) {
/* The data fit in a single small buffer.
* Allocate a new skb, copy the data and
* return the buffer to the free pool.
*/
- ql_process_mac_rx_skb(qdev, rx_ring, ib_mac_rsp,
- length, vlan_id);
+ ql_process_mac_rx_skb(qdev, rx_ring, ib_mac_rsp, length,
+ vlan_id);
} else if ((ib_mac_rsp->flags3 & IB_MAC_IOCB_RSP_DL) &&
!(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK) &&
(ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T)) {
/* TCP packet in a page chunk that's been checksummed.
* Tack it on to our GRO skb and let it go.
*/
- ql_process_mac_rx_gro_page(qdev, rx_ring, ib_mac_rsp,
- length, vlan_id);
+ ql_process_mac_rx_gro_page(qdev, rx_ring, ib_mac_rsp, length,
+ vlan_id);
} else if (ib_mac_rsp->flags3 & IB_MAC_IOCB_RSP_DL) {
/* Non-TCP packet in a page chunk. Allocate an
* skb, tack it on frags, and send it up.
*/
- ql_process_mac_rx_page(qdev, rx_ring, ib_mac_rsp,
- length, vlan_id);
+ ql_process_mac_rx_page(qdev, rx_ring, ib_mac_rsp, length,
+ vlan_id);
} else {
/* Non-TCP/UDP large frames that span multiple buffers
* can be processed corrrectly by the split frame logic.
*/
ql_process_mac_split_rx_intr(qdev, rx_ring, ib_mac_rsp,
- vlan_id);
+ vlan_id);
}
return (unsigned long)length;
@@ -2222,15 +2210,16 @@ static int ql_napi_poll_msix(struct napi_struct *napi, int budget)
"Enter, NAPI POLL cq_id = %d.\n", rx_ring->cq_id);
/* Service the TX rings first. They start
- * right after the RSS rings. */
+ * right after the RSS rings.
+ */
for (i = qdev->rss_ring_count; i < qdev->rx_ring_count; i++) {
trx_ring = &qdev->rx_ring[i];
/* If this TX completion ring belongs to this vector and
* it's not empty then service it.
*/
if ((ctx->irq_mask & (1 << trx_ring->cq_id)) &&
- (ql_read_sh_reg(trx_ring->prod_idx_sh_reg) !=
- trx_ring->cnsmr_idx)) {
+ (ql_read_sh_reg(trx_ring->prod_idx_sh_reg) !=
+ trx_ring->cnsmr_idx)) {
netif_printk(qdev, intr, KERN_DEBUG, qdev->ndev,
"%s: Servicing TX completion ring %d.\n",
__func__, trx_ring->cq_id);
@@ -2304,7 +2293,7 @@ static int qlge_update_hw_vlan_features(struct net_device *ndev,
}
static int qlge_set_features(struct net_device *ndev,
- netdev_features_t features)
+ netdev_features_t features)
{
netdev_features_t changed = ndev->features ^ features;
int err;
@@ -2447,7 +2436,7 @@ static irqreturn_t qlge_isr(int irq, void *dev_id)
* Check MPI processor activity.
*/
if ((var & STS_PI) &&
- (ql_read32(qdev, INTR_MASK) & INTR_MASK_PI)) {
+ (ql_read32(qdev, INTR_MASK) & INTR_MASK_PI)) {
/*
* We've got an async event or mailbox completion.
* Handle it and clear the source of the interrupt.
@@ -2456,7 +2445,7 @@ static irqreturn_t qlge_isr(int irq, void *dev_id)
"Got MPI processor interrupt.\n");
ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
queue_delayed_work_on(smp_processor_id(),
- qdev->workqueue, &qdev->mpi_work, 0);
+ qdev->workqueue, &qdev->mpi_work, 0);
work_done++;
}
@@ -2639,7 +2628,6 @@ static netdev_tx_t qlge_send(struct sk_buff *skb, struct net_device *ndev)
return NETDEV_TX_OK;
}
-
static void ql_free_shadow_space(struct ql_adapter *qdev)
{
if (qdev->rx_ring_shadow_reg_area) {
@@ -2887,7 +2875,8 @@ static void ql_free_rx_resources(struct ql_adapter *qdev,
}
/* Allocate queues and buffers for this completions queue based
- * on the values in the parameter structure. */
+ * on the values in the parameter structure.
+ */
static int ql_alloc_rx_resources(struct ql_adapter *qdev,
struct rx_ring *rx_ring)
{
@@ -3530,19 +3519,17 @@ static int ql_route_initialize(struct ql_adapter *qdev)
return status;
status = ql_set_routing_reg(qdev, RT_IDX_IP_CSUM_ERR_SLOT,
- RT_IDX_IP_CSUM_ERR, 1);
+ RT_IDX_IP_CSUM_ERR, 1);
if (status) {
netif_err(qdev, ifup, qdev->ndev,
- "Failed to init routing register "
- "for IP CSUM error packets.\n");
+ "Failed to init routing register for IP CSUM error packets.\n");
goto exit;
}
status = ql_set_routing_reg(qdev, RT_IDX_TCP_UDP_CSUM_ERR_SLOT,
- RT_IDX_TU_CSUM_ERR, 1);
+ RT_IDX_TU_CSUM_ERR, 1);
if (status) {
netif_err(qdev, ifup, qdev->ndev,
- "Failed to init routing register "
- "for TCP/UDP CSUM error packets.\n");
+ "Failed to init routing register for TCP/UDP CSUM error packets.\n");
goto exit;
}
status = ql_set_routing_reg(qdev, RT_IDX_BCAST_SLOT, RT_IDX_BCAST, 1);
@@ -3556,7 +3543,7 @@ static int ql_route_initialize(struct ql_adapter *qdev)
*/
if (qdev->rss_ring_count > 1) {
status = ql_set_routing_reg(qdev, RT_IDX_RSS_MATCH_SLOT,
- RT_IDX_RSS_MATCH, 1);
+ RT_IDX_RSS_MATCH, 1);
if (status) {
netif_err(qdev, ifup, qdev->ndev,
"Failed to init routing register for MATCH RSS packets.\n");
@@ -3654,7 +3641,7 @@ static int ql_adapter_initialize(struct ql_adapter *qdev)
/* Default WOL is enable on Mezz cards */
if (qdev->pdev->subsystem_device == 0x0068 ||
- qdev->pdev->subsystem_device == 0x0180)
+ qdev->pdev->subsystem_device == 0x0180)
qdev->wol = WAKE_MAGIC;
/* Start up the rx queues. */
@@ -3731,8 +3718,9 @@ static int ql_adapter_reset(struct ql_adapter *qdev)
/* Wait for the NIC and MGMNT FIFOs to empty. */
ql_wait_fifo_empty(qdev);
- } else
+ } else {
clear_bit(QL_ASIC_RECOVERY, &qdev->flags);
+ }
ql_write32(qdev, RST_FO, (RST_FO_FR << 16) | RST_FO_FR);
@@ -3880,7 +3868,7 @@ static int ql_adapter_up(struct ql_adapter *qdev)
* link is up the turn on the carrier.
*/
if ((ql_read32(qdev, STS) & qdev->port_init) &&
- (ql_read32(qdev, STS) & qdev->port_link_up))
+ (ql_read32(qdev, STS) & qdev->port_link_up))
ql_link_on(qdev);
/* Restore rx mode. */
clear_bit(QL_ALLMULTI, &qdev->flags);
@@ -4099,21 +4087,20 @@ static int qlge_change_mtu(struct net_device *ndev, int new_mtu)
struct ql_adapter *qdev = netdev_priv(ndev);
int status;
- if (ndev->mtu == 1500 && new_mtu == 9000) {
+ if (ndev->mtu == 1500 && new_mtu == 9000)
netif_err(qdev, ifup, qdev->ndev, "Changing to jumbo MTU.\n");
- } else if (ndev->mtu == 9000 && new_mtu == 1500) {
+ else if (ndev->mtu == 9000 && new_mtu == 1500)
netif_err(qdev, ifup, qdev->ndev, "Changing to normal MTU.\n");
- } else
+ else
return -EINVAL;
queue_delayed_work(qdev->workqueue,
- &qdev->mpi_port_cfg_work, 3*HZ);
+ &qdev->mpi_port_cfg_work, 3 * HZ);
ndev->mtu = new_mtu;
- if (!netif_running(qdev->ndev)) {
+ if (!netif_running(qdev->ndev))
return 0;
- }
status = ql_change_rx_buffers(qdev);
if (status) {
@@ -4267,7 +4254,8 @@ static int qlge_set_mac_address(struct net_device *ndev, void *p)
if (status)
return status;
status = ql_set_mac_addr_reg(qdev, (u8 *) ndev->dev_addr,
- MAC_ADDR_TYPE_CAM_MAC, qdev->func * MAX_CQ);
+ MAC_ADDR_TYPE_CAM_MAC,
+ qdev->func * MAX_CQ);
if (status)
netif_err(qdev, hw, qdev->ndev, "Failed to load MAC address.\n");
ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
@@ -4334,7 +4322,7 @@ static int ql_get_alt_pcie_func(struct ql_adapter *qdev)
u32 nic_func1, nic_func2;
status = ql_read_mpi_reg(qdev, MPI_TEST_FUNC_PORT_CFG,
- &temp);
+ &temp);
if (status)
return status;
@@ -4578,11 +4566,12 @@ static int qlge_probe(struct pci_dev *pdev,
{
struct net_device *ndev = NULL;
struct ql_adapter *qdev = NULL;
- static int cards_found = 0;
+ static int cards_found;
int err = 0;
ndev = alloc_etherdev_mq(sizeof(struct ql_adapter),
- min(MAX_CPUS, netif_get_num_default_rss_queues()));
+ min(MAX_CPUS,
+ netif_get_num_default_rss_queues()));
if (!ndev)
return -ENOMEM;
diff --git a/drivers/staging/qlge/qlge_mpi.c b/drivers/staging/qlge/qlge_mpi.c
index 9e422bbbb6ab..bb03b2fa7233 100644
--- a/drivers/staging/qlge/qlge_mpi.c
+++ b/drivers/staging/qlge/qlge_mpi.c
@@ -134,7 +134,7 @@ static int ql_get_mb_sts(struct ql_adapter *qdev, struct mbox_params *mbcp)
for (i = 0; i < mbcp->out_count; i++) {
status =
ql_read_mpi_reg(qdev, qdev->mailbox_out + i,
- &mbcp->mbox_out[i]);
+ &mbcp->mbox_out[i]);
if (status) {
netif_err(qdev, drv, qdev->ndev, "Failed mailbox read.\n");
break;
@@ -184,7 +184,7 @@ static int ql_exec_mb_cmd(struct ql_adapter *qdev, struct mbox_params *mbcp)
*/
for (i = 0; i < mbcp->in_count; i++) {
status = ql_write_mpi_reg(qdev, qdev->mailbox_in + i,
- mbcp->mbox_in[i]);
+ mbcp->mbox_in[i]);
if (status)
goto end;
}
@@ -293,7 +293,7 @@ static void ql_link_up(struct ql_adapter *qdev, struct mbox_params *mbcp)
*/
ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
queue_delayed_work(qdev->workqueue,
- &qdev->mpi_port_cfg_work, 0);
+ &qdev->mpi_port_cfg_work, 0);
}
ql_link_on(qdev);
@@ -544,7 +544,6 @@ static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp)
if (status)
goto end;
-
/* If we're generating a system error, then there's nothing
* to wait for.
*/
@@ -730,7 +729,6 @@ int ql_mb_set_port_cfg(struct ql_adapter *qdev)
mbcp->mbox_in[1] = qdev->link_config;
mbcp->mbox_in[2] = qdev->max_frame_size;
-
status = ql_mailbox_command(qdev, mbcp);
if (status)
return status;
@@ -747,7 +745,7 @@ int ql_mb_set_port_cfg(struct ql_adapter *qdev)
}
static int ql_mb_dump_ram(struct ql_adapter *qdev, u64 req_dma, u32 addr,
- u32 size)
+ u32 size)
{
int status = 0;
struct mbox_params mbc;
@@ -768,7 +766,6 @@ static int ql_mb_dump_ram(struct ql_adapter *qdev, u64 req_dma, u32 addr,
mbcp->mbox_in[7] = LSW(MSD(req_dma));
mbcp->mbox_in[8] = MSW(addr);
-
status = ql_mailbox_command(qdev, mbcp);
if (status)
return status;
@@ -782,14 +779,14 @@ static int ql_mb_dump_ram(struct ql_adapter *qdev, u64 req_dma, u32 addr,
/* Issue a mailbox command to dump RISC RAM. */
int ql_dump_risc_ram_area(struct ql_adapter *qdev, void *buf,
- u32 ram_addr, int word_count)
+ u32 ram_addr, int word_count)
{
int status;
char *my_buf;
dma_addr_t buf_dma;
my_buf = pci_alloc_consistent(qdev->pdev, word_count * sizeof(u32),
- &buf_dma);
+ &buf_dma);
if (!my_buf)
return -EIO;
@@ -798,7 +795,7 @@ int ql_dump_risc_ram_area(struct ql_adapter *qdev, void *buf,
memcpy(buf, my_buf, word_count * sizeof(u32));
pci_free_consistent(qdev->pdev, word_count * sizeof(u32), my_buf,
- buf_dma);
+ buf_dma);
return status;
}
@@ -850,7 +847,6 @@ int ql_mb_wol_mode(struct ql_adapter *qdev, u32 wol)
mbcp->mbox_in[0] = MB_CMD_SET_WOL_MODE;
mbcp->mbox_in[1] = wol;
-
status = ql_mailbox_command(qdev, mbcp);
if (status)
return status;
@@ -922,7 +918,7 @@ static int ql_idc_wait(struct ql_adapter *qdev)
*/
wait_time =
wait_for_completion_timeout(&qdev->ide_completion,
- wait_time);
+ wait_time);
if (!wait_time) {
netif_err(qdev, drv, qdev->ndev, "IDC Timeout.\n");
break;
@@ -965,7 +961,6 @@ int ql_mb_set_led_cfg(struct ql_adapter *qdev, u32 led_config)
mbcp->mbox_in[0] = MB_CMD_SET_LED_CFG;
mbcp->mbox_in[1] = led_config;
-
status = ql_mailbox_command(qdev, mbcp);
if (status)
return status;
@@ -1130,8 +1125,7 @@ void ql_mpi_port_cfg_work(struct work_struct *work)
}
if (qdev->link_config & CFG_JUMBO_FRAME_SIZE &&
- qdev->max_frame_size ==
- CFG_DEFAULT_MAX_FRAME_SIZE)
+ qdev->max_frame_size == CFG_DEFAULT_MAX_FRAME_SIZE)
goto end;
qdev->link_config |= CFG_JUMBO_FRAME_SIZE;
@@ -1278,7 +1272,7 @@ void ql_mpi_reset_work(struct work_struct *work)
netif_err(qdev, drv, qdev->ndev, "Core is dumped!\n");
qdev->core_is_dumped = 1;
queue_delayed_work(qdev->workqueue,
- &qdev->mpi_core_to_log, 5 * HZ);
+ &qdev->mpi_core_to_log, 5 * HZ);
}
ql_soft_reset_mpi_risc(qdev);
}
diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
index e984b4605e91..16cb5b31a31d 100644
--- a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
+++ b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
@@ -291,7 +291,7 @@ static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
remain_len = ies_len - (next_ie - ies);
ssid_ie[1] = 0;
- memcpy(ssid_ie+2, next_ie, remain_len);
+ memcpy(ssid_ie + 2, next_ie, remain_len);
len_diff -= ssid_len_ori;
break;
@@ -363,14 +363,14 @@ static void issue_beacon(struct adapter *padapter, int timeout_ms)
memcpy(pframe, cur_network->ies, cur_network->ie_length);
len_diff = update_hidden_ssid(
- pframe+_BEACON_IE_OFFSET_
- , cur_network->ie_length-_BEACON_IE_OFFSET_
+ pframe + _BEACON_IE_OFFSET_
+ , cur_network->ie_length - _BEACON_IE_OFFSET_
, pmlmeinfo->hidden_ssid_mode
);
- pframe += (cur_network->ie_length+len_diff);
- pattrib->pktlen += (cur_network->ie_length+len_diff);
- wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr+TXDESC_OFFSET+sizeof(struct ieee80211_hdr_3addr)+_BEACON_IE_OFFSET_,
- pattrib->pktlen-sizeof(struct ieee80211_hdr_3addr)-_BEACON_IE_OFFSET_, NULL, &wps_ielen);
+ pframe += (cur_network->ie_length + len_diff);
+ pattrib->pktlen += (cur_network->ie_length + len_diff);
+ wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr + TXDESC_OFFSET + sizeof(struct ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_,
+ pattrib->pktlen - sizeof(struct ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_, NULL, &wps_ielen);
if (wps_ie && wps_ielen > 0)
rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
if (sr != 0)
@@ -504,7 +504,7 @@ static void issue_probersp(struct adapter *padapter, unsigned char *da)
#if defined(CONFIG_88EU_AP_MODE)
if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
- pwps_ie = rtw_get_wps_ie(cur_network->ies+_FIXED_IE_LENGTH_, cur_network->ie_length-_FIXED_IE_LENGTH_, NULL, &wps_ielen);
+ pwps_ie = rtw_get_wps_ie(cur_network->ies + _FIXED_IE_LENGTH_, cur_network->ie_length - _FIXED_IE_LENGTH_, NULL, &wps_ielen);
/* inerset & update wps_probe_resp_ie */
if (pmlmepriv->wps_probe_resp_ie && pwps_ie && wps_ielen > 0) {
@@ -522,13 +522,13 @@ static void issue_probersp(struct adapter *padapter, unsigned char *da)
pattrib->pktlen += wps_offset;
wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];/* to get ie data len */
- if ((wps_offset+wps_ielen+2) <= MAX_IE_SZ) {
- memcpy(pframe, pmlmepriv->wps_probe_resp_ie, wps_ielen+2);
- pframe += wps_ielen+2;
- pattrib->pktlen += wps_ielen+2;
+ if ((wps_offset + wps_ielen + 2) <= MAX_IE_SZ) {
+ memcpy(pframe, pmlmepriv->wps_probe_resp_ie, wps_ielen + 2);
+ pframe += wps_ielen + 2;
+ pattrib->pktlen += wps_ielen + 2;
}
- if ((wps_offset+wps_ielen+2+remainder_ielen) <= MAX_IE_SZ) {
+ if ((wps_offset + wps_ielen + 2 + remainder_ielen) <= MAX_IE_SZ) {
memcpy(pframe, premainder_ie, remainder_ielen);
pframe += remainder_ielen;
pattrib->pktlen += remainder_ielen;
@@ -751,7 +751,7 @@ static void issue_auth(struct adapter *padapter, struct sta_info *psta,
struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
- if (pmgntframe == NULL)
+ if (!pmgntframe)
return;
/* update attribute */
@@ -943,7 +943,7 @@ static void issue_asocrsp(struct adapter *padapter, unsigned short status,
pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, pstat->bssratelen, pstat->bssrateset, &pattrib->pktlen);
} else {
pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pstat->bssrateset, &pattrib->pktlen);
- pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, pstat->bssratelen-8, pstat->bssrateset+8, &pattrib->pktlen);
+ pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, pstat->bssratelen - 8, pstat->bssrateset + 8, &pattrib->pktlen);
}
if ((pstat->flags & WLAN_STA_HT) && (pmlmepriv->htpriv.ht_option)) {
@@ -952,17 +952,17 @@ static void issue_asocrsp(struct adapter *padapter, unsigned short status,
/* FILL HT CAP INFO IE */
pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pnetwork->ie_length - _BEACON_IE_OFFSET_));
if (pbuf && ie_len > 0) {
- memcpy(pframe, pbuf, ie_len+2);
- pframe += (ie_len+2);
- pattrib->pktlen += (ie_len+2);
+ memcpy(pframe, pbuf, ie_len + 2);
+ pframe += (ie_len + 2);
+ pattrib->pktlen += (ie_len + 2);
}
/* FILL HT ADD INFO IE */
pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pnetwork->ie_length - _BEACON_IE_OFFSET_));
if (pbuf && ie_len > 0) {
- memcpy(pframe, pbuf, ie_len+2);
- pframe += (ie_len+2);
- pattrib->pktlen += (ie_len+2);
+ memcpy(pframe, pbuf, ie_len + 2);
+ pframe += (ie_len + 2);
+ pattrib->pktlen += (ie_len + 2);
}
}
@@ -973,14 +973,14 @@ static void issue_asocrsp(struct adapter *padapter, unsigned short status,
for (pbuf = ie + _BEACON_IE_OFFSET_;; pbuf += (ie_len + 2)) {
pbuf = rtw_get_ie(pbuf, _VENDOR_SPECIFIC_IE_, &ie_len, (pnetwork->ie_length - _BEACON_IE_OFFSET_ - (ie_len + 2)));
- if (pbuf && !memcmp(pbuf+2, WMM_PARA_IE, 6)) {
- memcpy(pframe, pbuf, ie_len+2);
- pframe += (ie_len+2);
- pattrib->pktlen += (ie_len+2);
+ if (pbuf && !memcmp(pbuf + 2, WMM_PARA_IE, 6)) {
+ memcpy(pframe, pbuf, ie_len + 2);
+ pframe += (ie_len + 2);
+ pattrib->pktlen += (ie_len + 2);
break;
}
- if ((pbuf == NULL) || (ie_len == 0))
+ if (!pbuf || ie_len == 0)
break;
}
}
@@ -1082,8 +1082,8 @@ static void issue_assocreq(struct adapter *padapter)
/* Check if the AP's supported rates are also supported by STA. */
for (j = 0; j < sta_bssrate_len; j++) {
/* Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP */
- if ((pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK)
- == (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK))
+ if ((pmlmeinfo->network.SupportedRates[i] | IEEE80211_BASIC_RATE_MASK)
+ == (sta_bssrate[j] | IEEE80211_BASIC_RATE_MASK))
break;
}
@@ -1120,7 +1120,7 @@ static void issue_assocreq(struct adapter *padapter)
/* HT caps */
if (padapter->mlmepriv.htpriv.ht_option) {
p = rtw_get_ie((pmlmeinfo->network.ies + sizeof(struct ndis_802_11_fixed_ie)), _HT_CAPABILITY_IE_, &ie_len, (pmlmeinfo->network.ie_length - sizeof(struct ndis_802_11_fixed_ie)));
- if ((p != NULL) && (!(is_ap_in_tkip(padapter)))) {
+ if (p && !is_ap_in_tkip(padapter)) {
memcpy(&pmlmeinfo->HT_caps, p + 2, sizeof(struct ieee80211_ht_cap));
/* to disable 40M Hz support while gd_bw_40MHz_en = 0 */
@@ -1263,7 +1263,7 @@ int issue_nulldata(struct adapter *padapter, unsigned char *da,
struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
/* da == NULL, assume it's null data for sta to ap*/
- if (da == NULL)
+ if (!da)
da = pnetwork->MacAddress;
do {
@@ -1392,7 +1392,7 @@ int issue_qos_nulldata(struct adapter *padapter, unsigned char *da,
struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
/* da == NULL, assume it's null data for sta to ap*/
- if (da == NULL)
+ if (!da)
da = pnetwork->MacAddress;
do {
@@ -1444,7 +1444,7 @@ static int _issue_deauth(struct adapter *padapter, unsigned char *da,
__le16 le_tmp;
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
- if (pmgntframe == NULL)
+ if (!pmgntframe)
goto exit;
/* update attribute */
@@ -1780,7 +1780,7 @@ static void issue_action_BSSCoexistPacket(struct adapter *padapter)
pbss_network = (struct wlan_bssid_ex *)&pnetwork->network;
p = rtw_get_ie(pbss_network->ies + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pbss_network->ie_length - _FIXED_IE_LENGTH_);
- if ((p == NULL) || (len == 0)) { /* non-HT */
+ if (!p || len == 0) { /* non-HT */
if ((pbss_network->Configuration.DSConfig <= 0) || (pbss_network->Configuration.DSConfig > 14))
continue;
@@ -1833,7 +1833,7 @@ unsigned int send_delba(struct adapter *padapter, u8 initiator, u8 *addr)
return _SUCCESS;
psta = rtw_get_stainfo(pstapriv, addr);
- if (psta == NULL)
+ if (!psta)
return _SUCCESS;
if (initiator == 0) { /* recipient */
@@ -1874,7 +1874,7 @@ unsigned int send_beacon(struct adapter *padapter)
yield();
rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8 *)(&bxmitok));
poll++;
- } while ((poll%10) != 0 && !bxmitok && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);
+ } while ((poll % 10) != 0 && !bxmitok && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);
} while (!bxmitok && issue < 100 && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);
if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
@@ -2082,7 +2082,7 @@ static u8 collect_bss_info(struct adapter *padapter,
/* checking rate info... */
i = 0;
p = rtw_get_ie(bssid->ies + ie_offset, _SUPPORTEDRATES_IE_, &len, bssid->ie_length - ie_offset);
- if (p != NULL) {
+ if (p) {
if (len > NDIS_802_11_LENGTH_RATES_EX) {
DBG_88E("%s()-%d: IE too long (%d) for survey event\n", __func__, __LINE__, len);
return _FAIL;
@@ -2093,7 +2093,7 @@ static u8 collect_bss_info(struct adapter *padapter,
p = rtw_get_ie(bssid->ies + ie_offset, _EXT_SUPPORTEDRATES_IE_, &len, bssid->ie_length - ie_offset);
if (p) {
- if (len > (NDIS_802_11_LENGTH_RATES_EX-i)) {
+ if (len > (NDIS_802_11_LENGTH_RATES_EX - i)) {
DBG_88E("%s()-%d: IE too long (%d) for survey event\n", __func__, __LINE__, len);
return _FAIL;
}
@@ -2518,7 +2518,7 @@ static unsigned int OnProbeReq(struct adapter *padapter,
return _SUCCESS;
if (!check_fwstate(pmlmepriv, _FW_LINKED) &&
- !check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE))
+ !check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE))
return _SUCCESS;
p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, &ielen,
@@ -2526,7 +2526,7 @@ static unsigned int OnProbeReq(struct adapter *padapter,
/* check (wildcard) SSID */
if (p) {
- if ((ielen != 0 && memcmp((void *)(p+2), (void *)cur->ssid.ssid, cur->ssid.ssid_length)) ||
+ if ((ielen != 0 && memcmp((void *)(p + 2), (void *)cur->ssid.ssid, cur->ssid.ssid_length)) ||
(ielen == 0 && pmlmeinfo->hidden_ssid_mode))
return _SUCCESS;
@@ -2583,7 +2583,7 @@ static unsigned int OnBeacon(struct adapter *padapter,
}
/* check the vendor of the assoc AP */
- pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe+sizeof(struct ieee80211_hdr_3addr), len-sizeof(struct ieee80211_hdr_3addr));
+ pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe + sizeof(struct ieee80211_hdr_3addr), len - sizeof(struct ieee80211_hdr_3addr));
/* update TSF Value */
update_TSF(pmlmeext, pframe, len);
@@ -2596,7 +2596,7 @@ static unsigned int OnBeacon(struct adapter *padapter,
if (((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
- if (psta != NULL) {
+ if (psta) {
ret = rtw_check_bcn_info(padapter, pframe, len);
if (!ret) {
DBG_88E_LEVEL(_drv_info_, "ap has changed, disconnect now\n ");
@@ -2610,7 +2610,7 @@ static unsigned int OnBeacon(struct adapter *padapter,
}
} else if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
- if (psta != NULL) {
+ if (psta) {
/* update WMM, ERP in the beacon */
/* todo: the timer is used instead of the number of the beacon received */
if ((sta_rx_pkts(psta) & 0xf) == 0)
@@ -2729,7 +2729,7 @@ static unsigned int OnAuth(struct adapter *padapter,
if ((pstat->auth_seq + 1) != seq) {
DBG_88E("(1)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
- seq, pstat->auth_seq+1);
+ seq, pstat->auth_seq + 1);
status = _STATS_OUT_OF_AUTH_SEQ_;
goto auth_fail;
}
@@ -2742,7 +2742,7 @@ static unsigned int OnAuth(struct adapter *padapter,
pstat->authalg = algorithm;
} else {
DBG_88E("(2)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
- seq, pstat->auth_seq+1);
+ seq, pstat->auth_seq + 1);
status = _STATS_OUT_OF_AUTH_SEQ_;
goto auth_fail;
}
@@ -2761,7 +2761,7 @@ static unsigned int OnAuth(struct adapter *padapter,
p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, &ie_len,
len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4);
- if ((p == NULL) || (ie_len <= 0)) {
+ if (!p || ie_len <= 0) {
DBG_88E("auth rejected because challenge failure!(1)\n");
status = _STATS_CHALLENGE_FAIL_;
goto auth_fail;
@@ -2779,7 +2779,7 @@ static unsigned int OnAuth(struct adapter *padapter,
}
} else {
DBG_88E("(3)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
- seq, pstat->auth_seq+1);
+ seq, pstat->auth_seq + 1);
status = _STATS_OUT_OF_AUTH_SEQ_;
goto auth_fail;
}
@@ -2855,7 +2855,7 @@ static unsigned int OnAuthClient(struct adapter *padapter,
p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, &len,
pkt_len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_);
- if (p == NULL)
+ if (!p)
goto authclnt_fail;
memcpy((void *)(pmlmeinfo->chg_txt), (void *)(p + 2), len);
@@ -2975,7 +2975,7 @@ static unsigned int OnAssocReq(struct adapter *padapter,
goto OnAssocReqFail;
} else {
/* check if ssid match */
- if (memcmp((void *)(p+2), cur->ssid.ssid, cur->ssid.ssid_length))
+ if (memcmp((void *)(p + 2), cur->ssid.ssid, cur->ssid.ssid_length))
status = _STATS_FAILURE_;
if (ie_len != cur->ssid.ssid_length)
@@ -2987,7 +2987,7 @@ static unsigned int OnAssocReq(struct adapter *padapter,
/* check if the supported rate is ok */
p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SUPPORTEDRATES_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
- if (p == NULL) {
+ if (!p) {
DBG_88E("Rx a sta assoc-req which supported rate is empty!\n");
/* use our own rate set as statoin used */
/* memcpy(supportRate, AP_BSSRATE, AP_BSSRATE_LEN); */
@@ -2996,14 +2996,15 @@ static unsigned int OnAssocReq(struct adapter *padapter,
status = _STATS_FAILURE_;
goto OnAssocReqFail;
} else {
- memcpy(supportRate, p+2, ie_len);
+ memcpy(supportRate, p + 2, ie_len);
supportRateNum = ie_len;
p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _EXT_SUPPORTEDRATES_IE_, &ie_len,
pkt_len - WLAN_HDR_A3_LEN - ie_offset);
- if (p != NULL) {
+ if (p) {
if (supportRateNum <= sizeof(supportRate)) {
- memcpy(supportRate+supportRateNum, p+2, ie_len);
+ memcpy(supportRate + supportRateNum,
+ p + 2, ie_len);
supportRateNum += ie_len;
}
}
@@ -3031,7 +3032,7 @@ static unsigned int OnAssocReq(struct adapter *padapter,
wpa_ie = elems.rsn_ie;
wpa_ie_len = elems.rsn_ie_len;
- if (rtw_parse_wpa2_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
+ if (rtw_parse_wpa2_ie(wpa_ie - 2, wpa_ie_len + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
pstat->dot8021xalg = 1;/* psk, todo:802.1x */
pstat->wpa_psk |= BIT(1);
@@ -3052,7 +3053,7 @@ static unsigned int OnAssocReq(struct adapter *padapter,
wpa_ie = elems.wpa_ie;
wpa_ie_len = elems.wpa_ie_len;
- if (rtw_parse_wpa_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
+ if (rtw_parse_wpa_ie(wpa_ie - 2, wpa_ie_len + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
pstat->dot8021xalg = 1;/* psk, todo:802.1x */
pstat->wpa_psk |= BIT(0);
@@ -3094,7 +3095,7 @@ static unsigned int OnAssocReq(struct adapter *padapter,
/* AP support WPA/RSN, and sta is going to do WPS, but AP is not ready */
/* that the selected registrar of AP is _FLASE */
- if ((psecuritypriv->wpa_psk > 0) && (pstat->flags & (WLAN_STA_WPS|WLAN_STA_MAYBE_WPS))) {
+ if ((psecuritypriv->wpa_psk > 0) && (pstat->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS))) {
if (pmlmepriv->wps_beacon_ie) {
u8 selected_registrar = 0;
@@ -3131,7 +3132,7 @@ static unsigned int OnAssocReq(struct adapter *padapter,
copy_len = min_t(int, wpa_ie_len + 2, sizeof(pstat->wpa_ie));
}
if (copy_len > 0)
- memcpy(pstat->wpa_ie, wpa_ie-2, copy_len);
+ memcpy(pstat->wpa_ie, wpa_ie - 2, copy_len);
}
/* check if there is WMM IE & support WWM-PS */
pstat->flags &= ~WLAN_STA_WME;
@@ -3146,14 +3147,14 @@ static unsigned int OnAssocReq(struct adapter *padapter,
p = pframe + WLAN_HDR_A3_LEN + ie_offset; ie_len = 0;
for (;;) {
p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
- if (p != NULL) {
- if (!memcmp(p+2, WMM_IE, 6)) {
+ if (p) {
+ if (!memcmp(p + 2, WMM_IE, 6)) {
pstat->flags |= WLAN_STA_WME;
pstat->qos_option = 1;
- pstat->qos_info = *(p+8);
+ pstat->qos_info = *(p + 8);
- pstat->max_sp_len = (pstat->qos_info>>5) & 0x3;
+ pstat->max_sp_len = (pstat->qos_info >> 5) & 0x3;
if ((pstat->qos_info & 0xf) != 0xf)
pstat->has_legacy_ac = true;
@@ -3162,22 +3163,22 @@ static unsigned int OnAssocReq(struct adapter *padapter,
if (pstat->qos_info & 0xf) {
if (pstat->qos_info & BIT(0))
- pstat->uapsd_vo = BIT(0)|BIT(1);
+ pstat->uapsd_vo = BIT(0) | BIT(1);
else
pstat->uapsd_vo = 0;
if (pstat->qos_info & BIT(1))
- pstat->uapsd_vi = BIT(0)|BIT(1);
+ pstat->uapsd_vi = BIT(0) | BIT(1);
else
pstat->uapsd_vi = 0;
if (pstat->qos_info & BIT(2))
- pstat->uapsd_bk = BIT(0)|BIT(1);
+ pstat->uapsd_bk = BIT(0) | BIT(1);
else
pstat->uapsd_bk = 0;
if (pstat->qos_info & BIT(3))
- pstat->uapsd_be = BIT(0)|BIT(1);
+ pstat->uapsd_be = BIT(0) | BIT(1);
else
pstat->uapsd_be = 0;
}
@@ -3245,7 +3246,7 @@ static unsigned int OnAssocReq(struct adapter *padapter,
DBG_88E(" old AID %d\n", pstat->aid);
} else {
for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++)
- if (pstapriv->sta_aid[pstat->aid - 1] == NULL)
+ if (!pstapriv->sta_aid[pstat->aid - 1])
break;
/* if (pstat->aid > NUM_STA) { */
@@ -3958,7 +3959,7 @@ static void init_channel_list(struct adapter *padapter,
((o->bw == BW40MINUS) || (o->bw == BW40PLUS)))
continue;
- if (reg == NULL) {
+ if (!reg) {
reg = &channel_list->reg_class[cla];
cla++;
reg->reg_class = o->op_class;
@@ -4515,7 +4516,7 @@ void mlmeext_joinbss_event_callback(struct adapter *padapter, int join_res)
/* set per sta rate after updating HT cap. */
set_sta_rate(padapter, psta);
rtw_hal_set_hwreg(padapter, HW_VAR_TX_RPT_MAX_MACID, (u8 *)&psta->mac_id);
- media_status = (psta->mac_id<<8)|1; /* MACID|OPMODE: 1 means connect */
+ media_status = (psta->mac_id << 8) | 1; /* MACID|OPMODE: 1 means connect */
rtw_hal_set_hwreg(padapter, HW_VAR_H2C_MEDIA_STATUS_RPT, (u8 *)&media_status);
}
@@ -4844,7 +4845,7 @@ u8 setopmode_hdl(struct adapter *padapter, u8 *pbuf)
pmlmeinfo->state = WIFI_FW_AP_STATE;
type = _HW_STATE_AP_;
} else if (psetop->mode == Ndis802_11Infrastructure) {
- pmlmeinfo->state &= ~(BIT(0)|BIT(1));/* clear state */
+ pmlmeinfo->state &= ~(BIT(0) | BIT(1));/* clear state */
pmlmeinfo->state |= WIFI_FW_STATION_STATE;/* set to STATION_STATE */
type = _HW_STATE_STATION_;
} else if (psetop->mode == Ndis802_11IBSS) {
@@ -5040,7 +5041,7 @@ u8 disconnect_hdl(struct adapter *padapter, unsigned char *pbuf)
u8 val8;
if (is_client_associated_to_ap(padapter))
- issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms/100, 100);
+ issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms / 100, 100);
rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, NULL);
rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
@@ -5084,7 +5085,7 @@ static int rtw_scan_ch_decision(struct adapter *padapter,
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
/* clear out first */
- memset(out, 0, sizeof(struct rtw_ieee80211_channel)*out_num);
+ memset(out, 0, sizeof(struct rtw_ieee80211_channel) * out_num);
/* acquire channels from in */
j = 0;
@@ -5263,7 +5264,7 @@ u8 set_stakey_hdl(struct adapter *padapter, u8 *pbuf)
DBG_88E("r871x_set_stakey_hdl(): enc_algorithm=%d\n", pparm->algorithm);
- if ((psta->mac_id < 1) || (psta->mac_id > (NUM_STA-4))) {
+ if ((psta->mac_id < 1) || (psta->mac_id > (NUM_STA - 4))) {
DBG_88E("r871x_set_stakey_hdl():set_stakey failed, mac_id(aid)=%d\n", psta->mac_id);
return H2C_REJECTED;
}
@@ -5333,14 +5334,14 @@ u8 set_tx_beacon_cmd(struct adapter *padapter)
ptxBeacon_parm = kmemdup(&pmlmeinfo->network,
sizeof(struct wlan_bssid_ex), GFP_ATOMIC);
- if (ptxBeacon_parm == NULL) {
+ if (!ptxBeacon_parm) {
kfree(ph2c);
res = _FAIL;
goto exit;
}
- len_diff = update_hidden_ssid(ptxBeacon_parm->ies+_BEACON_IE_OFFSET_,
- ptxBeacon_parm->ie_length-_BEACON_IE_OFFSET_,
+ len_diff = update_hidden_ssid(ptxBeacon_parm->ies + _BEACON_IE_OFFSET_,
+ ptxBeacon_parm->ie_length - _BEACON_IE_OFFSET_,
pmlmeinfo->hidden_ssid_mode);
ptxBeacon_parm->ie_length += len_diff;
@@ -5361,7 +5362,7 @@ u8 mlme_evt_hdl(struct adapter *padapter, unsigned char *pbuf)
peventbuf = (uint *)pbuf;
evt_sz = (u16)(*peventbuf & 0xffff);
- evt_code = (u8)((*peventbuf>>16) & 0xff);
+ evt_code = (u8)((*peventbuf >> 16) & 0xff);
/* checking if event code is valid */
if (evt_code >= MAX_C2HEVT) {
diff --git a/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c b/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c
index 03dc7e5fcc38..c4f58507dbfd 100644
--- a/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c
+++ b/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c
@@ -154,8 +154,8 @@ void ips_enter(struct adapter *padapter)
int ips_leave(struct adapter *padapter)
{
struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
- struct security_priv *psecuritypriv = &(padapter->securitypriv);
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct security_priv *psecuritypriv = &padapter->securitypriv;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
int result = _SUCCESS;
int keyid;
@@ -200,28 +200,24 @@ int ips_leave(struct adapter *padapter)
static bool rtw_pwr_unassociated_idle(struct adapter *adapter)
{
- struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
- bool ret = false;
+ struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
if (time_after_eq(adapter->pwrctrlpriv.ips_deny_time, jiffies))
- goto exit;
+ return false;
if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE|WIFI_SITE_MONITOR) ||
check_fwstate(pmlmepriv, WIFI_UNDER_LINKING|WIFI_UNDER_WPS) ||
check_fwstate(pmlmepriv, WIFI_AP_STATE) ||
check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE))
- goto exit;
-
- ret = true;
+ return false;
-exit:
- return ret;
+ return true;
}
void rtw_ps_processor(struct adapter *padapter)
{
struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
enum rt_rf_power_state rfpwrstate;
pwrpriv->ps_processing = true;
@@ -282,7 +278,7 @@ static void pwr_state_check_handler(struct timer_list *t)
*/
void rtw_set_rpwm(struct adapter *padapter, u8 pslv)
{
- u8 rpwm;
+ u8 rpwm;
struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
pslv = PS_STATE(pslv);
@@ -335,8 +331,8 @@ void rtw_set_rpwm(struct adapter *padapter, u8 pslv)
static u8 PS_RDY_CHECK(struct adapter *padapter)
{
unsigned long curr_time, delta_time;
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
curr_time = jiffies;
delta_time = curr_time - pwrpriv->DelayLPSLastTimeStamp;
@@ -437,7 +433,7 @@ s32 LPS_RF_ON_check(struct adapter *padapter, u32 delay_ms)
/* */
void LPS_Enter(struct adapter *padapter)
{
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
+ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
if (!PS_RDY_CHECK(padapter))
return;
@@ -463,7 +459,7 @@ void LPS_Enter(struct adapter *padapter)
/* Leave the leisure power save mode. */
void LPS_Leave(struct adapter *padapter)
{
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
+ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
if (pwrpriv->bLeisurePs) {
if (pwrpriv->pwr_mode != PS_MODE_ACTIVE) {
@@ -483,8 +479,8 @@ void LPS_Leave(struct adapter *padapter)
/* */
void LeaveAllPowerSaveMode(struct adapter *Adapter)
{
- struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv);
- u8 enqueue = 0;
+ struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
+ u8 enqueue = 0;
if (check_fwstate(pmlmepriv, _FW_LINKED))
rtw_lps_ctrl_wk_cmd(Adapter, LPS_CTRL_LEAVE, enqueue);
@@ -611,7 +607,7 @@ exit:
int rtw_pm_set_lps(struct adapter *padapter, u8 mode)
{
- int ret = 0;
+ int ret = 0;
struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv;
if (mode < PS_MODE_NUM) {
diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
index 5e687f6d2c3e..c642825ca8ef 100644
--- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
+++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
@@ -207,10 +207,10 @@ static RT_CHANNEL_PLAN_MAP RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = {
{0x02, 0x1F}, /* 0x57, RT_CHANNEL_DOMAIN_FCC1_FCC10 */
};
-static RT_CHANNEL_PLAN_MAP RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = {0x03, 0x02}; /* use the conbination for max channel numbers */
+ /* use the combination for max channel numbers */
+static RT_CHANNEL_PLAN_MAP RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = {0x03, 0x02};
-/*
- * Search the @param ch in given @param ch_set
+/* Search the @param ch in given @param ch_set
* @ch_set: the given channel set
* @ch: the given channel number
*
@@ -229,8 +229,7 @@ int rtw_ch_set_search_ch(RT_CHANNEL_INFO *ch_set, const u32 ch)
return i;
}
-/*
- * Check the @param ch is fit with setband setting of @param adapter
+/* Check the @param ch is fit with setband setting of @param adapter
* @adapter: the given adapter
* @ch: the given channel number
*
@@ -2265,7 +2264,7 @@ inline struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv)
/****************************************************************************
-Following are some TX fuctions for WiFi MLME
+Following are some TX functions for WiFi MLME
*****************************************************************************/
@@ -2956,7 +2955,7 @@ exit:
return ret;
}
-/* if psta == NULL, indiate we are station(client) now... */
+/* if psta == NULL, indicate we are station(client) now... */
void issue_auth(struct adapter *padapter, struct sta_info *psta, unsigned short status)
{
struct xmit_frame *pmgntframe;
@@ -3356,9 +3355,11 @@ void issue_assocreq(struct adapter *padapter)
(!memcmp(pIE->data, WPS_OUI, 4))) {
vs_ie_length = pIE->Length;
if ((!padapter->registrypriv.wifi_spec) && (!memcmp(pIE->data, WPS_OUI, 4))) {
- /* Commented by Kurt 20110629 */
- /* In some older APs, WPS handshake */
- /* would be fail if we append vender extensions informations to AP */
+ /* Commented by Kurt 20110629
+ * In some older APs, WPS handshake
+ * would be fail if we append vendor
+ * extensions information to AP
+ */
vs_ie_length = 14;
}
@@ -3406,7 +3407,7 @@ exit:
rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len);
}
-/* when wait_ack is ture, this function shoule be called at process context */
+/* when wait_ack is true, this function should be called at process context */
static int _issue_nulldata(struct adapter *padapter, unsigned char *da,
unsigned int power_mode, bool wait_ack)
{
@@ -3481,7 +3482,7 @@ exit:
/*
* [IMPORTANT] Don't call this function in interrupt context
*
- * When wait_ms > 0, this function shoule be called at process context
+ * When wait_ms > 0, this function should be called at process context
* da == NULL for station mode
*/
int issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms)
@@ -3493,7 +3494,7 @@ int issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned int pow
struct sta_info *psta;
- /* da == NULL, assum it's null data for sta to ap*/
+ /* da == NULL, assume it's null data for sta to ap*/
if (!da)
da = get_my_bssid(&(pmlmeinfo->network));
@@ -3558,14 +3559,14 @@ s32 issue_nulldata_in_interrupt(struct adapter *padapter, u8 *da)
pmlmeext = &padapter->mlmeextpriv;
pmlmeinfo = &pmlmeext->mlmext_info;
- /* da == NULL, assum it's null data for sta to ap*/
+ /* da == NULL, assume it's null data for sta to ap*/
if (!da)
da = get_my_bssid(&(pmlmeinfo->network));
return _issue_nulldata(padapter, da, 0, false);
}
-/* when wait_ack is ture, this function shoule be called at process context */
+/* when wait_ack is true, this function should be called at process context */
static int _issue_qos_nulldata(struct adapter *padapter, unsigned char *da,
u16 tid, bool wait_ack)
{
@@ -3644,7 +3645,7 @@ exit:
return ret;
}
-/* when wait_ms >0 , this function shoule be called at process context */
+/* when wait_ms >0 , this function should be called at process context */
/* da == NULL for station mode */
int issue_qos_nulldata(struct adapter *padapter, unsigned char *da, u16 tid, int try_cnt, int wait_ms)
{
@@ -3653,7 +3654,7 @@ int issue_qos_nulldata(struct adapter *padapter, unsigned char *da, u16 tid, int
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
- /* da == NULL, assum it's null data for sta to ap*/
+ /* da == NULL, assume it's null data for sta to ap*/
if (!da)
da = get_my_bssid(&(pmlmeinfo->network));
@@ -4264,7 +4265,7 @@ unsigned int send_beacon(struct adapter *padapter)
/****************************************************************************
-Following are some utitity fuctions for WiFi MLME
+Following are some utility functions for WiFi MLME
*****************************************************************************/
@@ -4568,7 +4569,7 @@ u8 collect_bss_info(struct adapter *padapter, union recv_frame *precv_frame, str
}
#endif
- /* mark bss info receving from nearby channel as SignalQuality 101 */
+ /* mark bss info receiving from nearby channel as SignalQuality 101 */
if (bssid->Configuration.DSConfig != rtw_get_oper_ch(padapter))
bssid->PhyInfo.SignalQuality = 101;
@@ -4589,7 +4590,7 @@ void start_create_ibss(struct adapter *padapter)
/* update wireless mode */
update_wireless_mode(padapter);
- /* udpate capability */
+ /* update capability */
caps = rtw_get_capability((struct wlan_bssid_ex *)pnetwork);
update_capinfo(padapter, caps);
if (caps&cap_IBSS) {/* adhoc master */
@@ -4644,7 +4645,7 @@ void start_clnt_join(struct adapter *padapter)
/* update wireless mode */
update_wireless_mode(padapter);
- /* udpate capability */
+ /* update capability */
caps = rtw_get_capability((struct wlan_bssid_ex *)pnetwork);
update_capinfo(padapter, caps);
if (caps&cap_ESS) {
@@ -5379,8 +5380,7 @@ static void rtw_mlmeext_disconnect(struct adapter *padapter)
/* set_opmode_cmd(padapter, infra_client_with_mlme); */
- /*
- * For safety, prevent from keeping macid sleep.
+ /* For safety, prevent from keeping macid sleep.
* If we can sure all power mode enter/leave are paired,
* this check can be removed.
* Lucas@20131113
@@ -5441,7 +5441,7 @@ void mlmeext_joinbss_event_callback(struct adapter *padapter, int join_res)
/* turn on dynamic functions */
Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, true);
- /* update IOT-releated issue */
+ /* update IOT-related issue */
update_IOT_info(padapter);
rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, cur_network->SupportedRates);
@@ -5449,7 +5449,7 @@ void mlmeext_joinbss_event_callback(struct adapter *padapter, int join_res)
/* BCN interval */
rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&pmlmeinfo->bcn_interval));
- /* udpate capability */
+ /* update capability */
update_capinfo(padapter, pmlmeinfo->capability);
/* WMM, Update EDCA param */
@@ -6385,7 +6385,9 @@ u8 sitesurvey_cmd_hdl(struct adapter *padapter, u8 *pbuf)
Save_DM_Func_Flag(padapter);
Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, false);
- /* config the initial gain under scaning, need to write the BB registers */
+ /* config the initial gain under scanning, need to write the BB
+ * registers
+ */
initialgain = 0x1e;
rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
diff --git a/drivers/staging/rtl8723bs/hal/HalPhyRf_8723B.c b/drivers/staging/rtl8723bs/hal/HalPhyRf_8723B.c
index 1ca9063a269f..338dd0b7a6eb 100644
--- a/drivers/staging/rtl8723bs/hal/HalPhyRf_8723B.c
+++ b/drivers/staging/rtl8723bs/hal/HalPhyRf_8723B.c
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0
-/******************************************************************************
+/*****************************************************************************
*
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
*
@@ -82,7 +82,9 @@ static void setIqkMatrix_8723B(
/* if (RFPath == ODM_RF_PATH_A) */
switch (RFPath) {
case ODM_RF_PATH_A:
- /* wirte new elements A, C, D to regC80 and regC94, element B is always 0 */
+ /* write new elements A, C, D to regC80 and regC94,
+ * element B is always 0
+ */
value32 = (ele_D<<22)|((ele_C&0x3F)<<16)|ele_A;
PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XATxIQImbalance, bMaskDWord, value32);
@@ -93,7 +95,9 @@ static void setIqkMatrix_8723B(
PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, BIT24, value32);
break;
case ODM_RF_PATH_B:
- /* wirte new elements A, C, D to regC88 and regC9C, element B is always 0 */
+ /* write new elements A, C, D to regC88 and regC9C,
+ * element B is always 0
+ */
value32 = (ele_D<<22)|((ele_C&0x3F)<<16)|ele_A;
PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XBTxIQImbalance, bMaskDWord, value32);
@@ -166,7 +170,7 @@ void DoIQK_8723B(
/*-----------------------------------------------------------------------------
* Function: odm_TxPwrTrackSetPwr88E()
*
- * Overview: 88E change all channel tx power accordign to flag.
+ * Overview: 88E change all channel tx power according to flag.
* OFDM & CCK are all different.
*
* Input: NONE
diff --git a/drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c b/drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c
index 66127f6c8e4d..de8caa6cd418 100644
--- a/drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c
+++ b/drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c
@@ -750,7 +750,7 @@ static void Hal_BT_EfusePowerSwitch(
rtw_write8(padapter, 0x6B, tempval);
/* Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay */
- /* So don't wirte 0x6A[14]= 1 and 0x6A[15]= 0 together! */
+ /* So don't write 0x6A[14]= 1 and 0x6A[15]= 0 together! */
msleep(1);
/* disable BT output isolation */
/* 0x6A[15] = 0 */
@@ -765,7 +765,7 @@ static void Hal_BT_EfusePowerSwitch(
rtw_write8(padapter, 0x6B, tempval);
/* Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay */
- /* So don't wirte 0x6A[14]= 1 and 0x6A[15]= 0 together! */
+ /* So don't write 0x6A[14]= 1 and 0x6A[15]= 0 together! */
/* disable BT power cut */
/* 0x6A[14] = 1 */
@@ -1231,7 +1231,7 @@ static u16 hal_EfuseGetCurrentSize_WiFi(
goto exit;
error:
- /* report max size to prevent wirte efuse */
+ /* report max size to prevent write efuse */
EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &efuse_addr, bPseudoTest);
exit:
@@ -2237,7 +2237,7 @@ void rtl8723b_InitAntenna_Selection(struct adapter *padapter)
u8 val;
val = rtw_read8(padapter, REG_LEDCFG2);
- /* Let 8051 take control antenna settting */
+ /* Let 8051 take control antenna setting */
val |= BIT(7); /* DPDT_SEL_EN, 0x4C[23] */
rtw_write8(padapter, REG_LEDCFG2, val);
}
@@ -3191,22 +3191,26 @@ static void rtl8723b_fill_default_txdesc(
if (bmcst)
ptxdesc->bmc = 1;
- /* 2009.11.05. tynli_test. Suggested by SD4 Filen for FW LPS. */
- /* (1) The sequence number of each non-Qos frame / broadcast / multicast / */
- /* mgnt frame should be controled by Hw because Fw will also send null data */
- /* which we cannot control when Fw LPS enable. */
- /* --> default enable non-Qos data sequense number. 2010.06.23. by tynli. */
- /* (2) Enable HW SEQ control for beacon packet, because we use Hw beacon. */
- /* (3) Use HW Qos SEQ to control the seq num of Ext port non-Qos packets. */
- /* 2010.06.23. Added by tynli. */
+ /* 2009.11.05. tynli_test. Suggested by SD4 Filen for FW LPS.
+ * (1) The sequence number of each non-Qos frame / broadcast /
+ * multicast / mgnt frame should be controlled by Hw because Fw
+ * will also send null data which we cannot control when Fw LPS
+ * enable.
+ * --> default enable non-Qos data sequense number. 2010.06.23.
+ * by tynli.
+ * (2) Enable HW SEQ control for beacon packet, because we use
+ * Hw beacon.
+ * (3) Use HW Qos SEQ to control the seq num of Ext port non-Qos
+ * packets.
+ * 2010.06.23. Added by tynli.
+ */
if (!pattrib->qos_en) /* Hw set sequence number */
ptxdesc->en_hwseq = 1; /* HWSEQ_EN */
}
-/*
- *Description:
+/* Description:
*
- *Parameters:
+ * Parameters:
* pxmitframe xmitframe
* pbuf where to fill tx desc
*/
@@ -3543,7 +3547,7 @@ static void hw_var_set_mlme_sitesurvey(struct adapter *padapter, u8 variable, u8
rtw_write8(padapter, reg_bcn_ctl, val8);
}
- /* Save orignal RRSR setting. */
+ /* Save original RRSR setting. */
pHalData->RegRRSR = rtw_read16(padapter, REG_RRSR);
} else {
/* sitesurvey done */
@@ -3561,7 +3565,7 @@ static void hw_var_set_mlme_sitesurvey(struct adapter *padapter, u8 variable, u8
value_rcr |= rcr_clear_bit;
rtw_write32(padapter, REG_RCR, value_rcr);
- /* Restore orignal RRSR setting. */
+ /* Restore original RRSR setting. */
rtw_write16(padapter, REG_RRSR, pHalData->RegRRSR);
}
}
@@ -4329,8 +4333,7 @@ void GetHwReg8723B(struct adapter *padapter, u8 variable, u8 *val)
}
}
-/*
- *Description:
+/* Description:
* Change default setting of specified variable.
*/
u8 SetHalDefVar8723B(struct adapter *padapter, enum HAL_DEF_VARIABLE variable, void *pval)
@@ -4348,8 +4351,7 @@ u8 SetHalDefVar8723B(struct adapter *padapter, enum HAL_DEF_VARIABLE variable, v
return bResult;
}
-/*
- *Description:
+/* Description:
* Query setting of specified variable.
*/
u8 GetHalDefVar8723B(struct adapter *padapter, enum HAL_DEF_VARIABLE variable, void *pval)
diff --git a/drivers/staging/rts5208/rtsx.c b/drivers/staging/rts5208/rtsx.c
index cb95ad6fa4f9..15fc96b42032 100644
--- a/drivers/staging/rts5208/rtsx.c
+++ b/drivers/staging/rts5208/rtsx.c
@@ -831,7 +831,8 @@ static int rtsx_probe(struct pci_dev *pci,
host = scsi_host_alloc(&rtsx_host_template, sizeof(*dev));
if (!host) {
dev_err(&pci->dev, "Unable to allocate the scsi host\n");
- return -ENOMEM;
+ err = -ENOMEM;
+ goto scsi_host_alloc_fail;
}
dev = host_to_rtsx(host);
@@ -971,7 +972,8 @@ ioremap_fail:
kfree(dev->chip);
chip_alloc_fail:
dev_err(&pci->dev, "%s failed\n", __func__);
-
+scsi_host_alloc_fail:
+ pci_release_regions(pci);
return err;
}
@@ -983,6 +985,7 @@ static void rtsx_remove(struct pci_dev *pci)
quiesce_and_remove_host(dev);
release_everything(dev);
+ pci_release_regions(pci);
}
/* PCI IDs */
diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c
index 826016c3431a..33485184a98a 100644
--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c
+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c
@@ -193,17 +193,6 @@ static int snd_bcm2835_playback_close(struct snd_pcm_substream *substream)
return 0;
}
-static int snd_bcm2835_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
-}
-
-static int snd_bcm2835_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream)
{
struct bcm2835_chip *chip = snd_pcm_substream_chip(substream);
@@ -316,9 +305,6 @@ snd_bcm2835_pcm_pointer(struct snd_pcm_substream *substream)
static const struct snd_pcm_ops snd_bcm2835_playback_ops = {
.open = snd_bcm2835_playback_open,
.close = snd_bcm2835_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_bcm2835_pcm_hw_params,
- .hw_free = snd_bcm2835_pcm_hw_free,
.prepare = snd_bcm2835_pcm_prepare,
.trigger = snd_bcm2835_pcm_trigger,
.pointer = snd_bcm2835_pcm_pointer,
@@ -328,9 +314,6 @@ static const struct snd_pcm_ops snd_bcm2835_playback_ops = {
static const struct snd_pcm_ops snd_bcm2835_playback_spdif_ops = {
.open = snd_bcm2835_playback_spdif_open,
.close = snd_bcm2835_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_bcm2835_pcm_hw_params,
- .hw_free = snd_bcm2835_pcm_hw_free,
.prepare = snd_bcm2835_pcm_prepare,
.trigger = snd_bcm2835_pcm_trigger,
.pointer = snd_bcm2835_pcm_pointer,
@@ -362,7 +345,7 @@ int snd_bcm2835_new_pcm(struct bcm2835_chip *chip, const char *name,
spdif ? &snd_bcm2835_playback_spdif_ops :
&snd_bcm2835_playback_ops);
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
+ snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
chip->card->dev, 128 * 1024, 128 * 1024);
if (spdif)
diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
index beb6a0063bb8..1ef31a984741 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
@@ -60,6 +60,9 @@ MODULE_PARM_DESC(max_video_width, "Threshold for video mode");
module_param(max_video_height, int, 0644);
MODULE_PARM_DESC(max_video_height, "Threshold for video mode");
+/* camera instance counter */
+static atomic_t camera_instance = ATOMIC_INIT(0);
+
/* global device data array */
static struct bm2835_mmal_dev *gdev[MAX_BCM2835_CAMERAS];
@@ -1870,7 +1873,6 @@ static int bcm2835_mmal_probe(struct platform_device *pdev)
/* v4l2 core mutex used to protect all fops and v4l2 ioctls. */
mutex_init(&dev->mutex);
- dev->camera_num = camera;
dev->max_width = resolutions[camera][0];
dev->max_height = resolutions[camera][1];
@@ -1886,8 +1888,9 @@ static int bcm2835_mmal_probe(struct platform_device *pdev)
dev->capture.fmt = &formats[3]; /* JPEG */
/* v4l device registration */
- snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name),
- "%s", BM2835_MMAL_MODULE_NAME);
+ dev->camera_num = v4l2_device_set_name(&dev->v4l2_dev,
+ BM2835_MMAL_MODULE_NAME,
+ &camera_instance);
ret = v4l2_device_register(NULL, &dev->v4l2_dev);
if (ret) {
dev_err(&pdev->dev, "%s: could not register V4L2 device: %d\n",
diff --git a/drivers/staging/wilc1000/netdev.c b/drivers/staging/wilc1000/netdev.c
index d2c0b0f7cf63..3fd8e008f733 100644
--- a/drivers/staging/wilc1000/netdev.c
+++ b/drivers/staging/wilc1000/netdev.c
@@ -96,21 +96,18 @@ void wilc_mac_indicate(struct wilc *wilc)
static struct net_device *get_if_handler(struct wilc *wilc, u8 *mac_header)
{
- u8 *bssid, *bssid1;
struct net_device *ndev = NULL;
struct wilc_vif *vif;
-
- bssid = mac_header + 10;
- bssid1 = mac_header + 4;
+ struct ieee80211_hdr *h = (struct ieee80211_hdr *)mac_header;
list_for_each_entry_rcu(vif, &wilc->vif_list, list) {
if (vif->mode == WILC_STATION_MODE)
- if (ether_addr_equal_unaligned(bssid, vif->bssid)) {
+ if (ether_addr_equal_unaligned(h->addr2, vif->bssid)) {
ndev = vif->ndev;
goto out;
}
if (vif->mode == WILC_AP_MODE)
- if (ether_addr_equal_unaligned(bssid1, vif->bssid)) {
+ if (ether_addr_equal_unaligned(h->addr1, vif->bssid)) {
ndev = vif->ndev;
goto out;
}
diff --git a/drivers/staging/wilc1000/wlan.c b/drivers/staging/wilc1000/wlan.c
index d3de76126b78..ba5446724c93 100644
--- a/drivers/staging/wilc1000/wlan.c
+++ b/drivers/staging/wilc1000/wlan.c
@@ -890,29 +890,6 @@ int wilc_wlan_start(struct wilc *wilc)
if (wilc->io_type == WILC_HIF_SDIO && wilc->dev_irq_num)
reg |= WILC_HAVE_SDIO_IRQ_GPIO;
-#ifdef WILC_DISABLE_PMU
-#else
- reg |= WILC_HAVE_USE_PMU;
-#endif
-
-#ifdef WILC_SLEEP_CLK_SRC_XO
- reg |= WILC_HAVE_SLEEP_CLK_SRC_XO;
-#elif defined WILC_SLEEP_CLK_SRC_RTC
- reg |= WILC_HAVE_SLEEP_CLK_SRC_RTC;
-#endif
-
-#ifdef WILC_EXT_PA_INV_TX_RX
- reg |= WILC_HAVE_EXT_PA_INV_TX_RX;
-#endif
- reg |= WILC_HAVE_USE_IRQ_AS_HOST_WAKE;
- reg |= WILC_HAVE_LEGACY_RF_SETTINGS;
-#ifdef XTAL_24
- reg |= WILC_HAVE_XTAL_24;
-#endif
-#ifdef DISABLE_WILC_UART
- reg |= WILC_HAVE_DISABLE_WILC_UART;
-#endif
-
ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_1, reg);
if (!ret) {
release_bus(wilc, WILC_BUS_RELEASE_ONLY);
diff --git a/drivers/staging/wilc1000/wlan.h b/drivers/staging/wilc1000/wlan.h
index 1f6957cf2e9c..44ae6ed6882c 100644
--- a/drivers/staging/wilc1000/wlan.h
+++ b/drivers/staging/wilc1000/wlan.h
@@ -197,6 +197,7 @@
#define IS_MANAGMEMENT_CALLBACK 0x080
#define IS_MGMT_STATUS_SUCCES 0x040
+#define WILC_WID_TYPE GENMASK(15, 12)
/********************************************
*
* Tx/Rx Queue Structure
diff --git a/drivers/staging/wilc1000/wlan_cfg.c b/drivers/staging/wilc1000/wlan_cfg.c
index 6f6b286788d1..2538435b82fd 100644
--- a/drivers/staging/wilc1000/wlan_cfg.c
+++ b/drivers/staging/wilc1000/wlan_cfg.c
@@ -4,6 +4,7 @@
* All rights reserved.
*/
+#include <linux/bitfield.h>
#include "wlan_if.h"
#include "wlan.h"
#include "wlan_cfg.h"
@@ -132,7 +133,6 @@ static int wilc_wlan_cfg_set_bin(u8 *frame, u32 offset, u16 id, u8 *b, u32 size)
*
********************************************/
-#define GET_WID_TYPE(wid) (((wid) >> 12) & 0x7)
static void wilc_wlan_parse_response_frame(struct wilc *wl, u8 *info, int size)
{
u16 wid;
@@ -142,7 +142,7 @@ static void wilc_wlan_parse_response_frame(struct wilc *wl, u8 *info, int size)
i = 0;
wid = get_unaligned_le16(info);
- switch (GET_WID_TYPE(wid)) {
+ switch (FIELD_GET(WILC_WID_TYPE, wid)) {
case WID_CHAR:
do {
if (wl->cfg.b[i].id == WID_NIL)
@@ -244,7 +244,7 @@ static void wilc_wlan_parse_info_frame(struct wilc *wl, u8 *info)
int wilc_wlan_cfg_set_wid(u8 *frame, u32 offset, u16 id, u8 *buf, int size)
{
- u8 type = (id >> 12) & 0xf;
+ u8 type = FIELD_GET(WILC_WID_TYPE, id);
int ret = 0;
switch (type) {
@@ -290,7 +290,7 @@ int wilc_wlan_cfg_get_wid(u8 *frame, u32 offset, u16 id)
int wilc_wlan_cfg_get_val(struct wilc *wl, u16 wid, u8 *buffer,
u32 buffer_size)
{
- u32 type = (wid >> 12) & 0xf;
+ u8 type = FIELD_GET(WILC_WID_TYPE, wid);
int i, ret = 0;
i = 0;
diff --git a/include/linux/b1pcmcia.h b/include/linux/b1pcmcia.h
deleted file mode 100644
index 12a867c6061e..000000000000
--- a/include/linux/b1pcmcia.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* $Id: b1pcmcia.h,v 1.1.8.2 2001/09/23 22:25:05 kai Exp $
- *
- * Exported functions of module b1pcmcia to be called by
- * avm_cs card services module.
- *
- * Copyright 1999 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 _B1PCMCIA_H_
-#define _B1PCMCIA_H_
-
-int b1pcmcia_addcard_b1(unsigned int port, unsigned irq);
-int b1pcmcia_addcard_m1(unsigned int port, unsigned irq);
-int b1pcmcia_addcard_m2(unsigned int port, unsigned irq);
-int b1pcmcia_delcard(unsigned int port, unsigned irq);
-
-#endif /* _B1PCMCIA_H_ */
diff --git a/include/linux/isdn/capilli.h b/include/linux/isdn/capilli.h
index d75e1ad72964..12be09b6883b 100644
--- a/include/linux/isdn/capilli.h
+++ b/include/linux/isdn/capilli.h
@@ -69,7 +69,6 @@ struct capi_ctr {
unsigned short state; /* controller state */
int blocked; /* output blocked */
int traceflag; /* capi trace */
- wait_queue_head_t state_wait_queue;
struct proc_dir_entry *procent;
char procfn[128];
@@ -80,8 +79,6 @@ 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_suspend_output(struct capi_ctr * card);
-void capi_ctr_resume_output(struct capi_ctr * card);
void capi_ctr_handle_message(struct capi_ctr * card, u16 appl, struct sk_buff *skb);
// ---------------------------------------------------------------------------
@@ -91,23 +88,8 @@ struct capi_driver {
char name[32]; /* driver name */
char revision[32];
- int (*add_card)(struct capi_driver *driver, capicardparams *data);
-
/* management information for kcapi */
struct list_head list;
};
-void register_capi_driver(struct capi_driver *driver);
-void unregister_capi_driver(struct capi_driver *driver);
-
-// ---------------------------------------------------------------------------
-// library functions for use by hardware controller drivers
-
-void capilib_new_ncci(struct list_head *head, u16 applid, u32 ncci, u32 winsize);
-void capilib_free_ncci(struct list_head *head, u16 applid, u32 ncci);
-void capilib_release_appl(struct list_head *head, u16 applid);
-void capilib_release(struct list_head *head);
-void capilib_data_b3_conf(struct list_head *head, u16 applid, u32 ncci, u16 msgid);
-u16 capilib_data_b3_req(struct list_head *head, u16 applid, u32 ncci, u16 msgid);
-
#endif /* __CAPILLI_H__ */
diff --git a/include/linux/isdn/capiutil.h b/include/linux/isdn/capiutil.h
index 44bd6046e6e2..953fd500dff7 100644
--- a/include/linux/isdn/capiutil.h
+++ b/include/linux/isdn/capiutil.h
@@ -57,460 +57,4 @@ static inline void capimsg_setu32(void *m, int off, __u32 val)
#define CAPIMSG_SETCONTROL(m, contr) capimsg_setu32(m, 8, contr)
#define CAPIMSG_SETDATALEN(m, len) capimsg_setu16(m, 16, len)
-/*----- 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;
-
-/*
- * capi_cmsg2message() assembles the parameter from _cmsg to a CAPI 2.0
- * conform message
- */
-unsigned capi_cmsg2message(_cmsg * cmsg, __u8 * msg);
-
-/*
- * capi_message2cmsg disassembles a CAPI message an writes the parameter
- * into _cmsg for easy access
- */
-unsigned capi_message2cmsg(_cmsg * cmsg, __u8 * msg);
-
-/*
- * capi_cmsg_header() fills the _cmsg structure with default values, so only
- * parameter with non default values must be changed before sending the
- * message.
- */
-unsigned capi_cmsg_header(_cmsg * cmsg, __u16 _ApplId,
- __u8 _Command, __u8 _Subcommand,
- __u16 _Messagenumber, __u32 _Controller);
-
-/*-----------------------------------------------------------------------*/
-
-/*
- * 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_cmsg2str(_cmsg *cmsg);
-_cdebbuf *capi_message2str(__u8 *msg);
-
-/*-----------------------------------------------------------------------*/
-
-static inline void capi_cmsg_answer(_cmsg * cmsg)
-{
- cmsg->Subcommand |= 0x01;
-}
-
-/*-----------------------------------------------------------------------*/
-
-static inline void capi_fill_CONNECT_B3_REQ(_cmsg * cmsg, __u16 ApplId, __u16 Messagenumber,
- __u32 adr,
- _cstruct NCPI)
-{
- capi_cmsg_header(cmsg, ApplId, 0x82, 0x80, Messagenumber, adr);
- cmsg->NCPI = NCPI;
-}
-
-static inline void capi_fill_FACILITY_REQ(_cmsg * cmsg, __u16 ApplId, __u16 Messagenumber,
- __u32 adr,
- __u16 FacilitySelector,
- _cstruct FacilityRequestParameter)
-{
- capi_cmsg_header(cmsg, ApplId, 0x80, 0x80, Messagenumber, adr);
- cmsg->FacilitySelector = FacilitySelector;
- cmsg->FacilityRequestParameter = FacilityRequestParameter;
-}
-
-static inline void capi_fill_INFO_REQ(_cmsg * cmsg, __u16 ApplId, __u16 Messagenumber,
- __u32 adr,
- _cstruct CalledPartyNumber,
- _cstruct BChannelinformation,
- _cstruct Keypadfacility,
- _cstruct Useruserdata,
- _cstruct Facilitydataarray)
-{
- capi_cmsg_header(cmsg, ApplId, 0x08, 0x80, Messagenumber, adr);
- cmsg->CalledPartyNumber = CalledPartyNumber;
- cmsg->BChannelinformation = BChannelinformation;
- cmsg->Keypadfacility = Keypadfacility;
- cmsg->Useruserdata = Useruserdata;
- cmsg->Facilitydataarray = Facilitydataarray;
-}
-
-static inline void capi_fill_LISTEN_REQ(_cmsg * cmsg, __u16 ApplId, __u16 Messagenumber,
- __u32 adr,
- __u32 InfoMask,
- __u32 CIPmask,
- __u32 CIPmask2,
- _cstruct CallingPartyNumber,
- _cstruct CallingPartySubaddress)
-{
- capi_cmsg_header(cmsg, ApplId, 0x05, 0x80, Messagenumber, adr);
- cmsg->InfoMask = InfoMask;
- cmsg->CIPmask = CIPmask;
- cmsg->CIPmask2 = CIPmask2;
- cmsg->CallingPartyNumber = CallingPartyNumber;
- cmsg->CallingPartySubaddress = CallingPartySubaddress;
-}
-
-static inline void capi_fill_ALERT_REQ(_cmsg * cmsg, __u16 ApplId, __u16 Messagenumber,
- __u32 adr,
- _cstruct BChannelinformation,
- _cstruct Keypadfacility,
- _cstruct Useruserdata,
- _cstruct Facilitydataarray)
-{
- capi_cmsg_header(cmsg, ApplId, 0x01, 0x80, Messagenumber, adr);
- cmsg->BChannelinformation = BChannelinformation;
- cmsg->Keypadfacility = Keypadfacility;
- cmsg->Useruserdata = Useruserdata;
- cmsg->Facilitydataarray = Facilitydataarray;
-}
-
-static inline void capi_fill_CONNECT_REQ(_cmsg * cmsg, __u16 ApplId, __u16 Messagenumber,
- __u32 adr,
- __u16 CIPValue,
- _cstruct CalledPartyNumber,
- _cstruct CallingPartyNumber,
- _cstruct CalledPartySubaddress,
- _cstruct CallingPartySubaddress,
- __u16 B1protocol,
- __u16 B2protocol,
- __u16 B3protocol,
- _cstruct B1configuration,
- _cstruct B2configuration,
- _cstruct B3configuration,
- _cstruct BC,
- _cstruct LLC,
- _cstruct HLC,
- _cstruct BChannelinformation,
- _cstruct Keypadfacility,
- _cstruct Useruserdata,
- _cstruct Facilitydataarray)
-{
-
- capi_cmsg_header(cmsg, ApplId, 0x02, 0x80, Messagenumber, adr);
- cmsg->CIPValue = CIPValue;
- cmsg->CalledPartyNumber = CalledPartyNumber;
- cmsg->CallingPartyNumber = CallingPartyNumber;
- cmsg->CalledPartySubaddress = CalledPartySubaddress;
- cmsg->CallingPartySubaddress = CallingPartySubaddress;
- cmsg->B1protocol = B1protocol;
- cmsg->B2protocol = B2protocol;
- cmsg->B3protocol = B3protocol;
- cmsg->B1configuration = B1configuration;
- cmsg->B2configuration = B2configuration;
- cmsg->B3configuration = B3configuration;
- cmsg->BC = BC;
- cmsg->LLC = LLC;
- cmsg->HLC = HLC;
- cmsg->BChannelinformation = BChannelinformation;
- cmsg->Keypadfacility = Keypadfacility;
- cmsg->Useruserdata = Useruserdata;
- cmsg->Facilitydataarray = Facilitydataarray;
-}
-
-static inline void capi_fill_DATA_B3_REQ(_cmsg * cmsg, __u16 ApplId, __u16 Messagenumber,
- __u32 adr,
- __u32 Data,
- __u16 DataLength,
- __u16 DataHandle,
- __u16 Flags)
-{
-
- capi_cmsg_header(cmsg, ApplId, 0x86, 0x80, Messagenumber, adr);
- cmsg->Data = Data;
- cmsg->DataLength = DataLength;
- cmsg->DataHandle = DataHandle;
- cmsg->Flags = Flags;
-}
-
-static inline void capi_fill_DISCONNECT_REQ(_cmsg * cmsg, __u16 ApplId, __u16 Messagenumber,
- __u32 adr,
- _cstruct BChannelinformation,
- _cstruct Keypadfacility,
- _cstruct Useruserdata,
- _cstruct Facilitydataarray)
-{
-
- capi_cmsg_header(cmsg, ApplId, 0x04, 0x80, Messagenumber, adr);
- cmsg->BChannelinformation = BChannelinformation;
- cmsg->Keypadfacility = Keypadfacility;
- cmsg->Useruserdata = Useruserdata;
- cmsg->Facilitydataarray = Facilitydataarray;
-}
-
-static inline void capi_fill_DISCONNECT_B3_REQ(_cmsg * cmsg, __u16 ApplId, __u16 Messagenumber,
- __u32 adr,
- _cstruct NCPI)
-{
-
- capi_cmsg_header(cmsg, ApplId, 0x84, 0x80, Messagenumber, adr);
- cmsg->NCPI = NCPI;
-}
-
-static inline void capi_fill_MANUFACTURER_REQ(_cmsg * cmsg, __u16 ApplId, __u16 Messagenumber,
- __u32 adr,
- __u32 ManuID,
- __u32 Class,
- __u32 Function,
- _cstruct ManuData)
-{
-
- capi_cmsg_header(cmsg, ApplId, 0xff, 0x80, Messagenumber, adr);
- cmsg->ManuID = ManuID;
- cmsg->Class = Class;
- cmsg->Function = Function;
- cmsg->ManuData = ManuData;
-}
-
-static inline void capi_fill_RESET_B3_REQ(_cmsg * cmsg, __u16 ApplId, __u16 Messagenumber,
- __u32 adr,
- _cstruct NCPI)
-{
-
- capi_cmsg_header(cmsg, ApplId, 0x87, 0x80, Messagenumber, adr);
- cmsg->NCPI = NCPI;
-}
-
-static inline void capi_fill_SELECT_B_PROTOCOL_REQ(_cmsg * cmsg, __u16 ApplId, __u16 Messagenumber,
- __u32 adr,
- __u16 B1protocol,
- __u16 B2protocol,
- __u16 B3protocol,
- _cstruct B1configuration,
- _cstruct B2configuration,
- _cstruct B3configuration)
-{
-
- capi_cmsg_header(cmsg, ApplId, 0x41, 0x80, Messagenumber, adr);
- cmsg->B1protocol = B1protocol;
- cmsg->B2protocol = B2protocol;
- cmsg->B3protocol = B3protocol;
- cmsg->B1configuration = B1configuration;
- cmsg->B2configuration = B2configuration;
- cmsg->B3configuration = B3configuration;
-}
-
-static inline void capi_fill_CONNECT_RESP(_cmsg * cmsg, __u16 ApplId, __u16 Messagenumber,
- __u32 adr,
- __u16 Reject,
- __u16 B1protocol,
- __u16 B2protocol,
- __u16 B3protocol,
- _cstruct B1configuration,
- _cstruct B2configuration,
- _cstruct B3configuration,
- _cstruct ConnectedNumber,
- _cstruct ConnectedSubaddress,
- _cstruct LLC,
- _cstruct BChannelinformation,
- _cstruct Keypadfacility,
- _cstruct Useruserdata,
- _cstruct Facilitydataarray)
-{
- capi_cmsg_header(cmsg, ApplId, 0x02, 0x83, Messagenumber, adr);
- cmsg->Reject = Reject;
- cmsg->B1protocol = B1protocol;
- cmsg->B2protocol = B2protocol;
- cmsg->B3protocol = B3protocol;
- cmsg->B1configuration = B1configuration;
- cmsg->B2configuration = B2configuration;
- cmsg->B3configuration = B3configuration;
- cmsg->ConnectedNumber = ConnectedNumber;
- cmsg->ConnectedSubaddress = ConnectedSubaddress;
- cmsg->LLC = LLC;
- cmsg->BChannelinformation = BChannelinformation;
- cmsg->Keypadfacility = Keypadfacility;
- cmsg->Useruserdata = Useruserdata;
- cmsg->Facilitydataarray = Facilitydataarray;
-}
-
-static inline void capi_fill_CONNECT_ACTIVE_RESP(_cmsg * cmsg, __u16 ApplId, __u16 Messagenumber,
- __u32 adr)
-{
-
- capi_cmsg_header(cmsg, ApplId, 0x03, 0x83, Messagenumber, adr);
-}
-
-static inline void capi_fill_CONNECT_B3_ACTIVE_RESP(_cmsg * cmsg, __u16 ApplId, __u16 Messagenumber,
- __u32 adr)
-{
-
- capi_cmsg_header(cmsg, ApplId, 0x83, 0x83, Messagenumber, adr);
-}
-
-static inline void capi_fill_CONNECT_B3_RESP(_cmsg * cmsg, __u16 ApplId, __u16 Messagenumber,
- __u32 adr,
- __u16 Reject,
- _cstruct NCPI)
-{
- capi_cmsg_header(cmsg, ApplId, 0x82, 0x83, Messagenumber, adr);
- cmsg->Reject = Reject;
- cmsg->NCPI = NCPI;
-}
-
-static inline void capi_fill_CONNECT_B3_T90_ACTIVE_RESP(_cmsg * cmsg, __u16 ApplId, __u16 Messagenumber,
- __u32 adr)
-{
-
- capi_cmsg_header(cmsg, ApplId, 0x88, 0x83, Messagenumber, adr);
-}
-
-static inline void capi_fill_DATA_B3_RESP(_cmsg * cmsg, __u16 ApplId, __u16 Messagenumber,
- __u32 adr,
- __u16 DataHandle)
-{
-
- capi_cmsg_header(cmsg, ApplId, 0x86, 0x83, Messagenumber, adr);
- cmsg->DataHandle = DataHandle;
-}
-
-static inline void capi_fill_DISCONNECT_B3_RESP(_cmsg * cmsg, __u16 ApplId, __u16 Messagenumber,
- __u32 adr)
-{
-
- capi_cmsg_header(cmsg, ApplId, 0x84, 0x83, Messagenumber, adr);
-}
-
-static inline void capi_fill_DISCONNECT_RESP(_cmsg * cmsg, __u16 ApplId, __u16 Messagenumber,
- __u32 adr)
-{
-
- capi_cmsg_header(cmsg, ApplId, 0x04, 0x83, Messagenumber, adr);
-}
-
-static inline void capi_fill_FACILITY_RESP(_cmsg * cmsg, __u16 ApplId, __u16 Messagenumber,
- __u32 adr,
- __u16 FacilitySelector)
-{
-
- capi_cmsg_header(cmsg, ApplId, 0x80, 0x83, Messagenumber, adr);
- cmsg->FacilitySelector = FacilitySelector;
-}
-
-static inline void capi_fill_INFO_RESP(_cmsg * cmsg, __u16 ApplId, __u16 Messagenumber,
- __u32 adr)
-{
-
- capi_cmsg_header(cmsg, ApplId, 0x08, 0x83, Messagenumber, adr);
-}
-
-static inline void capi_fill_MANUFACTURER_RESP(_cmsg * cmsg, __u16 ApplId, __u16 Messagenumber,
- __u32 adr,
- __u32 ManuID,
- __u32 Class,
- __u32 Function,
- _cstruct ManuData)
-{
-
- capi_cmsg_header(cmsg, ApplId, 0xff, 0x83, Messagenumber, adr);
- cmsg->ManuID = ManuID;
- cmsg->Class = Class;
- cmsg->Function = Function;
- cmsg->ManuData = ManuData;
-}
-
-static inline void capi_fill_RESET_B3_RESP(_cmsg * cmsg, __u16 ApplId, __u16 Messagenumber,
- __u32 adr)
-{
-
- capi_cmsg_header(cmsg, ApplId, 0x87, 0x83, Messagenumber, adr);
-}
-
#endif /* __CAPIUTIL_H__ */
diff --git a/include/linux/kernelcapi.h b/include/linux/kernelcapi.h
index 075fab5f92e1..94ba42bf9da1 100644
--- a/include/linux/kernelcapi.h
+++ b/include/linux/kernelcapi.h
@@ -10,46 +10,12 @@
#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>
-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 register_capictr_notifier(struct notifier_block *nb);
-int unregister_capictr_notifier(struct notifier_block *nb);
-
#define CAPI_NOERROR 0x0000
#define CAPI_TOOMANYAPPLS 0x1001
@@ -76,45 +42,4 @@ int unregister_capictr_notifier(struct notifier_block *nb);
#define CAPI_MSGCTRLERNOTSUPPORTEXTEQUIP 0x110a
#define CAPI_MSGCTRLERONLYSUPPORTEXTEQUIP 0x110b
-typedef enum {
- CapiMessageNotSupportedInCurrentState = 0x2001,
- CapiIllContrPlciNcci = 0x2002,
- CapiNoPlciAvailable = 0x2003,
- CapiNoNcciAvailable = 0x2004,
- CapiNoListenResourcesAvailable = 0x2005,
- CapiNoFaxResourcesAvailable = 0x2006,
- CapiIllMessageParmCoding = 0x2007,
-} RESOURCE_CODING_PROBLEM;
-
-typedef enum {
- CapiB1ProtocolNotSupported = 0x3001,
- CapiB2ProtocolNotSupported = 0x3002,
- CapiB3ProtocolNotSupported = 0x3003,
- CapiB1ProtocolParameterNotSupported = 0x3004,
- CapiB2ProtocolParameterNotSupported = 0x3005,
- CapiB3ProtocolParameterNotSupported = 0x3006,
- CapiBProtocolCombinationNotSupported = 0x3007,
- CapiNcpiNotSupported = 0x3008,
- CapiCipValueUnknown = 0x3009,
- CapiFlagsNotSupported = 0x300a,
- CapiFacilityNotSupported = 0x300b,
- CapiDataLengthNotSupportedByCurrentProtocol = 0x300c,
- CapiResetProcedureNotSupportedByCurrentProtocol = 0x300d,
- CapiTeiAssignmentFailed = 0x300e,
-} REQUESTED_SERVICES_PROBLEM;
-
-typedef enum {
- CapiSuccess = 0x0000,
- CapiSupplementaryServiceNotSupported = 0x300e,
- CapiRequestNotAllowedInThisState = 0x3010,
-} SUPPLEMENTARY_SERVICE_INFO;
-
-typedef enum {
- CapiProtocolErrorLayer1 = 0x3301,
- CapiProtocolErrorLayer2 = 0x3302,
- CapiProtocolErrorLayer3 = 0x3303,
- CapiTimeOut = 0x3303, // SuppServiceReason
- CapiCallGivenToOtherApplication = 0x3304,
-} CAPI_REASON;
-
#endif /* __KERNELCAPI_H__ */
diff --git a/include/uapi/linux/b1lli.h b/include/uapi/linux/b1lli.h
deleted file mode 100644
index 4ae6ac9950df..000000000000
--- a/include/uapi/linux/b1lli.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-/* $Id: b1lli.h,v 1.8.8.3 2001/09/23 22:25:05 kai Exp $
- *
- * ISDN lowlevel-module for AVM B1-card.
- *
- * Copyright 1996 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 _B1LLI_H_
-#define _B1LLI_H_
-/*
- * struct for loading t4 file
- */
-typedef struct avmb1_t4file {
- int len;
- unsigned char *data;
-} avmb1_t4file;
-
-typedef struct avmb1_loaddef {
- int contr;
- avmb1_t4file t4file;
-} avmb1_loaddef;
-
-typedef struct avmb1_loadandconfigdef {
- int contr;
- avmb1_t4file t4file;
- avmb1_t4file t4config;
-} avmb1_loadandconfigdef;
-
-typedef struct avmb1_resetdef {
- int contr;
-} avmb1_resetdef;
-
-typedef struct avmb1_getdef {
- int contr;
- int cardtype;
- int cardstate;
-} avmb1_getdef;
-
-/*
- * struct for adding new cards
- */
-typedef struct avmb1_carddef {
- int port;
- int irq;
-} avmb1_carddef;
-
-#define AVM_CARDTYPE_B1 0
-#define AVM_CARDTYPE_T1 1
-#define AVM_CARDTYPE_M1 2
-#define AVM_CARDTYPE_M2 3
-
-typedef struct avmb1_extcarddef {
- int port;
- int irq;
- int cardtype;
- int cardnr; /* for HEMA/T1 */
-} avmb1_extcarddef;
-
-#define AVMB1_LOAD 0 /* load image to card */
-#define AVMB1_ADDCARD 1 /* add a new card - OBSOLETE */
-#define AVMB1_RESETCARD 2 /* reset a card */
-#define AVMB1_LOAD_AND_CONFIG 3 /* load image and config to card */
-#define AVMB1_ADDCARD_WITH_TYPE 4 /* add a new card, with cardtype */
-#define AVMB1_GET_CARDINFO 5 /* get cardtype */
-#define AVMB1_REMOVECARD 6 /* remove a card - OBSOLETE */
-
-#define AVMB1_REGISTERCARD_IS_OBSOLETE
-
-#endif /* _B1LLI_H_ */
diff --git a/include/uapi/linux/gigaset_dev.h b/include/uapi/linux/gigaset_dev.h
deleted file mode 100644
index 279551af8ebf..000000000000
--- a/include/uapi/linux/gigaset_dev.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
-/*
- * interface to user space for the gigaset driver
- *
- * Copyright (c) 2004 by Hansjoerg Lipp <hjlipp@web.de>
- *
- * =====================================================================
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- * =====================================================================
- */
-
-#ifndef GIGASET_INTERFACE_H
-#define GIGASET_INTERFACE_H
-
-#include <linux/ioctl.h>
-
-/* The magic IOCTL value for this interface. */
-#define GIGASET_IOCTL 0x47
-
-/* enable/disable device control via character device (lock out ISDN subsys) */
-#define GIGASET_REDIR _IOWR(GIGASET_IOCTL, 0, int)
-
-/* enable adapter configuration mode (M10x only) */
-#define GIGASET_CONFIG _IOWR(GIGASET_IOCTL, 1, int)
-
-/* set break characters (M105 only) */
-#define GIGASET_BRKCHARS _IOW(GIGASET_IOCTL, 2, unsigned char[6])
-
-/* get version information selected by arg[0] */
-#define GIGASET_VERSION _IOWR(GIGASET_IOCTL, 3, unsigned[4])
-/* values for GIGASET_VERSION arg[0] */
-#define GIGVER_DRIVER 0 /* get driver version */
-#define GIGVER_COMPAT 1 /* get interface compatibility version */
-#define GIGVER_FWBASE 2 /* get base station firmware version */
-
-#endif
diff --git a/include/uapi/linux/hysdn_if.h b/include/uapi/linux/hysdn_if.h
deleted file mode 100644
index 99f77c517e6d..000000000000
--- a/include/uapi/linux/hysdn_if.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-/* $Id: hysdn_if.h,v 1.1.8.3 2001/09/23 22:25:05 kai Exp $
- *
- * Linux driver for HYSDN cards
- * ioctl definitions shared by hynetmgr and driver.
- *
- * Author Werner Cornelius (werner@titro.de) for Hypercope GmbH
- * Copyright 1999 by Werner Cornelius (werner@titro.de)
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-/****************/
-/* error values */
-/****************/
-#define ERR_NONE 0 /* no error occurred */
-#define ERR_ALREADY_BOOT 1000 /* we are already booting */
-#define EPOF_BAD_MAGIC 1001 /* bad magic in POF header */
-#define ERR_BOARD_DPRAM 1002 /* board DPRAM failed */
-#define EPOF_INTERNAL 1003 /* internal POF handler error */
-#define EPOF_BAD_IMG_SIZE 1004 /* POF boot image size invalid */
-#define ERR_BOOTIMG_FAIL 1005 /* 1. stage boot image did not start */
-#define ERR_BOOTSEQ_FAIL 1006 /* 2. stage boot seq handshake timeout */
-#define ERR_POF_TIMEOUT 1007 /* timeout waiting for card pof ready */
-#define ERR_NOT_BOOTED 1008 /* operation only allowed when booted */
-#define ERR_CONF_LONG 1009 /* conf line is too long */
-#define ERR_INV_CHAN 1010 /* invalid channel number */
-#define ERR_ASYNC_TIME 1011 /* timeout sending async data */
-
-
-
-