Merge tag 'staging-5.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 29 Jan 2020 18:15:11 +0000 (10:15 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 29 Jan 2020 18:15:11 +0000 (10:15 -0800)
Pull staging and IIO updates from Greg KH:
 "Here is the big staging/iio driver patches for 5.6-rc1

  Included in here are:

   - lots of new IIO drivers and updates for that subsystem

   - the usual huge quantity of minor cleanups for staging drivers

   - removal of the following staging drivers:
       - isdn/avm
       - isdn/gigaset
       - isdn/hysdn
       - octeon-usb
       - octeon ethernet

  Overall we deleted far more lines than we added, removing over 40k of
  old and obsolete driver code.

  All of these changes have been in linux-next for a while with no
  reported issues"

* tag 'staging-5.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (353 commits)
  staging: most: usb: check for NULL device
  staging: next: configfs: fix release link
  staging: most: core: fix logging messages
  staging: most: core: remove container struct
  staging: most: remove struct device core driver
  staging: most: core: drop device reference
  staging: most: remove device from interface structure
  staging: comedi: drivers: fix spelling mistake "to" -> "too"
  staging: exfat: remove fs_func struct.
  staging: wilc1000: avoid mutex unlock without lock in wilc_wlan_handle_txq()
  staging: wilc1000: return zero on success and non-zero on function failure
  staging: axis-fifo: replace spinlock with mutex
  staging: wilc1000: remove unused code prior to throughput enhancement in SPI
  staging: wilc1000: added 'wilc_' prefix for 'struct assoc_resp' name
  staging: wilc1000: move firmware API struct's to separate header file
  staging: wilc1000: remove use of infinite loop conditions
  staging: kpc2000: rename variables with kpc namespace
  staging: vt6656: Remove memory buffer from vnt_download_firmware.
  staging: vt6656: Just check NEWRSR_DECRYPTOK for RX_FLAG_DECRYPTED.
  staging: vt6656: Use vnt_rx_tail struct for tail variables.
  ...

353 files changed:
Documentation/ABI/testing/sysfs-bus-iio
Documentation/ABI/testing/sysfs-bus-iio-dma-buffer [new file with mode: 0644]
Documentation/devicetree/bindings/iio/accel/adi,adis16240.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/iio/accel/bma180.txt
Documentation/devicetree/bindings/iio/accel/bosch,bma400.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/iio/accel/kionix,kxcjk1013.txt
Documentation/devicetree/bindings/iio/adc/adi,ad7091r5.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/iio/adc/lltc,ltc2496.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/iio/adc/sigma-delta-modulator.txt [deleted file]
Documentation/devicetree/bindings/iio/adc/sigma-delta-modulator.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/iio/imu/adi,adis16480.txt
Documentation/devicetree/bindings/iio/pressure/asc,dlhl60d.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/iio/proximity/parallax-ping.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/iio/temperature/maxim_thermocouple.txt
Documentation/devicetree/bindings/vendor-prefixes.yaml
Documentation/isdn/avmb1.rst [deleted file]
Documentation/isdn/gigaset.rst [deleted file]
Documentation/isdn/hysdn.rst [deleted file]
Documentation/isdn/index.rst
Documentation/isdn/interface_capi.rst
Documentation/userspace-api/ioctl/ioctl-number.rst
MAINTAINERS
drivers/iio/accel/Kconfig
drivers/iio/accel/Makefile
drivers/iio/accel/adis16201.c
drivers/iio/accel/adis16209.c
drivers/iio/accel/bma180.c
drivers/iio/accel/bma400.h [new file with mode: 0644]
drivers/iio/accel/bma400_core.c [new file with mode: 0644]
drivers/iio/accel/bma400_i2c.c [new file with mode: 0644]
drivers/iio/accel/kxcjk-1013.c
drivers/iio/accel/st_accel.h
drivers/iio/accel/st_accel_i2c.c
drivers/iio/accel/st_accel_spi.c
drivers/iio/adc/Kconfig
drivers/iio/adc/Makefile
drivers/iio/adc/ad7091r-base.c [new file with mode: 0644]
drivers/iio/adc/ad7091r-base.h [new file with mode: 0644]
drivers/iio/adc/ad7091r5.c [new file with mode: 0644]
drivers/iio/adc/ad7124.c
drivers/iio/adc/ad7266.c
drivers/iio/adc/ad7780.c
drivers/iio/adc/ad7791.c
drivers/iio/adc/ad7793.c
drivers/iio/adc/ad7887.c
drivers/iio/adc/ad7923.c
drivers/iio/adc/ad799x.c
drivers/iio/adc/ad_sigma_delta.c
drivers/iio/adc/at91-sama5d2_adc.c
drivers/iio/adc/ltc2496.c [new file with mode: 0644]
drivers/iio/adc/ltc2497-core.c [new file with mode: 0644]
drivers/iio/adc/ltc2497.c
drivers/iio/adc/ltc2497.h [new file with mode: 0644]
drivers/iio/adc/max9611.c
drivers/iio/adc/stm32-adc-core.c
drivers/iio/adc/stm32-adc-core.h
drivers/iio/adc/stm32-adc.c
drivers/iio/adc/stm32-dfsdm-adc.c
drivers/iio/adc/ti-ads1015.c
drivers/iio/adc/ti-ads7950.c
drivers/iio/buffer/industrialio-buffer-dma.c
drivers/iio/buffer/industrialio-buffer-dmaengine.c
drivers/iio/buffer/kfifo_buf.c
drivers/iio/chemical/Makefile
drivers/iio/chemical/atlas-ph-sensor.c [deleted file]
drivers/iio/chemical/atlas-sensor.c [new file with mode: 0644]
drivers/iio/common/ssp_sensors/ssp.h
drivers/iio/common/ssp_sensors/ssp_dev.c
drivers/iio/common/ssp_sensors/ssp_spi.c
drivers/iio/common/st_sensors/st_sensors_core.c
drivers/iio/common/st_sensors/st_sensors_i2c.c
drivers/iio/common/st_sensors/st_sensors_spi.c
drivers/iio/common/st_sensors/st_sensors_trigger.c
drivers/iio/dac/ad5592r-base.c
drivers/iio/dac/ad7303.c
drivers/iio/dac/stm32-dac-core.c
drivers/iio/frequency/adf4350.c
drivers/iio/gyro/Kconfig
drivers/iio/gyro/adis16136.c
drivers/iio/gyro/adis16260.c
drivers/iio/gyro/itg3200_core.c
drivers/iio/gyro/st_gyro.h
drivers/iio/gyro/st_gyro_core.c
drivers/iio/gyro/st_gyro_i2c.c
drivers/iio/gyro/st_gyro_spi.c
drivers/iio/humidity/dht11.c
drivers/iio/humidity/hts221_core.c
drivers/iio/iio_core.h
drivers/iio/imu/adis.c
drivers/iio/imu/adis16400.c
drivers/iio/imu/adis16460.c
drivers/iio/imu/adis16480.c
drivers/iio/imu/adis_buffer.c
drivers/iio/imu/inv_mpu6050/Kconfig
drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c
drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
drivers/iio/imu/inv_mpu6050/inv_mpu_magn.c
drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c
drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c
drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c
drivers/iio/industrialio-buffer.c
drivers/iio/industrialio-core.c
drivers/iio/light/apds9960.c
drivers/iio/light/lm3533-als.c
drivers/iio/light/si1145.c
drivers/iio/light/st_uvis25_i2c.c
drivers/iio/magnetometer/ak8975.c
drivers/iio/magnetometer/st_magn_i2c.c
drivers/iio/magnetometer/st_magn_spi.c
drivers/iio/pressure/Kconfig
drivers/iio/pressure/Makefile
drivers/iio/pressure/bmp280-i2c.c
drivers/iio/pressure/dlhl60d.c [new file with mode: 0644]
drivers/iio/pressure/st_pressure.h
drivers/iio/pressure/st_pressure_i2c.c
drivers/iio/pressure/st_pressure_spi.c
drivers/iio/proximity/Kconfig
drivers/iio/proximity/Makefile
drivers/iio/proximity/as3935.c
drivers/iio/proximity/ping.c [new file with mode: 0644]
drivers/iio/resolver/ad2s1200.c
drivers/iio/temperature/max31856.c
drivers/iio/temperature/maxim_thermocouple.c
drivers/iio/trigger/stm32-timer-trigger.c
drivers/isdn/Makefile
drivers/isdn/capi/Kconfig
drivers/isdn/capi/Makefile
drivers/isdn/capi/capi.c
drivers/isdn/capi/capilib.c [deleted file]
drivers/isdn/capi/capiutil.c
drivers/isdn/capi/kcapi.c
drivers/isdn/capi/kcapi.h
drivers/isdn/capi/kcapi_proc.c
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/android/ashmem.c
drivers/staging/axis-fifo/axis-fifo.c
drivers/staging/comedi/drivers/das6402.c
drivers/staging/exfat/Kconfig
drivers/staging/exfat/Makefile
drivers/staging/exfat/exfat.h
drivers/staging/exfat/exfat_blkdev.c
drivers/staging/exfat/exfat_core.c
drivers/staging/exfat/exfat_super.c
drivers/staging/hp/hp100.c
drivers/staging/iio/accel/adis16203.c
drivers/staging/iio/accel/adis16240.c
drivers/staging/isdn/Kconfig [deleted file]
drivers/staging/isdn/Makefile [deleted file]
drivers/staging/isdn/TODO [deleted file]
drivers/staging/isdn/avm/Kconfig [deleted file]
drivers/staging/isdn/avm/Makefile [deleted file]
drivers/staging/isdn/avm/avm_cs.c [deleted file]
drivers/staging/isdn/avm/avmcard.h [deleted file]
drivers/staging/isdn/avm/b1.c [deleted file]
drivers/staging/isdn/avm/b1dma.c [deleted file]
drivers/staging/isdn/avm/b1isa.c [deleted file]
drivers/staging/isdn/avm/b1pci.c [deleted file]
drivers/staging/isdn/avm/b1pcmcia.c [deleted file]
drivers/staging/isdn/avm/c4.c [deleted file]
drivers/staging/isdn/avm/t1isa.c [deleted file]
drivers/staging/isdn/avm/t1pci.c [deleted file]
drivers/staging/isdn/gigaset/Kconfig [deleted file]
drivers/staging/isdn/gigaset/Makefile [deleted file]
drivers/staging/isdn/gigaset/asyncdata.c [deleted file]
drivers/staging/isdn/gigaset/bas-gigaset.c [deleted file]
drivers/staging/isdn/gigaset/capi.c [deleted file]
drivers/staging/isdn/gigaset/common.c [deleted file]
drivers/staging/isdn/gigaset/dummyll.c [deleted file]
drivers/staging/isdn/gigaset/ev-layer.c [deleted file]
drivers/staging/isdn/gigaset/gigaset.h [deleted file]
drivers/staging/isdn/gigaset/interface.c [deleted file]
drivers/staging/isdn/gigaset/isocdata.c [deleted file]
drivers/staging/isdn/gigaset/proc.c [deleted file]
drivers/staging/isdn/gigaset/ser-gigaset.c [deleted file]
drivers/staging/isdn/gigaset/usb-gigaset.c [deleted file]
drivers/staging/isdn/hysdn/Kconfig [deleted file]
drivers/staging/isdn/hysdn/Makefile [deleted file]
drivers/staging/isdn/hysdn/boardergo.c [deleted file]
drivers/staging/isdn/hysdn/boardergo.h [deleted file]
drivers/staging/isdn/hysdn/hycapi.c [deleted file]
drivers/staging/isdn/hysdn/hysdn_boot.c [deleted file]
drivers/staging/isdn/hysdn/hysdn_defs.h [deleted file]
drivers/staging/isdn/hysdn/hysdn_init.c [deleted file]
drivers/staging/isdn/hysdn/hysdn_net.c [deleted file]
drivers/staging/isdn/hysdn/hysdn_pof.h [deleted file]
drivers/staging/isdn/hysdn/hysdn_procconf.c [deleted file]
drivers/staging/isdn/hysdn/hysdn_proclog.c [deleted file]
drivers/staging/isdn/hysdn/hysdn_sched.c [deleted file]
drivers/staging/isdn/hysdn/ince1pc.h [deleted file]
drivers/staging/kpc2000/kpc2000_i2c.c
drivers/staging/kpc2000/kpc_dma/fileops.c
drivers/staging/most/Makefile
drivers/staging/most/cdev/Makefile
drivers/staging/most/cdev/cdev.c
drivers/staging/most/configfs.c
drivers/staging/most/core.c
drivers/staging/most/core.h [deleted file]
drivers/staging/most/dim2/Makefile
drivers/staging/most/dim2/dim2.c
drivers/staging/most/i2c/Makefile
drivers/staging/most/i2c/i2c.c
drivers/staging/most/most.h [new file with mode: 0644]
drivers/staging/most/net/Makefile
drivers/staging/most/net/net.c
drivers/staging/most/sound/Makefile
drivers/staging/most/sound/sound.c
drivers/staging/most/usb/Makefile
drivers/staging/most/usb/usb.c
drivers/staging/most/video/Makefile
drivers/staging/most/video/video.c
drivers/staging/mt7621-dts/mt7621.dtsi
drivers/staging/nvec/nvec_kbd.c
drivers/staging/octeon-usb/Kconfig [deleted file]
drivers/staging/octeon-usb/Makefile [deleted file]
drivers/staging/octeon-usb/TODO [deleted file]
drivers/staging/octeon-usb/octeon-hcd.c [deleted file]
drivers/staging/octeon-usb/octeon-hcd.h [deleted file]
drivers/staging/octeon/Kconfig [deleted file]
drivers/staging/octeon/Makefile [deleted file]
drivers/staging/octeon/TODO [deleted file]
drivers/staging/octeon/ethernet-defines.h [deleted file]
drivers/staging/octeon/ethernet-mdio.c [deleted file]
drivers/staging/octeon/ethernet-mdio.h [deleted file]
drivers/staging/octeon/ethernet-mem.c [deleted file]
drivers/staging/octeon/ethernet-mem.h [deleted file]
drivers/staging/octeon/ethernet-rgmii.c [deleted file]
drivers/staging/octeon/ethernet-rx.c [deleted file]
drivers/staging/octeon/ethernet-rx.h [deleted file]
drivers/staging/octeon/ethernet-sgmii.c [deleted file]
drivers/staging/octeon/ethernet-spi.c [deleted file]
drivers/staging/octeon/ethernet-tx.c [deleted file]
drivers/staging/octeon/ethernet-tx.h [deleted file]
drivers/staging/octeon/ethernet-util.h [deleted file]
drivers/staging/octeon/ethernet.c [deleted file]
drivers/staging/octeon/octeon-ethernet.h [deleted file]
drivers/staging/octeon/octeon-stubs.h [deleted file]
drivers/staging/qlge/qlge.h
drivers/staging/qlge/qlge_dbg.c
drivers/staging/qlge/qlge_ethtool.c
drivers/staging/qlge/qlge_main.c
drivers/staging/qlge/qlge_mpi.c
drivers/staging/rtl8188eu/core/rtw_ap.c
drivers/staging/rtl8188eu/core/rtw_efuse.c
drivers/staging/rtl8188eu/core/rtw_ieee80211.c
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
drivers/staging/rtl8188eu/core/rtw_pwrctrl.c
drivers/staging/rtl8188eu/core/rtw_wlan_util.c
drivers/staging/rtl8188eu/core/rtw_xmit.c
drivers/staging/rtl8188eu/hal/odm.c
drivers/staging/rtl8188eu/hal/odm_rtl8188e.c
drivers/staging/rtl8188eu/hal/phy.c
drivers/staging/rtl8188eu/hal/rtl8188e_dm.c
drivers/staging/rtl8188eu/include/hal8188e_phy_cfg.h
drivers/staging/rtl8188eu/include/hal_intf.h
drivers/staging/rtl8188eu/include/ieee80211.h
drivers/staging/rtl8188eu/include/odm.h
drivers/staging/rtl8188eu/include/rtl8188e_dm.h
drivers/staging/rtl8188eu/include/rtw_rf.h
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
drivers/staging/rtl8192e/rtl8192e/rtl_core.c
drivers/staging/rtl8192u/Makefile
drivers/staging/rtl8192u/ieee80211/Makefile [deleted file]
drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
drivers/staging/rtl8192u/r8192U_core.c
drivers/staging/rtl8192u/r8192U_wx.c
drivers/staging/rtl8192u/r819xU_phy.c
drivers/staging/rtl8712/rtl8712_recv.c
drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
drivers/staging/rtl8723bs/hal/HalPhyRf.c
drivers/staging/rtl8723bs/hal/HalPhyRf.h
drivers/staging/rtl8723bs/hal/HalPhyRf_8723B.c
drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c
drivers/staging/rts5208/Makefile
drivers/staging/rts5208/rtsx.c
drivers/staging/vc04_services/Makefile
drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c
drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
drivers/staging/vc04_services/interface/vchi/vchi.h
drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c
drivers/staging/vt6655/rf.c
drivers/staging/vt6656/baseband.c
drivers/staging/vt6656/device.h
drivers/staging/vt6656/dpc.c
drivers/staging/vt6656/firmware.c
drivers/staging/vt6656/int.c
drivers/staging/vt6656/main_usb.c
drivers/staging/vt6656/rxtx.c
drivers/staging/vt6656/usbpipe.c
drivers/staging/vt6656/usbpipe.h
drivers/staging/wfx/TODO
drivers/staging/wfx/bh.c
drivers/staging/wfx/bus_spi.c
drivers/staging/wfx/data_rx.c
drivers/staging/wfx/data_rx.h
drivers/staging/wfx/data_tx.c
drivers/staging/wfx/data_tx.h
drivers/staging/wfx/debug.c
drivers/staging/wfx/fwio.c
drivers/staging/wfx/hif_api_cmd.h
drivers/staging/wfx/hif_api_mib.h
drivers/staging/wfx/hif_rx.c
drivers/staging/wfx/hif_tx.c
drivers/staging/wfx/hif_tx.h
drivers/staging/wfx/hif_tx_mib.h
drivers/staging/wfx/hwio.h
drivers/staging/wfx/main.c
drivers/staging/wfx/queue.c
drivers/staging/wfx/queue.h
drivers/staging/wfx/scan.c
drivers/staging/wfx/scan.h
drivers/staging/wfx/secure_link.h
drivers/staging/wfx/sta.c
drivers/staging/wfx/sta.h
drivers/staging/wfx/traces.h
drivers/staging/wfx/wfx.h
drivers/staging/wilc1000/fw.h [new file with mode: 0644]
drivers/staging/wilc1000/hif.c
drivers/staging/wilc1000/hif.h
drivers/staging/wilc1000/netdev.c
drivers/staging/wilc1000/netdev.h
drivers/staging/wilc1000/sdio.c
drivers/staging/wilc1000/spi.c
drivers/staging/wilc1000/wlan.c
drivers/staging/wilc1000/wlan.h
drivers/staging/wilc1000/wlan_cfg.c
drivers/staging/wilc1000/wlan_if.h
drivers/staging/wlan-ng/prism2mgmt.c
include/linux/b1pcmcia.h [deleted file]
include/linux/iio/accel/kxcjk_1013.h
include/linux/iio/adc/ad_sigma_delta.h
include/linux/iio/buffer_impl.h
include/linux/iio/common/st_sensors.h
include/linux/iio/common/st_sensors_i2c.h
include/linux/iio/frequency/adf4350.h
include/linux/iio/imu/adis.h
include/linux/iio/magnetometer/ak8975.h [deleted file]
include/linux/iio/types.h
include/linux/isdn/capilli.h
include/linux/isdn/capiutil.h
include/linux/kernelcapi.h
include/linux/platform_data/ad7266.h
include/linux/platform_data/ads1015.h [deleted file]
include/uapi/linux/b1lli.h [deleted file]
include/uapi/linux/gigaset_dev.h [deleted file]
include/uapi/linux/hysdn_if.h [deleted file]

index faaa216..d3e53a6 100644 (file)
@@ -1726,3 +1726,16 @@ Contact: linux-iio@vger.kernel.org
 Description:
                List of valid periods (in seconds) for which the light intensity
                must be above the threshold level before interrupt is asserted.
+
+What:          /sys/bus/iio/devices/iio:deviceX/in_filter_notch_center_frequency
+KernelVersion: 5.5
+Contact:       linux-iio@vger.kernel.org
+Description:
+               Center frequency in Hz for a notch filter. Used i.e. for line
+               noise suppression.
+
+What:          /sys/bus/iio/devices/iio:deviceX/in_temp_thermocouple_type
+KernelVersion: 5.5
+Contact:       linux-iio@vger.kernel.org
+Description:
+               One of the following thermocouple types: B, E, J, K, N, R, S, T.
diff --git a/Documentation/ABI/testing/sysfs-bus-iio-dma-buffer b/Documentation/ABI/testing/sysfs-bus-iio-dma-buffer
new file mode 100644 (file)
index 0000000..d526e65
--- /dev/null
@@ -0,0 +1,19 @@
+What:          /sys/bus/iio/devices/iio:deviceX/buffer/length_align_bytes
+KernelVersion: 5.4
+Contact:       linux-iio@vger.kernel.org
+Description:
+               DMA buffers tend to have a alignment requirement for the
+               buffers. If this alignment requirement is not met samples might
+               be dropped from the buffer.
+
+               This property reports the alignment requirements in bytes.
+               This means that the buffer size in bytes needs to be a integer
+               multiple of the number reported by this file.
+
+               The alignment requirements in number of sample sets will depend
+               on the enabled channels and the bytes per channel. This means
+               that the alignment requirement in samples sets might change
+               depending on which and how many channels are enabled. Whereas
+               the alignment requirement reported in bytes by this property
+               will remain static and does not depend on which channels are
+               enabled.
diff --git a/Documentation/devicetree/bindings/iio/accel/adi,adis16240.yaml b/Documentation/devicetree/bindings/iio/accel/adi,adis16240.yaml
new file mode 100644 (file)
index 0000000..4147f02
--- /dev/null
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/accel/adi,adis16240.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ADIS16240 Programmable Impact Sensor and Recorder driver
+
+maintainers:
+  - Alexandru Ardelean <alexandru.ardelean@analog.com>
+
+description: |
+  ADIS16240 Programmable Impact Sensor and Recorder driver that supports
+  SPI interface.
+    https://www.analog.com/en/products/adis16240.html
+
+properties:
+  compatible:
+    enum:
+      - adi,adis16240
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    spi0 {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        /* Example for a SPI device node */
+        accelerometer@0 {
+            compatible = "adi,adis16240";
+            reg = <0>;
+            spi-max-frequency = <2500000>;
+            interrupt-parent = <&gpio0>;
+            interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+        };
+    };
index 3b25b4c..f532372 100644 (file)
@@ -1,11 +1,14 @@
-* Bosch BMA180 / BMA250 triaxial acceleration sensor
+* Bosch BMA180 / BMA25x triaxial acceleration sensor
 
 http://omapworld.com/BMA180_111_1002839.pdf
 http://ae-bst.resource.bosch.com/media/products/dokumente/bma250/bst-bma250-ds002-05.pdf
 
 Required properties:
 
-  - compatible : should be "bosch,bma180" or "bosch,bma250"
+  - compatible : should be one of:
+    "bosch,bma180"
+    "bosch,bma250"
+    "bosch,bma254"
   - reg : the I2C address of the sensor
 
 Optional properties:
diff --git a/Documentation/devicetree/bindings/iio/accel/bosch,bma400.yaml b/Documentation/devicetree/bindings/iio/accel/bosch,bma400.yaml
new file mode 100644 (file)
index 0000000..c1c6d6f
--- /dev/null
@@ -0,0 +1,54 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/accel/bosch,bma400.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Bosch BMA400 triaxial acceleration sensor
+
+maintainers:
+  - Dan Robertson <dan@dlrobertson.com>
+
+description: |
+  Acceleration and temperature iio sensors with an i2c interface
+
+  Specifications about the sensor can be found at:
+    https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BMA400-DS000.pdf
+
+properties:
+  compatible:
+    enum:
+      - bosch,bma400
+
+  reg:
+    maxItems: 1
+
+  vdd-supply:
+    description: phandle to the regulator that provides power to the accelerometer
+
+  vddio-supply:
+    description: phandle to the regulator that provides power to the sensor's IO
+
+  interrupts:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    i2c {
+      #address-cells = <1>;
+      #size-cells = <0>;
+      accelerometer@14 {
+        compatible = "bosch,bma400";
+        reg = <0x14>;
+        vdd-supply = <&vdd>;
+        vddio-supply = <&vddio>;
+        interrupt-parent = <&gpio0>;
+        interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+      };
+    };
index eb76a02..ce950e1 100644 (file)
@@ -9,9 +9,16 @@ Required properties:
     "kionix,kxtf9"
  - reg: i2c slave address
 
+Optional properties:
+
+  - mount-matrix: an optional 3x3 mounting rotation matrix
+
 Example:
 
 kxtf9@f {
        compatible = "kionix,kxtf9";
        reg = <0x0F>;
+       mount-matrix =  "0", "1", "0",
+                       "1", "0", "0",
+                       "0", "0", "1";
 };
diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7091r5.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad7091r5.yaml
new file mode 100644 (file)
index 0000000..31ffa27
--- /dev/null
@@ -0,0 +1,54 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/adc/adi,ad7091r5.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Analog Devices AD7091R5 4-Channel 12-Bit ADC
+
+maintainers:
+  - Beniamin Bia <beniamin.bia@analog.com>
+
+description: |
+  Analog Devices AD7091R5 4-Channel 12-Bit ADC
+  https://www.analog.com/media/en/technical-documentation/data-sheets/ad7091r-5.pdf
+
+properties:
+  compatible:
+    enum:
+      - adi,ad7091r5
+
+  reg:
+    maxItems: 1
+
+  vref-supply:
+    description:
+      Phandle to the vref power supply
+
+  interrupts:
+    maxItems: 1
+
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        adc@2f {
+                compatible = "adi,ad7091r5";
+                reg = <0x2f>;
+
+                interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
+                interrupt-parent = <&gpio>;
+        };
+    };
+...
diff --git a/Documentation/devicetree/bindings/iio/adc/lltc,ltc2496.yaml b/Documentation/devicetree/bindings/iio/adc/lltc,ltc2496.yaml
new file mode 100644 (file)
index 0000000..5900999
--- /dev/null
@@ -0,0 +1,47 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/adc/lltc,ltc2496.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Linear Technology / Analog Devices LTC2496 ADC
+
+maintainers:
+ - Lars-Peter Clausen <lars@metafoo.de>
+ - Michael Hennerich <Michael.Hennerich@analog.com>
+ - Stefan Popa <stefan.popa@analog.com>
+
+properties:
+  compatible:
+    enum:
+      - lltc,ltc2496
+
+  vref-supply:
+    description: phandle to an external regulator providing the reference voltage
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/phandle
+
+  reg:
+    description: spi chipselect number according to the usual spi bindings
+
+  spi-max-frequency:
+    description: maximal spi bus frequency supported
+
+required:
+  - compatible
+  - vref-supply
+  - reg
+
+examples:
+  - |
+    spi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        adc@0 {
+            compatible = "lltc,ltc2496";
+            reg = <0>;
+            vref-supply = <&ltc2496_reg>;
+            spi-max-frequency = <2000000>;
+        };
+    };
diff --git a/Documentation/devicetree/bindings/iio/adc/sigma-delta-modulator.txt b/Documentation/devicetree/bindings/iio/adc/sigma-delta-modulator.txt
deleted file mode 100644 (file)
index 59b92cd..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-Device-Tree bindings for sigma delta modulator
-
-Required properties:
-- compatible: should be "ads1201", "sd-modulator". "sd-modulator" can be use
-       as a generic SD modulator if modulator not specified in compatible list.
-- #io-channel-cells = <0>: See the IIO bindings section "IIO consumers".
-
-Example node:
-
-       ads1202: adc {
-               compatible = "sd-modulator";
-               #io-channel-cells = <0>;
-       };
diff --git a/Documentation/devicetree/bindings/iio/adc/sigma-delta-modulator.yaml b/Documentation/devicetree/bindings/iio/adc/sigma-delta-modulator.yaml
new file mode 100644 (file)
index 0000000..a390343
--- /dev/null
@@ -0,0 +1,37 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/adc/sigma-delta-modulator.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Device-Tree bindings for sigma delta modulator
+
+maintainers:
+  - Arnaud Pouliquen <arnaud.pouliquen@st.com>
+
+properties:
+  compatible:
+    description: |
+      "sd-modulator" can be used as a generic SD modulator,
+      if the modulator is not specified in the compatible list.
+    enum:
+      - sd-modulator
+      - ads1201
+
+  '#io-channel-cells':
+    const: 0
+
+required:
+  - compatible
+  - '#io-channel-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    ads1202: adc {
+      compatible = "sd-modulator";
+      #io-channel-cells = <0>;
+    };
+
+...
index ed7783f..cd903a1 100644 (file)
@@ -8,6 +8,7 @@ Required properties for the ADIS16480:
        * "adi,adis16480"
        * "adi,adis16485"
        * "adi,adis16488"
+       * "adi,adis16490"
        * "adi,adis16495-1"
        * "adi,adis16495-2"
        * "adi,adis16495-3"
diff --git a/Documentation/devicetree/bindings/iio/pressure/asc,dlhl60d.yaml b/Documentation/devicetree/bindings/iio/pressure/asc,dlhl60d.yaml
new file mode 100644 (file)
index 0000000..9f5ca9c
--- /dev/null
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/pressure/asc,dlhl60d.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: All Sensors DLH series low voltage digital pressure sensors
+
+maintainers:
+  - Tomislav Denis <tomislav.denis@avl.com>
+
+description: |
+  Bindings for the All Sensors DLH series pressure sensors.
+
+  Specifications about the sensors can be found at:
+    http://www.allsensors.com/cad/DS-0355_Rev_B.PDF
+
+properties:
+  compatible:
+    enum:
+      - asc,dlhl60d
+      - asc,dlhl60g
+
+  reg:
+    description: I2C device address
+    maxItems: 1
+
+  interrupts:
+    description: interrupt mapping for EOC(data ready) pin
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    i2c0 {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        pressure@29 {
+            compatible = "asc,dlhl60d";
+            reg = <0x29>;
+            interrupt-parent = <&gpio0>;
+            interrupts = <10 IRQ_TYPE_EDGE_RISING>;
+        };
+    };
+...
diff --git a/Documentation/devicetree/bindings/iio/proximity/parallax-ping.yaml b/Documentation/devicetree/bindings/iio/proximity/parallax-ping.yaml
new file mode 100644 (file)
index 0000000..a079c99
--- /dev/null
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/proximity/parallax-ping.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Parallax PING))) and LaserPING range finder
+
+maintainers:
+  - Andreas Klinger <ak@it-klinger.de>
+
+description: |
+  Bit-banging driver using one GPIO:
+  - ping-gpios is raised by the driver to start measurement
+  - direction of ping-gpio is then switched into input with an interrupt
+    for receiving distance value as PWM signal
+
+  Specifications about the devices can be found at:
+  http://parallax.com/sites/default/files/downloads/28041-LaserPING-2m-Rangefinder-Guide.pdf
+  http://parallax.com/sites/default/files/downloads/28015-PING-Documentation-v1.6.pdf
+
+properties:
+  compatible:
+    enum:
+      - parallax,ping
+      - parallax,laserping
+
+  ping-gpios:
+    description:
+      Definition of the GPIO for the triggering and echo (output and input)
+      This GPIO is set for about 5 us by the driver to tell the device it
+      should initiate the measurement cycle. Afterwards the GPIO is switched
+      to input direction with an interrupt. The device sets it and the
+      length of the input signal corresponds to the measured distance.
+      It needs to be an GPIO which is able to deliver an interrupt because
+      the time between two interrupts is measured in the driver.
+      See Documentation/devicetree/bindings/gpio/gpio.txt for information
+      on how to specify a consumer gpio.
+    maxItems: 1
+
+required:
+  - compatible
+  - ping-gpios
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    proximity {
+        compatible = "parallax,laserping";
+        ping-gpios = <&gpio0 26 GPIO_ACTIVE_HIGH>;
+    };
index 28bc5c4..bb85cd0 100644 (file)
@@ -5,7 +5,10 @@ Maxim thermocouple support
 
 Required properties:
 
-       - compatible: must be "maxim,max31855" or "maxim,max6675"
+       - compatible: must be "maxim,max6675" or one of the following:
+          "maxim,max31855k", "maxim,max31855j", "maxim,max31855n",
+          "maxim,max31855s", "maxim,max31855t", "maxim,max31855e",
+          "maxim,max31855r"; the generic "max,max31855" is deprecated.
        - reg: SPI chip select number for the device
        - spi-max-frequency: must be 4300000
        - spi-cpha: must be defined for max6675 to enable SPI mode 1
@@ -15,7 +18,7 @@ Required properties:
 Example:
 
        max31855@0 {
-               compatible = "maxim,max31855";
+               compatible = "maxim,max31855k";
                reg = <0>;
                spi-max-frequency = <4300000>;
        };
index 9cb3bc6..315ebac 100644 (file)
@@ -109,6 +109,8 @@ patternProperties:
     description: Artesyn Embedded Technologies Inc.
   "^asahi-kasei,.*":
     description: Asahi Kasei Corp.
+  "^asc,.*":
+    description: All Sensors Corporation
   "^aspeed,.*":
     description: ASPEED Technology Inc.
   "^asus,.*":
@@ -717,6 +719,8 @@ patternProperties:
     description: Panasonic Corporation
   "^parade,.*":
     description: Parade Technologies Inc.
+  "^parallax,.*":
+    description: Parallax Inc.
   "^pda,.*":
     description: Precision Design Associates, Inc.
   "^pericom,.*":
diff --git a/Documentation/isdn/avmb1.rst b/Documentation/isdn/avmb1.rst
deleted file mode 100644 (file)
index de3961e..0000000
+++ /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 (file)
index 98b4ec5..0000000
+++ /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 (file)
index 0a168d1..0000000
+++ /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).
index 407e74b..9622939 100644 (file)
@@ -9,9 +9,6 @@ ISDN
 
    interface_capi
 
-   avmb1
-   gigaset
-   hysdn
    m_isdn
 
    credits
index 01a4b5a..fe24214 100644 (file)
@@ -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)
@@ -300,13 +269,6 @@ register/unregister a device (controller) with Kernel CAPI
 
 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,
@@ -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
index 4ef8643..2e91370 100644 (file)
@@ -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!
index 5590daf..eb2ea59 100644 (file)
@@ -674,6 +674,14 @@ S: Maintained
 F:     Documentation/i2c/busses/i2c-ali1563.rst
 F:     drivers/i2c/busses/i2c-ali1563.c
 
+ALL SENSORS DLH SERIES PRESSURE SENSORS DRIVER
+M:     Tomislav Denis <tomislav.denis@avl.com>
+W:     http://www.allsensors.com/
+S:     Maintained
+L:     linux-iio@vger.kernel.org
+F:     drivers/iio/pressure/dlhl60d.c
+F:     Documentation/devicetree/bindings/iio/pressure/asc,dlhl60d.yaml
+
 ALLEGRO DVT VIDEO IP CORE DRIVER
 M:     Michael Tretter <m.tretter@pengutronix.de>
 R:     Pengutronix Kernel Team <kernel@pengutronix.de>
@@ -907,6 +915,14 @@ S: Supported
 F:     drivers/iio/dac/ad5758.c
 F:     Documentation/devicetree/bindings/iio/dac/ad5758.txt
 
+ANALOG DEVICES INC AD7091R5 DRIVER
+M:     Beniamin Bia <beniamin.bia@analog.com>
+L:     linux-iio@vger.kernel.org
+W:     http://ez.analog.com/community/linux-device-drivers
+S:     Supported
+F:     drivers/iio/adc/ad7091r5.c
+F:     Documentation/devicetree/bindings/iio/adc/adi,ad7091r5.yaml
+
 ANALOG DEVICES INC AD7124 DRIVER
 M:     Stefan Popa <stefan.popa@analog.com>
 L:     linux-iio@vger.kernel.org
@@ -1061,7 +1077,7 @@ S:        Supported
 F:     Documentation/ABI/testing/sysfs-bus-iio-frequency-ad9523
 F:     Documentation/ABI/testing/sysfs-bus-iio-frequency-adf4350
 F:     drivers/iio/*/ad*
-F:     drivers/iio/adc/ltc2497*
+F:     drivers/iio/adc/ltc249*
 X:     drivers/iio/*/adjd*
 F:     drivers/staging/iio/*/ad*
 
@@ -3116,6 +3132,13 @@ S:       Supported
 F:     drivers/net/bonding/
 F:     include/uapi/linux/if_bonding.h
 
+BOSCH SENSORTEC BMA400 ACCELEROMETER IIO DRIVER
+M:     Dan Robertson <dan@dlrobertson.com>
+L:     linux-iio@vger.kernel.org
+S:     Maintained
+F:     drivers/iio/accel/bma400*
+F:     Documentation/devicetree/bindings/iio/accel/bosch,bma400.yaml
+
 BPF (Safe dynamic programs and tools)
 M:     Alexei Starovoitov <ast@kernel.org>
 M:     Daniel Borkmann <daniel@iogearbox.net>
@@ -8862,7 +8885,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
@@ -8870,7 +8893,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/
@@ -12528,6 +12550,13 @@ L:     platform-driver-x86@vger.kernel.org
 S:     Maintained
 F:     drivers/platform/x86/panasonic-laptop.c
 
+PARALLAX PING IIO SENSOR DRIVER
+M:     Andreas Klinger <ak@it-klinger.de>
+L:     linux-iio@vger.kernel.org
+S:     Maintained
+F:     Documentation/devicetree/bindings/iio/proximity/parallax-ping.yaml
+F:     drivers/iio/proximity/ping.c
+
 PARALLEL LCD/KEYPAD PANEL DRIVER
 M:     Willy Tarreau <willy@haproxy.com>
 M:     Ksenija Stanojevic <ksenija.stanojevic@gmail.com>
index d4ef35a..5d91a6d 100644 (file)
@@ -89,13 +89,13 @@ config ADXL372_I2C
          module will be called adxl372_i2c.
 
 config BMA180
-       tristate "Bosch BMA180/BMA250 3-Axis Accelerometer Driver"
+       tristate "Bosch BMA180/BMA25x 3-Axis Accelerometer Driver"
        depends on I2C
        select IIO_BUFFER
        select IIO_TRIGGERED_BUFFER
        help
          Say Y here if you want to build a driver for the Bosch BMA180 or
-         BMA250 triaxial acceleration sensor.
+         BMA25x triaxial acceleration sensor.
 
          To compile this driver as a module, choose M here: the
          module will be called bma180.
@@ -112,6 +112,22 @@ config BMA220
          To compile this driver as a module, choose M here: the
          module will be called bma220_spi.
 
+config BMA400
+       tristate "Bosch BMA400 3-Axis Accelerometer Driver"
+       select REGMAP
+       select BMA400_I2C if I2C
+       help
+         Say Y here if you want to build a driver for the Bosch BMA400
+         triaxial acceleration sensor.
+
+         To compile this driver as a module, choose M here: the
+         module will be called bma400_core and you will also get
+         bma400_i2c if I2C is enabled.
+
+config BMA400_I2C
+       tristate
+       depends on BMA400
+
 config BMC150_ACCEL
        tristate "Bosch BMC150 Accelerometer Driver"
        select IIO_BUFFER
index 56bd021..3a051cf 100644 (file)
@@ -14,6 +14,8 @@ obj-$(CONFIG_ADXL372_I2C) += adxl372_i2c.o
 obj-$(CONFIG_ADXL372_SPI) += adxl372_spi.o
 obj-$(CONFIG_BMA180) += bma180.o
 obj-$(CONFIG_BMA220) += bma220_spi.o
+obj-$(CONFIG_BMA400) += bma400_core.o
+obj-$(CONFIG_BMA400_I2C) += bma400_i2c.o
 obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
 obj-$(CONFIG_BMC150_ACCEL_I2C) += bmc150-accel-i2c.o
 obj-$(CONFIG_BMC150_ACCEL_SPI) += bmc150-accel-spi.o
index c4810c7..0f0f27a 100644 (file)
@@ -233,6 +233,12 @@ static const char * const adis16201_status_error_msgs[] = {
        [ADIS16201_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 2.975V",
 };
 
+static const struct adis_timeout adis16201_timeouts = {
+       .reset_ms = ADIS16201_STARTUP_DELAY_MS,
+       .sw_reset_ms = ADIS16201_STARTUP_DELAY_MS,
+       .self_test_ms = ADIS16201_STARTUP_DELAY_MS,
+};
+
 static const struct adis_data adis16201_data = {
        .read_delay = 20,
        .msc_ctrl_reg = ADIS16201_MSC_CTRL_REG,
@@ -241,7 +247,7 @@ static const struct adis_data adis16201_data = {
 
        .self_test_mask = ADIS16201_MSC_CTRL_SELF_TEST_EN,
        .self_test_no_autoclear = true,
-       .startup_delay = ADIS16201_STARTUP_DELAY_MS,
+       .timeouts = &adis16201_timeouts,
 
        .status_error_msgs = adis16201_status_error_msgs,
        .status_error_mask = BIT(ADIS16201_DIAG_STAT_SPI_FAIL_BIT) |
index 98d77af..c6dbd24 100644 (file)
@@ -243,6 +243,12 @@ static const char * const adis16209_status_error_msgs[] = {
        [ADIS16209_STAT_POWER_LOW_BIT] = "Power supply below 2.975V",
 };
 
+static const struct adis_timeout adis16209_timeouts = {
+       .reset_ms = ADIS16209_STARTUP_DELAY_MS,
+       .self_test_ms = ADIS16209_STARTUP_DELAY_MS,
+       .sw_reset_ms = ADIS16209_STARTUP_DELAY_MS,
+};
+
 static const struct adis_data adis16209_data = {
        .read_delay = 30,
        .msc_ctrl_reg = ADIS16209_MSC_CTRL_REG,
@@ -251,7 +257,7 @@ static const struct adis_data adis16209_data = {
 
        .self_test_mask = ADIS16209_MSC_CTRL_SELF_TEST_EN,
        .self_test_no_autoclear = true,
-       .startup_delay = ADIS16209_STARTUP_DELAY_MS,
+       .timeouts = &adis16209_timeouts,
 
        .status_error_msgs = adis16209_status_error_msgs,
        .status_error_mask = BIT(ADIS16209_STAT_SELFTEST_FAIL_BIT) |
index 1574e46..fcd91d5 100644 (file)
@@ -9,6 +9,7 @@
  * SPI is not supported by driver
  * BMA180: 7-bit I2C slave address 0x40 or 0x41
  * BMA250: 7-bit I2C slave address 0x18 or 0x19
+ * BMA254: 7-bit I2C slave address 0x18 or 0x19
  */
 
 #include <linux/module.h>
@@ -18,6 +19,7 @@
 #include <linux/of_device.h>
 #include <linux/of.h>
 #include <linux/bitops.h>
+#include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/iio/iio.h>
 enum chip_ids {
        BMA180,
        BMA250,
+       BMA254,
 };
 
 struct bma180_data;
 
 struct bma180_part_info {
+       u8 chip_id;
        const struct iio_chan_spec *channels;
        unsigned int num_channels;
        const int *scale_table;
        unsigned int num_scales;
        const int *bw_table;
        unsigned int num_bw;
+       int center_temp;
 
        u8 int_reset_reg, int_reset_mask;
        u8 sleep_reg, sleep_mask;
@@ -51,6 +56,7 @@ struct bma180_part_info {
        u8 scale_reg, scale_mask;
        u8 power_reg, power_mask, lowpower_val;
        u8 int_enable_reg, int_enable_mask;
+       u8 int_map_reg, int_enable_dataready_int1_mask;
        u8 softreset_reg;
 
        int (*chip_config)(struct bma180_data *data);
@@ -89,6 +95,8 @@ struct bma180_part_info {
 #define BMA180_RESET_VAL       0xb6
 
 #define BMA180_ID_REG_VAL      0x03
+#define BMA250_ID_REG_VAL      0x03
+#define BMA254_ID_REG_VAL      0xfa /* 250 decimal */
 
 /* Chip power modes */
 #define BMA180_LOW_POWER       0x03
@@ -109,7 +117,26 @@ struct bma180_part_info {
 #define BMA250_INT1_DATA_MASK  BIT(0)
 #define BMA250_INT_RESET_MASK  BIT(7) /* Reset pending interrupts */
 
+#define BMA254_RANGE_REG       0x0f
+#define BMA254_BW_REG          0x10
+#define BMA254_POWER_REG       0x11
+#define BMA254_RESET_REG       0x14
+#define BMA254_INT_ENABLE_REG  0x17
+#define BMA254_INT_MAP_REG     0x1a
+#define BMA254_INT_RESET_REG   0x21
+
+#define BMA254_RANGE_MASK      GENMASK(3, 0) /* Range of accel values */
+#define BMA254_BW_MASK         GENMASK(4, 0) /* Accel bandwidth */
+#define BMA254_SUSPEND_MASK    BIT(7) /* chip will sleep */
+#define BMA254_LOWPOWER_MASK   BIT(6)
+#define BMA254_DATA_INTEN_MASK BIT(4)
+#define BMA254_INT2_DATA_MASK  BIT(7)
+#define BMA254_INT1_DATA_MASK  BIT(0)
+#define BMA254_INT_RESET_MASK  BIT(7) /* Reset pending interrupts */
+
 struct bma180_data {
+       struct regulator *vdd_supply;
+       struct regulator *vddio_supply;
        struct i2c_client *client;
        struct iio_trigger *trig;
        const struct bma180_part_info *part_info;
@@ -132,8 +159,8 @@ enum bma180_chan {
 static int bma180_bw_table[] = { 10, 20, 40, 75, 150, 300 }; /* Hz */
 static int bma180_scale_table[] = { 1275, 1863, 2452, 3727, 4903, 9709, 19417 };
 
-static int bma250_bw_table[] = { 8, 16, 31, 63, 125, 250 }; /* Hz */
-static int bma250_scale_table[] = { 0, 0, 0, 38344, 0, 76590, 0, 0, 153180, 0,
+static int bma25x_bw_table[] = { 8, 16, 31, 63, 125, 250 }; /* Hz */
+static int bma25x_scale_table[] = { 0, 0, 0, 38344, 0, 76590, 0, 0, 153180, 0,
        0, 0, 306458 };
 
 static int bma180_get_data_reg(struct bma180_data *data, enum bma180_chan chan)
@@ -307,8 +334,11 @@ static int bma180_chip_init(struct bma180_data *data)
 
        if (ret < 0)
                return ret;
-       if (ret != BMA180_ID_REG_VAL)
+       if (ret != data->part_info->chip_id) {
+               dev_err(&data->client->dev, "wrong chip ID %d expected %d\n",
+                       ret, data->part_info->chip_id);
                return -ENODEV;
+       }
 
        ret = bma180_soft_reset(data);
        if (ret)
@@ -355,7 +385,7 @@ err:
        return ret;
 }
 
-static int bma250_chip_config(struct bma180_data *data)
+static int bma25x_chip_config(struct bma180_data *data)
 {
        int ret = bma180_chip_init(data);
 
@@ -367,8 +397,12 @@ static int bma250_chip_config(struct bma180_data *data)
        ret = bma180_set_scale(data, 38344); /* 2 G */
        if (ret)
                goto err;
-       ret = bma180_set_bits(data, BMA250_INT_MAP_REG,
-               BMA250_INT1_DATA_MASK, 1);
+       /*
+        * This enables dataready interrupt on the INT1 pin
+        * FIXME: support using the INT2 pin
+        */
+       ret = bma180_set_bits(data, data->part_info->int_map_reg,
+               data->part_info->int_enable_dataready_int1_mask, 1);
        if (ret)
                goto err;
 
@@ -394,7 +428,7 @@ err:
        dev_err(&data->client->dev, "failed to disable the chip\n");
 }
 
-static void bma250_chip_disable(struct bma180_data *data)
+static void bma25x_chip_disable(struct bma180_data *data)
 {
        if (bma180_set_new_data_intr_state(data, false))
                goto err;
@@ -497,7 +531,7 @@ static int bma180_read_raw(struct iio_dev *indio_dev,
                        return -EINVAL;
                }
        case IIO_CHAN_INFO_OFFSET:
-               *val = 48; /* 0 LSB @ 24 degree C */
+               *val = data->part_info->center_temp;
                return IIO_VAL_INT;
        default:
                return -EINVAL;
@@ -627,34 +661,96 @@ static const struct iio_chan_spec bma250_channels[] = {
        IIO_CHAN_SOFT_TIMESTAMP(4),
 };
 
+static const struct iio_chan_spec bma254_channels[] = {
+       BMA180_ACC_CHANNEL(X, 12),
+       BMA180_ACC_CHANNEL(Y, 12),
+       BMA180_ACC_CHANNEL(Z, 12),
+       BMA180_TEMP_CHANNEL,
+       IIO_CHAN_SOFT_TIMESTAMP(4),
+};
+
 static const struct bma180_part_info bma180_part_info[] = {
        [BMA180] = {
-               bma180_channels, ARRAY_SIZE(bma180_channels),
-               bma180_scale_table, ARRAY_SIZE(bma180_scale_table),
-               bma180_bw_table, ARRAY_SIZE(bma180_bw_table),
-               BMA180_CTRL_REG0, BMA180_RESET_INT,
-               BMA180_CTRL_REG0, BMA180_SLEEP,
-               BMA180_BW_TCS, BMA180_BW,
-               BMA180_OFFSET_LSB1, BMA180_RANGE,
-               BMA180_TCO_Z, BMA180_MODE_CONFIG, BMA180_LOW_POWER,
-               BMA180_CTRL_REG3, BMA180_NEW_DATA_INT,
-               BMA180_RESET,
-               bma180_chip_config,
-               bma180_chip_disable,
+               .chip_id = BMA180_ID_REG_VAL,
+               .channels = bma180_channels,
+               .num_channels = ARRAY_SIZE(bma180_channels),
+               .scale_table = bma180_scale_table,
+               .num_scales = ARRAY_SIZE(bma180_scale_table),
+               .bw_table = bma180_bw_table,
+               .num_bw = ARRAY_SIZE(bma180_bw_table),
+               .center_temp = 48, /* 0 LSB @ 24 degree C */
+               .int_reset_reg = BMA180_CTRL_REG0,
+               .int_reset_mask = BMA180_RESET_INT,
+               .sleep_reg = BMA180_CTRL_REG0,
+               .sleep_mask = BMA180_SLEEP,
+               .bw_reg = BMA180_BW_TCS,
+               .bw_mask = BMA180_BW,
+               .scale_reg = BMA180_OFFSET_LSB1,
+               .scale_mask = BMA180_RANGE,
+               .power_reg = BMA180_TCO_Z,
+               .power_mask = BMA180_MODE_CONFIG,
+               .lowpower_val = BMA180_LOW_POWER,
+               .int_enable_reg = BMA180_CTRL_REG3,
+               .int_enable_mask = BMA180_NEW_DATA_INT,
+               .softreset_reg = BMA180_RESET,
+               .chip_config = bma180_chip_config,
+               .chip_disable = bma180_chip_disable,
        },
        [BMA250] = {
-               bma250_channels, ARRAY_SIZE(bma250_channels),
-               bma250_scale_table, ARRAY_SIZE(bma250_scale_table),
-               bma250_bw_table, ARRAY_SIZE(bma250_bw_table),
-               BMA250_INT_RESET_REG, BMA250_INT_RESET_MASK,
-               BMA250_POWER_REG, BMA250_SUSPEND_MASK,
-               BMA250_BW_REG, BMA250_BW_MASK,
-               BMA250_RANGE_REG, BMA250_RANGE_MASK,
-               BMA250_POWER_REG, BMA250_LOWPOWER_MASK, 1,
-               BMA250_INT_ENABLE_REG, BMA250_DATA_INTEN_MASK,
-               BMA250_RESET_REG,
-               bma250_chip_config,
-               bma250_chip_disable,
+               .chip_id = BMA250_ID_REG_VAL,
+               .channels = bma250_channels,
+               .num_channels = ARRAY_SIZE(bma250_channels),
+               .scale_table = bma25x_scale_table,
+               .num_scales = ARRAY_SIZE(bma25x_scale_table),
+               .bw_table = bma25x_bw_table,
+               .num_bw = ARRAY_SIZE(bma25x_bw_table),
+               .center_temp = 48, /* 0 LSB @ 24 degree C */
+               .int_reset_reg = BMA250_INT_RESET_REG,
+               .int_reset_mask = BMA250_INT_RESET_MASK,
+               .sleep_reg = BMA250_POWER_REG,
+               .sleep_mask = BMA250_SUSPEND_MASK,
+               .bw_reg = BMA250_BW_REG,
+               .bw_mask = BMA250_BW_MASK,
+               .scale_reg = BMA250_RANGE_REG,
+               .scale_mask = BMA250_RANGE_MASK,
+               .power_reg = BMA250_POWER_REG,
+               .power_mask = BMA250_LOWPOWER_MASK,
+               .lowpower_val = 1,
+               .int_enable_reg = BMA250_INT_ENABLE_REG,
+               .int_enable_mask = BMA250_DATA_INTEN_MASK,
+               .int_map_reg = BMA250_INT_MAP_REG,
+               .int_enable_dataready_int1_mask = BMA250_INT1_DATA_MASK,
+               .softreset_reg = BMA250_RESET_REG,
+               .chip_config = bma25x_chip_config,
+               .chip_disable = bma25x_chip_disable,
+       },
+       [BMA254] = {
+               .chip_id = BMA254_ID_REG_VAL,
+               .channels = bma254_channels,
+               .num_channels = ARRAY_SIZE(bma254_channels),
+               .scale_table = bma25x_scale_table,
+               .num_scales = ARRAY_SIZE(bma25x_scale_table),
+               .bw_table = bma25x_bw_table,
+               .num_bw = ARRAY_SIZE(bma25x_bw_table),
+               .center_temp = 46, /* 0 LSB @ 23 degree C */
+               .int_reset_reg = BMA254_INT_RESET_REG,
+               .int_reset_mask = BMA254_INT_RESET_MASK,
+               .sleep_reg = BMA254_POWER_REG,
+               .sleep_mask = BMA254_SUSPEND_MASK,
+               .bw_reg = BMA254_BW_REG,
+               .bw_mask = BMA254_BW_MASK,
+               .scale_reg = BMA254_RANGE_REG,
+               .scale_mask = BMA254_RANGE_MASK,
+               .power_reg = BMA254_POWER_REG,
+               .power_mask = BMA254_LOWPOWER_MASK,
+               .lowpower_val = 1,
+               .int_enable_reg = BMA254_INT_ENABLE_REG,
+               .int_enable_mask = BMA254_DATA_INTEN_MASK,
+               .int_map_reg = BMA254_INT_MAP_REG,
+               .int_enable_dataready_int1_mask = BMA254_INT1_DATA_MASK,
+               .softreset_reg = BMA254_RESET_REG,
+               .chip_config = bma25x_chip_config,
+               .chip_disable = bma25x_chip_disable,
        },
 };
 
@@ -712,12 +808,13 @@ static const struct iio_trigger_ops bma180_trigger_ops = {
 static int bma180_probe(struct i2c_client *client,
                const struct i2c_device_id *id)
 {
+       struct device *dev = &client->dev;
        struct bma180_data *data;
        struct iio_dev *indio_dev;
        enum chip_ids chip;
        int ret;
 
-       indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+       indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
        if (!indio_dev)
                return -ENOMEM;
 
@@ -725,22 +822,56 @@ static int bma180_probe(struct i2c_client *client,
        i2c_set_clientdata(client, indio_dev);
        data->client = client;
        if (client->dev.of_node)
-               chip = (enum chip_ids)of_device_get_match_data(&client->dev);
+               chip = (enum chip_ids)of_device_get_match_data(dev);
        else
                chip = id->driver_data;
        data->part_info = &bma180_part_info[chip];
 
-       ret = iio_read_mount_matrix(&client->dev, "mount-matrix",
+       ret = iio_read_mount_matrix(dev, "mount-matrix",
                                &data->orientation);
        if (ret)
                return ret;
 
+       data->vdd_supply = devm_regulator_get(dev, "vdd");
+       if (IS_ERR(data->vdd_supply)) {
+               if (PTR_ERR(data->vdd_supply) != -EPROBE_DEFER)
+                       dev_err(dev, "Failed to get vdd regulator %d\n",
+                               (int)PTR_ERR(data->vdd_supply));
+               return PTR_ERR(data->vdd_supply);
+       }
+       data->vddio_supply = devm_regulator_get(dev, "vddio");
+       if (IS_ERR(data->vddio_supply)) {
+               if (PTR_ERR(data->vddio_supply) != -EPROBE_DEFER)
+                       dev_err(dev, "Failed to get vddio regulator %d\n",
+                               (int)PTR_ERR(data->vddio_supply));
+               return PTR_ERR(data->vddio_supply);
+       }
+       /* Typical voltage 2.4V these are min and max */
+       ret = regulator_set_voltage(data->vdd_supply, 1620000, 3600000);
+       if (ret)
+               return ret;
+       ret = regulator_set_voltage(data->vddio_supply, 1200000, 3600000);
+       if (ret)
+               return ret;
+       ret = regulator_enable(data->vdd_supply);
+       if (ret) {
+               dev_err(dev, "Failed to enable vdd regulator: %d\n", ret);
+               return ret;
+       }
+       ret = regulator_enable(data->vddio_supply);
+       if (ret) {
+               dev_err(dev, "Failed to enable vddio regulator: %d\n", ret);
+               goto err_disable_vdd;
+       }
+       /* Wait to make sure we started up properly (3 ms at least) */
+       usleep_range(3000, 5000);
+
        ret = data->part_info->chip_config(data);
        if (ret < 0)
                goto err_chip_disable;
 
        mutex_init(&data->mutex);
-       indio_dev->dev.parent = &client->dev;
+       indio_dev->dev.parent = dev;
        indio_dev->channels = data->part_info->channels;
        indio_dev->num_channels = data->part_info->num_channels;
        indio_dev->name = id->name;
@@ -755,15 +886,15 @@ static int bma180_probe(struct i2c_client *client,
                        goto err_chip_disable;
                }
 
-               ret = devm_request_irq(&client->dev, client->irq,
+               ret = devm_request_irq(dev, client->irq,
                        iio_trigger_generic_data_rdy_poll, IRQF_TRIGGER_RISING,
                        "bma180_event", data->trig);
                if (ret) {
-                       dev_err(&client->dev, "unable to request IRQ\n");
+                       dev_err(dev, "unable to request IRQ\n");
                        goto err_trigger_free;
                }
 
-               data->trig->dev.parent = &client->dev;
+               data->trig->dev.parent = dev;
                data->trig->ops = &bma180_trigger_ops;
                iio_trigger_set_drvdata(data->trig, indio_dev);
                indio_dev->trig = iio_trigger_get(data->trig);
@@ -776,13 +907,13 @@ static int bma180_probe(struct i2c_client *client,
        ret = iio_triggered_buffer_setup(indio_dev, NULL,
                        bma180_trigger_handler, NULL);
        if (ret < 0) {
-               dev_err(&client->dev, "unable to setup iio triggered buffer\n");
+               dev_err(dev, "unable to setup iio triggered buffer\n");
                goto err_trigger_unregister;
        }
 
        ret = iio_device_register(indio_dev);
        if (ret < 0) {
-               dev_err(&client->dev, "unable to register iio device\n");
+               dev_err(dev, "unable to register iio device\n");
                goto err_buffer_cleanup;
        }
 
@@ -797,6 +928,9 @@ err_trigger_free:
        iio_trigger_free(data->trig);
 err_chip_disable:
        data->part_info->chip_disable(data);
+       regulator_disable(data->vddio_supply);
+err_disable_vdd:
+       regulator_disable(data->vdd_supply);
 
        return ret;
 }
@@ -816,6 +950,8 @@ static int bma180_remove(struct i2c_client *client)
        mutex_lock(&data->mutex);
        data->part_info->chip_disable(data);
        mutex_unlock(&data->mutex);
+       regulator_disable(data->vddio_supply);
+       regulator_disable(data->vdd_supply);
 
        return 0;
 }
@@ -856,6 +992,7 @@ static SIMPLE_DEV_PM_OPS(bma180_pm_ops, bma180_suspend, bma180_resume);
 static const struct i2c_device_id bma180_ids[] = {
        { "bma180", BMA180 },
        { "bma250", BMA250 },
+       { "bma254", BMA254 },
        { }
 };
 
@@ -870,6 +1007,10 @@ static const struct of_device_id bma180_of_match[] = {
                .compatible = "bosch,bma250",
                .data = (void *)BMA250
        },
+       {
+               .compatible = "bosch,bma254",
+               .data = (void *)BMA254
+       },
        { }
 };
 MODULE_DEVICE_TABLE(of, bma180_of_match);
@@ -889,5 +1030,5 @@ module_i2c_driver(bma180_driver);
 
 MODULE_AUTHOR("Kravchenko Oleksandr <x0199363@ti.com>");
 MODULE_AUTHOR("Texas Instruments, Inc.");
-MODULE_DESCRIPTION("Bosch BMA180/BMA250 triaxial acceleration sensor");
+MODULE_DESCRIPTION("Bosch BMA180/BMA25x triaxial acceleration sensor");
 MODULE_LICENSE("GPL");
diff --git a/drivers/iio/accel/bma400.h b/drivers/iio/accel/bma400.h
new file mode 100644 (file)
index 0000000..5ad10db
--- /dev/null
@@ -0,0 +1,99 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Register constants and other forward declarations needed by the bma400
+ * sources.
+ *
+ * Copyright 2019 Dan Robertson <dan@dlrobertson.com>
+ */
+
+#ifndef _BMA400_H_
+#define _BMA400_H_
+
+#include <linux/bits.h>
+#include <linux/regmap.h>
+
+/*
+ * Read-Only Registers
+ */
+
+/* Status and ID registers */
+#define BMA400_CHIP_ID_REG          0x00
+#define BMA400_ERR_REG              0x02
+#define BMA400_STATUS_REG           0x03
+
+/* Acceleration registers */
+#define BMA400_X_AXIS_LSB_REG       0x04
+#define BMA400_X_AXIS_MSB_REG       0x05
+#define BMA400_Y_AXIS_LSB_REG       0x06
+#define BMA400_Y_AXIS_MSB_REG       0x07
+#define BMA400_Z_AXIS_LSB_REG       0x08
+#define BMA400_Z_AXIS_MSB_REG       0x09
+
+/* Sensor time registers */
+#define BMA400_SENSOR_TIME0         0x0a
+#define BMA400_SENSOR_TIME1         0x0b
+#define BMA400_SENSOR_TIME2         0x0c
+
+/* Event and interrupt registers */
+#define BMA400_EVENT_REG            0x0d
+#define BMA400_INT_STAT0_REG        0x0e
+#define BMA400_INT_STAT1_REG        0x0f
+#define BMA400_INT_STAT2_REG        0x10
+
+/* Temperature register */
+#define BMA400_TEMP_DATA_REG        0x11
+
+/* FIFO length and data registers */
+#define BMA400_FIFO_LENGTH0_REG     0x12
+#define BMA400_FIFO_LENGTH1_REG     0x13
+#define BMA400_FIFO_DATA_REG        0x14
+
+/* Step count registers */
+#define BMA400_STEP_CNT0_REG        0x15
+#define BMA400_STEP_CNT1_REG        0x16
+#define BMA400_STEP_CNT3_REG        0x17
+#define BMA400_STEP_STAT_REG        0x18
+
+/*
+ * Read-write configuration registers
+ */
+#define BMA400_ACC_CONFIG0_REG      0x19
+#define BMA400_ACC_CONFIG1_REG      0x1a
+#define BMA400_ACC_CONFIG2_REG      0x1b
+#define BMA400_CMD_REG              0x7e
+
+/* Chip ID of BMA 400 devices found in the chip ID register. */
+#define BMA400_ID_REG_VAL           0x90
+
+#define BMA400_LP_OSR_SHIFT         5
+#define BMA400_NP_OSR_SHIFT         4
+#define BMA400_SCALE_SHIFT          6
+
+#define BMA400_TWO_BITS_MASK        GENMASK(1, 0)
+#define BMA400_LP_OSR_MASK          GENMASK(6, 5)
+#define BMA400_NP_OSR_MASK          GENMASK(5, 4)
+#define BMA400_ACC_ODR_MASK         GENMASK(3, 0)
+#define BMA400_ACC_SCALE_MASK       GENMASK(7, 6)
+
+#define BMA400_ACC_ODR_MIN_RAW      0x05
+#define BMA400_ACC_ODR_LP_RAW       0x06
+#define BMA400_ACC_ODR_MAX_RAW      0x0b
+
+#define BMA400_ACC_ODR_MAX_HZ       800
+#define BMA400_ACC_ODR_MIN_WHOLE_HZ 25
+#define BMA400_ACC_ODR_MIN_HZ       12
+
+#define BMA400_SCALE_MIN            38357
+#define BMA400_SCALE_MAX            306864
+
+#define BMA400_NUM_REGULATORS       2
+#define BMA400_VDD_REGULATOR        0
+#define BMA400_VDDIO_REGULATOR      1
+
+extern const struct regmap_config bma400_regmap_config;
+
+int bma400_probe(struct device *dev, struct regmap *regmap, const char *name);
+
+int bma400_remove(struct device *dev);
+
+#endif
diff --git a/drivers/iio/accel/bma400_core.c b/drivers/iio/accel/bma400_core.c
new file mode 100644 (file)
index 0000000..cc77f89
--- /dev/null
@@ -0,0 +1,853 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Core IIO driver for Bosch BMA400 triaxial acceleration sensor.
+ *
+ * Copyright 2019 Dan Robertson <dan@dlrobertson.com>
+ *
+ * TODO:
+ *  - Support for power management
+ *  - Support events and interrupts
+ *  - Create channel for step count
+ *  - Create channel for sensor time
+ */
+
+#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+
+#include "bma400.h"
+
+/*
+ * The G-range selection may be one of 2g, 4g, 8, or 16g. The scale may
+ * be selected with the acc_range bits of the ACC_CONFIG1 register.
+ * NB: This buffer is populated in the device init.
+ */
+static int bma400_scales[8];
+
+/*
+ * See the ACC_CONFIG1 section of the datasheet.
+ * NB: This buffer is populated in the device init.
+ */
+static int bma400_sample_freqs[14];
+
+static const int bma400_osr_range[] = { 0, 1, 3 };
+
+/* See the ACC_CONFIG0 section of the datasheet */
+enum bma400_power_mode {
+       POWER_MODE_SLEEP   = 0x00,
+       POWER_MODE_LOW     = 0x01,
+       POWER_MODE_NORMAL  = 0x02,
+       POWER_MODE_INVALID = 0x03,
+};
+
+struct bma400_sample_freq {
+       int hz;
+       int uhz;
+};
+
+struct bma400_data {
+       struct device *dev;
+       struct regmap *regmap;
+       struct regulator_bulk_data regulators[BMA400_NUM_REGULATORS];
+       struct mutex mutex; /* data register lock */
+       struct iio_mount_matrix orientation;
+       enum bma400_power_mode power_mode;
+       struct bma400_sample_freq sample_freq;
+       int oversampling_ratio;
+       int scale;
+};
+
+static bool bma400_is_writable_reg(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case BMA400_CHIP_ID_REG:
+       case BMA400_ERR_REG:
+       case BMA400_STATUS_REG:
+       case BMA400_X_AXIS_LSB_REG:
+       case BMA400_X_AXIS_MSB_REG:
+       case BMA400_Y_AXIS_LSB_REG:
+       case BMA400_Y_AXIS_MSB_REG:
+       case BMA400_Z_AXIS_LSB_REG:
+       case BMA400_Z_AXIS_MSB_REG:
+       case BMA400_SENSOR_TIME0:
+       case BMA400_SENSOR_TIME1:
+       case BMA400_SENSOR_TIME2:
+       case BMA400_EVENT_REG:
+       case BMA400_INT_STAT0_REG:
+       case BMA400_INT_STAT1_REG:
+       case BMA400_INT_STAT2_REG:
+       case BMA400_TEMP_DATA_REG:
+       case BMA400_FIFO_LENGTH0_REG:
+       case BMA400_FIFO_LENGTH1_REG:
+       case BMA400_FIFO_DATA_REG:
+       case BMA400_STEP_CNT0_REG:
+       case BMA400_STEP_CNT1_REG:
+       case BMA400_STEP_CNT3_REG:
+       case BMA400_STEP_STAT_REG:
+               return false;
+       default:
+               return true;
+       }
+}
+
+static bool bma400_is_volatile_reg(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case BMA400_ERR_REG:
+       case BMA400_STATUS_REG:
+       case BMA400_X_AXIS_LSB_REG:
+       case BMA400_X_AXIS_MSB_REG:
+       case BMA400_Y_AXIS_LSB_REG:
+       case BMA400_Y_AXIS_MSB_REG:
+       case BMA400_Z_AXIS_LSB_REG:
+       case BMA400_Z_AXIS_MSB_REG:
+       case BMA400_SENSOR_TIME0:
+       case BMA400_SENSOR_TIME1:
+       case BMA400_SENSOR_TIME2:
+       case BMA400_EVENT_REG:
+       case BMA400_INT_STAT0_REG:
+       case BMA400_INT_STAT1_REG:
+       case BMA400_INT_STAT2_REG:
+       case BMA400_TEMP_DATA_REG:
+       case BMA400_FIFO_LENGTH0_REG:
+       case BMA400_FIFO_LENGTH1_REG:
+       case BMA400_FIFO_DATA_REG:
+       case BMA400_STEP_CNT0_REG:
+       case BMA400_STEP_CNT1_REG:
+       case BMA400_STEP_CNT3_REG:
+       case BMA400_STEP_STAT_REG:
+               return true;
+       default:
+               return false;
+       }
+}
+
+const struct regmap_config bma400_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+       .max_register = BMA400_CMD_REG,
+       .cache_type = REGCACHE_RBTREE,
+       .writeable_reg = bma400_is_writable_reg,
+       .volatile_reg = bma400_is_volatile_reg,
+};
+EXPORT_SYMBOL(bma400_regmap_config);
+
+static const struct iio_mount_matrix *
+bma400_accel_get_mount_matrix(const struct iio_dev *indio_dev,
+                             const struct iio_chan_spec *chan)
+{
+       struct bma400_data *data = iio_priv(indio_dev);
+
+       return &data->orientation;
+}
+
+static const struct iio_chan_spec_ext_info bma400_ext_info[] = {
+       IIO_MOUNT_MATRIX(IIO_SHARED_BY_DIR, bma400_accel_get_mount_matrix),
+       { }
+};
+
+#define BMA400_ACC_CHANNEL(_axis) { \
+       .type = IIO_ACCEL, \
+       .modified = 1, \
+       .channel2 = IIO_MOD_##_axis, \
+       .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+       .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
+               BIT(IIO_CHAN_INFO_SCALE) | \
+               BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
+       .info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
+               BIT(IIO_CHAN_INFO_SCALE) | \
+               BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
+       .ext_info = bma400_ext_info, \
+}
+
+static const struct iio_chan_spec bma400_channels[] = {
+       BMA400_ACC_CHANNEL(X),
+       BMA400_ACC_CHANNEL(Y),
+       BMA400_ACC_CHANNEL(Z),
+       {
+               .type = IIO_TEMP,
+               .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
+               .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ),
+       },
+};
+
+static int bma400_get_temp_reg(struct bma400_data *data, int *val, int *val2)
+{
+       unsigned int raw_temp;
+       int host_temp;
+       int ret;
+
+       if (data->power_mode == POWER_MODE_SLEEP)
+               return -EBUSY;
+
+       ret = regmap_read(data->regmap, BMA400_TEMP_DATA_REG, &raw_temp);
+       if (ret)
+               return ret;
+
+       host_temp = sign_extend32(raw_temp, 7);
+       /*
+        * The formula for the TEMP_DATA register in the datasheet
+        * is: x * 0.5 + 23
+        */
+       *val = (host_temp >> 1) + 23;
+       *val2 = (host_temp & 0x1) * 500000;
+       return IIO_VAL_INT_PLUS_MICRO;
+}
+
+static int bma400_get_accel_reg(struct bma400_data *data,
+                               const struct iio_chan_spec *chan,
+                               int *val)
+{
+       __le16 raw_accel;
+       int lsb_reg;
+       int ret;
+
+       if (data->power_mode == POWER_MODE_SLEEP)
+               return -EBUSY;
+
+       switch (chan->channel2) {
+       case IIO_MOD_X:
+               lsb_reg = BMA400_X_AXIS_LSB_REG;
+               break;
+       case IIO_MOD_Y:
+               lsb_reg = BMA400_Y_AXIS_LSB_REG;
+               break;
+       case IIO_MOD_Z:
+               lsb_reg = BMA400_Z_AXIS_LSB_REG;
+               break;
+       default:
+               dev_err(data->dev, "invalid axis channel modifier\n");
+               return -EINVAL;
+       }
+
+       /* bulk read two registers, with the base being the LSB register */
+       ret = regmap_bulk_read(data->regmap, lsb_reg, &raw_accel,
+                              sizeof(raw_accel));
+       if (ret)
+               return ret;
+
+       *val = sign_extend32(le16_to_cpu(raw_accel), 11);
+       return IIO_VAL_INT;
+}
+
+static void bma400_output_data_rate_from_raw(int raw, unsigned int *val,
+                                            unsigned int *val2)
+{
+       *val = BMA400_ACC_ODR_MAX_HZ >> (BMA400_ACC_ODR_MAX_RAW - raw);
+       if (raw > BMA400_ACC_ODR_MIN_RAW)
+               *val2 = 0;
+       else
+               *val2 = 500000;
+}
+
+static int bma400_get_accel_output_data_rate(struct bma400_data *data)
+{
+       unsigned int val;
+       unsigned int odr;
+       int ret;
+
+       switch (data->power_mode) {
+       case POWER_MODE_LOW:
+               /*
+                * Runs at a fixed rate in low-power mode. See section 4.3
+                * in the datasheet.
+                */
+               bma400_output_data_rate_from_raw(BMA400_ACC_ODR_LP_RAW,
+                                                &data->sample_freq.hz,
+                                                &data->sample_freq.uhz);
+               return 0;
+       case POWER_MODE_NORMAL:
+               /*
+                * In normal mode the ODR can be found in the ACC_CONFIG1
+                * register.
+                */
+               ret = regmap_read(data->regmap, BMA400_ACC_CONFIG1_REG, &val);
+               if (ret)
+                       goto error;
+
+               odr = val & BMA400_ACC_ODR_MASK;
+               if (odr < BMA400_ACC_ODR_MIN_RAW ||
+                   odr > BMA400_ACC_ODR_MAX_RAW) {
+                       ret = -EINVAL;
+                       goto error;
+               }
+
+               bma400_output_data_rate_from_raw(odr, &data->sample_freq.hz,
+                                                &data->sample_freq.uhz);
+               return 0;
+       case POWER_MODE_SLEEP:
+               data->sample_freq.hz = 0;
+               data->sample_freq.uhz = 0;
+               return 0;
+       default:
+               ret = 0;
+               goto error;
+       }
+error:
+       data->sample_freq.hz = -1;
+       data->sample_freq.uhz = -1;
+       return ret;
+}
+
+static int bma400_set_accel_output_data_rate(struct bma400_data *data,
+                                            int hz, int uhz)
+{
+       unsigned int idx;
+       unsigned int odr;
+       unsigned int val;
+       int ret;
+
+       if (hz >= BMA400_ACC_ODR_MIN_WHOLE_HZ) {
+               if (uhz || hz > BMA400_ACC_ODR_MAX_HZ)
+                       return -EINVAL;
+
+               /* Note this works because MIN_WHOLE_HZ is odd */
+               idx = __ffs(hz);
+
+               if (hz >> idx != BMA400_ACC_ODR_MIN_WHOLE_HZ)
+                       return -EINVAL;
+
+               idx += BMA400_ACC_ODR_MIN_RAW + 1;
+       } else if (hz == BMA400_ACC_ODR_MIN_HZ && uhz == 500000) {
+               idx = BMA400_ACC_ODR_MIN_RAW;
+       } else {
+               return -EINVAL;
+       }
+
+       ret = regmap_read(data->regmap, BMA400_ACC_CONFIG1_REG, &val);
+       if (ret)
+               return ret;
+
+       /* preserve the range and normal mode osr */
+       odr = (~BMA400_ACC_ODR_MASK & val) | idx;
+
+       ret = regmap_write(data->regmap, BMA400_ACC_CONFIG1_REG, odr);
+       if (ret)
+               return ret;
+
+       bma400_output_data_rate_from_raw(idx, &data->sample_freq.hz,
+                                        &data->sample_freq.uhz);
+       return 0;
+}
+
+static int bma400_get_accel_oversampling_ratio(struct bma400_data *data)
+{
+       unsigned int val;
+       unsigned int osr;
+       int ret;
+
+       /*
+        * The oversampling ratio is stored in a different register
+        * based on the power-mode. In normal mode the OSR is stored
+        * in ACC_CONFIG1. In low-power mode it is stored in
+        * ACC_CONFIG0.
+        */
+       switch (data->power_mode) {
+       case POWER_MODE_LOW:
+               ret = regmap_read(data->regmap, BMA400_ACC_CONFIG0_REG, &val);
+               if (ret) {
+                       data->oversampling_ratio = -1;
+                       return ret;
+               }
+
+               osr = (val & BMA400_LP_OSR_MASK) >> BMA400_LP_OSR_SHIFT;
+
+               data->oversampling_ratio = osr;
+               return 0;
+       case POWER_MODE_NORMAL:
+               ret = regmap_read(data->regmap, BMA400_ACC_CONFIG1_REG, &val);
+               if (ret) {
+                       data->oversampling_ratio = -1;
+                       return ret;
+               }
+
+               osr = (val & BMA400_NP_OSR_MASK) >> BMA400_NP_OSR_SHIFT;
+
+               data->oversampling_ratio = osr;
+               return 0;
+       case POWER_MODE_SLEEP:
+               data->oversampling_ratio = 0;
+               return 0;
+       default:
+               data->oversampling_ratio = -1;
+               return -EINVAL;
+       }
+}
+
+static int bma400_set_accel_oversampling_ratio(struct bma400_data *data,
+                                              int val)
+{
+       unsigned int acc_config;
+       int ret;
+
+       if (val & ~BMA400_TWO_BITS_MASK)
+               return -EINVAL;
+
+       /*
+        * The oversampling ratio is stored in a different register
+        * based on the power-mode.
+        */
+       switch (data->power_mode) {
+       case POWER_MODE_LOW:
+               ret = regmap_read(data->regmap, BMA400_ACC_CONFIG0_REG,
+                                 &acc_config);
+               if (ret)
+                       return ret;
+
+               ret = regmap_write(data->regmap, BMA400_ACC_CONFIG0_REG,
+                                  (acc_config & ~BMA400_LP_OSR_MASK) |
+                                  (val << BMA400_LP_OSR_SHIFT));
+               if (ret) {
+                       dev_err(data->dev, "Failed to write out OSR\n");
+                       return ret;
+               }
+
+               data->oversampling_ratio = val;
+               return 0;
+       case POWER_MODE_NORMAL:
+               ret = regmap_read(data->regmap, BMA400_ACC_CONFIG1_REG,
+                                 &acc_config);
+               if (ret)
+                       return ret;
+
+               ret = regmap_write(data->regmap, BMA400_ACC_CONFIG1_REG,
+                                  (acc_config & ~BMA400_NP_OSR_MASK) |
+                                  (val << BMA400_NP_OSR_SHIFT));
+               if (ret) {
+                       dev_err(data->dev, "Failed to write out OSR\n");
+                       return ret;
+               }
+
+               data->oversampling_ratio = val;
+               return 0;
+       default:
+               return -EINVAL;
+       }
+       return ret;
+}
+
+static int bma400_accel_scale_to_raw(struct bma400_data *data,
+                                    unsigned int val)
+{
+       int raw;
+
+       if (val == 0)
+               return -EINVAL;
+
+       /* Note this works because BMA400_SCALE_MIN is odd */
+       raw = __ffs(val);
+
+       if (val >> raw != BMA400_SCALE_MIN)
+               return -EINVAL;
+
+       return raw;
+}
+
+static int bma400_get_accel_scale(struct bma400_data *data)
+{
+       unsigned int raw_scale;
+       unsigned int val;
+       int ret;
+
+       ret = regmap_read(data->regmap, BMA400_ACC_CONFIG1_REG, &val);
+       if (ret)
+               return ret;
+
+       raw_scale = (val & BMA400_ACC_SCALE_MASK) >> BMA400_SCALE_SHIFT;
+       if (raw_scale > BMA400_TWO_BITS_MASK)
+               return -EINVAL;
+
+       data->scale = BMA400_SCALE_MIN << raw_scale;
+
+       return 0;
+}
+
+static int bma400_set_accel_scale(struct bma400_data *data, unsigned int val)
+{
+       unsigned int acc_config;
+       int raw;
+       int ret;
+
+       ret = regmap_read(data->regmap, BMA400_ACC_CONFIG1_REG, &acc_config);
+       if (ret)
+               return ret;
+
+       raw = bma400_accel_scale_to_raw(data, val);
+       if (raw < 0)
+               return raw;
+
+       ret = regmap_write(data->regmap, BMA400_ACC_CONFIG1_REG,
+                          (acc_config & ~BMA400_ACC_SCALE_MASK) |
+                          (raw << BMA400_SCALE_SHIFT));
+       if (ret)
+               return ret;
+
+       data->scale = val;
+       return 0;
+}
+
+static int bma400_get_power_mode(struct bma400_data *data)
+{
+       unsigned int val;
+       int ret;
+
+       ret = regmap_read(data->regmap, BMA400_STATUS_REG, &val);
+       if (ret) {
+               dev_err(data->dev, "Failed to read status register\n");
+               return ret;
+       }
+
+       data->power_mode = (val >> 1) & BMA400_TWO_BITS_MASK;
+       return 0;
+}
+
+static int bma400_set_power_mode(struct bma400_data *data,
+                                enum bma400_power_mode mode)
+{
+       unsigned int val;
+       int ret;
+
+       ret = regmap_read(data->regmap, BMA400_ACC_CONFIG0_REG, &val);
+       if (ret)
+               return ret;
+
+       if (data->power_mode == mode)
+               return 0;
+
+       if (mode == POWER_MODE_INVALID)
+               return -EINVAL;
+
+       /* Preserve the low-power oversample ratio etc */
+       ret = regmap_write(data->regmap, BMA400_ACC_CONFIG0_REG,
+                          mode | (val & ~BMA400_TWO_BITS_MASK));
+       if (ret) {
+               dev_err(data->dev, "Failed to write to power-mode\n");
+               return ret;
+       }
+
+       data->power_mode = mode;
+
+       /*
+        * Update our cached osr and odr based on the new
+        * power-mode.
+        */
+       bma400_get_accel_output_data_rate(data);
+       bma400_get_accel_oversampling_ratio(data);
+       return 0;
+}
+
+static void bma400_init_tables(void)
+{
+       int raw;
+       int i;
+
+       for (i = 0; i + 1 < ARRAY_SIZE(bma400_sample_freqs); i += 2) {
+               raw = (i / 2) + 5;
+               bma400_output_data_rate_from_raw(raw, &bma400_sample_freqs[i],
+                                                &bma400_sample_freqs[i + 1]);
+       }
+
+       for (i = 0; i + 1 < ARRAY_SIZE(bma400_scales); i += 2) {
+               raw = i / 2;
+               bma400_scales[i] = 0;
+               bma400_scales[i + 1] = BMA400_SCALE_MIN << raw;
+       }
+}
+
+static int bma400_init(struct bma400_data *data)
+{
+       unsigned int val;
+       int ret;
+
+       /* Try to read chip_id register. It must return 0x90. */
+       ret = regmap_read(data->regmap, BMA400_CHIP_ID_REG, &val);
+       if (ret) {
+               dev_err(data->dev, "Failed to read chip id register\n");
+               goto out;
+       }
+
+       if (val != BMA400_ID_REG_VAL) {
+               dev_err(data->dev, "Chip ID mismatch\n");
+               ret = -ENODEV;
+               goto out;
+       }
+
+       data->regulators[BMA400_VDD_REGULATOR].supply = "vdd";
+       data->regulators[BMA400_VDDIO_REGULATOR].supply = "vddio";
+       ret = devm_regulator_bulk_get(data->dev,
+                                     ARRAY_SIZE(data->regulators),
+                                     data->regulators);
+       if (ret) {
+               if (ret != -EPROBE_DEFER)
+                       dev_err(data->dev,
+                               "Failed to get regulators: %d\n",
+                               ret);
+
+               goto out;
+       }
+       ret = regulator_bulk_enable(ARRAY_SIZE(data->regulators),
+                                   data->regulators);
+       if (ret) {
+               dev_err(data->dev, "Failed to enable regulators: %d\n",
+                       ret);
+               goto out;
+       }
+
+       ret = bma400_get_power_mode(data);
+       if (ret) {
+               dev_err(data->dev, "Failed to get the initial power-mode\n");
+               goto err_reg_disable;
+       }
+
+       if (data->power_mode != POWER_MODE_NORMAL) {
+               ret = bma400_set_power_mode(data, POWER_MODE_NORMAL);
+               if (ret) {
+                       dev_err(data->dev, "Failed to wake up the device\n");
+                       goto err_reg_disable;
+               }
+               /*
+                * TODO: The datasheet waits 1500us here in the example, but
+                * lists 2/ODR as the wakeup time.
+                */
+               usleep_range(1500, 2000);
+       }
+
+       bma400_init_tables();
+
+       ret = bma400_get_accel_output_data_rate(data);
+       if (ret)
+               goto err_reg_disable;
+
+       ret = bma400_get_accel_oversampling_ratio(data);
+       if (ret)
+               goto err_reg_disable;
+
+       ret = bma400_get_accel_scale(data);
+       if (ret)
+               goto err_reg_disable;
+
+       /*
+        * Once the interrupt engine is supported we might use the
+        * data_src_reg, but for now ensure this is set to the
+        * variable ODR filter selectable by the sample frequency
+        * channel.
+        */
+       return regmap_write(data->regmap, BMA400_ACC_CONFIG2_REG, 0x00);
+
+err_reg_disable:
+       regulator_bulk_disable(ARRAY_SIZE(data->regulators),
+                              data->regulators);
+out:
+       return ret;
+}
+
+static int bma400_read_raw(struct iio_dev *indio_dev,
+                          struct iio_chan_spec const *chan, int *val,
+                          int *val2, long mask)
+{
+       struct bma400_data *data = iio_priv(indio_dev);
+       int ret;
+
+       switch (mask) {
+       case IIO_CHAN_INFO_PROCESSED:
+               mutex_lock(&data->mutex);
+               ret = bma400_get_temp_reg(data, val, val2);
+               mutex_unlock(&data->mutex);
+               return ret;
+       case IIO_CHAN_INFO_RAW:
+               mutex_lock(&data->mutex);
+               ret = bma400_get_accel_reg(data, chan, val);
+               mutex_unlock(&data->mutex);
+               return ret;
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               switch (chan->type) {
+               case IIO_ACCEL:
+                       if (data->sample_freq.hz < 0)
+                               return -EINVAL;
+
+                       *val = data->sample_freq.hz;
+                       *val2 = data->sample_freq.uhz;
+                       return IIO_VAL_INT_PLUS_MICRO;
+               case IIO_TEMP:
+                       /*
+                        * Runs at a fixed sampling frequency. See Section 4.4
+                        * of the datasheet.
+                        */
+                       *val = 6;
+                       *val2 = 250000;
+                       return IIO_VAL_INT_PLUS_MICRO;
+               default:
+                       return -EINVAL;
+               }
+       case IIO_CHAN_INFO_SCALE:
+               *val = 0;
+               *val2 = data->scale;
+               return IIO_VAL_INT_PLUS_MICRO;
+       case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
+               /*
+                * TODO: We could avoid this logic and returning -EINVAL here if
+                * we set both the low-power and normal mode OSR registers when
+                * we configure the device.
+                */
+               if (data->oversampling_ratio < 0)
+                       return -EINVAL;
+
+               *val = data->oversampling_ratio;
+               return IIO_VAL_INT;
+       default:
+               return -EINVAL;
+       }
+}
+
+static int bma400_read_avail(struct iio_dev *indio_dev,
+                            struct iio_chan_spec const *chan,
+                            const int **vals, int *type, int *length,
+                            long mask)
+{
+       switch (mask) {
+       case IIO_CHAN_INFO_SCALE:
+               *type = IIO_VAL_INT_PLUS_MICRO;
+               *vals = bma400_scales;
+               *length = ARRAY_SIZE(bma400_scales);
+               return IIO_AVAIL_LIST;
+       case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
+               *type = IIO_VAL_INT;
+               *vals = bma400_osr_range;
+               *length = ARRAY_SIZE(bma400_osr_range);
+               return IIO_AVAIL_RANGE;
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               *type = IIO_VAL_INT_PLUS_MICRO;
+               *vals = bma400_sample_freqs;
+               *length = ARRAY_SIZE(bma400_sample_freqs);
+               return IIO_AVAIL_LIST;
+       default:
+               return -EINVAL;
+       }
+}
+
+static int bma400_write_raw(struct iio_dev *indio_dev,
+                           struct iio_chan_spec const *chan, int val, int val2,
+                           long mask)
+{
+       struct bma400_data *data = iio_priv(indio_dev);
+       int ret;
+
+       switch (mask) {
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               /*
+                * The sample frequency is readonly for the temperature
+                * register and a fixed value in low-power mode.
+                */
+               if (chan->type != IIO_ACCEL)
+                       return -EINVAL;
+
+               mutex_lock(&data->mutex);
+               ret = bma400_set_accel_output_data_rate(data, val, val2);
+               mutex_unlock(&data->mutex);
+               return ret;
+       case IIO_CHAN_INFO_SCALE:
+               if (val != 0 ||
+                   val2 < BMA400_SCALE_MIN || val2 > BMA400_SCALE_MAX)
+                       return -EINVAL;
+
+               mutex_lock(&data->mutex);
+               ret = bma400_set_accel_scale(data, val2);
+               mutex_unlock(&data->mutex);
+               return ret;
+       case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
+               mutex_lock(&data->mutex);
+               ret = bma400_set_accel_oversampling_ratio(data, val);
+               mutex_unlock(&data->mutex);
+               return ret;
+       default:
+               return -EINVAL;
+       }
+}
+
+static int bma400_write_raw_get_fmt(struct iio_dev *indio_dev,
+                                   struct iio_chan_spec const *chan,
+                                   long mask)
+{
+       switch (mask) {
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               return IIO_VAL_INT_PLUS_MICRO;
+       case IIO_CHAN_INFO_SCALE:
+               return IIO_VAL_INT_PLUS_MICRO;
+       case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
+               return IIO_VAL_INT;
+       default:
+               return -EINVAL;
+       }
+}
+
+static const struct iio_info bma400_info = {
+       .read_raw          = bma400_read_raw,
+       .read_avail        = bma400_read_avail,
+       .write_raw         = bma400_write_raw,
+       .write_raw_get_fmt = bma400_write_raw_get_fmt,
+};
+
+int bma400_probe(struct device *dev, struct regmap *regmap, const char *name)
+{
+       struct iio_dev *indio_dev;
+       struct bma400_data *data;
+       int ret;
+
+       indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
+       if (!indio_dev)
+               return -ENOMEM;
+
+       data = iio_priv(indio_dev);
+       data->regmap = regmap;
+       data->dev = dev;
+
+       ret = bma400_init(data);
+       if (ret)
+               return ret;
+
+       ret = iio_read_mount_matrix(dev, "mount-matrix", &data->orientation);
+       if (ret)
+               return ret;
+
+       mutex_init(&data->mutex);
+       indio_dev->dev.parent = dev;
+       indio_dev->name = name;
+       indio_dev->info = &bma400_info;
+       indio_dev->channels = bma400_channels;
+       indio_dev->num_channels = ARRAY_SIZE(bma400_channels);
+       indio_dev->modes = INDIO_DIRECT_MODE;
+
+       dev_set_drvdata(dev, indio_dev);
+
+       return iio_device_register(indio_dev);
+}
+EXPORT_SYMBOL(bma400_probe);
+
+int bma400_remove(struct device *dev)
+{
+       struct iio_dev *indio_dev = dev_get_drvdata(dev);
+       struct bma400_data *data = iio_priv(indio_dev);
+       int ret;
+
+       mutex_lock(&data->mutex);
+       ret = bma400_set_power_mode(data, POWER_MODE_SLEEP);
+       mutex_unlock(&data->mutex);
+
+       regulator_bulk_disable(ARRAY_SIZE(data->regulators),
+                              data->regulators);
+
+       iio_device_unregister(indio_dev);
+
+       return ret;
+}
+EXPORT_SYMBOL(bma400_remove);
+
+MODULE_AUTHOR("Dan Robertson <dan@dlrobertson.com>");
+MODULE_DESCRIPTION("Bosch BMA400 triaxial acceleration sensor core");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/accel/bma400_i2c.c b/drivers/iio/accel/bma400_i2c.c
new file mode 100644 (file)
index 0000000..9dcb7cc
--- /dev/null
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * I2C IIO driver for Bosch BMA400 triaxial acceleration sensor.
+ *
+ * Copyright 2019 Dan Robertson <dan@dlrobertson.com>
+ *
+ * I2C address is either 0x14 or 0x15 depending on SDO
+ */
+#include <linux/i2c.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+
+#include "bma400.h"
+
+static int bma400_i2c_probe(struct i2c_client *client,
+                           const struct i2c_device_id *id)
+{
+       struct regmap *regmap;
+
+       regmap = devm_regmap_init_i2c(client, &bma400_regmap_config);
+       if (IS_ERR(regmap)) {
+               dev_err(&client->dev, "failed to create regmap\n");
+               return PTR_ERR(regmap);
+       }
+
+       return bma400_probe(&client->dev, regmap, id->name);
+}
+
+static int bma400_i2c_remove(struct i2c_client *client)
+{
+       return bma400_remove(&client->dev);
+}
+
+static const struct i2c_device_id bma400_i2c_ids[] = {
+       { "bma400", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, bma400_i2c_ids);
+
+static const struct of_device_id bma400_of_i2c_match[] = {
+       { .compatible = "bosch,bma400" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, bma400_of_i2c_match);
+
+static struct i2c_driver bma400_i2c_driver = {
+       .driver = {
+               .name = "bma400",
+               .of_match_table = bma400_of_i2c_match,
+       },
+       .probe    = bma400_i2c_probe,
+       .remove   = bma400_i2c_remove,
+       .id_table = bma400_i2c_ids,
+};
+
+module_i2c_driver(bma400_i2c_driver);
+
+MODULE_AUTHOR("Dan Robertson <dan@dlrobertson.com>");
+MODULE_DESCRIPTION("Bosch BMA400 triaxial acceleration sensor (I2C)");
+MODULE_LICENSE("GPL");
index fee535d..c9924a6 100644 (file)
@@ -130,6 +130,7 @@ struct kxcjk1013_data {
        struct i2c_client *client;
        struct iio_trigger *dready_trig;
        struct iio_trigger *motion_trig;
+       struct iio_mount_matrix orientation;
        struct mutex mutex;
        s16 buffer[8];
        u8 odr_bits;
@@ -983,6 +984,20 @@ static const struct iio_event_spec kxcjk1013_event = {
                                 BIT(IIO_EV_INFO_PERIOD)
 };
 
+static const struct iio_mount_matrix *
+kxcjk1013_get_mount_matrix(const struct iio_dev *indio_dev,
+                          const struct iio_chan_spec *chan)
+{
+       struct kxcjk1013_data *data = iio_priv(indio_dev);
+
+       return &data->orientation;
+}
+
+static const struct iio_chan_spec_ext_info kxcjk1013_ext_info[] = {
+       IIO_MOUNT_MATRIX(IIO_SHARED_BY_TYPE, kxcjk1013_get_mount_matrix),
+       { }
+};
+
 #define KXCJK1013_CHANNEL(_axis) {                                     \
        .type = IIO_ACCEL,                                              \
        .modified = 1,                                                  \
@@ -999,6 +1014,7 @@ static const struct iio_event_spec kxcjk1013_event = {
                .endianness = IIO_LE,                                   \
        },                                                              \
        .event_spec = &kxcjk1013_event,                         \
+       .ext_info = kxcjk1013_ext_info,                                 \
        .num_event_specs = 1                                            \
 }
 
@@ -1267,11 +1283,18 @@ static int kxcjk1013_probe(struct i2c_client *client,
        data->client = client;
 
        pdata = dev_get_platdata(&client->dev);
-       if (pdata)
+       if (pdata) {
                data->active_high_intr = pdata->active_high_intr;
-       else
+               data->orientation = pdata->orientation;
+       } else {
                data->active_high_intr = true; /* default polarity */
 
+               ret = iio_read_mount_matrix(&client->dev, "mount-matrix",
+                                           &data->orientation);
+               if (ret)
+                       return ret;
+       }
+
        if (id) {
                data->chipset = (enum kx_chipset)(id->driver_data);
                name = id->name;
index af09943..5b13e29 100644 (file)
@@ -64,7 +64,7 @@ enum st_accel_type {
 * struct st_sensors_platform_data - default accel platform data
 * @drdy_int_pin: default accel DRDY is available on INT1 pin.
 */
-static const struct st_sensors_platform_data default_accel_pdata = {
+static __maybe_unused const struct st_sensors_platform_data default_accel_pdata = {
        .drdy_int_pin = 1,
 };
 
index 50fa0fc..633955d 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/iio/common/st_sensors_i2c.h>
 #include "st_accel.h"
 
-#ifdef CONFIG_OF
 static const struct of_device_id st_accel_of_match[] = {
        {
                /* An older compatible */
@@ -108,9 +107,6 @@ static const struct of_device_id st_accel_of_match[] = {
        {},
 };
 MODULE_DEVICE_TABLE(of, st_accel_of_match);
-#else
-#define st_accel_of_match NULL
-#endif
 
 #ifdef CONFIG_ACPI
 static const struct acpi_device_id st_accel_acpi_match[] = {
@@ -119,8 +115,6 @@ static const struct acpi_device_id st_accel_acpi_match[] = {
        { },
 };
 MODULE_DEVICE_TABLE(acpi, st_accel_acpi_match);
-#else
-#define st_accel_acpi_match NULL
 #endif
 
 static const struct i2c_device_id st_accel_id_table[] = {
@@ -195,7 +189,7 @@ static int st_accel_i2c_remove(struct i2c_client *client)
 static struct i2c_driver st_accel_driver = {
        .driver = {
                .name = "st-accel-i2c",
-               .of_match_table = of_match_ptr(st_accel_of_match),
+               .of_match_table = st_accel_of_match,
                .acpi_match_table = ACPI_PTR(st_accel_acpi_match),
        },
        .probe_new = st_accel_i2c_probe,
index 8af7027..568ff1b 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/iio/common/st_sensors_spi.h>
 #include "st_accel.h"
 
-#ifdef CONFIG_OF
 /*
  * For new single-chip sensors use <device_name> as compatible string.
  * For old single-chip devices keep <device_name>-accel to maintain
@@ -96,9 +95,6 @@ static const struct of_device_id st_accel_of_match[] = {
        {}
 };
 MODULE_DEVICE_TABLE(of, st_accel_of_match);
-#else
-#define st_accel_of_match      NULL
-#endif
 
 static int st_accel_spi_probe(struct spi_device *spi)
 {
@@ -107,8 +103,7 @@ static int st_accel_spi_probe(struct spi_device *spi)
        struct iio_dev *indio_dev;
        int err;
 
-       st_sensors_of_name_probe(&spi->dev, st_accel_of_match,
-                                spi->modalias, sizeof(spi->modalias));
+       st_sensors_dev_name_probe(&spi->dev, spi->modalias, sizeof(spi->modalias));
 
        settings = st_accel_get_settings(spi->modalias);
        if (!settings) {
@@ -166,7 +161,7 @@ MODULE_DEVICE_TABLE(spi, st_accel_id_table);
 static struct spi_driver st_accel_driver = {
        .driver = {
                .name = "st-accel-spi",
-               .of_match_table = of_match_ptr(st_accel_of_match),
+               .of_match_table = st_accel_of_match,
        },
        .probe = st_accel_spi_probe,
        .remove = st_accel_spi_remove,
index 5d8540b..82e3308 100644 (file)
@@ -21,6 +21,13 @@ config AD_SIGMA_DELTA
        select IIO_BUFFER
        select IIO_TRIGGERED_BUFFER
 
+config AD7091R5
+       tristate "Analog Devices AD7091R5 ADC Driver"
+       depends on I2C
+       select REGMAP_I2C
+       help
+         Say yes here to build support for Analog Devices AD7091R-5 ADC.
+
 config AD7124
        tristate "Analog Devices AD7124 and similar sigma-delta ADCs driver"
        depends on SPI_MASTER
@@ -523,6 +530,16 @@ config LTC2485
          To compile this driver as a module, choose M here: the module will be
          called ltc2485.
 
+config LTC2496
+       tristate "Linear Technology LTC2496 ADC driver"
+       depends on SPI
+       help
+         Say yes here to build support for Linear Technology LTC2496
+         16-Bit 8-/16-Channel Delta Sigma ADC.
+
+         To compile this driver as a module, choose M here: the module will be
+         called ltc2496.
+
 config LTC2497
        tristate "Linear Technology LTC2497 ADC driver"
        depends on I2C
index a1f1fbe..9192289 100644 (file)
@@ -6,6 +6,7 @@
 # When adding new entries keep the list in alphabetical order
 obj-$(CONFIG_AB8500_GPADC) += ab8500-gpadc.o
 obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o
+obj-$(CONFIG_AD7091R5) += ad7091r5.o ad7091r-base.o
 obj-$(CONFIG_AD7124) += ad7124.o
 obj-$(CONFIG_AD7266) += ad7266.o
 obj-$(CONFIG_AD7291) += ad7291.o
@@ -50,7 +51,8 @@ obj-$(CONFIG_LPC18XX_ADC) += lpc18xx_adc.o
 obj-$(CONFIG_LPC32XX_ADC) += lpc32xx_adc.o
 obj-$(CONFIG_LTC2471) += ltc2471.o
 obj-$(CONFIG_LTC2485) += ltc2485.o
-obj-$(CONFIG_LTC2497) += ltc2497.o
+obj-$(CONFIG_LTC2496) += ltc2496.o ltc2497-core.o
+obj-$(CONFIG_LTC2497) += ltc2497.o ltc2497-core.o
 obj-$(CONFIG_MAX1027) += max1027.o
 obj-$(CONFIG_MAX11100) += max11100.o
 obj-$(CONFIG_MAX1118) += max1118.o
diff --git a/drivers/iio/adc/ad7091r-base.c b/drivers/iio/adc/ad7091r-base.c
new file mode 100644 (file)
index 0000000..33c4035
--- /dev/null
@@ -0,0 +1,298 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * AD7091RX Analog to Digital converter driver
+ *
+ * Copyright 2014-2019 Analog Devices Inc.
+ */
+
+#include <linux/bitops.h>
+#include <linux/iio/events.h>
+#include <linux/iio/iio.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+
+#include "ad7091r-base.h"
+
+#define AD7091R_REG_RESULT  0
+#define AD7091R_REG_CHANNEL 1
+#define AD7091R_REG_CONF    2
+#define AD7091R_REG_ALERT   3
+#define AD7091R_REG_CH_LOW_LIMIT(ch) ((ch) * 3 + 4)
+#define AD7091R_REG_CH_HIGH_LIMIT(ch) ((ch) * 3 + 5)
+#define AD7091R_REG_CH_HYSTERESIS(ch) ((ch) * 3 + 6)
+
+/* AD7091R_REG_RESULT */
+#define AD7091R_REG_RESULT_CH_ID(x)        (((x) >> 13) & 0x3)
+#define AD7091R_REG_RESULT_CONV_RESULT(x)   ((x) & 0xfff)
+
+/* AD7091R_REG_CONF */
+#define AD7091R_REG_CONF_AUTO   BIT(8)
+#define AD7091R_REG_CONF_CMD    BIT(10)
+
+#define AD7091R_REG_CONF_MODE_MASK  \
+       (AD7091R_REG_CONF_AUTO | AD7091R_REG_CONF_CMD)
+
+enum ad7091r_mode {
+       AD7091R_MODE_SAMPLE,
+       AD7091R_MODE_COMMAND,
+       AD7091R_MODE_AUTOCYCLE,
+};
+
+struct ad7091r_state {
+       struct device *dev;
+       struct regmap *map;
+       struct regulator *vref;
+       const struct ad7091r_chip_info *chip_info;
+       enum ad7091r_mode mode;
+       struct mutex lock; /*lock to prevent concurent reads */
+};
+
+static int ad7091r_set_mode(struct ad7091r_state *st, enum ad7091r_mode mode)
+{
+       int ret, conf;
+
+       switch (mode) {
+       case AD7091R_MODE_SAMPLE:
+               conf = 0;
+               break;
+       case AD7091R_MODE_COMMAND:
+               conf = AD7091R_REG_CONF_CMD;
+               break;
+       case AD7091R_MODE_AUTOCYCLE:
+               conf = AD7091R_REG_CONF_AUTO;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       ret = regmap_update_bits(st->map, AD7091R_REG_CONF,
+                                AD7091R_REG_CONF_MODE_MASK, conf);
+       if (ret)
+               return ret;
+
+       st->mode = mode;
+
+       return 0;
+}
+
+static int ad7091r_set_channel(struct ad7091r_state *st, unsigned int channel)
+{
+       unsigned int dummy;
+       int ret;
+
+       /* AD7091R_REG_CHANNEL specified which channels to be converted */
+       ret = regmap_write(st->map, AD7091R_REG_CHANNEL,
+                       BIT(channel) | (BIT(channel) << 8));
+       if (ret)
+               return ret;
+
+       /*
+        * There is a latency of one conversion before the channel conversion
+        * sequence is updated
+        */
+       return regmap_read(st->map, AD7091R_REG_RESULT, &dummy);
+}
+
+static int ad7091r_read_one(struct iio_dev *iio_dev,
+               unsigned int channel, unsigned int *read_val)
+{
+       struct ad7091r_state *st = iio_priv(iio_dev);
+       unsigned int val;
+       int ret;
+
+       ret = ad7091r_set_channel(st, channel);
+       if (ret)
+               return ret;
+
+       ret = regmap_read(st->map, AD7091R_REG_RESULT, &val);
+       if (ret)
+               return ret;
+
+       if (AD7091R_REG_RESULT_CH_ID(val) != channel)
+               return -EIO;
+
+       *read_val = AD7091R_REG_RESULT_CONV_RESULT(val);
+
+       return 0;
+}
+
+static int ad7091r_read_raw(struct iio_dev *iio_dev,
+                          struct iio_chan_spec const *chan,
+                          int *val, int *val2, long m)
+{
+       struct ad7091r_state *st = iio_priv(iio_dev);
+       unsigned int read_val;
+       int ret;
+
+       mutex_lock(&st->lock);
+
+       switch (m) {
+       case IIO_CHAN_INFO_RAW:
+               if (st->mode != AD7091R_MODE_COMMAND) {
+                       ret = -EBUSY;
+                       goto unlock;
+               }
+
+               ret = ad7091r_read_one(iio_dev, chan->channel, &read_val);
+               if (ret)
+                       goto unlock;
+
+               *val = read_val;
+               ret = IIO_VAL_INT;
+               break;
+
+       case IIO_CHAN_INFO_SCALE:
+               if (st->vref) {
+                       ret = regulator_get_voltage(st->vref);
+                       if (ret < 0)
+                               goto unlock;
+
+                       *val = ret / 1000;
+               } else {
+                       *val = st->chip_info->vref_mV;
+               }
+
+               *val2 = chan->scan_type.realbits;
+               ret = IIO_VAL_FRACTIONAL_LOG2;
+               break;
+
+       default:
+               ret = -EINVAL;
+               break;
+       }
+
+unlock:
+       mutex_unlock(&st->lock);
+       return ret;
+}
+
+static const struct iio_info ad7091r_info = {
+       .read_raw = ad7091r_read_raw,
+};
+
+static irqreturn_t ad7091r_event_handler(int irq, void *private)
+{
+       struct ad7091r_state *st = (struct ad7091r_state *) private;
+       struct iio_dev *iio_dev = dev_get_drvdata(st->dev);
+       unsigned int i, read_val;
+       int ret;
+       s64 timestamp = iio_get_time_ns(iio_dev);
+
+       ret = regmap_read(st->map, AD7091R_REG_ALERT, &read_val);
+       if (ret)
+               return IRQ_HANDLED;
+
+       for (i = 0; i < st->chip_info->num_channels; i++) {
+               if (read_val & BIT(i * 2))
+                       iio_push_event(iio_dev,
+                                       IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, i,
+                                               IIO_EV_TYPE_THRESH,
+                                               IIO_EV_DIR_RISING), timestamp);
+               if (read_val & BIT(i * 2 + 1))
+                       iio_push_event(iio_dev,
+                                       IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, i,
+                                               IIO_EV_TYPE_THRESH,
+                                               IIO_EV_DIR_FALLING), timestamp);
+       }
+
+       return IRQ_HANDLED;
+}
+
+static void ad7091r_remove(void *data)
+{
+       struct ad7091r_state *st = data;
+
+       regulator_disable(st->vref);
+}
+
+int ad7091r_probe(struct device *dev, const char *name,
+               const struct ad7091r_chip_info *chip_info,
+               struct regmap *map, int irq)
+{
+       struct iio_dev *iio_dev;
+       struct ad7091r_state *st;
+       int ret;
+
+       iio_dev = devm_iio_device_alloc(dev, sizeof(*st));
+       if (!iio_dev)
+               return -ENOMEM;
+
+       st = iio_priv(iio_dev);
+       st->dev = dev;
+       st->chip_info = chip_info;
+       st->map = map;
+
+       iio_dev->dev.parent = dev;
+       iio_dev->name = name;
+       iio_dev->info = &ad7091r_info;
+       iio_dev->modes = INDIO_DIRECT_MODE;
+
+       iio_dev->num_channels = chip_info->num_channels;
+       iio_dev->channels = chip_info->channels;
+
+       if (irq) {
+               ret = devm_request_threaded_irq(dev, irq, NULL,
+                               ad7091r_event_handler,
+                               IRQF_TRIGGER_FALLING | IRQF_ONESHOT, name, st);
+               if (ret)
+                       return ret;
+       }
+
+       st->vref = devm_regulator_get_optional(dev, "vref");
+       if (IS_ERR(st->vref)) {
+               if (PTR_ERR(st->vref) == -EPROBE_DEFER)
+                       return -EPROBE_DEFER;
+               st->vref = NULL;
+       } else {
+               ret = regulator_enable(st->vref);
+               if (ret)
+                       return ret;
+               ret = devm_add_action_or_reset(dev, ad7091r_remove, st);
+               if (ret)
+                       return ret;
+       }
+
+       /* Use command mode by default to convert only desired channels*/
+       ret = ad7091r_set_mode(st, AD7091R_MODE_COMMAND);
+       if (ret)
+               return ret;
+
+       return devm_iio_device_register(dev, iio_dev);
+}
+EXPORT_SYMBOL_GPL(ad7091r_probe);
+
+static bool ad7091r_writeable_reg(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case AD7091R_REG_RESULT:
+       case AD7091R_REG_ALERT:
+               return false;
+       default:
+               return true;
+       }
+}
+
+static bool ad7091r_volatile_reg(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case AD7091R_REG_RESULT:
+       case AD7091R_REG_ALERT:
+               return true;
+       default:
+               return false;
+       }
+}
+
+const struct regmap_config ad7091r_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 16,
+       .writeable_reg = ad7091r_writeable_reg,
+       .volatile_reg = ad7091r_volatile_reg,
+};
+EXPORT_SYMBOL_GPL(ad7091r_regmap_config);
+
+MODULE_AUTHOR("Beniamin Bia <beniamin.bia@analog.com>");
+MODULE_DESCRIPTION("Analog Devices AD7091Rx multi-channel converters");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/adc/ad7091r-base.h b/drivers/iio/adc/ad7091r-base.h
new file mode 100644 (file)
index 0000000..509748a
--- /dev/null
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * AD7091RX Analog to Digital converter driver
+ *
+ * Copyright 2014-2019 Analog Devices Inc.
+ */
+
+#ifndef __DRIVERS_IIO_ADC_AD7091R_BASE_H__
+#define __DRIVERS_IIO_ADC_AD7091R_BASE_H__
+
+struct device;
+struct ad7091r_state;
+
+struct ad7091r_chip_info {
+       unsigned int num_channels;
+       const struct iio_chan_spec *channels;
+       unsigned int vref_mV;
+};
+
+extern const struct regmap_config ad7091r_regmap_config;
+
+int ad7091r_probe(struct device *dev, const char *name,
+               const struct ad7091r_chip_info *chip_info,
+               struct regmap *map, int irq);
+
+#endif /* __DRIVERS_IIO_ADC_AD7091R_BASE_H__ */
diff --git a/drivers/iio/adc/ad7091r5.c b/drivers/iio/adc/ad7091r5.c
new file mode 100644 (file)
index 0000000..9665679
--- /dev/null
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * AD7091R5 Analog to Digital converter driver
+ *
+ * Copyright 2014-2019 Analog Devices Inc.
+ */
+
+#include <linux/i2c.h>
+#include <linux/iio/iio.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+
+#include "ad7091r-base.h"
+
+static const struct iio_event_spec ad7091r5_events[] = {
+       {
+               .type = IIO_EV_TYPE_THRESH,
+               .dir = IIO_EV_DIR_RISING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                                BIT(IIO_EV_INFO_ENABLE),
+       },
+       {
+               .type = IIO_EV_TYPE_THRESH,
+               .dir = IIO_EV_DIR_FALLING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                                BIT(IIO_EV_INFO_ENABLE),
+       },
+       {
+               .type = IIO_EV_TYPE_THRESH,
+               .dir = IIO_EV_DIR_EITHER,
+               .mask_separate = BIT(IIO_EV_INFO_HYSTERESIS),
+       },
+};
+
+#define AD7091R_CHANNEL(idx, bits, ev, num_ev) { \
+       .type = IIO_VOLTAGE, \
+       .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+       .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+       .indexed = 1, \
+       .channel = idx, \
+       .event_spec = ev, \
+       .num_event_specs = num_ev, \
+       .scan_type.storagebits = 16, \
+       .scan_type.realbits = bits, \
+}
+static const struct iio_chan_spec ad7091r5_channels_irq[] = {
+       AD7091R_CHANNEL(0, 12, ad7091r5_events, ARRAY_SIZE(ad7091r5_events)),
+       AD7091R_CHANNEL(1, 12, ad7091r5_events, ARRAY_SIZE(ad7091r5_events)),
+       AD7091R_CHANNEL(2, 12, ad7091r5_events, ARRAY_SIZE(ad7091r5_events)),
+       AD7091R_CHANNEL(3, 12, ad7091r5_events, ARRAY_SIZE(ad7091r5_events)),
+};
+
+static const struct iio_chan_spec ad7091r5_channels_noirq[] = {
+       AD7091R_CHANNEL(0, 12, NULL, 0),
+       AD7091R_CHANNEL(1, 12, NULL, 0),
+       AD7091R_CHANNEL(2, 12, NULL, 0),
+       AD7091R_CHANNEL(3, 12, NULL, 0),
+};
+
+static const struct ad7091r_chip_info ad7091r5_chip_info_irq = {
+       .channels = ad7091r5_channels_irq,
+       .num_channels = ARRAY_SIZE(ad7091r5_channels_irq),
+       .vref_mV = 2500,
+};
+
+static const struct ad7091r_chip_info ad7091r5_chip_info_noirq = {
+       .channels = ad7091r5_channels_noirq,
+       .num_channels = ARRAY_SIZE(ad7091r5_channels_noirq),
+       .vref_mV = 2500,
+};
+
+static int ad7091r5_i2c_probe(struct i2c_client *i2c,
+               const struct i2c_device_id *id)
+{
+       const struct ad7091r_chip_info *chip_info;
+       struct regmap *map = devm_regmap_init_i2c(i2c, &ad7091r_regmap_config);
+
+       if (IS_ERR(map))
+               return PTR_ERR(map);
+
+       if (i2c->irq)
+               chip_info = &ad7091r5_chip_info_irq;
+       else
+               chip_info = &ad7091r5_chip_info_noirq;
+
+       return ad7091r_probe(&i2c->dev, id->name, chip_info, map, i2c->irq);
+}
+
+static const struct of_device_id ad7091r5_dt_ids[] = {
+       { .compatible = "adi,ad7091r5" },
+       {},
+};
+MODULE_DEVICE_TABLE(of, ad7091r5_dt_ids);
+
+static const struct i2c_device_id ad7091r5_i2c_ids[] = {
+       {"ad7091r5", 0},
+       {}
+};
+MODULE_DEVICE_TABLE(i2c, ad7091r5_i2c_ids);
+
+static struct i2c_driver ad7091r5_driver = {
+       .driver = {
+               .name = "ad7091r5",
+               .of_match_table = ad7091r5_dt_ids,
+       },
+       .probe = ad7091r5_i2c_probe,
+       .id_table = ad7091r5_i2c_ids,
+};
+module_i2c_driver(ad7091r5_driver);
+
+MODULE_AUTHOR("Beniamin Bia <beniamin.bia@analog.com>");
+MODULE_DESCRIPTION("Analog Devices AD7091R5 multi-channel ADC driver");
+MODULE_LICENSE("GPL v2");
index 306bf15..d9915dc 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/err.h>
+#include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/regulator/consumer.h>
@@ -224,6 +225,7 @@ static const struct ad_sigma_delta_info ad7124_sigma_delta_info = {
        .addr_shift = 0,
        .read_mask = BIT(6),
        .data_reg = AD7124_DATA,
+       .irq_flags = IRQF_TRIGGER_FALLING,
 };
 
 static int ad7124_set_channel_odr(struct ad7124_state *st,
index c31b8ea..c8524f0 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/spi/spi.h>
 #include <linux/regulator/consumer.h>
 #include <linux/err.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/module.h>
 
 #include <linux/interrupt.h>
@@ -34,7 +34,7 @@ struct ad7266_state {
        enum ad7266_range       range;
        enum ad7266_mode        mode;
        bool                    fixed_addr;
-       struct gpio             gpios[3];
+       struct gpio_desc        *gpios[3];
 
        /*
         * DMA (thus cache coherency maintenance) requires the
@@ -117,7 +117,7 @@ static void ad7266_select_input(struct ad7266_state *st, unsigned int nr)
        }
 
        for (i = 0; i < 3; ++i)
-               gpio_set_value(st->gpios[i].gpio, (bool)(nr & BIT(i)));
+               gpiod_set_value(st->gpios[i], (bool)(nr & BIT(i)));
 }
 
 static int ad7266_update_scan_mode(struct iio_dev *indio_dev,
@@ -376,7 +376,7 @@ static void ad7266_init_channels(struct iio_dev *indio_dev)
 }
 
 static const char * const ad7266_gpio_labels[] = {
-       "AD0", "AD1", "AD2",
+       "ad0", "ad1", "ad2",
 };
 
 static int ad7266_probe(struct spi_device *spi)
@@ -419,14 +419,14 @@ static int ad7266_probe(struct spi_device *spi)
 
                if (!st->fixed_addr) {
                        for (i = 0; i < ARRAY_SIZE(st->gpios); ++i) {
-                               st->gpios[i].gpio = pdata->addr_gpios[i];
-                               st->gpios[i].flags = GPIOF_OUT_INIT_LOW;
-                               st->gpios[i].label = ad7266_gpio_labels[i];
+                               st->gpios[i] = devm_gpiod_get(&spi->dev,
+                                                     ad7266_gpio_labels[i],
+                                                     GPIOD_OUT_LOW);
+                               if (IS_ERR(st->gpios[i])) {
+                                       ret = PTR_ERR(st->gpios[i]);
+                                       goto error_disable_reg;
+                               }
                        }
-                       ret = gpio_request_array(st->gpios,
-                               ARRAY_SIZE(st->gpios));
-                       if (ret)
-                               goto error_disable_reg;
                }
        } else {
                st->fixed_addr = true;
@@ -465,7 +465,7 @@ static int ad7266_probe(struct spi_device *spi)
        ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
                &ad7266_trigger_handler, &iio_triggered_buffer_setup_ops);
        if (ret)
-               goto error_free_gpios;
+               goto error_disable_reg;
 
        ret = iio_device_register(indio_dev);
        if (ret)
@@ -475,9 +475,6 @@ static int ad7266_probe(struct spi_device *spi)
 
 error_buffer_cleanup:
        iio_triggered_buffer_cleanup(indio_dev);
-error_free_gpios:
-       if (!st->fixed_addr)
-               gpio_free_array(st->gpios, ARRAY_SIZE(st->gpios));
 error_disable_reg:
        if (!IS_ERR(st->reg))
                regulator_disable(st->reg);
@@ -492,8 +489,6 @@ static int ad7266_remove(struct spi_device *spi)
 
        iio_device_unregister(indio_dev);
        iio_triggered_buffer_cleanup(indio_dev);
-       if (!st->fixed_addr)
-               gpio_free_array(st->gpios, ARRAY_SIZE(st->gpios));
        if (!IS_ERR(st->reg))
                regulator_disable(st->reg);
 
index 217a5a5..291c1a8 100644 (file)
@@ -203,6 +203,7 @@ static const struct ad_sigma_delta_info ad7780_sigma_delta_info = {
        .set_mode = ad7780_set_mode,
        .postprocess_sample = ad7780_postprocess_sample,
        .has_registers = false,
+       .irq_flags = IRQF_TRIGGER_LOW,
 };
 
 #define AD7780_CHANNEL(bits, wordsize) \
index 54025ea..abb2393 100644 (file)
@@ -205,6 +205,7 @@ static const struct ad_sigma_delta_info ad7791_sigma_delta_info = {
        .has_registers = true,
        .addr_shift = 4,
        .read_mask = BIT(3),
+       .irq_flags = IRQF_TRIGGER_LOW,
 };
 
 static int ad7791_read_raw(struct iio_dev *indio_dev,
index bbc41ec..b747db9 100644 (file)
@@ -206,6 +206,7 @@ static const struct ad_sigma_delta_info ad7793_sigma_delta_info = {
        .has_registers = true,
        .addr_shift = 3,
        .read_mask = BIT(6),
+       .irq_flags = IRQF_TRIGGER_LOW,
 };
 
 static const struct ad_sd_calib_data ad7793_calib_arr[6] = {
index 6223043..c6a3428 100644 (file)
@@ -43,11 +43,17 @@ enum ad7887_channels {
 /**
  * struct ad7887_chip_info - chip specifc information
  * @int_vref_mv:       the internal reference voltage
- * @channel:           channel specification
+ * @channels:          channels specification
+ * @num_channels:      number of channels
+ * @dual_channels:     channels specification in dual mode
+ * @num_dual_channels: number of channels in dual mode
  */
 struct ad7887_chip_info {
        u16                             int_vref_mv;
-       struct iio_chan_spec            channel[3];
+       const struct iio_chan_spec      *channels;
+       unsigned int                    num_channels;
+       const struct iio_chan_spec      *dual_channels;
+       unsigned int                    num_dual_channels;
 };
 
 struct ad7887_state {
@@ -183,45 +189,43 @@ static int ad7887_read_raw(struct iio_dev *indio_dev,
        return -EINVAL;
 }
 
+#define AD7887_CHANNEL(x) { \
+       .type = IIO_VOLTAGE, \
+       .indexed = 1, \
+       .channel = (x), \
+       .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+       .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+       .address = (x), \
+       .scan_index = (x), \
+       .scan_type = { \
+               .sign = 'u', \
+               .realbits = 12, \
+               .storagebits = 16, \
+               .shift = 0, \
+               .endianness = IIO_BE, \
+       }, \
+}
+
+static const struct iio_chan_spec ad7887_channels[] = {
+       AD7887_CHANNEL(0),
+       IIO_CHAN_SOFT_TIMESTAMP(1),
+};
+
+static const struct iio_chan_spec ad7887_dual_channels[] = {
+       AD7887_CHANNEL(0),
+       AD7887_CHANNEL(1),
+       IIO_CHAN_SOFT_TIMESTAMP(2),
+};
 
 static const struct ad7887_chip_info ad7887_chip_info_tbl[] = {
        /*
         * More devices added in future
         */
        [ID_AD7887] = {
-               .channel[0] = {
-                       .type = IIO_VOLTAGE,
-                       .indexed = 1,
-                       .channel = 1,
-                       .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
-                       .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
-                       .address = 1,
-                       .scan_index = 1,
-                       .scan_type = {
-                               .sign = 'u',
-                               .realbits = 12,
-                               .storagebits = 16,
-                               .shift = 0,
-                               .endianness = IIO_BE,
-                       },
-               },
-               .channel[1] = {
-                       .type = IIO_VOLTAGE,
-                       .indexed = 1,
-                       .channel = 0,
-                       .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
-                       .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
-                       .address = 0,
-                       .scan_index = 0,
-                       .scan_type = {
-                               .sign = 'u',
-                               .realbits = 12,
-                               .storagebits = 16,
-                               .shift = 0,
-                               .endianness = IIO_BE,
-                       },
-               },
-               .channel[2] = IIO_CHAN_SOFT_TIMESTAMP(2),
+               .channels = ad7887_channels,
+               .num_channels = ARRAY_SIZE(ad7887_channels),
+               .dual_channels = ad7887_dual_channels,
+               .num_dual_channels = ARRAY_SIZE(ad7887_dual_channels),
                .int_vref_mv = 2500,
        },
 };
@@ -306,11 +310,11 @@ static int ad7887_probe(struct spi_device *spi)
                spi_message_init(&st->msg[AD7887_CH1]);
                spi_message_add_tail(&st->xfer[3], &st->msg[AD7887_CH1]);
 
-               indio_dev->channels = st->chip_info->channel;
-               indio_dev->num_channels = 3;
+               indio_dev->channels = st->chip_info->dual_channels;
+               indio_dev->num_channels = st->chip_info->num_dual_channels;
        } else {
-               indio_dev->channels = &st->chip_info->channel[1];
-               indio_dev->num_channels = 2;
+               indio_dev->channels = st->chip_info->channels;
+               indio_dev->num_channels = st->chip_info->num_channels;
        }
 
        ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
index 3212eb4..1d124c8 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * AD7904/AD7914/AD7923/AD7924 SPI ADC driver
+ * AD7904/AD7914/AD7923/AD7924/AD7908/AD7918/AD7928 SPI ADC driver
  *
  * Copyright 2011 Analog Devices Inc (from AD7923 Driver)
  * Copyright 2012 CS Systemes d'Information
 #define AD7923_PM_MODE_AS      (1)             /* auto shutdown */
 #define AD7923_PM_MODE_FS      (2)             /* full shutdown */
 #define AD7923_PM_MODE_OPS     (3)             /* normal operation */
-#define AD7923_CHANNEL_0       (0)             /* analog input 0 */
-#define AD7923_CHANNEL_1       (1)             /* analog input 1 */
-#define AD7923_CHANNEL_2       (2)             /* analog input 2 */
-#define AD7923_CHANNEL_3       (3)             /* analog input 3 */
 #define AD7923_SEQUENCE_OFF    (0)             /* no sequence fonction */
 #define AD7923_SEQUENCE_PROTECT        (2)             /* no interrupt write cycle */
 #define AD7923_SEQUENCE_ON     (3)             /* continuous sequence */
 
-#define AD7923_MAX_CHAN                4
 
 #define AD7923_PM_MODE_WRITE(mode)     ((mode) << 4)    /* write mode */
 #define AD7923_CHANNEL_WRITE(channel)  ((channel) << 6) /* write channel */
@@ -78,6 +73,9 @@ enum ad7923_id {
        AD7904,
        AD7914,
        AD7924,
+       AD7908,
+       AD7918,
+       AD7928
 };
 
 #define AD7923_V_CHAN(index, bits)                                     \
@@ -106,9 +104,25 @@ const struct iio_chan_spec name ## _channels[] = { \
        IIO_CHAN_SOFT_TIMESTAMP(4), \
 }
 
+#define DECLARE_AD7908_CHANNELS(name, bits) \
+const struct iio_chan_spec name ## _channels[] = { \
+       AD7923_V_CHAN(0, bits), \
+       AD7923_V_CHAN(1, bits), \
+       AD7923_V_CHAN(2, bits), \
+       AD7923_V_CHAN(3, bits), \
+       AD7923_V_CHAN(4, bits), \
+       AD7923_V_CHAN(5, bits), \
+       AD7923_V_CHAN(6, bits), \
+       AD7923_V_CHAN(7, bits), \
+       IIO_CHAN_SOFT_TIMESTAMP(8), \
+}
+
 static DECLARE_AD7923_CHANNELS(ad7904, 8);
 static DECLARE_AD7923_CHANNELS(ad7914, 10);
 static DECLARE_AD7923_CHANNELS(ad7924, 12);
+static DECLARE_AD7908_CHANNELS(ad7908, 8);
+static DECLARE_AD7908_CHANNELS(ad7918, 10);
+static DECLARE_AD7908_CHANNELS(ad7928, 12);
 
 static const struct ad7923_chip_info ad7923_chip_info[] = {
        [AD7904] = {
@@ -123,6 +137,18 @@ static const struct ad7923_chip_info ad7923_chip_info[] = {
                .channels = ad7924_channels,
                .num_channels = ARRAY_SIZE(ad7924_channels),
        },
+       [AD7908] = {
+               .channels = ad7908_channels,
+               .num_channels = ARRAY_SIZE(ad7908_channels),
+       },
+       [AD7918] = {
+               .channels = ad7918_channels,
+               .num_channels = ARRAY_SIZE(ad7918_channels),
+       },
+       [AD7928] = {
+               .channels = ad7928_channels,
+               .num_channels = ARRAY_SIZE(ad7928_channels),
+       },
 };
 
 /**
@@ -135,7 +161,11 @@ static int ad7923_update_scan_mode(struct iio_dev *indio_dev,
        int i, cmd, len;
 
        len = 0;
-       for_each_set_bit(i, active_scan_mask, AD7923_MAX_CHAN) {
+       /*
+        * For this driver the last channel is always the software timestamp so
+        * skip that one.
+        */
+       for_each_set_bit(i, active_scan_mask, indio_dev->num_channels - 1) {
                cmd = AD7923_WRITE_CR | AD7923_CHANNEL_WRITE(i) |
                        AD7923_SEQUENCE_WRITE(AD7923_SEQUENCE_OFF) |
                        st->settings;
@@ -188,7 +218,7 @@ done:
        return IRQ_HANDLED;
 }
 
-static int ad7923_scan_direct(struct ad7923_state *st, unsigned ch)
+static int ad7923_scan_direct(struct ad7923_state *st, unsigned int ch)
 {
        int ret, cmd;
 
@@ -348,13 +378,29 @@ static const struct spi_device_id ad7923_id[] = {
        {"ad7914", AD7914},
        {"ad7923", AD7924},
        {"ad7924", AD7924},
+       {"ad7908", AD7908},
+       {"ad7918", AD7918},
+       {"ad7928", AD7928},
        {}
 };
 MODULE_DEVICE_TABLE(spi, ad7923_id);
 
+static const struct of_device_id ad7923_of_match[] = {
+       { .compatible = "adi,ad7904", },
+       { .compatible = "adi,ad7914", },
+       { .compatible = "adi,ad7923", },
+       { .compatible = "adi,ad7924", },
+       { .compatible = "adi,ad7908", },
+       { .compatible = "adi,ad7918", },
+       { .compatible = "adi,ad7928", },
+       { },
+};
+MODULE_DEVICE_TABLE(of, ad7923_of_match);
+
 static struct spi_driver ad7923_driver = {
        .driver = {
                .name   = "ad7923",
+               .of_match_table = ad7923_of_match,
        },
        .probe          = ad7923_probe,
        .remove         = ad7923_remove,
@@ -364,5 +410,5 @@ module_spi_driver(ad7923_driver);
 
 MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
 MODULE_AUTHOR("Patrick Vasseur <patrick.vasseur@c-s.fr>");
-MODULE_DESCRIPTION("Analog Devices AD7904/AD7914/AD7923/AD7924 ADC");
+MODULE_DESCRIPTION("Analog Devices AD7923 and similar ADC");
 MODULE_LICENSE("GPL v2");
index f658012..ef013af 100644 (file)
@@ -167,6 +167,21 @@ static int ad799x_read_config(struct ad799x_state *st)
        }
 }
 
+static int ad799x_update_config(struct ad799x_state *st, u16 config)
+{
+       int ret;
+
+       ret = ad799x_write_config(st, config);
+       if (ret < 0)
+               return ret;
+       ret = ad799x_read_config(st);
+       if (ret < 0)
+               return ret;
+       st->config = ret;
+
+       return 0;
+}
+
 /**
  * ad799x_trigger_handler() bh of trigger launched polling to ring buffer
  *
@@ -808,13 +823,9 @@ static int ad799x_probe(struct i2c_client *client,
        indio_dev->channels = st->chip_config->channel;
        indio_dev->num_channels = chip_info->num_channels;
 
-       ret = ad799x_write_config(st, st->chip_config->default_config);
-       if (ret < 0)
-               goto error_disable_vref;
-       ret = ad799x_read_config(st);
-       if (ret < 0)
+       ret = ad799x_update_config(st, st->chip_config->default_config);
+       if (ret)
                goto error_disable_vref;
-       st->config = ret;
 
        ret = iio_triggered_buffer_setup(indio_dev, NULL,
                &ad799x_trigger_handler, NULL);
@@ -864,6 +875,48 @@ static int ad799x_remove(struct i2c_client *client)
        return 0;
 }
 
+static int __maybe_unused ad799x_suspend(struct device *dev)
+{
+       struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+       struct ad799x_state *st = iio_priv(indio_dev);
+
+       regulator_disable(st->vref);
+       regulator_disable(st->reg);
+
+       return 0;
+}
+
+static int __maybe_unused ad799x_resume(struct device *dev)
+{
+       struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+       struct ad799x_state *st = iio_priv(indio_dev);
+       int ret;
+
+       ret = regulator_enable(st->reg);
+       if (ret) {
+               dev_err(dev, "Unable to enable vcc regulator\n");
+               return ret;
+       }
+       ret = regulator_enable(st->vref);
+       if (ret) {
+               regulator_disable(st->reg);
+               dev_err(dev, "Unable to enable vref regulator\n");
+               return ret;
+       }
+
+       /* resync config */
+       ret = ad799x_update_config(st, st->config);
+       if (ret) {
+               regulator_disable(st->vref);
+               regulator_disable(st->reg);
+               return ret;
+       }
+
+       return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(ad799x_pm_ops, ad799x_suspend, ad799x_resume);
+
 static const struct i2c_device_id ad799x_id[] = {
        { "ad7991", ad7991 },
        { "ad7995", ad7995 },
@@ -881,6 +934,7 @@ MODULE_DEVICE_TABLE(i2c, ad799x_id);
 static struct i2c_driver ad799x_driver = {
        .driver = {
                .name = "ad799x",
+               .pm = &ad799x_pm_ops,
        },
        .probe = ad799x_probe,
        .remove = ad799x_remove,
index 8ba9048..8115b6d 100644 (file)
@@ -500,7 +500,7 @@ static int ad_sd_probe_trigger(struct iio_dev *indio_dev)
 
        ret = request_irq(sigma_delta->spi->irq,
                          ad_sd_data_rdy_trig_poll,
-                         IRQF_TRIGGER_LOW,
+                         sigma_delta->info->irq_flags,
                          indio_dev->name,
                          sigma_delta);
        if (ret)
index e1850f3..a5c7771 100644 (file)
@@ -1444,10 +1444,10 @@ static void at91_adc_dma_init(struct platform_device *pdev)
        if (st->dma_st.dma_chan)
                return;
 
-       st->dma_st.dma_chan = dma_request_slave_channel(&pdev->dev, "rx");
-
-       if (!st->dma_st.dma_chan)  {
+       st->dma_st.dma_chan = dma_request_chan(&pdev->dev, "rx");
+       if (IS_ERR(st->dma_st.dma_chan))  {
                dev_info(&pdev->dev, "can't get DMA channel\n");
+               st->dma_st.dma_chan = NULL;
                goto dma_exit;
        }
 
diff --git a/drivers/iio/adc/ltc2496.c b/drivers/iio/adc/ltc2496.c
new file mode 100644 (file)
index 0000000..88a3015
--- /dev/null
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * ltc2496.c - Driver for Analog Devices/Linear Technology LTC2496 ADC
+ *
+ * Based on ltc2497.c which has
+ * Copyright (C) 2017 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ *
+ * Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/2496fc.pdf
+ */
+
+#include <linux/spi/spi.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/driver.h>
+#include <linux/module.h>
+#include <linux/of.h>
+
+#include "ltc2497.h"
+
+struct ltc2496_driverdata {
+       /* this must be the first member */
+       struct ltc2497core_driverdata common_ddata;
+       struct spi_device *spi;
+
+       /*
+        * DMA (thus cache coherency maintenance) requires the
+        * transfer buffers to live in their own cache lines.
+        */
+       unsigned char rxbuf[3] ____cacheline_aligned;
+       unsigned char txbuf[3];
+};
+
+static int ltc2496_result_and_measure(struct ltc2497core_driverdata *ddata,
+                                     u8 address, int *val)
+{
+       struct ltc2496_driverdata *st =
+               container_of(ddata, struct ltc2496_driverdata, common_ddata);
+       struct spi_transfer t = {
+               .tx_buf = st->txbuf,
+               .rx_buf = st->rxbuf,
+               .len = sizeof(st->txbuf),
+       };
+       int ret;
+
+       st->txbuf[0] = LTC2497_ENABLE | address;
+
+       ret = spi_sync_transfer(st->spi, &t, 1);
+       if (ret < 0)  {
+               dev_err(&st->spi->dev, "spi_sync_transfer failed: %pe\n",
+                       ERR_PTR(ret));
+               return ret;
+       }
+
+       if (val)
+               *val = ((st->rxbuf[0] & 0x3f) << 12 |
+                       st->rxbuf[1] << 4 | st->rxbuf[2] >> 4) -
+                       (1 << 17);
+
+       return 0;
+}
+
+static int ltc2496_probe(struct spi_device *spi)
+{
+       struct iio_dev *indio_dev;
+       struct ltc2496_driverdata *st;
+       struct device *dev = &spi->dev;
+
+       indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
+       if (!indio_dev)
+               return -ENOMEM;
+
+       st = iio_priv(indio_dev);
+       spi_set_drvdata(spi, indio_dev);
+       st->spi = spi;
+       st->common_ddata.result_and_measure = ltc2496_result_and_measure;
+
+       return ltc2497core_probe(dev, indio_dev);
+}
+
+static int ltc2496_remove(struct spi_device *spi)
+{
+       struct iio_dev *indio_dev = spi_get_drvdata(spi);
+
+       ltc2497core_remove(indio_dev);
+
+       return 0;
+}
+
+static const struct of_device_id ltc2496_of_match[] = {
+       { .compatible = "lltc,ltc2496", },
+       {},
+};
+MODULE_DEVICE_TABLE(of, ltc2496_of_match);
+
+static struct spi_driver ltc2496_driver = {
+       .driver = {
+               .name = "ltc2496",
+               .of_match_table = of_match_ptr(ltc2496_of_match),
+       },
+       .probe = ltc2496_probe,
+       .remove = ltc2496_remove,
+};
+module_spi_driver(ltc2496_driver);
+
+MODULE_AUTHOR("Uwe Kleine-König <u.kleine-könig@pengutronix.de>");
+MODULE_DESCRIPTION("Linear Technology LTC2496 ADC driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/adc/ltc2497-core.c b/drivers/iio/adc/ltc2497-core.c
new file mode 100644 (file)
index 0000000..f5f7039
--- /dev/null
@@ -0,0 +1,243 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * ltc2497-core.c - Common code for Analog Devices/Linear Technology
+ * LTC2496 and LTC2497 ADCs
+ *
+ * Copyright (C) 2017 Analog Devices Inc.
+ */
+
+#include <linux/delay.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/driver.h>
+#include <linux/module.h>
+#include <linux/regulator/consumer.h>
+
+#include "ltc2497.h"
+
+#define LTC2497_SGL                    BIT(4)
+#define LTC2497_DIFF                   0
+#define LTC2497_SIGN                   BIT(3)
+
+static int ltc2497core_wait_conv(struct ltc2497core_driverdata *ddata)
+{
+       s64 time_elapsed;
+
+       time_elapsed = ktime_ms_delta(ktime_get(), ddata->time_prev);
+
+       if (time_elapsed < LTC2497_CONVERSION_TIME_MS) {
+               /* delay if conversion time not passed
+                * since last read or write
+                */
+               if (msleep_interruptible(
+                   LTC2497_CONVERSION_TIME_MS - time_elapsed))
+                       return -ERESTARTSYS;
+
+               return 0;
+       }
+
+       if (time_elapsed - LTC2497_CONVERSION_TIME_MS <= 0) {
+               /* We're in automatic mode -
+                * so the last reading is still not outdated
+                */
+               return 0;
+       }
+
+       return 1;
+}
+
+static int ltc2497core_read(struct ltc2497core_driverdata *ddata, u8 address, int *val)
+{
+       int ret;
+
+       ret = ltc2497core_wait_conv(ddata);
+       if (ret < 0)
+               return ret;
+
+       if (ret || ddata->addr_prev != address) {
+               ret = ddata->result_and_measure(ddata, address, NULL);
+               if (ret < 0)
+                       return ret;
+               ddata->addr_prev = address;
+
+               if (msleep_interruptible(LTC2497_CONVERSION_TIME_MS))
+                       return -ERESTARTSYS;
+       }
+
+       ret = ddata->result_and_measure(ddata, address, val);
+       if (ret < 0)
+               return ret;
+
+       ddata->time_prev = ktime_get();
+
+       return ret;
+}
+
+static int ltc2497core_read_raw(struct iio_dev *indio_dev,
+                           struct iio_chan_spec const *chan,
+                           int *val, int *val2, long mask)
+{
+       struct ltc2497core_driverdata *ddata = iio_priv(indio_dev);
+       int ret;
+
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               mutex_lock(&indio_dev->mlock);
+               ret = ltc2497core_read(ddata, chan->address, val);
+               mutex_unlock(&indio_dev->mlock);
+               if (ret < 0)
+                       return ret;
+
+               return IIO_VAL_INT;
+
+       case IIO_CHAN_INFO_SCALE:
+               ret = regulator_get_voltage(ddata->ref);
+               if (ret < 0)
+                       return ret;
+
+               *val = ret / 1000;
+               *val2 = 17;
+
+               return IIO_VAL_FRACTIONAL_LOG2;
+
+       default:
+               return -EINVAL;
+       }
+}
+
+#define LTC2497_CHAN(_chan, _addr, _ds_name) { \
+       .type = IIO_VOLTAGE, \
+       .indexed = 1, \
+       .channel = (_chan), \
+       .address = (_addr | (_chan / 2) | ((_chan & 1) ? LTC2497_SIGN : 0)), \
+       .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+       .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+       .datasheet_name = (_ds_name), \
+}
+
+#define LTC2497_CHAN_DIFF(_chan, _addr) { \
+       .type = IIO_VOLTAGE, \
+       .indexed = 1, \
+       .channel = (_chan) * 2 + ((_addr) & LTC2497_SIGN ? 1 : 0), \
+       .channel2 = (_chan) * 2 + ((_addr) & LTC2497_SIGN ? 0 : 1),\
+       .address = (_addr | _chan), \
+       .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+       .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+       .differential = 1, \
+}
+
+static const struct iio_chan_spec ltc2497core_channel[] = {
+       LTC2497_CHAN(0, LTC2497_SGL, "CH0"),
+       LTC2497_CHAN(1, LTC2497_SGL, "CH1"),
+       LTC2497_CHAN(2, LTC2497_SGL, "CH2"),
+       LTC2497_CHAN(3, LTC2497_SGL, "CH3"),
+       LTC2497_CHAN(4, LTC2497_SGL, "CH4"),
+       LTC2497_CHAN(5, LTC2497_SGL, "CH5"),
+       LTC2497_CHAN(6, LTC2497_SGL, "CH6"),
+       LTC2497_CHAN(7, LTC2497_SGL, "CH7"),
+       LTC2497_CHAN(8, LTC2497_SGL, "CH8"),
+       LTC2497_CHAN(9, LTC2497_SGL, "CH9"),
+       LTC2497_CHAN(10, LTC2497_SGL, "CH10"),
+       LTC2497_CHAN(11, LTC2497_SGL, "CH11"),
+       LTC2497_CHAN(12, LTC2497_SGL, "CH12"),
+       LTC2497_CHAN(13, LTC2497_SGL, "CH13"),
+       LTC2497_CHAN(14, LTC2497_SGL, "CH14"),
+       LTC2497_CHAN(15, LTC2497_SGL, "CH15"),
+       LTC2497_CHAN_DIFF(0, LTC2497_DIFF),
+       LTC2497_CHAN_DIFF(1, LTC2497_DIFF),
+       LTC2497_CHAN_DIFF(2, LTC2497_DIFF),
+       LTC2497_CHAN_DIFF(3, LTC2497_DIFF),
+       LTC2497_CHAN_DIFF(4, LTC2497_DIFF),
+       LTC2497_CHAN_DIFF(5, LTC2497_DIFF),
+       LTC2497_CHAN_DIFF(6, LTC2497_DIFF),
+       LTC2497_CHAN_DIFF(7, LTC2497_DIFF),
+       LTC2497_CHAN_DIFF(0, LTC2497_DIFF | LTC2497_SIGN),
+       LTC2497_CHAN_DIFF(1, LTC2497_DIFF | LTC2497_SIGN),
+       LTC2497_CHAN_DIFF(2, LTC2497_DIFF | LTC2497_SIGN),
+       LTC2497_CHAN_DIFF(3, LTC2497_DIFF | LTC2497_SIGN),
+       LTC2497_CHAN_DIFF(4, LTC2497_DIFF | LTC2497_SIGN),
+       LTC2497_CHAN_DIFF(5, LTC2497_DIFF | LTC2497_SIGN),
+       LTC2497_CHAN_DIFF(6, LTC2497_DIFF | LTC2497_SIGN),
+       LTC2497_CHAN_DIFF(7, LTC2497_DIFF | LTC2497_SIGN),
+};
+
+static const struct iio_info ltc2497core_info = {
+       .read_raw = ltc2497core_read_raw,
+};
+
+int ltc2497core_probe(struct device *dev, struct iio_dev *indio_dev)
+{
+       struct ltc2497core_driverdata *ddata = iio_priv(indio_dev);
+       int ret;
+
+       indio_dev->dev.parent = dev;
+       indio_dev->name = dev_name(dev);
+       indio_dev->info = &ltc2497core_info;
+       indio_dev->modes = INDIO_DIRECT_MODE;
+       indio_dev->channels = ltc2497core_channel;
+       indio_dev->num_channels = ARRAY_SIZE(ltc2497core_channel);
+
+       ret = ddata->result_and_measure(ddata, LTC2497_CONFIG_DEFAULT, NULL);
+       if (ret < 0)
+               return ret;
+
+       ddata->ref = devm_regulator_get(dev, "vref");
+       if (IS_ERR(ddata->ref)) {
+               if (PTR_ERR(ddata->ref) != -EPROBE_DEFER)
+                       dev_err(dev, "Failed to get vref regulator: %pe\n",
+                               ddata->ref);
+
+               return PTR_ERR(ddata->ref);
+       }
+
+       ret = regulator_enable(ddata->ref);
+       if (ret < 0) {
+               dev_err(dev, "Failed to enable vref regulator: %pe\n",
+                       ERR_PTR(ret));
+               return ret;
+       }
+
+       if (dev->platform_data) {
+               struct iio_map *plat_data;
+
+               plat_data = (struct iio_map *)dev->platform_data;
+
+               ret = iio_map_array_register(indio_dev, plat_data);
+               if (ret) {
+                       dev_err(&indio_dev->dev, "iio map err: %d\n", ret);
+                       goto err_regulator_disable;
+               }
+       }
+
+       ddata->addr_prev = LTC2497_CONFIG_DEFAULT;
+       ddata->time_prev = ktime_get();
+
+       ret = iio_device_register(indio_dev);
+       if (ret < 0)
+               goto err_array_unregister;
+
+       return 0;
+
+err_array_unregister:
+       iio_map_array_unregister(indio_dev);
+
+err_regulator_disable:
+       regulator_disable(ddata->ref);
+
+       return ret;
+}
+EXPORT_SYMBOL_NS(ltc2497core_probe, LTC2497);
+
+void ltc2497core_remove(struct iio_dev *indio_dev)
+{
+       struct ltc2497core_driverdata *ddata = iio_priv(indio_dev);
+
+       iio_device_unregister(indio_dev);
+
+       iio_map_array_unregister(indio_dev);
+
+       regulator_disable(ddata->ref);
+}
+EXPORT_SYMBOL_NS(ltc2497core_remove, LTC2497);
+
+MODULE_DESCRIPTION("common code for LTC2496/LTC2497 drivers");
+MODULE_LICENSE("GPL v2");
index 4704060..5db63d7 100644 (file)
@@ -7,27 +7,18 @@
  * Datasheet: http://cds.linear.com/docs/en/datasheet/2497fd.pdf
  */
 
-#include <linux/delay.h>
 #include <linux/i2c.h>
 #include <linux/iio/iio.h>
 #include <linux/iio/driver.h>
-#include <linux/iio/sysfs.h>
 #include <linux/module.h>
 #include <linux/of.h>
-#include <linux/regulator/consumer.h>
 
-#define LTC2497_ENABLE                 0xA0
-#define LTC2497_SGL                    BIT(4)
-#define LTC2497_DIFF                   0
-#define LTC2497_SIGN                   BIT(3)
-#define LTC2497_CONFIG_DEFAULT         LTC2497_ENABLE
-#define LTC2497_CONVERSION_TIME_MS     150ULL
+#include "ltc2497.h"
 
-struct ltc2497_st {
+struct ltc2497_driverdata {
+       /* this must be the first member */
+       struct ltc2497core_driverdata common_ddata;
        struct i2c_client *client;
-       struct regulator *ref;
-       ktime_t time_prev;
-       u8 addr_prev;
        /*
         * DMA (thus cache coherency maintenance) requires the
         * transfer buffers to live in their own cache lines.
@@ -35,232 +26,59 @@ struct ltc2497_st {
        __be32 buf ____cacheline_aligned;
 };
 
-static int ltc2497_wait_conv(struct ltc2497_st *st)
+static int ltc2497_result_and_measure(struct ltc2497core_driverdata *ddata,
+                                     u8 address, int *val)
 {
-       s64 time_elapsed;
-
-       time_elapsed = ktime_ms_delta(ktime_get(), st->time_prev);
-
-       if (time_elapsed < LTC2497_CONVERSION_TIME_MS) {
-               /* delay if conversion time not passed
-                * since last read or write
-                */
-               if (msleep_interruptible(
-                   LTC2497_CONVERSION_TIME_MS - time_elapsed))
-                       return -ERESTARTSYS;
-
-               return 0;
-       }
-
-       if (time_elapsed - LTC2497_CONVERSION_TIME_MS <= 0) {
-               /* We're in automatic mode -
-                * so the last reading is stil not outdated
-                */
-               return 0;
-       }
-
-       return 1;
-}
-
-static int ltc2497_read(struct ltc2497_st *st, u8 address, int *val)
-{
-       struct i2c_client *client = st->client;
-       int ret;
-
-       ret = ltc2497_wait_conv(st);
-       if (ret < 0)
-               return ret;
-
-       if (ret || st->addr_prev != address) {
-               ret = i2c_smbus_write_byte(st->client,
-                                          LTC2497_ENABLE | address);
-               if (ret < 0)
-                       return ret;
-               st->addr_prev = address;
-               if (msleep_interruptible(LTC2497_CONVERSION_TIME_MS))
-                       return -ERESTARTSYS;
-       }
-       ret = i2c_master_recv(client, (char *)&st->buf, 3);
-       if (ret < 0)  {
-               dev_err(&client->dev, "i2c_master_recv failed\n");
-               return ret;
-       }
-       st->time_prev = ktime_get();
-
-       /* convert and shift the result,
-        * and finally convert from offset binary to signed integer
-        */
-       *val = (be32_to_cpu(st->buf) >> 14) - (1 << 17);
-
-       return ret;
-}
-
-static int ltc2497_read_raw(struct iio_dev *indio_dev,
-                           struct iio_chan_spec const *chan,
-                           int *val, int *val2, long mask)
-{
-       struct ltc2497_st *st = iio_priv(indio_dev);
+       struct ltc2497_driverdata *st =
+               container_of(ddata, struct ltc2497_driverdata, common_ddata);
        int ret;
 
-       switch (mask) {
-       case IIO_CHAN_INFO_RAW:
-               mutex_lock(&indio_dev->mlock);
-               ret = ltc2497_read(st, chan->address, val);
-               mutex_unlock(&indio_dev->mlock);
-               if (ret < 0)
-                       return ret;
-
-               return IIO_VAL_INT;
-
-       case IIO_CHAN_INFO_SCALE:
-               ret = regulator_get_voltage(st->ref);
-               if (ret < 0)
+       if (val) {
+               ret = i2c_master_recv(st->client, (char *)&st->buf, 3);
+               if (ret < 0) {
+                       dev_err(&st->client->dev, "i2c_master_recv failed\n");
                        return ret;
+               }
 
-               *val = ret / 1000;
-               *val2 = 17;
-
-               return IIO_VAL_FRACTIONAL_LOG2;
-
-       default:
-               return -EINVAL;
+               *val = (be32_to_cpu(st->buf) >> 14) - (1 << 17);
        }
-}
 
-#define LTC2497_CHAN(_chan, _addr, _ds_name) { \
-       .type = IIO_VOLTAGE, \
-       .indexed = 1, \
-       .channel = (_chan), \
-       .address = (_addr | (_chan / 2) | ((_chan & 1) ? LTC2497_SIGN : 0)), \
-       .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
-       .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
-       .datasheet_name = (_ds_name), \
-}
-
-#define LTC2497_CHAN_DIFF(_chan, _addr) { \
-       .type = IIO_VOLTAGE, \
-       .indexed = 1, \
-       .channel = (_chan) * 2 + ((_addr) & LTC2497_SIGN ? 1 : 0), \
-       .channel2 = (_chan) * 2 + ((_addr) & LTC2497_SIGN ? 0 : 1),\
-       .address = (_addr | _chan), \
-       .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
-       .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
-       .differential = 1, \
+       ret = i2c_smbus_write_byte(st->client,
+                                  LTC2497_ENABLE | address);
+       if (ret)
+               dev_err(&st->client->dev, "i2c transfer failed: %pe\n",
+                       ERR_PTR(ret));
+       return ret;
 }
 
-static const struct iio_chan_spec ltc2497_channel[] = {
-       LTC2497_CHAN(0, LTC2497_SGL, "CH0"),
-       LTC2497_CHAN(1, LTC2497_SGL, "CH1"),
-       LTC2497_CHAN(2, LTC2497_SGL, "CH2"),
-       LTC2497_CHAN(3, LTC2497_SGL, "CH3"),
-       LTC2497_CHAN(4, LTC2497_SGL, "CH4"),
-       LTC2497_CHAN(5, LTC2497_SGL, "CH5"),
-       LTC2497_CHAN(6, LTC2497_SGL, "CH6"),
-       LTC2497_CHAN(7, LTC2497_SGL, "CH7"),
-       LTC2497_CHAN(8, LTC2497_SGL, "CH8"),
-       LTC2497_CHAN(9, LTC2497_SGL, "CH9"),
-       LTC2497_CHAN(10, LTC2497_SGL, "CH10"),
-       LTC2497_CHAN(11, LTC2497_SGL, "CH11"),
-       LTC2497_CHAN(12, LTC2497_SGL, "CH12"),
-       LTC2497_CHAN(13, LTC2497_SGL, "CH13"),
-       LTC2497_CHAN(14, LTC2497_SGL, "CH14"),
-       LTC2497_CHAN(15, LTC2497_SGL, "CH15"),
-       LTC2497_CHAN_DIFF(0, LTC2497_DIFF),
-       LTC2497_CHAN_DIFF(1, LTC2497_DIFF),
-       LTC2497_CHAN_DIFF(2, LTC2497_DIFF),
-       LTC2497_CHAN_DIFF(3, LTC2497_DIFF),
-       LTC2497_CHAN_DIFF(4, LTC2497_DIFF),
-       LTC2497_CHAN_DIFF(5, LTC2497_DIFF),
-       LTC2497_CHAN_DIFF(6, LTC2497_DIFF),
-       LTC2497_CHAN_DIFF(7, LTC2497_DIFF),
-       LTC2497_CHAN_DIFF(0, LTC2497_DIFF | LTC2497_SIGN),
-       LTC2497_CHAN_DIFF(1, LTC2497_DIFF | LTC2497_SIGN),
-       LTC2497_CHAN_DIFF(2, LTC2497_DIFF | LTC2497_SIGN),
-       LTC2497_CHAN_DIFF(3, LTC2497_DIFF | LTC2497_SIGN),
-       LTC2497_CHAN_DIFF(4, LTC2497_DIFF | LTC2497_SIGN),
-       LTC2497_CHAN_DIFF(5, LTC2497_DIFF | LTC2497_SIGN),
-       LTC2497_CHAN_DIFF(6, LTC2497_DIFF | LTC2497_SIGN),
-       LTC2497_CHAN_DIFF(7, LTC2497_DIFF | LTC2497_SIGN),
-};
-
-static const struct iio_info ltc2497_info = {
-       .read_raw = ltc2497_read_raw,
-};
-
 static int ltc2497_probe(struct i2c_client *client,
                         const struct i2c_device_id *id)
 {
        struct iio_dev *indio_dev;
-       struct ltc2497_st *st;
-       struct iio_map *plat_data;
-       int ret;
+       struct ltc2497_driverdata *st;
+       struct device *dev = &client->dev;
 
        if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
                                     I2C_FUNC_SMBUS_WRITE_BYTE))
                return -EOPNOTSUPP;
 
-       indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));
+       indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
        if (!indio_dev)
                return -ENOMEM;
 
        st = iio_priv(indio_dev);
        i2c_set_clientdata(client, indio_dev);
        st->client = client;
+       st->common_ddata.result_and_measure = ltc2497_result_and_measure;
 
-       indio_dev->dev.parent = &client->dev;
-       indio_dev->name = id->name;
-       indio_dev->info = &ltc2497_info;
-       indio_dev->modes = INDIO_DIRECT_MODE;
-       indio_dev->channels = ltc2497_channel;
-       indio_dev->num_channels = ARRAY_SIZE(ltc2497_channel);
-
-       st->ref = devm_regulator_get(&client->dev, "vref");
-       if (IS_ERR(st->ref))
-               return PTR_ERR(st->ref);
-
-       ret = regulator_enable(st->ref);
-       if (ret < 0)
-               return ret;
-
-       if (client->dev.platform_data) {
-               plat_data = ((struct iio_map *)client->dev.platform_data);
-               ret = iio_map_array_register(indio_dev, plat_data);
-               if (ret) {
-                       dev_err(&indio_dev->dev, "iio map err: %d\n", ret);
-                       goto err_regulator_disable;
-               }
-       }
-
-       ret = i2c_smbus_write_byte(st->client, LTC2497_CONFIG_DEFAULT);
-       if (ret < 0)
-               goto err_array_unregister;
-
-       st->addr_prev = LTC2497_CONFIG_DEFAULT;
-       st->time_prev = ktime_get();
-
-       ret = iio_device_register(indio_dev);
-       if (ret < 0)
-               goto err_array_unregister;
-
-       return 0;
-
-err_array_unregister:
-       iio_map_array_unregister(indio_dev);
-
-err_regulator_disable:
-       regulator_disable(st->ref);
-
-       return ret;
+       return ltc2497core_probe(dev, indio_dev);
 }
 
 static int ltc2497_remove(struct i2c_client *client)
 {
        struct iio_dev *indio_dev = i2c_get_clientdata(client);
-       struct ltc2497_st *st = iio_priv(indio_dev);
 
-       iio_map_array_unregister(indio_dev);
-       iio_device_unregister(indio_dev);
-       regulator_disable(st->ref);
+       ltc2497core_remove(indio_dev);
 
        return 0;
 }
diff --git a/drivers/iio/adc/ltc2497.h b/drivers/iio/adc/ltc2497.h
new file mode 100644 (file)
index 0000000..d0b42dd
--- /dev/null
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#define LTC2497_ENABLE                 0xA0
+#define LTC2497_CONFIG_DEFAULT         LTC2497_ENABLE
+#define LTC2497_CONVERSION_TIME_MS     150ULL
+
+struct ltc2497core_driverdata {
+       struct regulator *ref;
+       ktime_t time_prev;
+       u8 addr_prev;
+       int (*result_and_measure)(struct ltc2497core_driverdata *ddata,
+                                 u8 address, int *val);
+};
+
+int ltc2497core_probe(struct device *dev, struct iio_dev *indio_dev);
+void ltc2497core_remove(struct iio_dev *indio_dev);
+
+MODULE_IMPORT_NS(LTC2497);
index e480529..04d5ff7 100644 (file)
@@ -115,22 +115,17 @@ enum max9611_conf_ids {
  *                   where data shall be read from
  */
 static const unsigned int max9611_mux_conf[][2] = {
-       /* CONF_SENSE_1x */
-       { MAX9611_MUX_SENSE_1x, MAX9611_REG_CSA_DATA },
-       /* CONF_SENSE_4x */
-       { MAX9611_MUX_SENSE_4x, MAX9611_REG_CSA_DATA },
-       /* CONF_SENSE_8x */
-       { MAX9611_MUX_SENSE_8x, MAX9611_REG_CSA_DATA },
-       /* CONF_IN_VOLT */
-       { MAX9611_INPUT_VOLT, MAX9611_REG_RS_DATA },
-       /* CONF_TEMP */
-       { MAX9611_MUX_TEMP, MAX9611_REG_TEMP_DATA },
+       [CONF_SENSE_1x] = { MAX9611_MUX_SENSE_1x, MAX9611_REG_CSA_DATA },
+       [CONF_SENSE_4x] = { MAX9611_MUX_SENSE_4x, MAX9611_REG_CSA_DATA },
+       [CONF_SENSE_8x] = { MAX9611_MUX_SENSE_8x, MAX9611_REG_CSA_DATA },
+       [CONF_IN_VOLT]  = { MAX9611_INPUT_VOLT, MAX9611_REG_RS_DATA },
+       [CONF_TEMP]     = { MAX9611_MUX_TEMP, MAX9611_REG_TEMP_DATA },
 };
 
 enum max9611_csa_gain {
-       CSA_GAIN_1x,
-       CSA_GAIN_4x,
-       CSA_GAIN_8x,
+       CSA_GAIN_1x = CONF_SENSE_1x,
+       CSA_GAIN_4x = CONF_SENSE_4x,
+       CSA_GAIN_8x = CONF_SENSE_8x,
 };
 
 enum max9611_csa_gain_params {
@@ -148,18 +143,9 @@ enum max9611_csa_gain_params {
  * value; use this structure to retrieve the correct LSB and offset values.
  */
 static const unsigned int max9611_gain_conf[][2] = {
-       { /* [0] CSA_GAIN_1x */
-               MAX9611_CSA_1X_LSB_nV,
-               MAX9611_CSA_1X_OFFS_RAW,
-       },
-       { /* [1] CSA_GAIN_4x */
-               MAX9611_CSA_4X_LSB_nV,
-               MAX9611_CSA_4X_OFFS_RAW,
-       },
-       { /* [2] CSA_GAIN_8x */
-               MAX9611_CSA_8X_LSB_nV,
-               MAX9611_CSA_8X_OFFS_RAW,
-       },
+       [CSA_GAIN_1x] = { MAX9611_CSA_1X_LSB_nV, MAX9611_CSA_1X_OFFS_RAW, },
+       [CSA_GAIN_4x] = { MAX9611_CSA_4X_LSB_nV, MAX9611_CSA_4X_OFFS_RAW, },
+       [CSA_GAIN_8x] = { MAX9611_CSA_8X_LSB_nV, MAX9611_CSA_8X_OFFS_RAW, },
 };
 
 enum max9611_chan_addrs {
index 6537f4f..2df88d2 100644 (file)
@@ -280,21 +280,21 @@ out:
 static const struct stm32_adc_common_regs stm32f4_adc_common_regs = {
        .csr = STM32F4_ADC_CSR,
        .ccr = STM32F4_ADC_CCR,
-       .eoc1_msk = STM32F4_EOC1,
-       .eoc2_msk = STM32F4_EOC2,
-       .eoc3_msk = STM32F4_EOC3,
+       .eoc1_msk = STM32F4_EOC1 | STM32F4_OVR1,
+       .eoc2_msk = STM32F4_EOC2 | STM32F4_OVR2,
+       .eoc3_msk = STM32F4_EOC3 | STM32F4_OVR3,
        .ier = STM32F4_ADC_CR1,
-       .eocie_msk = STM32F4_EOCIE,
+       .eocie_msk = STM32F4_EOCIE | STM32F4_OVRIE,
 };
 
 /* STM32H7 common registers definitions */
 static const struct stm32_adc_common_regs stm32h7_adc_common_regs = {
        .csr = STM32H7_ADC_CSR,
        .ccr = STM32H7_ADC_CCR,
-       .eoc1_msk = STM32H7_EOC_MST,
-       .eoc2_msk = STM32H7_EOC_SLV,
+       .eoc1_msk = STM32H7_EOC_MST | STM32H7_OVR_MST,
+       .eoc2_msk = STM32H7_EOC_SLV | STM32H7_OVR_SLV,
        .ier = STM32H7_ADC_IER,
-       .eocie_msk = STM32H7_EOCIE,
+       .eocie_msk = STM32H7_EOCIE | STM32H7_OVRIE,
 };
 
 static const unsigned int stm32_adc_offset[STM32_ADC_MAX_ADCS] = {
@@ -688,7 +688,8 @@ static int stm32_adc_probe(struct platform_device *pdev)
        priv->vref = devm_regulator_get(&pdev->dev, "vref");
        if (IS_ERR(priv->vref)) {
                ret = PTR_ERR(priv->vref);
-               dev_err(&pdev->dev, "vref get failed, %d\n", ret);
+               if (ret != -EPROBE_DEFER)
+                       dev_err(&pdev->dev, "vref get failed, %d\n", ret);
                return ret;
        }
 
@@ -696,7 +697,8 @@ static int stm32_adc_probe(struct platform_device *pdev)
        if (IS_ERR(priv->aclk)) {
                ret = PTR_ERR(priv->aclk);
                if (ret != -ENOENT) {
-                       dev_err(&pdev->dev, "Can't get 'adc' clock\n");
+                       if (ret != -EPROBE_DEFER)
+                               dev_err(&pdev->dev, "Can't get 'adc' clock\n");
                        return ret;
                }
                priv->aclk = NULL;
@@ -706,7 +708,8 @@ static int stm32_adc_probe(struct platform_device *pdev)
        if (IS_ERR(priv->bclk)) {
                ret = PTR_ERR(priv->bclk);
                if (ret != -ENOENT) {
-                       dev_err(&pdev->dev, "Can't get 'bus' clock\n");
+                       if (ret != -EPROBE_DEFER)
+                               dev_err(&pdev->dev, "Can't get 'bus' clock\n");
                        return ret;
                }
                priv->bclk = NULL;
index 2579d51..2322809 100644 (file)
 #define STM32F4_ADC_CCR                        (STM32_ADCX_COMN_OFFSET + 0x04)
 
 /* STM32F4_ADC_SR - bit fields */
+#define STM32F4_OVR                    BIT(5)
 #define STM32F4_STRT                   BIT(4)
 #define STM32F4_EOC                    BIT(1)
 
 /* STM32F4_ADC_CR1 - bit fields */
+#define STM32F4_OVRIE                  BIT(26)
 #define STM32F4_RES_SHIFT              24
 #define STM32F4_RES_MASK               GENMASK(25, 24)
 #define STM32F4_SCAN                   BIT(8)
 #define STM32F4_ADON                   BIT(0)
 
 /* STM32F4_ADC_CSR - bit fields */
+#define STM32F4_OVR3                   BIT(21)
 #define STM32F4_EOC3                   BIT(17)
+#define STM32F4_OVR2                   BIT(13)
 #define STM32F4_EOC2                   BIT(9)
+#define STM32F4_OVR1                   BIT(5)
 #define STM32F4_EOC1                   BIT(1)
 
 /* STM32F4_ADC_CCR - bit fields */
 
 /* STM32H7_ADC_ISR - bit fields */
 #define STM32MP1_VREGREADY             BIT(12)
+#define STM32H7_OVR                    BIT(4)
 #define STM32H7_EOC                    BIT(2)
 #define STM32H7_ADRDY                  BIT(0)
 
 /* STM32H7_ADC_IER - bit fields */
+#define STM32H7_OVRIE                  STM32H7_OVR
 #define STM32H7_EOCIE                  STM32H7_EOC
 
 /* STM32H7_ADC_CR - bit fields */
@@ -155,7 +162,9 @@ enum stm32h7_adc_dmngt {
 #define STM32H7_LINCALFACT_MASK                GENMASK(29, 0)
 
 /* STM32H7_ADC_CSR - bit fields */
+#define STM32H7_OVR_SLV                        BIT(20)
 #define STM32H7_EOC_SLV                        BIT(18)
+#define STM32H7_OVR_MST                        BIT(4)
 #define STM32H7_EOC_MST                        BIT(2)
 
 /* STM32H7_ADC_CCR - bit fields */
index 3b291d7..80c3f96 100644 (file)
@@ -117,7 +117,9 @@ struct stm32_adc_regs {
  * struct stm32_adc_regspec - stm32 registers definition
  * @dr:                        data register offset
  * @ier_eoc:           interrupt enable register & eocie bitfield
+ * @ier_ovr:           interrupt enable register & overrun bitfield
  * @isr_eoc:           interrupt status register & eoc bitfield
+ * @isr_ovr:           interrupt status register & overrun bitfield
  * @sqr:               reference to sequence registers array
  * @exten:             trigger control register & bitfield
  * @extsel:            trigger selection register & bitfield
@@ -128,7 +130,9 @@ struct stm32_adc_regs {
 struct stm32_adc_regspec {
        const u32 dr;
        const struct stm32_adc_regs ier_eoc;
+       const struct stm32_adc_regs ier_ovr;
        const struct stm32_adc_regs isr_eoc;
+       const struct stm32_adc_regs isr_ovr;
        const struct stm32_adc_regs *sqr;
        const struct stm32_adc_regs exten;
        const struct stm32_adc_regs extsel;
@@ -337,7 +341,9 @@ static const unsigned int stm32f4_adc_smp_cycles[STM32_ADC_MAX_SMP + 1] = {
 static const struct stm32_adc_regspec stm32f4_adc_regspec = {
        .dr = STM32F4_ADC_DR,
        .ier_eoc = { STM32F4_ADC_CR1, STM32F4_EOCIE },
+       .ier_ovr = { STM32F4_ADC_CR1, STM32F4_OVRIE },
        .isr_eoc = { STM32F4_ADC_SR, STM32F4_EOC },
+       .isr_ovr = { STM32F4_ADC_SR, STM32F4_OVR },
        .sqr = stm32f4_sq,
        .exten = { STM32F4_ADC_CR2, STM32F4_EXTEN_MASK, STM32F4_EXTEN_SHIFT },
        .extsel = { STM32F4_ADC_CR2, STM32F4_EXTSEL_MASK,
@@ -429,7 +435,9 @@ static const unsigned int stm32h7_adc_smp_cycles[STM32_ADC_MAX_SMP + 1] = {
 static const struct stm32_adc_regspec stm32h7_adc_regspec = {
        .dr = STM32H7_ADC_DR,
        .ier_eoc = { STM32H7_ADC_IER, STM32H7_EOCIE },
+       .ier_ovr = { STM32H7_ADC_IER, STM32H7_OVRIE },
        .isr_eoc = { STM32H7_ADC_ISR, STM32H7_EOC },
+       .isr_ovr = { STM32H7_ADC_ISR, STM32H7_OVR },
        .sqr = stm32h7_sq,
        .exten = { STM32H7_ADC_CFGR, STM32H7_EXTEN_MASK, STM32H7_EXTEN_SHIFT },
        .extsel = { STM32H7_ADC_CFGR, STM32H7_EXTSEL_MASK,
@@ -506,6 +514,18 @@ static void stm32_adc_conv_irq_disable(struct stm32_adc *adc)
                           adc->cfg->regs->ier_eoc.mask);
 }
 
+static void stm32_adc_ovr_irq_enable(struct stm32_adc *adc)
+{
+       stm32_adc_set_bits(adc, adc->cfg->regs->ier_ovr.reg,
+                          adc->cfg->regs->ier_ovr.mask);
+}
+
+static void stm32_adc_ovr_irq_disable(struct stm32_adc *adc)
+{
+       stm32_adc_clr_bits(adc, adc->cfg->regs->ier_ovr.reg,
+                          adc->cfg->regs->ier_ovr.mask);
+}
+
 static void stm32_adc_set_res(struct stm32_adc *adc)
 {
        const struct stm32_adc_regs *res = &adc->cfg->regs->res;
@@ -1205,6 +1225,19 @@ static int stm32_adc_read_raw(struct iio_dev *indio_dev,
        }
 }
 
+static irqreturn_t stm32_adc_threaded_isr(int irq, void *data)
+{
+       struct stm32_adc *adc = data;
+       struct iio_dev *indio_dev = iio_priv_to_dev(adc);
+       const struct stm32_adc_regspec *regs = adc->cfg->regs;
+       u32 status = stm32_adc_readl(adc, regs->isr_eoc.reg);
+
+       if (status & regs->isr_ovr.mask)
+               dev_err(&indio_dev->dev, "Overrun, stopping: restart needed\n");
+
+       return IRQ_HANDLED;
+}
+
 static irqreturn_t stm32_adc_isr(int irq, void *data)
 {
        struct stm32_adc *adc = data;
@@ -1212,6 +1245,19 @@ static irqreturn_t stm32_adc_isr(int irq, void *data)
        const struct stm32_adc_regspec *regs = adc->cfg->regs;
        u32 status = stm32_adc_readl(adc, regs->isr_eoc.reg);
 
+       if (status & regs->isr_ovr.mask) {
+               /*
+                * Overrun occurred on regular conversions: data for wrong
+                * channel may be read. Unconditionally disable interrupts
+                * to stop processing data and print error message.
+                * Restarting the capture can be done by disabling, then
+                * re-enabling it (e.g. write 0, then 1 to buffer/enable).
+                */
+               stm32_adc_ovr_irq_disable(adc);
+               stm32_adc_conv_irq_disable(adc);
+               return IRQ_WAKE_THREAD;
+       }
+
        if (status & regs->isr_eoc.mask) {
                /* Reading DR also clears EOC status flag */
                adc->buffer[adc->bufi] = stm32_adc_readw(adc, regs->dr);
@@ -1441,6 +1487,8 @@ static int __stm32_adc_buffer_postenable(struct iio_dev *indio_dev)
        /* Reset adc buffer index */
        adc->bufi = 0;
 
+       stm32_adc_ovr_irq_enable(adc);
+
        if (!adc->dma_chan)
                stm32_adc_conv_irq_enable(adc);
 
@@ -1481,6 +1529,8 @@ static void __stm32_adc_buffer_predisable(struct iio_dev *indio_dev)
        if (!adc->dma_chan)
                stm32_adc_conv_irq_disable(adc);
 
+       stm32_adc_ovr_irq_disable(adc);
+
        if (adc->dma_chan)
                dmaengine_terminate_sync(adc->dma_chan);
 
@@ -1746,9 +1796,21 @@ static int stm32_adc_dma_request(struct iio_dev *indio_dev)
        struct dma_slave_config config;
        int ret;
 
-       adc->dma_chan = dma_request_slave_channel(&indio_dev->dev, "rx");
-       if (!adc->dma_chan)
+       adc->dma_chan = dma_request_chan(&indio_dev->dev, "rx");
+       if (IS_ERR(adc->dma_chan)) {
+               ret = PTR_ERR(adc->dma_chan);
+               if (ret != -ENODEV) {
+                       if (ret != -EPROBE_DEFER)
+                               dev_err(&indio_dev->dev,
+                                       "DMA channel request failed with %d\n",
+                                       ret);
+                       return ret;
+               }
+
+               /* DMA is optional: fall back to IRQ mode */
+               adc->dma_chan = NULL;
                return 0;
+       }
 
        adc->rx_buf = dma_alloc_coherent(adc->dma_chan->device->dev,
                                         STM32_DMA_BUFFER_SIZE,
@@ -1818,8 +1880,9 @@ static int stm32_adc_probe(struct platform_device *pdev)
        if (adc->irq < 0)
                return adc->irq;
 
-       ret = devm_request_irq(&pdev->dev, adc->irq, stm32_adc_isr,
-                              0, pdev->name, adc);
+       ret = devm_request_threaded_irq(&pdev->dev, adc->irq, stm32_adc_isr,
+                                       stm32_adc_threaded_isr,
+                                       0, pdev->name, adc);
        if (ret) {
                dev_err(&pdev->dev, "failed to request IRQ\n");
                return ret;
index e493242..2aad2cd 100644 (file)
@@ -1204,6 +1204,8 @@ static int stm32_dfsdm_single_conv(struct iio_dev *indio_dev,
 
        stm32_dfsdm_stop_conv(adc);
 
+       stm32_dfsdm_process_data(adc, res);
+
 stop_dfsdm:
        stm32_dfsdm_stop_dfsdm(adc->dfsdm);
 
@@ -1219,14 +1221,32 @@ static int stm32_dfsdm_write_raw(struct iio_dev *indio_dev,
        unsigned int spi_freq;
        int ret = -EINVAL;
 
+       switch (ch->src) {
+       case DFSDM_CHANNEL_SPI_CLOCK_INTERNAL:
+               spi_freq = adc->dfsdm->spi_master_freq;
+               break;
+       case DFSDM_CHANNEL_SPI_CLOCK_INTERNAL_DIV2_FALLING:
+       case DFSDM_CHANNEL_SPI_CLOCK_INTERNAL_DIV2_RISING:
+               spi_freq = adc->dfsdm->spi_master_freq / 2;
+               break;
+       default:
+               spi_freq = adc->spi_freq;
+       }
+
        switch (mask) {
        case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
                ret = iio_device_claim_direct_mode(indio_dev);
                if (ret)
                        return ret;
+
                ret = stm32_dfsdm_compute_all_osrs(indio_dev, val);
-               if (!ret)
+               if (!ret) {
+                       dev_dbg(&indio_dev->dev,
+                               "Sampling rate changed from (%u) to (%u)\n",
+                               adc->sample_freq, spi_freq / val);
                        adc->oversamp = val;
+                       adc->sample_freq = spi_freq / val;
+               }
                iio_device_release_direct_mode(indio_dev);
                return ret;
 
@@ -1238,18 +1258,6 @@ static int stm32_dfsdm_write_raw(struct iio_dev *indio_dev,
                if (ret)
                        return ret;
 
-               switch (ch->src) {
-               case DFSDM_CHANNEL_SPI_CLOCK_INTERNAL:
-                       spi_freq = adc->dfsdm->spi_master_freq;
-                       break;
-               case DFSDM_CHANNEL_SPI_CLOCK_INTERNAL_DIV2_FALLING:
-               case DFSDM_CHANNEL_SPI_CLOCK_INTERNAL_DIV2_RISING:
-                       spi_freq = adc->dfsdm->spi_master_freq / 2;
-                       break;
-               default:
-                       spi_freq = adc->spi_freq;
-               }
-
                ret = dfsdm_adc_set_samp_freq(indio_dev, val, spi_freq);
                iio_device_release_direct_mode(indio_dev);
                return ret;
@@ -1383,9 +1391,13 @@ static int stm32_dfsdm_dma_request(struct iio_dev *indio_dev)
 {
        struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
 
-       adc->dma_chan = dma_request_slave_channel(&indio_dev->dev, "rx");
-       if (!adc->dma_chan)
-               return -EINVAL;
+       adc->dma_chan = dma_request_chan(&indio_dev->dev, "rx");
+       if (IS_ERR(adc->dma_chan)) {
+               int ret = PTR_ERR(adc->dma_chan);
+
+               adc->dma_chan = NULL;
+               return ret;
+       }
 
        adc->rx_buf = dma_alloc_coherent(adc->dma_chan->device->dev,
                                         DFSDM_DMA_BUFFER_SIZE,
@@ -1509,7 +1521,16 @@ static int stm32_dfsdm_adc_init(struct iio_dev *indio_dev)
        init_completion(&adc->completion);
 
        /* Optionally request DMA */
-       if (stm32_dfsdm_dma_request(indio_dev)) {
+       ret = stm32_dfsdm_dma_request(indio_dev);
+       if (ret) {
+               if (ret != -ENODEV) {
+                       if (ret != -EPROBE_DEFER)
+                               dev_err(&indio_dev->dev,
+                                       "DMA channel request failed with %d\n",
+                                       ret);
+                       return ret;
+               }
+
                dev_dbg(&indio_dev->dev, "No DMA support\n");
                return 0;
        }
index a550b13..5ea4f45 100644 (file)
  */
 
 #include <linux/module.h>
-#include <linux/of_device.h>
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/i2c.h>
+#include <linux/property.h>
 #include <linux/regmap.h>
 #include <linux/pm_runtime.h>
 #include <linux/mutex.h>
 #include <linux/delay.h>
 
-#include <linux/platform_data/ads1015.h>
-
 #include <linux/iio/iio.h>
 #include <linux/iio/types.h>
 #include <linux/iio/sysfs.h>
@@ -33,6 +31,8 @@
 
 #define ADS1015_DRV_NAME "ads1015"
 
+#define ADS1015_CHANNELS 8
+
 #define ADS1015_CONV_REG       0x00
 #define ADS1015_CFG_REG                0x01
 #define ADS1015_LO_THRESH_REG  0x02
@@ -77,6 +77,7 @@
 #define ADS1015_DEFAULT_CHAN           0
 
 enum chip_ids {
+       ADSXXXX = 0,
        ADS1015,
        ADS1115,
 };
@@ -219,6 +220,12 @@ static const struct iio_event_spec ads1015_events[] = {
        .datasheet_name = "AIN"#_chan"-AIN"#_chan2,             \
 }
 
+struct ads1015_channel_data {
+       bool enabled;
+       unsigned int pga;
+       unsigned int data_rate;
+};
+
 struct ads1015_thresh_data {
        unsigned int comp_queue;
        int high_thresh;
@@ -837,65 +844,58 @@ static const struct iio_info ads1115_info = {
        .attrs          = &ads1115_attribute_group,
 };
 
-#ifdef CONFIG_OF
-static int ads1015_get_channels_config_of(struct i2c_client *client)
+static int ads1015_client_get_channels_config(struct i2c_client *client)
 {
        struct iio_dev *indio_dev = i2c_get_clientdata(client);
        struct ads1015_data *data = iio_priv(indio_dev);
-       struct device_node *node;
+       struct device *dev = &client->dev;
+       struct fwnode_handle *node;
+       int i = -1;
 
-       if (!client->dev.of_node ||
-           !of_get_next_child(client->dev.of_node, NULL))
-               return -EINVAL;
-
-       for_each_child_of_node(client->dev.of_node, node) {
+       device_for_each_child_node(dev, node) {
                u32 pval;
                unsigned int channel;
                unsigned int pga = ADS1015_DEFAULT_PGA;
                unsigned int data_rate = ADS1015_DEFAULT_DATA_RATE;
 
-               if (of_property_read_u32(node, "reg", &pval)) {
-                       dev_err(&client->dev, "invalid reg on %pOF\n",
-                               node);
+               if (fwnode_property_read_u32(node, "reg", &pval)) {
+                       dev_err(dev, "invalid reg on %pfw\n", node);
                        continue;
                }
 
                channel = pval;
                if (channel >= ADS1015_CHANNELS) {
-                       dev_err(&client->dev,
-                               "invalid channel index %d on %pOF\n",
+                       dev_err(dev, "invalid channel index %d on %pfw\n",
                                channel, node);
                        continue;
                }
 
-               if (!of_property_read_u32(node, "ti,gain", &pval)) {
+               if (!fwnode_property_read_u32(node, "ti,gain", &pval)) {
                        pga = pval;
                        if (pga > 6) {
-                               dev_err(&client->dev, "invalid gain on %pOF\n",
-                                       node);
-                               of_node_put(node);
+                               dev_err(dev, "invalid gain on %pfw\n", node);
+                               fwnode_handle_put(node);
                                return -EINVAL;
                        }
                }
 
-               if (!of_property_read_u32(node, "ti,datarate", &pval)) {
+               if (!fwnode_property_read_u32(node, "ti,datarate", &pval)) {
                        data_rate = pval;
                        if (data_rate > 7) {
-                               dev_err(&client->dev,
-                                       "invalid data_rate on %pOF\n",
-                                       node);
-                               of_node_put(node);
+                               dev_err(dev, "invalid data_rate on %pfw\n", node);
+                               fwnode_handle_put(node);
                                return -EINVAL;
                        }
                }
 
                data->channel_data[channel].pga = pga;
                data->channel_data[channel].data_rate = data_rate;
+
+               i++;
        }
 
-       return 0;
+       return i < 0 ? -EINVAL : 0;
 }
-#endif
 
 static void ads1015_get_channels_config(struct i2c_client *client)
 {
@@ -903,19 +903,10 @@ static void ads1015_get_channels_config(struct i2c_client *client)
 
        struct iio_dev *indio_dev = i2c_get_clientdata(client);
        struct ads1015_data *data = iio_priv(indio_dev);
-       struct ads1015_platform_data *pdata = dev_get_platdata(&client->dev);
 
-       /* prefer platform data */
-       if (pdata) {
-               memcpy(data->channel_data, pdata->channel_data,
-                      sizeof(data->channel_data));
+       if (!ads1015_client_get_channels_config(client))
                return;
-       }
 
-#ifdef CONFIG_OF
-       if (!ads1015_get_channels_config_of(client))
-               return;
-#endif
        /* fallback on default configuration */
        for (k = 0; k < ADS1015_CHANNELS; ++k) {
                data->channel_data[k].pga = ADS1015_DEFAULT_PGA;
@@ -953,9 +944,8 @@ static int ads1015_probe(struct i2c_client *client,
        indio_dev->name = ADS1015_DRV_NAME;
        indio_dev->modes = INDIO_DIRECT_MODE;
 
-       if (client->dev.of_node)
-               chip = (enum chip_ids)of_device_get_match_data(&client->dev);
-       else
+       chip = (enum chip_ids)device_get_match_data(&client->dev);
+       if (chip == ADSXXXX)
                chip = id->driver_data;
        switch (chip) {
        case ADS1015:
@@ -970,6 +960,9 @@ static int ads1015_probe(struct i2c_client *client,
                indio_dev->info = &ads1115_info;
                data->data_rate = (unsigned int *) &ads1115_data_rate;
                break;
+       default:
+               dev_err(&client->dev, "Unknown chip %d\n", chip);
+               return -EINVAL;
        }
 
        data->event_channel = ADS1015_CHANNELS;
index 2e66e4d..f9edc12 100644 (file)
@@ -602,7 +602,7 @@ static int ti_ads7950_probe(struct spi_device *spi)
 
        st->reg = devm_regulator_get(&spi->dev, "vref");
        if (IS_ERR(st->reg)) {
-               dev_err(&spi->dev, "Failed get get regulator \"vref\"\n");
+               dev_err(&spi->dev, "Failed to get regulator \"vref\"\n");
                ret = PTR_ERR(st->reg);
                goto error_destroy_mutex;
        }
index 90cf6e5..a74bd9c 100644 (file)
@@ -476,7 +476,7 @@ static struct iio_dma_buffer_block *iio_dma_buffer_dequeue(
  * @n: Number of bytes to read
  * @user_buffer: Userspace buffer to copy the data to
  *
- * Should be used as the read_first_n callback for iio_buffer_access_ops
+ * Should be used as the read callback for iio_buffer_access_ops
  * struct for DMA buffers.
  */
 int iio_dma_buffer_read(struct iio_buffer *buffer, size_t n,
index bea4a75..b129693 100644 (file)
 #include <linux/dma-mapping.h>
 #include <linux/spinlock.h>
 #include <linux/err.h>
+#include <linux/module.h>
 
 #include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
 #include <linux/iio/buffer.h>
 #include <linux/iio/buffer_impl.h>
 #include <linux/iio/buffer-dma.h>
@@ -107,7 +109,7 @@ static void iio_dmaengine_buffer_release(struct iio_buffer *buf)
 }
 
 static const struct iio_buffer_access_funcs iio_dmaengine_buffer_ops = {
-       .read_first_n = iio_dma_buffer_read,
+       .read = iio_dma_buffer_read,
        .set_bytes_per_datum = iio_dma_buffer_set_bytes_per_datum,
        .set_length = iio_dma_buffer_set_length,
        .request_update = iio_dma_buffer_request_update,
@@ -125,6 +127,24 @@ static const struct iio_dma_buffer_ops iio_dmaengine_default_ops = {
        .abort = iio_dmaengine_buffer_abort,
 };
 
+static ssize_t iio_dmaengine_buffer_get_length_align(struct device *dev,
+       struct device_attribute *attr, char *buf)
+{
+       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+       struct dmaengine_buffer *dmaengine_buffer =
+               iio_buffer_to_dmaengine_buffer(indio_dev->buffer);
+
+       return sprintf(buf, "%u\n", dmaengine_buffer->align);
+}
+
+static IIO_DEVICE_ATTR(length_align_bytes, 0444,
+                      iio_dmaengine_buffer_get_length_align, NULL, 0);
+
+static const struct attribute *iio_dmaengine_buffer_attrs[] = {
+       &iio_dev_attr_length_align_bytes.dev_attr.attr,
+       NULL,
+};
+
 /**
  * iio_dmaengine_buffer_alloc() - Allocate new buffer which uses DMAengine
  * @dev: Parent device for the buffer
@@ -150,7 +170,7 @@ struct iio_buffer *iio_dmaengine_buffer_alloc(struct device *dev,
        if (!dmaengine_buffer)
                return ERR_PTR(-ENOMEM);
 
-       chan = dma_request_slave_channel_reason(dev, channel);
+       chan = dma_request_chan(dev, channel);
        if (IS_ERR(chan)) {
                ret = PTR_ERR(chan);
                goto err_free;
@@ -178,6 +198,8 @@ struct iio_buffer *iio_dmaengine_buffer_alloc(struct device *dev,
 
        iio_dma_buffer_init(&dmaengine_buffer->queue, chan->device->dev,
                &iio_dmaengine_default_ops);
+       iio_buffer_set_attrs(&dmaengine_buffer->queue.buffer,
+               iio_dmaengine_buffer_attrs);
 
        dmaengine_buffer->queue.buffer.access = &iio_dmaengine_buffer_ops;
 
@@ -206,3 +228,7 @@ void iio_dmaengine_buffer_free(struct iio_buffer *buffer)
        iio_buffer_put(buffer);
 }
 EXPORT_SYMBOL_GPL(iio_dmaengine_buffer_free);
+
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("DMA buffer for the IIO framework");
+MODULE_LICENSE("GPL");
index e78fc08..3150f8a 100644 (file)
@@ -98,8 +98,7 @@ static int iio_store_to_kfifo(struct iio_buffer *r,
        return 0;
 }
 
-static int iio_read_first_n_kfifo(struct iio_buffer *r,
-                          size_t n, char __user *buf)
+static int iio_read_kfifo(struct iio_buffer *r, size_t n, char __user *buf)
 {
        int ret, copied;
        struct iio_kfifo *kf = iio_to_kfifo(r);
@@ -141,7 +140,7 @@ static void iio_kfifo_buffer_release(struct iio_buffer *buffer)
 
 static const struct iio_buffer_access_funcs kfifo_access_funcs = {
        .store_to = &iio_store_to_kfifo,
-       .read_first_n = &iio_read_first_n_kfifo,
+       .read = &iio_read_kfifo,
        .data_available = iio_kfifo_buf_data_available,
        .request_update = &iio_request_update_kfifo,
        .set_bytes_per_datum = &iio_set_bytes_per_datum_kfifo,
index f97270b..33d3a59 100644 (file)
@@ -4,7 +4,7 @@
 #
 
 # When adding new entries keep the list in alphabetical order
-obj-$(CONFIG_ATLAS_PH_SENSOR)  += atlas-ph-sensor.o
+obj-$(CONFIG_ATLAS_PH_SENSOR)  += atlas-sensor.o
 obj-$(CONFIG_BME680) += bme680_core.o
 obj-$(CONFIG_BME680_I2C) += bme680_i2c.o
 obj-$(CONFIG_BME680_SPI) += bme680_spi.o
diff --git a/drivers/iio/chemical/atlas-ph-sensor.c b/drivers/iio/chemical/atlas-ph-sensor.c
deleted file mode 100644 (file)
index 6c175eb..0000000
+++ /dev/null
@@ -1,685 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * atlas-ph-sensor.c - Support for Atlas Scientific OEM pH-SM sensor
- *
- * Copyright (C) 2015-2018 Matt Ranostay
- * Author: Matt Ranostay <matt.ranostay@konsulko.com>
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/mutex.h>
-#include <linux/err.h>
-#include <linux/irq.h>
-#include <linux/irq_work.h>
-#include <linux/gpio.h>
-#include <linux/i2c.h>
-#include <linux/of_device.h>
-#include <linux/regmap.h>
-#include <linux/iio/iio.h>
-#include <linux/iio/buffer.h>
-#include <linux/iio/trigger.h>
-#include <linux/iio/trigger_consumer.h>
-#include <linux/iio/triggered_buffer.h>
-#include <linux/pm_runtime.h>
-
-#define ATLAS_REGMAP_NAME      "atlas_ph_regmap"
-#define ATLAS_DRV_NAME         "atlas_ph"
-
-#define ATLAS_REG_DEV_TYPE             0x00
-#define ATLAS_REG_DEV_VERSION          0x01
-
-#define ATLAS_REG_INT_CONTROL          0x04
-#define ATLAS_REG_INT_CONTROL_EN       BIT(3)
-
-#define ATLAS_REG_PWR_CONTROL          0x06
-
-#define ATLAS_REG_PH_CALIB_STATUS      0x0d
-#define ATLAS_REG_PH_CALIB_STATUS_MASK 0x07
-#define ATLAS_REG_PH_CALIB_STATUS_LOW  BIT(0)
-#define ATLAS_REG_PH_CALIB_STATUS_MID  BIT(1)
-#define ATLAS_REG_PH_CALIB_STATUS_HIGH BIT(2)
-
-#define ATLAS_REG_EC_CALIB_STATUS              0x0f
-#define ATLAS_REG_EC_CALIB_STATUS_MASK         0x0f
-#define ATLAS_REG_EC_CALIB_STATUS_DRY          BIT(0)
-#define ATLAS_REG_EC_CALIB_STATUS_SINGLE       BIT(1)
-#define ATLAS_REG_EC_CALIB_STATUS_LOW          BIT(2)
-#define ATLAS_REG_EC_CALIB_STATUS_HIGH         BIT(3)
-
-#define ATLAS_REG_PH_TEMP_DATA         0x0e
-#define ATLAS_REG_PH_DATA              0x16
-
-#define ATLAS_REG_EC_PROBE             0x08
-#define ATLAS_REG_EC_TEMP_DATA         0x10
-#define ATLAS_REG_EC_DATA              0x18
-#define ATLAS_REG_TDS_DATA             0x1c
-#define ATLAS_REG_PSS_DATA             0x20
-
-#define ATLAS_REG_ORP_CALIB_STATUS     0x0d
-#define ATLAS_REG_ORP_DATA             0x0e
-
-#define ATLAS_PH_INT_TIME_IN_MS                450
-#define ATLAS_EC_INT_TIME_IN_MS                650
-#define ATLAS_ORP_INT_TIME_IN_MS       450
-
-enum {
-       ATLAS_PH_SM,
-       ATLAS_EC_SM,
-       ATLAS_ORP_SM,
-};
-
-struct atlas_data {
-       struct i2c_client *client;
-       struct iio_trigger *trig;
-       struct atlas_device *chip;
-       struct regmap *regmap;
-       struct irq_work work;
-
-       __be32 buffer[6]; /* 96-bit data + 32-bit pad + 64-bit timestamp */
-};
-
-static const struct regmap_config atlas_regmap_config = {
-       .name = ATLAS_REGMAP_NAME,
-       .reg_bits = 8,
-       .val_bits = 8,
-};
-
-static const struct iio_chan_spec atlas_ph_channels[] = {
-       {
-               .type = IIO_PH,
-               .address = ATLAS_REG_PH_DATA,
-               .info_mask_separate =
-                       BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
-               .scan_index = 0,
-               .scan_type = {
-                       .sign = 'u',
-                       .realbits = 32,
-                       .storagebits = 32,
-                       .endianness = IIO_BE,
-               },
-       },
-       IIO_CHAN_SOFT_TIMESTAMP(1),
-       {
-               .type = IIO_TEMP,
-               .address = ATLAS_REG_PH_TEMP_DATA,
-               .info_mask_separate =
-                       BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
-               .output = 1,
-               .scan_index = -1
-       },
-};
-
-#define ATLAS_EC_CHANNEL(_idx, _addr) \
-       {\
-               .type = IIO_CONCENTRATION, \
-               .indexed = 1, \
-               .channel = _idx, \
-               .address = _addr, \
-               .info_mask_separate = \
-                       BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), \
-               .scan_index = _idx + 1, \
-               .scan_type = { \
-                       .sign = 'u', \
-                       .realbits = 32, \
-                       .storagebits = 32, \
-                       .endianness = IIO_BE, \
-               }, \
-       }
-
-static const struct iio_chan_spec atlas_ec_channels[] = {
-       {
-               .type = IIO_ELECTRICALCONDUCTIVITY,
-               .address = ATLAS_REG_EC_DATA,
-               .info_mask_separate =
-                       BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
-               .scan_index = 0,
-               .scan_type = {
-                       .sign = 'u',
-                       .realbits = 32,
-                       .storagebits = 32,
-                       .endianness = IIO_BE,
-               },
-       },
-       ATLAS_EC_CHANNEL(0, ATLAS_REG_TDS_DATA),
-       ATLAS_EC_CHANNEL(1, ATLAS_REG_PSS_DATA),
-       IIO_CHAN_SOFT_TIMESTAMP(3),
-       {
-               .type = IIO_TEMP,
-               .address = ATLAS_REG_EC_TEMP_DATA,
-               .info_mask_separate =
-                       BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
-               .output = 1,
-               .scan_index = -1
-       },
-};
-
-static const struct iio_chan_spec atlas_orp_channels[] = {
-       {
-               .type = IIO_VOLTAGE,
-               .address = ATLAS_REG_ORP_DATA,
-               .info_mask_separate =
-                       BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
-               .scan_index = 0,
-               .scan_type = {
-                       .sign = 's',
-                       .realbits = 32,
-                       .storagebits = 32,
-                       .endianness = IIO_BE,
-               },
-       },
-       IIO_CHAN_SOFT_TIMESTAMP(1),
-};
-
-static int atlas_check_ph_calibration(struct atlas_data *data)
-{
-       struct device *dev = &data->client->dev;
-       int ret;
-       unsigned int val;
-
-       ret = regmap_read(data->regmap, ATLAS_REG_PH_CALIB_STATUS, &val);
-       if (ret)
-               return ret;
-
-       if (!(val & ATLAS_REG_PH_CALIB_STATUS_MASK)) {
-               dev_warn(dev, "device has not been calibrated\n");
-               return 0;
-       }
-
-       if (!(val & ATLAS_REG_PH_CALIB_STATUS_LOW))
-               dev_warn(dev, "device missing low point calibration\n");
-
-       if (!(val & ATLAS_REG_PH_CALIB_STATUS_MID))
-               dev_warn(dev, "device missing mid point calibration\n");
-
-       if (!(val & ATLAS_REG_PH_CALIB_STATUS_HIGH))
-               dev_warn(dev, "device missing high point calibration\n");
-
-       return 0;
-}
-
-static int atlas_check_ec_calibration(struct atlas_data *data)
-{
-       struct device *dev = &data->client->dev;
-       int ret;
-       unsigned int val;
-       __be16  rval;
-
-       ret = regmap_bulk_read(data->regmap, ATLAS_REG_EC_PROBE, &rval, 2);
-       if (ret)
-               return ret;
-
-       val = be16_to_cpu(rval);
-       dev_info(dev, "probe set to K = %d.%.2d", val / 100, val % 100);
-
-       ret = regmap_read(data->regmap, ATLAS_REG_EC_CALIB_STATUS, &val);
-       if (ret)
-               return ret;
-
-       if (!(val & ATLAS_REG_EC_CALIB_STATUS_MASK)) {
-               dev_warn(dev, "device has not been calibrated\n");
-               return 0;
-       }
-
-       if (!(val & ATLAS_REG_EC_CALIB_STATUS_DRY))
-               dev_warn(dev, "device missing dry point calibration\n");
-
-       if (val & ATLAS_REG_EC_CALIB_STATUS_SINGLE) {
-               dev_warn(dev, "device using single point calibration\n");
-       } else {
-               if (!(val & ATLAS_REG_EC_CALIB_STATUS_LOW))
-                       dev_warn(dev, "device missing low point calibration\n");
-
-               if (!(val & ATLAS_REG_EC_CALIB_STATUS_HIGH))
-                       dev_warn(dev, "device missing high point calibration\n");
-       }
-
-       return 0;
-}
-
-static int atlas_check_orp_calibration(struct atlas_data *data)
-{
-       struct device *dev = &data->client->dev;
-       int ret;
-       unsigned int val;
-
-       ret = regmap_read(data->regmap, ATLAS_REG_ORP_CALIB_STATUS, &val);
-       if (ret)
-               return ret;
-
-       if (!val)
-               dev_warn(dev, "device has not been calibrated\n");
-
-       return 0;
-};
-
-struct atlas_device {
-       const struct iio_chan_spec *channels;
-       int num_channels;
-       int data_reg;
-
-       int (*calibration)(struct atlas_data *data);
-       int delay;
-};
-
-static struct atlas_device atlas_devices[] = {
-       [ATLAS_PH_SM] = {
-                               .channels = atlas_ph_channels,
-                               .num_channels = 3,
-                               .data_reg = ATLAS_REG_PH_DATA,
-                               .calibration = &atlas_check_ph_calibration,
-                               .delay = ATLAS_PH_INT_TIME_IN_MS,
-       },
-       [ATLAS_EC_SM] = {
-                               .channels = atlas_ec_channels,
-                               .num_channels = 5,
-                               .data_reg = ATLAS_REG_EC_DATA,
-                               .calibration = &atlas_check_ec_calibration,
-                               .delay = ATLAS_EC_INT_TIME_IN_MS,
-       },
-       [ATLAS_ORP_SM] = {
-                               .channels = atlas_orp_channels,
-                               .num_channels = 2,
-                               .data_reg = ATLAS_REG_ORP_DATA,
-                               .calibration = &atlas_check_orp_calibration,
-                               .delay = ATLAS_ORP_INT_TIME_IN_MS,
-       },
-};
-
-static int atlas_set_powermode(struct atlas_data *data, int on)
-{
-       return regmap_write(data->regmap, ATLAS_REG_PWR_CONTROL, on);
-}
-
-static int atlas_set_interrupt(struct atlas_data *data, bool state)
-{
-       return regmap_update_bits(data->regmap, ATLAS_REG_INT_CONTROL,
-                                 ATLAS_REG_INT_CONTROL_EN,
-                                 state ? ATLAS_REG_INT_CONTROL_EN : 0);
-}
-
-static int atlas_buffer_postenable(struct iio_dev *indio_dev)
-{
-       struct atlas_data *data = iio_priv(indio_dev);
-       int ret;
-
-       ret = iio_triggered_buffer_postenable(indio_dev);
-       if (ret)
-               return ret;
-
-       ret = pm_runtime_get_sync(&data->client->dev);
-       if (ret < 0) {
-               pm_runtime_put_noidle(&data->client->dev);
-               return ret;
-       }
-
-       return atlas_set_interrupt(data, true);
-}
-
-static int atlas_buffer_predisable(struct iio_dev *indio_dev)
-{
-       struct atlas_data *data = iio_priv(indio_dev);
-       int ret;
-
-       ret = atlas_set_interrupt(data, false);
-       if (ret)
-               return ret;
-
-       pm_runtime_mark_last_busy(&data->client->dev);
-       ret = pm_runtime_put_autosuspend(&data->client->dev);
-       if (ret)
-               return ret;
-
-       return iio_triggered_buffer_predisable(indio_dev);
-}
-
-static const struct iio_trigger_ops atlas_interrupt_trigger_ops = {
-};
-
-static const struct iio_buffer_setup_ops atlas_buffer_setup_ops = {
-       .postenable = atlas_buffer_postenable,
-       .predisable = atlas_buffer_predisable,
-};
-
-static void atlas_work_handler(struct irq_work *work)
-{
-       struct atlas_data *data = container_of(work, struct atlas_data, work);
-
-       iio_trigger_poll(data->trig);
-}
-
-static irqreturn_t atlas_trigger_handler(int irq, void *private)
-{
-       struct iio_poll_func *pf = private;
-       struct iio_dev *indio_dev = pf->indio_dev;
-       struct atlas_data *data = iio_priv(indio_dev);
-       int ret;
-
-       ret = regmap_bulk_read(data->regmap, data->chip->data_reg,
-                             (u8 *) &data->buffer,
-                             sizeof(__be32) * (data->chip->num_channels - 2));
-
-       if (!ret)
-               iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
-                               iio_get_time_ns(indio_dev));
-
-       iio_trigger_notify_done(indio_dev->trig);
-
-       return IRQ_HANDLED;
-}
-
-static irqreturn_t atlas_interrupt_handler(int irq, void *private)
-{
-       struct iio_dev *indio_dev = private;
-       struct atlas_data *data = iio_priv(indio_dev);
-
-       irq_work_queue(&data->work);
-
-       return IRQ_HANDLED;
-}
-
-static int atlas_read_measurement(struct atlas_data *data, int reg, __be32 *val)
-{
-       struct device *dev = &data->client->dev;
-       int suspended = pm_runtime_suspended(dev);
-       int ret;
-
-       ret = pm_runtime_get_sync(dev);
-       if (ret < 0) {
-               pm_runtime_put_noidle(dev);
-               return ret;
-       }
-
-       if (suspended)
-               msleep(data->chip->delay);
-
-       ret = regmap_bulk_read(data->regmap, reg, (u8 *) val, sizeof(*val));
-
-       pm_runtime_mark_last_busy(dev);
-       pm_runtime_put_autosuspend(dev);
-
-       return ret;
-}
-
-static int atlas_read_raw(struct iio_dev *indio_dev,
-                         struct iio_chan_spec const *chan,
-                         int *val, int *val2, long mask)
-{
-       struct atlas_data *data = iio_priv(indio_dev);
-
-       switch (mask) {
-       case IIO_CHAN_INFO_RAW: {
-               int ret;
-               __be32 reg;
-
-               switch (chan->type) {
-               case IIO_TEMP:
-                       ret = regmap_bulk_read(data->regmap, chan->address,
-                                             (u8 *) &reg, sizeof(reg));
-                       break;
-               case IIO_PH:
-               case IIO_CONCENTRATION:
-               case IIO_ELECTRICALCONDUCTIVITY:
-               case IIO_VOLTAGE:
-                       ret = iio_device_claim_direct_mode(indio_dev);
-                       if (ret)
-                               return ret;
-
-                       ret = atlas_read_measurement(data, chan->address, &reg);
-
-                       iio_device_release_direct_mode(indio_dev);
-                       break;
-               default:
-                       ret = -EINVAL;
-               }
-
-               if (!ret) {
-                       *val = be32_to_cpu(reg);
-                       ret = IIO_VAL_INT;
-               }
-               return ret;
-       }
-       case IIO_CHAN_INFO_SCALE:
-               switch (chan->type) {
-               case IIO_TEMP:
-                       *val = 10;
-                       return IIO_VAL_INT;
-               case IIO_PH:
-                       *val = 1; /* 0.001 */
-                       *val2 = 1000;
-                       break;
-               case IIO_ELECTRICALCONDUCTIVITY:
-                       *val = 1; /* 0.00001 */
-                       *val2 = 100000;
-                       break;
-               case IIO_CONCENTRATION:
-                       *val = 0; /* 0.000000001 */
-                       *val2 = 1000;
-                       return IIO_VAL_INT_PLUS_NANO;
-               case IIO_VOLTAGE:
-                       *val = 1; /* 0.1 */
-                       *val2 = 10;
-                       break;
-               default:
-                       return -EINVAL;
-               }
-               return IIO_VAL_FRACTIONAL;
-       }
-
-       return -EINVAL;
-}
-
-static int atlas_write_raw(struct iio_dev *indio_dev,
-                          struct iio_chan_spec const *chan,
-                          int val, int val2, long mask)
-{
-       struct atlas_data *data = iio_priv(indio_dev);
-       __be32 reg = cpu_to_be32(val / 10);
-
-       if (val2 != 0 || val < 0 || val > 20000)
-               return -EINVAL;
-
-       if (mask != IIO_CHAN_INFO_RAW || chan->type != IIO_TEMP)
-               return -EINVAL;
-
-       return regmap_bulk_write(data->regmap, chan->address,
-                                &reg, sizeof(reg));
-}
-
-static const struct iio_info atlas_info = {
-       .read_raw = atlas_read_raw,
-       .write_raw = atlas_write_raw,
-};
-
-static const struct i2c_device_id atlas_id[] = {
-       { "atlas-ph-sm", ATLAS_PH_SM},
-       { "atlas-ec-sm", ATLAS_EC_SM},
-       { "atlas-orp-sm", ATLAS_ORP_SM},
-       {}
-};
-MODULE_DEVICE_TABLE(i2c, atlas_id);
-
-static const struct of_device_id atlas_dt_ids[] = {
-       { .compatible = "atlas,ph-sm", .data = (void *)ATLAS_PH_SM, },
-       { .compatible = "atlas,ec-sm", .data = (void *)ATLAS_EC_SM, },
-       { .compatible = "atlas,orp-sm", .data = (void *)ATLAS_ORP_SM, },
-       { }
-};
-MODULE_DEVICE_TABLE(of, atlas_dt_ids);
-
-static int atlas_probe(struct i2c_client *client,
-                      const struct i2c_device_id *id)
-{
-       struct atlas_data *data;
-       struct atlas_device *chip;
-       const struct of_device_id *of_id;
-       struct iio_trigger *trig;
-       struct iio_dev *indio_dev;
-       int ret;
-
-       indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
-       if (!indio_dev)
-               return -ENOMEM;
-
-       of_id = of_match_device(atlas_dt_ids, &client->dev);
-       if (!of_id)
-               chip = &atlas_devices[id->driver_data];
-       else
-               chip = &atlas_devices[(unsigned long)of_id->data];
-
-       indio_dev->info = &atlas_info;
-       indio_dev->name = ATLAS_DRV_NAME;
-       indio_dev->channels = chip->channels;
-       indio_dev->num_channels = chip->num_channels;
-       indio_dev->modes = INDIO_BUFFER_SOFTWARE | INDIO_DIRECT_MODE;
-       indio_dev->dev.parent = &client->dev;
-
-       trig = devm_iio_trigger_alloc(&client->dev, "%s-dev%d",
-                                     indio_dev->name, indio_dev->id);
-
-       if (!trig)
-               return -ENOMEM;
-
-       data = iio_priv(indio_dev);
-       data->client = client;
-       data->trig = trig;
-       data->chip = chip;
-       trig->dev.parent = indio_dev->dev.parent;
-       trig->ops = &atlas_interrupt_trigger_ops;
-       iio_trigger_set_drvdata(trig, indio_dev);
-
-       i2c_set_clientdata(client, indio_dev);
-
-       data->regmap = devm_regmap_init_i2c(client, &atlas_regmap_config);
-       if (IS_ERR(data->regmap)) {
-               dev_err(&client->dev, "regmap initialization failed\n");
-               return PTR_ERR(data->regmap);
-       }
-
-       ret = pm_runtime_set_active(&client->dev);
-       if (ret)
-               return ret;
-
-       if (client->irq <= 0) {
-               dev_err(&client->dev, "no valid irq defined\n");
-               return -EINVAL;
-       }
-
-       ret = chip->calibration(data);
-       if (ret)
-               return ret;
-
-       ret = iio_trigger_register(trig);
-       if (ret) {
-               dev_err(&client->dev, "failed to register trigger\n");
-               return ret;
-       }
-
-       ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
-               &atlas_trigger_handler, &atlas_buffer_setup_ops);
-       if (ret) {
-               dev_err(&client->dev, "cannot setup iio trigger\n");
-               goto unregister_trigger;
-       }
-
-       init_irq_work(&data->work, atlas_work_handler);
-
-       /* interrupt pin toggles on new conversion */
-       ret = devm_request_threaded_irq(&client->dev, client->irq,
-                                       NULL, atlas_interrupt_handler,
-                                       IRQF_TRIGGER_RISING |
-                                       IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
-                                       "atlas_irq",
-                                       indio_dev);
-       if (ret) {
-               dev_err(&client->dev, "request irq (%d) failed\n", client->irq);
-               goto unregister_buffer;
-       }
-
-       ret = atlas_set_powermode(data, 1);
-       if (ret) {
-               dev_err(&client->dev, "cannot power device on");
-               goto unregister_buffer;
-       }
-
-       pm_runtime_enable(&client->dev);
-       pm_runtime_set_autosuspend_delay(&client->dev, 2500);
-       pm_runtime_use_autosuspend(&client->dev);
-
-       ret = iio_device_register(indio_dev);
-       if (ret) {
-               dev_err(&client->dev, "unable to register device\n");
-               goto unregister_pm;
-       }
-
-       return 0;
-
-unregister_pm:
-       pm_runtime_disable(&client->dev);
-       atlas_set_powermode(data, 0);
-
-unregister_buffer:
-       iio_triggered_buffer_cleanup(indio_dev);
-
-unregister_trigger:
-       iio_trigger_unregister(data->trig);
-
-       return ret;
-}
-
-static int atlas_remove(struct i2c_client *client)
-{
-       struct iio_dev *indio_dev = i2c_get_clientdata(client);
-       struct atlas_data *data = iio_priv(indio_dev);
-
-       iio_device_unregister(indio_dev);
-       iio_triggered_buffer_cleanup(indio_dev);
-       iio_trigger_unregister(data->trig);
-
-       pm_runtime_disable(&client->dev);
-       pm_runtime_set_suspended(&client->dev);
-       pm_runtime_put_noidle(&client->dev);
-
-       return atlas_set_powermode(data, 0);
-}
-
-#ifdef CONFIG_PM
-static int atlas_runtime_suspend(struct device *dev)
-{
-       struct atlas_data *data =
-                    iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
-
-       return atlas_set_powermode(data, 0);
-}
-
-static int atlas_runtime_resume(struct device *dev)
-{
-       struct atlas_data *data =
-                    iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
-
-       return atlas_set_powermode(data, 1);
-}
-#endif
-
-static const struct dev_pm_ops atlas_pm_ops = {
-       SET_RUNTIME_PM_OPS(atlas_runtime_suspend,
-                          atlas_runtime_resume, NULL)
-};
-
-static struct i2c_driver atlas_driver = {
-       .driver = {
-               .name   = ATLAS_DRV_NAME,
-               .of_match_table = of_match_ptr(atlas_dt_ids),
-               .pm     = &atlas_pm_ops,
-       },
-       .probe          = atlas_probe,
-       .remove         = atlas_remove,
-       .id_table       = atlas_id,
-};
-module_i2c_driver(atlas_driver);
-
-MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>");
-MODULE_DESCRIPTION("Atlas Scientific pH-SM sensor");
-MODULE_LICENSE("GPL");
diff --git a/drivers/iio/chemical/atlas-sensor.c b/drivers/iio/chemical/atlas-sensor.c
new file mode 100644 (file)
index 0000000..2f0a6fe
--- /dev/null
@@ -0,0 +1,695 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * atlas-sensor.c - Support for Atlas Scientific OEM SM sensors
+ *
+ * Copyright (C) 2015-2019 Konsulko Group
+ * Author: Matt Ranostay <matt.ranostay@konsulko.com>
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/err.h>
+#include <linux/irq.h>
+#include <linux/irq_work.h>
+#include <linux/i2c.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/pm_runtime.h>
+
+#define ATLAS_REGMAP_NAME      "atlas_regmap"
+#define ATLAS_DRV_NAME         "atlas"
+
+#define ATLAS_REG_DEV_TYPE             0x00
+#define ATLAS_REG_DEV_VERSION          0x01
+
+#define ATLAS_REG_INT_CONTROL          0x04
+#define ATLAS_REG_INT_CONTROL_EN       BIT(3)
+
+#define ATLAS_REG_PWR_CONTROL          0x06
+
+#define ATLAS_REG_PH_CALIB_STATUS      0x0d
+#define ATLAS_REG_PH_CALIB_STATUS_MASK 0x07
+#define ATLAS_REG_PH_CALIB_STATUS_LOW  BIT(0)
+#define ATLAS_REG_PH_CALIB_STATUS_MID  BIT(1)
+#define ATLAS_REG_PH_CALIB_STATUS_HIGH BIT(2)
+
+#define ATLAS_REG_EC_CALIB_STATUS              0x0f
+#define ATLAS_REG_EC_CALIB_STATUS_MASK         0x0f
+#define ATLAS_REG_EC_CALIB_STATUS_DRY          BIT(0)
+#define ATLAS_REG_EC_CALIB_STATUS_SINGLE       BIT(1)
+#define ATLAS_REG_EC_CALIB_STATUS_LOW          BIT(2)
+#define ATLAS_REG_EC_CALIB_STATUS_HIGH         BIT(3)
+
+#define ATLAS_REG_PH_TEMP_DATA         0x0e
+#define ATLAS_REG_PH_DATA              0x16
+
+#define ATLAS_REG_EC_PROBE             0x08
+#define ATLAS_REG_EC_TEMP_DATA         0x10
+#define ATLAS_REG_EC_DATA              0x18
+#define ATLAS_REG_TDS_DATA             0x1c
+#define ATLAS_REG_PSS_DATA             0x20
+
+#define ATLAS_REG_ORP_CALIB_STATUS     0x0d
+#define ATLAS_REG_ORP_DATA             0x0e
+
+#define ATLAS_PH_INT_TIME_IN_MS                450
+#define ATLAS_EC_INT_TIME_IN_MS                650
+#define ATLAS_ORP_INT_TIME_IN_MS       450
+
+enum {
+       ATLAS_PH_SM,
+       ATLAS_EC_SM,
+       ATLAS_ORP_SM,
+};
+
+struct atlas_data {
+       struct i2c_client *client;
+       struct iio_trigger *trig;
+       struct atlas_device *chip;
+       struct regmap *regmap;
+       struct irq_work work;
+
+       __be32 buffer[6]; /* 96-bit data + 32-bit pad + 64-bit timestamp */
+};
+
+static const struct regmap_config atlas_regmap_config = {
+       .name = ATLAS_REGMAP_NAME,
+       .reg_bits = 8,
+       .val_bits = 8,
+};
+
+static int atlas_buffer_num_channels(const struct iio_chan_spec *spec)
+{
+       int idx = 0;
+
+       for (; spec->type != IIO_TIMESTAMP; spec++)
+               idx++;
+
+       return idx;
+};
+
+static const struct iio_chan_spec atlas_ph_channels[] = {
+       {
+               .type = IIO_PH,
+               .address = ATLAS_REG_PH_DATA,
+               .info_mask_separate =
+                       BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+               .scan_index = 0,
+               .scan_type = {
+                       .sign = 'u',
+                       .realbits = 32,
+                       .storagebits = 32,
+                       .endianness = IIO_BE,
+               },
+       },
+       IIO_CHAN_SOFT_TIMESTAMP(1),
+       {
+               .type = IIO_TEMP,
+               .address = ATLAS_REG_PH_TEMP_DATA,
+               .info_mask_separate =
+                       BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+               .output = 1,
+               .scan_index = -1
+       },
+};
+
+#define ATLAS_EC_CHANNEL(_idx, _addr) \
+       {\
+               .type = IIO_CONCENTRATION, \
+               .indexed = 1, \
+               .channel = _idx, \
+               .address = _addr, \
+               .info_mask_separate = \
+                       BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), \
+               .scan_index = _idx + 1, \
+               .scan_type = { \
+                       .sign = 'u', \
+                       .realbits = 32, \
+                       .storagebits = 32, \
+                       .endianness = IIO_BE, \
+               }, \
+       }
+
+static const struct iio_chan_spec atlas_ec_channels[] = {
+       {
+               .type = IIO_ELECTRICALCONDUCTIVITY,
+               .address = ATLAS_REG_EC_DATA,
+               .info_mask_separate =
+                       BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+               .scan_index = 0,
+               .scan_type = {
+                       .sign = 'u',
+                       .realbits = 32,
+                       .storagebits = 32,
+                       .endianness = IIO_BE,
+               },
+       },
+       ATLAS_EC_CHANNEL(0, ATLAS_REG_TDS_DATA),
+       ATLAS_EC_CHANNEL(1, ATLAS_REG_PSS_DATA),
+       IIO_CHAN_SOFT_TIMESTAMP(3),
+       {
+               .type = IIO_TEMP,
+               .address = ATLAS_REG_EC_TEMP_DATA,
+               .info_mask_separate =
+                       BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+               .output = 1,
+               .scan_index = -1
+       },
+};
+
+static const struct iio_chan_spec atlas_orp_channels[] = {
+       {
+               .type = IIO_VOLTAGE,
+               .address = ATLAS_REG_ORP_DATA,
+               .info_mask_separate =
+                       BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+               .scan_index = 0,
+               .scan_type = {
+                       .sign = 's',
+                       .realbits = 32,
+                       .storagebits = 32,
+                       .endianness = IIO_BE,
+               },
+       },
+       IIO_CHAN_SOFT_TIMESTAMP(1),
+};
+
+static int atlas_check_ph_calibration(struct atlas_data *data)
+{
+       struct device *dev = &data->client->dev;
+       int ret;
+       unsigned int val;
+
+       ret = regmap_read(data->regmap, ATLAS_REG_PH_CALIB_STATUS, &val);
+       if (ret)
+               return ret;
+
+       if (!(val & ATLAS_REG_PH_CALIB_STATUS_MASK)) {
+               dev_warn(dev, "device has not been calibrated\n");
+               return 0;
+       }
+
+       if (!(val & ATLAS_REG_PH_CALIB_STATUS_LOW))
+               dev_warn(dev, "device missing low point calibration\n");
+
+       if (!(val & ATLAS_REG_PH_CALIB_STATUS_MID))
+               dev_warn(dev, "device missing mid point calibration\n");
+
+       if (!(val & ATLAS_REG_PH_CALIB_STATUS_HIGH))
+               dev_warn(dev, "device missing high point calibration\n");
+
+       return 0;
+}
+
+static int atlas_check_ec_calibration(struct atlas_data *data)
+{
+       struct device *dev = &data->client->dev;
+       int ret;
+       unsigned int val;
+       __be16  rval;
+
+       ret = regmap_bulk_read(data->regmap, ATLAS_REG_EC_PROBE, &rval, 2);
+       if (ret)
+               return ret;
+
+       val = be16_to_cpu(rval);
+       dev_info(dev, "probe set to K = %d.%.2d", val / 100, val % 100);
+
+       ret = regmap_read(data->regmap, ATLAS_REG_EC_CALIB_STATUS, &val);
+       if (ret)
+               return ret;
+
+       if (!(val & ATLAS_REG_EC_CALIB_STATUS_MASK)) {
+               dev_warn(dev, "device has not been calibrated\n");
+               return 0;
+       }
+
+       if (!(val & ATLAS_REG_EC_CALIB_STATUS_DRY))
+               dev_warn(dev, "device missing dry point calibration\n");
+
+       if (val & ATLAS_REG_EC_CALIB_STATUS_SINGLE) {
+               dev_warn(dev, "device using single point calibration\n");
+       } else {
+               if (!(val & ATLAS_REG_EC_CALIB_STATUS_LOW))
+                       dev_warn(dev, "device missing low point calibration\n");
+
+               if (!(val & ATLAS_REG_EC_CALIB_STATUS_HIGH))
+                       dev_warn(dev, "device missing high point calibration\n");
+       }
+
+       return 0;
+}
+
+static int atlas_check_orp_calibration(struct atlas_data *data)
+{
+       struct device *dev = &data->client->dev;
+       int ret;
+       unsigned int val;
+
+       ret = regmap_read(data->regmap, ATLAS_REG_ORP_CALIB_STATUS, &val);
+       if (ret)
+               return ret;
+
+       if (!val)
+               dev_warn(dev, "device has not been calibrated\n");
+
+       return 0;
+};
+
+struct atlas_device {
+       const struct iio_chan_spec *channels;
+       int num_channels;
+       int data_reg;
+
+       int (*calibration)(struct atlas_data *data);
+       int delay;
+};
+
+static struct atlas_device atlas_devices[] = {
+       [ATLAS_PH_SM] = {
+                               .channels = atlas_ph_channels,
+                               .num_channels = 3,
+                               .data_reg = ATLAS_REG_PH_DATA,
+                               .calibration = &atlas_check_ph_calibration,
+                               .delay = ATLAS_PH_INT_TIME_IN_MS,
+       },
+       [ATLAS_EC_SM] = {
+                               .channels = atlas_ec_channels,
+                               .num_channels = 5,
+                               .data_reg = ATLAS_REG_EC_DATA,
+                               .calibration = &atlas_check_ec_calibration,
+                               .delay = ATLAS_EC_INT_TIME_IN_MS,
+       },
+       [ATLAS_ORP_SM] = {
+                               .channels = atlas_orp_channels,
+                               .num_channels = 2,
+                               .data_reg = ATLAS_REG_ORP_DATA,
+                               .calibration = &atlas_check_orp_calibration,
+                               .delay = ATLAS_ORP_INT_TIME_IN_MS,
+       },
+};
+
+static int atlas_set_powermode(struct atlas_data *data, int on)
+{
+       return regmap_write(data->regmap, ATLAS_REG_PWR_CONTROL, on);
+}
+
+static int atlas_set_interrupt(struct atlas_data *data, bool state)
+{
+       return regmap_update_bits(data->regmap, ATLAS_REG_INT_CONTROL,
+                                 ATLAS_REG_INT_CONTROL_EN,
+                                 state ? ATLAS_REG_INT_CONTROL_EN : 0);
+}
+
+static int atlas_buffer_postenable(struct iio_dev *indio_dev)
+{
+       struct atlas_data *data = iio_priv(indio_dev);
+       int ret;
+
+       ret = iio_triggered_buffer_postenable(indio_dev);
+       if (ret)
+               return ret;
+
+       ret = pm_runtime_get_sync(&data->client->dev);
+       if (ret < 0) {
+               pm_runtime_put_noidle(&data->client->dev);
+               return ret;
+       }
+
+       return atlas_set_interrupt(data, true);
+}
+
+static int atlas_buffer_predisable(struct iio_dev *indio_dev)
+{
+       struct atlas_data *data = iio_priv(indio_dev);
+       int ret;
+
+       ret = atlas_set_interrupt(data, false);
+       if (ret)
+               return ret;
+
+       pm_runtime_mark_last_busy(&data->client->dev);
+       ret = pm_runtime_put_autosuspend(&data->client->dev);
+       if (ret)
+               return ret;
+
+       return iio_triggered_buffer_predisable(indio_dev);
+}
+
+static const struct iio_trigger_ops atlas_interrupt_trigger_ops = {
+};
+
+static const struct iio_buffer_setup_ops atlas_buffer_setup_ops = {
+       .postenable = atlas_buffer_postenable,
+       .predisable = atlas_buffer_predisable,
+};
+
+static void atlas_work_handler(struct irq_work *work)
+{
+       struct atlas_data *data = container_of(work, struct atlas_data, work);
+
+       iio_trigger_poll(data->trig);
+}
+
+static irqreturn_t atlas_trigger_handler(int irq, void *private)
+{
+       struct iio_poll_func *pf = private;
+       struct iio_dev *indio_dev = pf->indio_dev;
+       struct atlas_data *data = iio_priv(indio_dev);
+       int channels = atlas_buffer_num_channels(data->chip->channels);
+       int ret;
+
+       ret = regmap_bulk_read(data->regmap, data->chip->data_reg,
+                             (u8 *) &data->buffer,
+                             sizeof(__be32) * channels);
+
+       if (!ret)
+               iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
+                               iio_get_time_ns(indio_dev));
+
+       iio_trigger_notify_done(indio_dev->trig);
+
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t atlas_interrupt_handler(int irq, void *private)
+{
+       struct iio_dev *indio_dev = private;
+       struct atlas_data *data = iio_priv(indio_dev);
+
+       irq_work_queue(&data->work);
+
+       return IRQ_HANDLED;
+}
+
+static int atlas_read_measurement(struct atlas_data *data, int reg, __be32 *val)
+{
+       struct device *dev = &data->client->dev;
+       int suspended = pm_runtime_suspended(dev);
+       int ret;
+
+       ret = pm_runtime_get_sync(dev);
+       if (ret < 0) {
+               pm_runtime_put_noidle(dev);
+               return ret;
+       }
+
+       if (suspended)
+               msleep(data->chip->delay);
+
+       ret = regmap_bulk_read(data->regmap, reg, (u8 *) val, sizeof(*val));
+
+       pm_runtime_mark_last_busy(dev);
+       pm_runtime_put_autosuspend(dev);
+
+       return ret;
+}
+
+static int atlas_read_raw(struct iio_dev *indio_dev,
+                         struct iio_chan_spec const *chan,
+                         int *val, int *val2, long mask)
+{
+       struct atlas_data *data = iio_priv(indio_dev);
+
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW: {
+               int ret;
+               __be32 reg;
+
+               switch (chan->type) {
+               case IIO_TEMP:
+                       ret = regmap_bulk_read(data->regmap, chan->address,
+                                             (u8 *) &reg, sizeof(reg));
+                       break;
+               case IIO_PH:
+               case IIO_CONCENTRATION:
+               case IIO_ELECTRICALCONDUCTIVITY:
+               case IIO_VOLTAGE:
+                       ret = iio_device_claim_direct_mode(indio_dev);
+                       if (ret)
+                               return ret;
+
+                       ret = atlas_read_measurement(data, chan->address, &reg);
+
+                       iio_device_release_direct_mode(indio_dev);
+                       break;
+               default:
+                       ret = -EINVAL;
+               }
+
+               if (!ret) {
+                       *val = be32_to_cpu(reg);
+                       ret = IIO_VAL_INT;
+               }
+               return ret;
+       }
+       case IIO_CHAN_INFO_SCALE:
+               switch (chan->type) {
+               case IIO_TEMP:
+                       *val = 10;
+                       return IIO_VAL_INT;
+               case IIO_PH:
+                       *val = 1; /* 0.001 */
+                       *val2 = 1000;
+                       break;
+               case IIO_ELECTRICALCONDUCTIVITY:
+                       *val = 1; /* 0.00001 */
+                       *val2 = 100000;
+                       break;
+               case IIO_CONCENTRATION:
+                       *val = 0; /* 0.000000001 */
+                       *val2 = 1000;
+                       return IIO_VAL_INT_PLUS_NANO;
+               case IIO_VOLTAGE:
+                       *val = 1; /* 0.1 */
+                       *val2 = 10;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+               return IIO_VAL_FRACTIONAL;
+       }
+
+       return -EINVAL;
+}
+
+static int atlas_write_raw(struct iio_dev *indio_dev,
+                          struct iio_chan_spec const *chan,
+                          int val, int val2, long mask)
+{
+       struct atlas_data *data = iio_priv(indio_dev);
+       __be32 reg = cpu_to_be32(val / 10);
+
+       if (val2 != 0 || val < 0 || val > 20000)
+               return -EINVAL;
+
+       if (mask != IIO_CHAN_INFO_RAW || chan->type != IIO_TEMP)
+               return -EINVAL;
+
+       return regmap_bulk_write(data->regmap, chan->address,
+                                &reg, sizeof(reg));
+}
+
+static const struct iio_info atlas_info = {
+       .read_raw = atlas_read_raw,
+       .write_raw = atlas_write_raw,
+};
+
+static const struct i2c_device_id atlas_id[] = {
+       { "atlas-ph-sm", ATLAS_PH_SM},
+       { "atlas-ec-sm", ATLAS_EC_SM},
+       { "atlas-orp-sm", ATLAS_ORP_SM},
+       {}
+};
+MODULE_DEVICE_TABLE(i2c, atlas_id);
+
+static const struct of_device_id atlas_dt_ids[] = {
+       { .compatible = "atlas,ph-sm", .data = (void *)ATLAS_PH_SM, },
+       { .compatible = "atlas,ec-sm", .data = (void *)ATLAS_EC_SM, },
+       { .compatible = "atlas,orp-sm", .data = (void *)ATLAS_ORP_SM, },
+       { }
+};
+MODULE_DEVICE_TABLE(of, atlas_dt_ids);
+
+static int atlas_probe(struct i2c_client *client,
+                      const struct i2c_device_id *id)
+{
+       struct atlas_data *data;
+       struct atlas_device *chip;
+       const struct of_device_id *of_id;
+       struct iio_trigger *trig;
+       struct iio_dev *indio_dev;
+       int ret;
+
+       indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+       if (!indio_dev)
+               return -ENOMEM;
+
+       of_id = of_match_device(atlas_dt_ids, &client->dev);
+       if (!of_id)
+               chip = &atlas_devices[id->driver_data];
+       else
+               chip = &atlas_devices[(unsigned long)of_id->data];
+
+       indio_dev->info = &atlas_info;
+       indio_dev->name = ATLAS_DRV_NAME;
+       indio_dev->channels = chip->channels;
+       indio_dev->num_channels = chip->num_channels;
+       indio_dev->modes = INDIO_BUFFER_SOFTWARE | INDIO_DIRECT_MODE;
+       indio_dev->dev.parent = &client->dev;
+
+       trig = devm_iio_trigger_alloc(&client->dev, "%s-dev%d",
+                                     indio_dev->name, indio_dev->id);
+
+       if (!trig)
+               return -ENOMEM;
+
+       data = iio_priv(indio_dev);
+       data->client = client;
+       data->trig = trig;
+       data->chip = chip;
+       trig->dev.parent = indio_dev->dev.parent;
+       trig->ops = &atlas_interrupt_trigger_ops;
+       iio_trigger_set_drvdata(trig, indio_dev);
+
+       i2c_set_clientdata(client, indio_dev);
+
+       data->regmap = devm_regmap_init_i2c(client, &atlas_regmap_config);
+       if (IS_ERR(data->regmap)) {
+               dev_err(&client->dev, "regmap initialization failed\n");
+               return PTR_ERR(data->regmap);
+       }
+
+       ret = pm_runtime_set_active(&client->dev);
+       if (ret)
+               return ret;
+
+       if (client->irq <= 0) {
+               dev_err(&client->dev, "no valid irq defined\n");
+               return -EINVAL;
+       }
+
+       ret = chip->calibration(data);
+       if (ret)
+               return ret;
+
+       ret = iio_trigger_register(trig);
+       if (ret) {
+               dev_err(&client->dev, "failed to register trigger\n");
+               return ret;
+       }
+
+       ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
+               &atlas_trigger_handler, &atlas_buffer_setup_ops);
+       if (ret) {
+               dev_err(&client->dev, "cannot setup iio trigger\n");
+               goto unregister_trigger;
+       }
+
+       init_irq_work(&data->work, atlas_work_handler);
+
+       /* interrupt pin toggles on new conversion */
+       ret = devm_request_threaded_irq(&client->dev, client->irq,
+                                       NULL, atlas_interrupt_handler,
+                                       IRQF_TRIGGER_RISING |
+                                       IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+                                       "atlas_irq",
+                                       indio_dev);
+       if (ret) {
+               dev_err(&client->dev, "request irq (%d) failed\n", client->irq);
+               goto unregister_buffer;
+       }
+
+       ret = atlas_set_powermode(data, 1);
+       if (ret) {
+               dev_err(&client->dev, "cannot power device on");
+               goto unregister_buffer;
+       }
+
+       pm_runtime_enable(&client->dev);
+       pm_runtime_set_autosuspend_delay(&client->dev, 2500);
+       pm_runtime_use_autosuspend(&client->dev);
+
+       ret = iio_device_register(indio_dev);
+       if (ret) {
+               dev_err(&client->dev, "unable to register device\n");
+               goto unregister_pm;
+       }
+
+       return 0;
+
+unregister_pm:
+       pm_runtime_disable(&client->dev);
+       atlas_set_powermode(data, 0);
+
+unregister_buffer:
+       iio_triggered_buffer_cleanup(indio_dev);
+
+unregister_trigger:
+       iio_trigger_unregister(data->trig);
+
+       return ret;
+}
+
+static int atlas_remove(struct i2c_client *client)
+{
+       struct iio_dev *indio_dev = i2c_get_clientdata(client);
+       struct atlas_data *data = iio_priv(indio_dev);
+
+       iio_device_unregister(indio_dev);
+       iio_triggered_buffer_cleanup(indio_dev);
+       iio_trigger_unregister(data->trig);
+
+       pm_runtime_disable(&client->dev);
+       pm_runtime_set_suspended(&client->dev);
+       pm_runtime_put_noidle(&client->dev);
+
+       return atlas_set_powermode(data, 0);
+}
+
+#ifdef CONFIG_PM
+static int atlas_runtime_suspend(struct device *dev)
+{
+       struct atlas_data *data =
+                    iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
+
+       return atlas_set_powermode(data, 0);
+}
+
+static int atlas_runtime_resume(struct device *dev)
+{
+       struct atlas_data *data =
+                    iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
+
+       return atlas_set_powermode(data, 1);
+}
+#endif
+
+static const struct dev_pm_ops atlas_pm_ops = {
+       SET_RUNTIME_PM_OPS(atlas_runtime_suspend,
+                          atlas_runtime_resume, NULL)
+};
+
+static struct i2c_driver atlas_driver = {
+       .driver = {
+               .name   = ATLAS_DRV_NAME,
+               .of_match_table = of_match_ptr(atlas_dt_ids),
+               .pm     = &atlas_pm_ops,
+       },
+       .probe          = atlas_probe,
+       .remove         = atlas_remove,
+       .id_table       = atlas_id,
+};
+module_i2c_driver(atlas_driver);
+
+MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>");
+MODULE_DESCRIPTION("Atlas Scientific SM sensors");
+MODULE_LICENSE("GPL");
index 0a381bb..abb8327 100644 (file)
@@ -7,7 +7,7 @@
 #define __SSP_SENSORHUB_H__
 
 #include <linux/delay.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/iio/common/ssp_sensors.h>
 #include <linux/iio/iio.h>
 #include <linux/spi/spi.h>
@@ -168,9 +168,9 @@ struct ssp_sensorhub_info {
  * @fw_dl_state:       firmware download state
  * @comm_lock:         lock protecting the handshake
  * @pending_lock:      lock protecting pending list and completion
- * @mcu_reset_gpio   mcu reset line
- * @ap_mcu_gpio      ap to mcu gpio line
- * @mcu_ap_gpio      mcu to ap gpio line
+ * @mcu_reset_gpiod:   mcu reset line
+ * @ap_mcu_gpiod:      ap to mcu gpio line
+ * @mcu_ap_gpiod:      mcu to ap gpio line
  * @pending_list:      pending list for messages queued to be sent/read
  * @sensor_devs:       registered IIO devices table
  * @enable_refcount:   enable reference count for wdt (watchdog timer)
@@ -212,9 +212,9 @@ struct ssp_data {
        struct mutex comm_lock;
        struct mutex pending_lock;
 
-       int mcu_reset_gpio;
-       int ap_mcu_gpio;
-       int mcu_ap_gpio;
+       struct gpio_desc *mcu_reset_gpiod;
+       struct gpio_desc *ap_mcu_gpiod;
+       struct gpio_desc *mcu_ap_gpiod;
 
        struct list_head pending_list;
 
index 9c70553..a94dbcf 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/mfd/core.h>
 #include <linux/module.h>
 #include <linux/of.h>
-#include <linux/of_gpio.h>
 #include <linux/of_platform.h>
 #include "ssp.h"
 
@@ -61,9 +60,9 @@ static const struct mfd_cell sensorhub_sensor_devs[] = {
 
 static void ssp_toggle_mcu_reset_gpio(struct ssp_data *data)
 {
-       gpio_set_value(data->mcu_reset_gpio, 0);
+       gpiod_set_value(data->mcu_reset_gpiod, 0);
        usleep_range(1000, 1200);
-       gpio_set_value(data->mcu_reset_gpio, 1);
+       gpiod_set_value(data->mcu_reset_gpiod, 1);
        msleep(50);
 }
 
@@ -441,7 +440,6 @@ MODULE_DEVICE_TABLE(of, ssp_of_match);
 
 static struct ssp_data *ssp_parse_dt(struct device *dev)
 {
-       int ret;
        struct ssp_data *data;
        struct device_node *node = dev->of_node;
        const struct of_device_id *match;
@@ -450,26 +448,17 @@ static struct ssp_data *ssp_parse_dt(struct device *dev)
        if (!data)
                return NULL;
 
-       data->mcu_ap_gpio = of_get_named_gpio(node, "mcu-ap-gpios", 0);
-       if (data->mcu_ap_gpio < 0)
-               return NULL;
-
-       data->ap_mcu_gpio = of_get_named_gpio(node, "ap-mcu-gpios", 0);
-       if (data->ap_mcu_gpio < 0)
-               return NULL;
-
-       data->mcu_reset_gpio = of_get_named_gpio(node, "mcu-reset-gpios", 0);
-       if (data->mcu_reset_gpio < 0)
+       data->mcu_ap_gpiod = devm_gpiod_get(dev, "mcu-ap", GPIOD_IN);
+       if (IS_ERR(data->mcu_ap_gpiod))
                return NULL;
 
-       ret = devm_gpio_request_one(dev, data->ap_mcu_gpio, GPIOF_OUT_INIT_HIGH,
-                                   "ap-mcu-gpios");
-       if (ret)
+       data->ap_mcu_gpiod = devm_gpiod_get(dev, "ap-mcu", GPIOD_OUT_HIGH);
+       if (IS_ERR(data->ap_mcu_gpiod))
                return NULL;
 
-       ret = devm_gpio_request_one(dev, data->mcu_reset_gpio,
-                                   GPIOF_OUT_INIT_HIGH, "mcu-reset-gpios");
-       if (ret)
+       data->mcu_reset_gpiod = devm_gpiod_get(dev, "mcu-reset",
+                                              GPIOD_OUT_HIGH);
+       if (IS_ERR(data->mcu_reset_gpiod))
                return NULL;
 
        match = of_match_node(ssp_of_match, node);
index 7db3d58..4864c38 100644 (file)
@@ -155,9 +155,9 @@ static int ssp_check_lines(struct ssp_data *data, bool state)
 {
        int delay_cnt = 0;
 
-       gpio_set_value_cansleep(data->ap_mcu_gpio, state);
+       gpiod_set_value_cansleep(data->ap_mcu_gpiod, state);
 
-       while (gpio_get_value_cansleep(data->mcu_ap_gpio) != state) {
+       while (gpiod_get_value_cansleep(data->mcu_ap_gpiod) != state) {
                usleep_range(3000, 3500);
 
                if (data->shut_down || delay_cnt++ > 500) {
@@ -165,7 +165,7 @@ static int ssp_check_lines(struct ssp_data *data, bool state)
                                __func__, state);
 
                        if (!state)
-                               gpio_set_value_cansleep(data->ap_mcu_gpio, 1);
+                               gpiod_set_value_cansleep(data->ap_mcu_gpiod, 1);
 
                        return -ETIMEDOUT;
                }
@@ -197,7 +197,7 @@ static int ssp_do_transfer(struct ssp_data *data, struct ssp_msg *msg,
 
        status = spi_write(data->spi, msg->buffer, SSP_HEADER_SIZE);
        if (status < 0) {
-               gpio_set_value_cansleep(data->ap_mcu_gpio, 1);
+               gpiod_set_value_cansleep(data->ap_mcu_gpiod, 1);
                dev_err(SSP_DEV, "%s spi_write fail\n", __func__);
                goto _error_locked;
        }
index 4a3064f..e051edb 100644 (file)
@@ -12,9 +12,8 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/iio/iio.h>
+#include <linux/property.h>
 #include <linux/regulator/consumer.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
 #include <linux/regmap.h>
 #include <asm/unaligned.h>
 #include <linux/iio/common/st_sensors.h>
@@ -319,63 +318,49 @@ static int st_sensors_set_drdy_int_pin(struct iio_dev *indio_dev,
        return 0;
 }
 
-#ifdef CONFIG_OF
-static struct st_sensors_platform_data *st_sensors_of_probe(struct device *dev,
+static struct st_sensors_platform_data *st_sensors_dev_probe(struct device *dev,
                struct st_sensors_platform_data *defdata)
 {
        struct st_sensors_platform_data *pdata;
-       struct device_node *np = dev->of_node;
        u32 val;
 
-       if (!np)
+       if (!dev_fwnode(dev))
                return NULL;
 
        pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
-       if (!of_property_read_u32(np, "st,drdy-int-pin", &val) && (val <= 2))
+       if (!device_property_read_u32(dev, "st,drdy-int-pin", &val) && (val <= 2))
                pdata->drdy_int_pin = (u8) val;
        else
                pdata->drdy_int_pin = defdata ? defdata->drdy_int_pin : 0;
 
-       pdata->open_drain = of_property_read_bool(np, "drive-open-drain");
+       pdata->open_drain = device_property_read_bool(dev, "drive-open-drain");
 
        return pdata;
 }
 
 /**
- * st_sensors_of_name_probe() - device tree probe for ST sensor name
+ * st_sensors_dev_name_probe() - device probe for ST sensor name
  * @dev: driver model representation of the device.
- * @match: the OF match table for the device, containing compatible strings
- *     but also a .data field with the corresponding internal kernel name
- *     used by this sensor.
  * @name: device name buffer reference.
  * @len: device name buffer length.
  *
- * In effect this function matches a compatible string to an internal kernel
+ * In effect this function matches an ID to an internal kernel
  * name for a certain sensor device, so that the rest of the autodetection can
  * rely on that name from this point on. I2C/SPI devices will be renamed
  * to match the internal kernel convention.
  */
-void st_sensors_of_name_probe(struct device *dev,
-                             const struct of_device_id *match,
-                             char *name, int len)
+void st_sensors_dev_name_probe(struct device *dev, char *name, int len)
 {
-       const struct of_device_id *of_id;
+       const void *match;
 
-       of_id = of_match_device(match, dev);
-       if (!of_id || !of_id->data)
+       match = device_get_match_data(dev);
+       if (!match)
                return;
 
-       /* The name from the OF match takes precedence if present */
-       strlcpy(name, of_id->data, len);
+       /* The name from the match takes precedence if present */
+       strlcpy(name, match, len);
 }
-EXPORT_SYMBOL(st_sensors_of_name_probe);
-#else
-static struct st_sensors_platform_data *st_sensors_of_probe(struct device *dev,
-               struct st_sensors_platform_data *defdata)
-{
-       return NULL;
-}
-#endif
+EXPORT_SYMBOL(st_sensors_dev_name_probe);
 
 int st_sensors_init_sensor(struct iio_dev *indio_dev,
                                        struct st_sensors_platform_data *pdata)
@@ -385,7 +370,7 @@ int st_sensors_init_sensor(struct iio_dev *indio_dev,
        int err = 0;
 
        /* If OF/DT pdata exists, it will take precedence of anything else */
-       of_pdata = st_sensors_of_probe(indio_dev->dev.parent, pdata);
+       of_pdata = st_sensors_dev_probe(indio_dev->dev.parent, pdata);
        if (of_pdata)
                pdata = of_pdata;
 
index aa89d54..286830f 100644 (file)
@@ -11,8 +11,6 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/iio/iio.h>
-#include <linux/of_device.h>
-#include <linux/acpi.h>
 #include <linux/regmap.h>
 
 #include <linux/iio/common/st_sensors_i2c.h>
@@ -68,25 +66,6 @@ int st_sensors_i2c_configure(struct iio_dev *indio_dev,
 }
 EXPORT_SYMBOL(st_sensors_i2c_configure);
 
-#ifdef CONFIG_ACPI
-int st_sensors_match_acpi_device(struct device *dev)
-{
-       const struct acpi_device_id *acpi_id;
-       kernel_ulong_t driver_data = 0;
-
-       if (ACPI_HANDLE(dev)) {
-               acpi_id = acpi_match_device(dev->driver->acpi_match_table, dev);
-               if (!acpi_id) {
-                       dev_err(dev, "No driver data\n");
-                       return -EINVAL;
-               }
-               driver_data = acpi_id->driver_data;
-       }
-       return driver_data;
-}
-EXPORT_SYMBOL(st_sensors_match_acpi_device);
-#endif
-
 MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
 MODULE_DESCRIPTION("STMicroelectronics ST-sensors i2c driver");
 MODULE_LICENSE("GPL v2");
index 2262f81..1275fb0 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/iio/iio.h>
+#include <linux/property.h>
 #include <linux/regmap.h>
 
 #include <linux/iio/common/st_sensors_spi.h>
@@ -37,14 +38,15 @@ static const struct regmap_config st_sensors_spi_regmap_multiread_bit_config = {
  */
 static bool st_sensors_is_spi_3_wire(struct spi_device *spi)
 {
-       struct device_node *np = spi->dev.of_node;
        struct st_sensors_platform_data *pdata;
+       struct device *dev = &spi->dev;
 
-       pdata = (struct st_sensors_platform_data *)spi->dev.platform_data;
-       if ((np && of_property_read_bool(np, "spi-3wire")) ||
-           (pdata && pdata->spi_3wire)) {
+       if (device_property_read_bool(dev, "spi-3wire"))
+               return true;
+
+       pdata = (struct st_sensors_platform_data *)dev->platform_data;
+       if (pdata && pdata->spi_3wire)
                return true;
-       }
 
        return false;
 }
index 4a2efa0..e817537 100644 (file)
@@ -19,6 +19,9 @@
 
 /**
  * st_sensors_new_samples_available() - check if more samples came in
+ * @indio_dev: IIO device reference.
+ * @sdata: Sensor data.
+ *
  * returns:
  * 0 - no new samples available
  * 1 - new samples available
index 2d897e6..e211011 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/regulator/consumer.h>
 #include <linux/gpio/consumer.h>
 #include <linux/gpio/driver.h>
-#include <linux/gpio.h>
 #include <linux/property.h>
 
 #include <dt-bindings/iio/adi,ad5592r.h>
index 14bbac6..15af8a1 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/slab.h>
 #include <linux/sysfs.h>
 #include <linux/regulator/consumer.h>
-#include <linux/of.h>
 
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
@@ -202,7 +201,6 @@ static int ad7303_probe(struct spi_device *spi)
        const struct spi_device_id *id = spi_get_device_id(spi);
        struct iio_dev *indio_dev;
        struct ad7303_state *st;
-       bool ext_ref;
        int ret;
 
        indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
@@ -224,24 +222,15 @@ static int ad7303_probe(struct spi_device *spi)
        if (ret)
                return ret;
 
-       if (spi->dev.of_node) {
-               ext_ref = of_property_read_bool(spi->dev.of_node,
-                               "REF-supply");
-       } else {
-               struct ad7303_platform_data *pdata = spi->dev.platform_data;
-               if (pdata && pdata->use_external_ref)
-                       ext_ref = true;
-               else
-                   ext_ref = false;
-       }
-
-       if (ext_ref) {
-               st->vref_reg = devm_regulator_get(&spi->dev, "REF");
-               if (IS_ERR(st->vref_reg)) {
-                       ret = PTR_ERR(st->vref_reg);
+       st->vref_reg = devm_regulator_get_optional(&spi->dev, "REF");
+       if (IS_ERR(st->vref_reg)) {
+               ret = PTR_ERR(st->vref_reg);
+               if (ret != -ENODEV)
                        goto err_disable_vdd_reg;
-               }
+               st->vref_reg = NULL;
+       }
 
+       if (st->vref_reg) {
                ret = regulator_enable(st->vref_reg);
                if (ret)
                        goto err_disable_vdd_reg;
index 9e6b4cd..7e5809b 100644 (file)
 /**
  * struct stm32_dac_priv - stm32 DAC core private data
  * @pclk:              peripheral clock common for all DACs
- * @rst:               peripheral reset control
  * @vref:              regulator reference
  * @common:            Common data for all DAC instances
  */
 struct stm32_dac_priv {
        struct clk *pclk;
-       struct reset_control *rst;
        struct regulator *vref;
        struct stm32_dac_common common;
 };
@@ -94,6 +92,7 @@ static int stm32_dac_probe(struct platform_device *pdev)
        struct regmap *regmap;
        struct resource *res;
        void __iomem *mmio;
+       struct reset_control *rst;
        int ret;
 
        if (!dev->of_node)
@@ -148,11 +147,19 @@ static int stm32_dac_probe(struct platform_device *pdev)
        priv->common.vref_mv = ret / 1000;
        dev_dbg(dev, "vref+=%dmV\n", priv->common.vref_mv);
 
-       priv->rst = devm_reset_control_get_exclusive(dev, NULL);
-       if (!IS_ERR(priv->rst)) {
-               reset_control_assert(priv->rst);
+       rst = devm_reset_control_get_optional_exclusive(dev, NULL);
+       if (rst) {
+               if (IS_ERR(rst)) {
+                       ret = PTR_ERR(rst);
+                       if (ret != -EPROBE_DEFER)
+                               dev_err(dev, "reset get failed, %d\n", ret);
+
+                       goto err_hw_stop;
+               }
+
+               reset_control_assert(rst);
                udelay(2);
-               reset_control_deassert(priv->rst);
+               reset_control_deassert(rst);
        }
 
        if (cfg && cfg->has_hfsel) {
index ae0ca09..1c2dc9b 100644 (file)
 #include <linux/err.h>
 #include <linux/module.h>
 #include <linux/gcd.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <asm/div64.h>
 #include <linux/clk.h>
 #include <linux/of.h>
-#include <linux/of_gpio.h>
 
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
@@ -34,6 +33,7 @@ enum {
 struct adf4350_state {
        struct spi_device               *spi;
        struct regulator                *reg;
+       struct gpio_desc                *lock_detect_gpiod;
        struct adf4350_platform_data    *pdata;
        struct clk                      *clk;
        unsigned long                   clkin;
@@ -61,7 +61,6 @@ static struct adf4350_platform_data default_pdata = {
        .r3_user_settings = ADF4350_REG3_12BIT_CLKDIV_MODE(0),
        .r4_user_settings = ADF4350_REG4_OUTPUT_PWR(3) |
                            ADF4350_REG4_MUTE_TILL_LOCK_EN,
-       .gpio_lock_detect = -1,
 };
 
 static int adf4350_sync_config(struct adf4350_state *st)
@@ -317,8 +316,8 @@ static ssize_t adf4350_read(struct iio_dev *indio_dev,
                        (u64)st->fpfd;
                do_div(val, st->r1_mod * (1 << st->r4_rf_div_sel));
                /* PLL unlocked? return error */
-               if (gpio_is_valid(st->pdata->gpio_lock_detect))
-                       if (!gpio_get_value(st->pdata->gpio_lock_detect)) {
+               if (st->lock_detect_gpiod)
+                       if (!gpiod_get_value(st->lock_detect_gpiod)) {
                                dev_dbg(&st->spi->dev, "PLL un-locked\n");
                                ret = -EBUSY;
                        }
@@ -381,7 +380,6 @@ static struct adf4350_platform_data *adf4350_parse_dt(struct device *dev)
        struct device_node *np = dev->of_node;
        struct adf4350_platform_data *pdata;
        unsigned int tmp;
-       int ret;
 
        pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
        if (!pdata)
@@ -401,12 +399,6 @@ static struct adf4350_platform_data *adf4350_parse_dt(struct device *dev)
        of_property_read_u32(np, "adi,reference-div-factor", &tmp);
        pdata->ref_div_factor = tmp;
 
-       ret = of_get_gpio(np, 0);
-       if (ret < 0)
-               pdata->gpio_lock_detect = -1;
-       else
-               pdata->gpio_lock_detect = ret;
-
        pdata->ref_doubler_en = of_property_read_bool(np,
                        "adi,reference-doubler-enable");
        pdata->ref_div2_en = of_property_read_bool(np,
@@ -561,16 +553,10 @@ static int adf4350_probe(struct spi_device *spi)
 
        memset(st->regs_hw, 0xFF, sizeof(st->regs_hw));
 
-       if (gpio_is_valid(pdata->gpio_lock_detect)) {
-               ret = devm_gpio_request(&spi->dev, pdata->gpio_lock_detect,
-                                       indio_dev->name);
-               if (ret) {
-                       dev_err(&spi->dev, "fail to request lock detect GPIO-%d",
-                               pdata->gpio_lock_detect);
-                       goto error_disable_reg;
-               }
-               gpio_direction_input(pdata->gpio_lock_detect);
-       }
+       st->lock_detect_gpiod = devm_gpiod_get_optional(&spi->dev, NULL,
+                                                       GPIOD_IN);
+       if (IS_ERR(st->lock_detect_gpiod))
+               return PTR_ERR(st->lock_detect_gpiod);
 
        if (pdata->power_up_frequency) {
                ret = adf4350_set_freq(st, pdata->power_up_frequency);
index 95e6f96..7eaf777 100644 (file)
@@ -75,26 +75,26 @@ config BMG160_SPI
        select REGMAP_SPI
 
 config FXAS21002C
-       tristate "NXP FXAS21002C Gyro Sensor"
-       select IIO_BUFFER
-       select IIO_TRIGGERED_BUFFER
-       select FXAS21002C_I2C if (I2C)
-       select FXAS21002C_SPI if (SPI)
-       depends on (I2C || SPI_MASTER)
-       help
-         Say yes here to build support for NXP FXAS21002C Tri-axis Gyro
-         Sensor driver connected via I2C or SPI.
-
-         This driver can also be built as a module.  If so, the module
-         will be called fxas21002c_i2c or fxas21002c_spi.
+       tristate "NXP FXAS21002C Gyro Sensor"
+       select IIO_BUFFER
+       select IIO_TRIGGERED_BUFFER
+       select FXAS21002C_I2C if (I2C)
+       select FXAS21002C_SPI if (SPI)
+       depends on (I2C || SPI_MASTER)
+       help
+         Say yes here to build support for NXP FXAS21002C Tri-axis Gyro
+         Sensor driver connected via I2C or SPI.
+
+         This driver can also be built as a module.  If so, the module
+         will be called fxas21002c_i2c or fxas21002c_spi.
 
 config FXAS21002C_I2C
-       tristate
-       select REGMAP_I2C
+       tristate
+       select REGMAP_I2C
 
 config FXAS21002C_SPI
-       tristate
-       select REGMAP_SPI
+       tristate
+       select REGMAP_SPI
 
 config HID_SENSOR_GYRO_3D
        depends on HID_SENSOR_HUB
index d637d52..d5e03a4 100644 (file)
@@ -59,6 +59,7 @@
 struct adis16136_chip_info {
        unsigned int precision;
        unsigned int fullscale;
+       const struct adis_timeout *timeouts;
 };
 
 struct adis16136 {
@@ -185,12 +186,12 @@ static int adis16136_set_freq(struct adis16136 *adis16136, unsigned int freq)
        return adis_write_reg_16(&adis16136->adis, ADIS16136_REG_SMPL_PRD, t);
 }
 
-static int adis16136_get_freq(struct adis16136 *adis16136, unsigned int *freq)
+static int __adis16136_get_freq(struct adis16136 *adis16136, unsigned int *freq)
 {
        uint16_t t;
        int ret;
 
-       ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_SMPL_PRD, &t);
+       ret = __adis_read_reg_16(&adis16136->adis, ADIS16136_REG_SMPL_PRD, &t);
        if (ret)
                return ret;
 
@@ -224,10 +225,13 @@ static ssize_t adis16136_read_frequency(struct device *dev,
 {
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct adis16136 *adis16136 = iio_priv(indio_dev);
+       struct mutex *slock = &adis16136->adis.state_lock;
        unsigned int freq;
        int ret;
 
-       ret = adis16136_get_freq(adis16136, &freq);
+       mutex_lock(slock);
+       ret = __adis16136_get_freq(adis16136, &freq);
+       mutex_unlock(slock);
        if (ret)
                return ret;
 
@@ -252,42 +256,50 @@ static const unsigned adis16136_3db_divisors[] = {
 static int adis16136_set_filter(struct iio_dev *indio_dev, int val)
 {
        struct adis16136 *adis16136 = iio_priv(indio_dev);
+       struct mutex *slock = &adis16136->adis.state_lock;
        unsigned int freq;
        int i, ret;
 
-       ret = adis16136_get_freq(adis16136, &freq);
+       mutex_lock(slock);
+       ret = __adis16136_get_freq(adis16136, &freq);
        if (ret)
-               return ret;
+               goto out_unlock;
 
        for (i = ARRAY_SIZE(adis16136_3db_divisors) - 1; i >= 1; i--) {
                if (freq / adis16136_3db_divisors[i] >= val)
                        break;
        }
 
-       return adis_write_reg_16(&adis16136->adis, ADIS16136_REG_AVG_CNT, i);
+       ret = __adis_write_reg_16(&adis16136->adis, ADIS16136_REG_AVG_CNT, i);
+out_unlock:
+       mutex_unlock(slock);
+
+       return ret;
 }
 
 static int adis16136_get_filter(struct iio_dev *indio_dev, int *val)
 {
        struct adis16136 *adis16136 = iio_priv(indio_dev);
+       struct mutex *slock = &adis16136->adis.state_lock;
        unsigned int freq;
        uint16_t val16;
        int ret;
 
-       mutex_lock(&indio_dev->mlock);
+       mutex_lock(slock);
 
-       ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_AVG_CNT, &val16);
+       ret = __adis_read_reg_16(&adis16136->adis, ADIS16136_REG_AVG_CNT,
+                                &val16);
        if (ret)
                goto err_unlock;
 
-       ret = adis16136_get_freq(adis16136, &freq);
+       ret = __adis16136_get_freq(adis16136, &freq);
        if (ret)
                goto err_unlock;
 
        *val = freq / adis16136_3db_divisors[val16 & 0x07];
 
 err_unlock:
-       mutex_unlock(&indio_dev->mlock);
+       mutex_unlock(slock);
 
        return ret ? ret : IIO_VAL_INT;
 }
@@ -460,7 +472,6 @@ static const struct adis_data adis16136_data = {
        .msc_ctrl_reg = ADIS16136_REG_MSC_CTRL,
 
        .self_test_mask = ADIS16136_MSC_CTRL_SELF_TEST,
-       .startup_delay = 80,
 
        .read_delay = 10,
        .write_delay = 10,
@@ -479,30 +490,63 @@ enum adis16136_id {
        ID_ADIS16137,
 };
 
+static const struct adis_timeout adis16133_timeouts = {
+       .reset_ms = 75,
+       .sw_reset_ms = 75,
+       .self_test_ms = 50,
+};
+
+static const struct adis_timeout adis16136_timeouts = {
+       .reset_ms = 128,
+       .sw_reset_ms = 75,
+       .self_test_ms = 245,
+};
+
 static const struct adis16136_chip_info adis16136_chip_info[] = {
        [ID_ADIS16133] = {
                .precision = IIO_DEGREE_TO_RAD(1200),
                .fullscale = 24000,
+               .timeouts = &adis16133_timeouts,
        },
        [ID_ADIS16135] = {
                .precision = IIO_DEGREE_TO_RAD(300),
                .fullscale = 24000,
+               .timeouts = &adis16133_timeouts,
        },
        [ID_ADIS16136] = {
                .precision = IIO_DEGREE_TO_RAD(450),
                .fullscale = 24623,
+               .timeouts = &adis16136_timeouts,
        },
        [ID_ADIS16137] = {
                .precision = IIO_DEGREE_TO_RAD(1000),
                .fullscale = 24609,
+               .timeouts = &adis16136_timeouts,
        },
 };
 
+static struct adis_data *adis16136_adis_data_alloc(struct adis16136 *st,
+                                                  struct device *dev)
+{
+       struct adis_data *data;
+
+       data = devm_kmalloc(dev, sizeof(struct adis_data), GFP_KERNEL);
+       if (!data)
+               return ERR_PTR(-ENOMEM);
+
+       memcpy(data, &adis16136_data, sizeof(*data));
+
+       data->timeouts = st->chip_info->timeouts;
+
+       return data;
+}
+
 static int adis16136_probe(struct spi_device *spi)
 {
        const struct spi_device_id *id = spi_get_device_id(spi);
        struct adis16136 *adis16136;
        struct iio_dev *indio_dev;
+       const struct adis_data *adis16136_data;
        int ret;
 
        indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adis16136));
@@ -521,7 +565,11 @@ static int adis16136_probe(struct spi_device *spi)
        indio_dev->info = &adis16136_info;
        indio_dev->modes = INDIO_DIRECT_MODE;
 
-       ret = adis_init(&adis16136->adis, indio_dev, spi, &adis16136_data);
+       adis16136_data = adis16136_adis_data_alloc(adis16136, &spi->dev);
+       if (IS_ERR(adis16136_data))
+               return PTR_ERR(adis16136_data);
+
+       ret = adis_init(&adis16136->adis, indio_dev, spi, adis16136_data);
        if (ret)
                return ret;
 
index 207a0ce..be09b3e 100644 (file)
@@ -293,7 +293,7 @@ static int adis16260_write_raw(struct iio_dev *indio_dev,
                addr = adis16260_addresses[chan->scan_index][1];
                return adis_write_reg_16(adis, addr, val);
        case IIO_CHAN_INFO_SAMP_FREQ:
-               mutex_lock(&indio_dev->mlock);
+               mutex_lock(&adis->state_lock);
                if (spi_get_device_id(adis->spi)->driver_data)
                        t = 256 / val;
                else
@@ -308,9 +308,9 @@ static int adis16260_write_raw(struct iio_dev *indio_dev,
                        adis->spi->max_speed_hz = ADIS16260_SPI_SLOW;
                else
                        adis->spi->max_speed_hz = ADIS16260_SPI_FAST;
-               ret = adis_write_reg_8(adis, ADIS16260_SMPL_PRD, t);
+               ret = __adis_write_reg_8(adis, ADIS16260_SMPL_PRD, t);
 
-               mutex_unlock(&indio_dev->mlock);
+               mutex_unlock(&adis->state_lock);
                return ret;
        }
        return -EINVAL;
@@ -332,6 +332,12 @@ static const char * const adis1620_status_error_msgs[] = {
        [ADIS16260_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 4.75",
 };
 
+static const struct adis_timeout adis16260_timeouts = {
+       .reset_ms = ADIS16260_STARTUP_DELAY,
+       .sw_reset_ms = ADIS16260_STARTUP_DELAY,
+       .self_test_ms = ADIS16260_STARTUP_DELAY,
+};
+
 static const struct adis_data adis16260_data = {
        .write_delay = 30,
        .read_delay = 30,
@@ -340,7 +346,7 @@ static const struct adis_data adis16260_data = {
        .diag_stat_reg = ADIS16260_DIAG_STAT,
 
        .self_test_mask = ADIS16260_MSC_CTRL_MEM_TEST,
-       .startup_delay = ADIS16260_STARTUP_DELAY,
+       .timeouts = &adis16260_timeouts,
 
        .status_error_msgs = adis1620_status_error_msgs,
        .status_error_mask = BIT(ADIS16260_DIAG_STAT_FLASH_CHK_BIT) |
index 981ae22..b3afa55 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/i2c.h>
-#include <linux/gpio.h>
 #include <linux/slab.h>
 #include <linux/stat.h>
 #include <linux/module.h>
index 592f6b3..fd9171c 100644 (file)
@@ -28,7 +28,7 @@
  * struct st_sensors_platform_data - gyro platform data
  * @drdy_int_pin: DRDY on gyros is available only on INT2 pin.
  */
-static const struct st_sensors_platform_data gyro_pdata = {
+static __maybe_unused const struct st_sensors_platform_data gyro_pdata = {
        .drdy_int_pin = 2,
 };
 
index 57be68b..26c50b2 100644 (file)
@@ -138,7 +138,6 @@ static const struct st_sensor_settings st_gyro_sensors_settings[] = {
                        [2] = LSM330DLC_GYRO_DEV_NAME,
                        [3] = L3G4IS_GYRO_DEV_NAME,
                        [4] = LSM330_GYRO_DEV_NAME,
-                       [5] = LSM9DS0_GYRO_DEV_NAME,
                },
                .ch = (struct iio_chan_spec *)st_gyro_16bit_channels,
                .odr = {
@@ -208,6 +207,80 @@ static const struct st_sensor_settings st_gyro_sensors_settings[] = {
                .multi_read_bit = true,
                .bootime = 2,
        },
+       {
+               .wai = 0xd4,
+               .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
+               .sensors_supported = {
+                       [0] = LSM9DS0_GYRO_DEV_NAME,
+               },
+               .ch = (struct iio_chan_spec *)st_gyro_16bit_channels,
+               .odr = {
+                       .addr = 0x20,
+                       .mask = GENMASK(7, 6),
+                       .odr_avl = {
+                               { .hz = 95, .value = 0x00, },
+                               { .hz = 190, .value = 0x01, },
+                               { .hz = 380, .value = 0x02, },
+                               { .hz = 760, .value = 0x03, },
+                       },
+               },
+               .pw = {
+                       .addr = 0x20,
+                       .mask = BIT(3),
+                       .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
+                       .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
+               },
+               .enable_axis = {
+                       .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
+                       .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
+               },
+               .fs = {
+                       .addr = 0x23,
+                       .mask = GENMASK(5, 4),
+                       .fs_avl = {
+                               [0] = {
+                                       .num = ST_GYRO_FS_AVL_245DPS,
+                                       .value = 0x00,
+                                       .gain = IIO_DEGREE_TO_RAD(8750),
+                               },
+                               [1] = {
+                                       .num = ST_GYRO_FS_AVL_500DPS,
+                                       .value = 0x01,
+                                       .gain = IIO_DEGREE_TO_RAD(17500),
+                               },
+                               [2] = {
+                                       .num = ST_GYRO_FS_AVL_2000DPS,
+                                       .value = 0x02,
+                                       .gain = IIO_DEGREE_TO_RAD(70000),
+                               },
+                       },
+               },
+               .bdu = {
+                       .addr = 0x23,
+                       .mask = BIT(7),
+               },
+               .drdy_irq = {
+                       .int2 = {
+                               .addr = 0x22,
+                               .mask = BIT(3),
+                       },
+                       /*
+                        * The sensor has IHL (active low) and open
+                        * drain settings, but only for INT1 and not
+                        * for the DRDY line on INT2.
+                        */
+                       .stat_drdy = {
+                               .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
+                               .mask = GENMASK(2, 0),
+                       },
+               },
+               .sim = {
+                       .addr = 0x23,
+                       .value = BIT(0),
+               },
+               .multi_read_bit = true,
+               .bootime = 2,
+       },
        {
                .wai = 0xd7,
                .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
index 05a1a08..8190966 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/iio/common/st_sensors_i2c.h>
 #include "st_gyro.h"
 
-#ifdef CONFIG_OF
 static const struct of_device_id st_gyro_of_match[] = {
        {
                .compatible = "st,l3g4200d-gyro",
@@ -58,9 +57,6 @@ static const struct of_device_id st_gyro_of_match[] = {
        {},
 };
 MODULE_DEVICE_TABLE(of, st_gyro_of_match);
-#else
-#define st_gyro_of_match NULL
-#endif
 
 static int st_gyro_i2c_probe(struct i2c_client *client,
                             const struct i2c_device_id *id)
@@ -70,8 +66,7 @@ static int st_gyro_i2c_probe(struct i2c_client *client,
        struct iio_dev *indio_dev;
        int err;
 
-       st_sensors_of_name_probe(&client->dev, st_gyro_of_match,
-                                client->name, sizeof(client->name));
+       st_sensors_dev_name_probe(&client->dev, client->name, sizeof(client->name));
 
        settings = st_gyro_get_settings(client->name);
        if (!settings) {
@@ -122,7 +117,7 @@ MODULE_DEVICE_TABLE(i2c, st_gyro_id_table);
 static struct i2c_driver st_gyro_driver = {
        .driver = {
                .name = "st-gyro-i2c",
-               .of_match_table = of_match_ptr(st_gyro_of_match),
+               .of_match_table = st_gyro_of_match,
        },
        .probe = st_gyro_i2c_probe,
        .remove = st_gyro_i2c_remove,
index b5c6242..efb8627 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/iio/common/st_sensors_spi.h>
 #include "st_gyro.h"
 
-#ifdef CONFIG_OF
 /*
  * For new single-chip sensors use <device_name> as compatible string.
  * For old single-chip devices keep <device_name>-gyro to maintain
@@ -63,9 +62,6 @@ static const struct of_device_id st_gyro_of_match[] = {
        {},
 };
 MODULE_DEVICE_TABLE(of, st_gyro_of_match);
-#else
-#define st_gyro_of_match       NULL
-#endif
 
 static int st_gyro_spi_probe(struct spi_device *spi)
 {
@@ -74,8 +70,7 @@ static int st_gyro_spi_probe(struct spi_device *spi)
        struct iio_dev *indio_dev;
        int err;
 
-       st_sensors_of_name_probe(&spi->dev, st_gyro_of_match,
-                                spi->modalias, sizeof(spi->modalias));
+       st_sensors_dev_name_probe(&spi->dev, spi->modalias, sizeof(spi->modalias));
 
        settings = st_gyro_get_settings(spi->modalias);
        if (!settings) {
@@ -126,7 +121,7 @@ MODULE_DEVICE_TABLE(spi, st_gyro_id_table);
 static struct spi_driver st_gyro_driver = {
        .driver = {
                .name = "st-gyro-spi",
-               .of_match_table = of_match_ptr(st_gyro_of_match),
+               .of_match_table = st_gyro_of_match,
        },
        .probe = st_gyro_spi_probe,
        .remove = st_gyro_spi_remove,
index b459600..d05c6fd 100644 (file)
@@ -174,7 +174,6 @@ static irqreturn_t dht11_handle_irq(int irq, void *data)
        struct iio_dev *iio = data;
        struct dht11 *dht11 = iio_priv(iio);
 
-       /* TODO: Consider making the handler safe for IRQ sharing */
        if (dht11->num_edges < DHT11_EDGES_PER_READ && dht11->num_edges >= 0) {
                dht11->edges[dht11->num_edges].ts = ktime_get_boottime_ns();
                dht11->edges[dht11->num_edges++].value =
index 4922444..9003671 100644 (file)
 #define HTS221_REG_CNTRL1_ADDR         0x20
 #define HTS221_REG_CNTRL2_ADDR         0x21
 
-#define HTS221_REG_AVG_ADDR            0x10
-#define HTS221_REG_H_OUT_L             0x28
-#define HTS221_REG_T_OUT_L             0x2a
-
-#define HTS221_HUMIDITY_AVG_MASK       0x07
-#define HTS221_TEMP_AVG_MASK           0x38
-
 #define HTS221_ODR_MASK                        0x03
 #define HTS221_BDU_MASK                        BIT(2)
 #define HTS221_ENABLE_MASK             BIT(7)
@@ -66,8 +59,8 @@ static const struct hts221_odr hts221_odr_table[] = {
 
 static const struct hts221_avg hts221_avg_list[] = {
        {
-               .addr = HTS221_REG_AVG_ADDR,
-               .mask = HTS221_HUMIDITY_AVG_MASK,
+               .addr = 0x10,
+               .mask = 0x07,
                .avg_avl = {
                        4, /* 0.4 %RH */
                        8, /* 0.3 %RH */
@@ -80,8 +73,8 @@ static const struct hts221_avg hts221_avg_list[] = {
                },
        },
        {
-               .addr = HTS221_REG_AVG_ADDR,
-               .mask = HTS221_TEMP_AVG_MASK,
+               .addr = 0x10,
+               .mask = 0x38,
                .avg_avl = {
                        2, /* 0.08 degC */
                        4, /* 0.05 degC */
@@ -98,7 +91,7 @@ static const struct hts221_avg hts221_avg_list[] = {
 static const struct iio_chan_spec hts221_channels[] = {
        {
                .type = IIO_HUMIDITYRELATIVE,
-               .address = HTS221_REG_H_OUT_L,
+               .address = 0x28,
                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
                                      BIT(IIO_CHAN_INFO_OFFSET) |
                                      BIT(IIO_CHAN_INFO_SCALE) |
@@ -114,7 +107,7 @@ static const struct iio_chan_spec hts221_channels[] = {
        },
        {
                .type = IIO_TEMP,
-               .address = HTS221_REG_T_OUT_L,
+               .address = 0x2a,
                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
                                      BIT(IIO_CHAN_INFO_OFFSET) |
                                      BIT(IIO_CHAN_INFO_SCALE) |
index 159ea3f..fd9a5f1 100644 (file)
@@ -42,14 +42,14 @@ struct poll_table_struct;
 
 __poll_t iio_buffer_poll(struct file *filp,
                             struct poll_table_struct *wait);
-ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf,
-                                     size_t n, loff_t *f_ps);
+ssize_t iio_buffer_read_outer(struct file *filp, char __user *buf,
+                             size_t n, loff_t *f_ps);
 
 int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev);
 void iio_buffer_free_sysfs_and_mask(struct iio_dev *indio_dev);
 
 #define iio_buffer_poll_addr (&iio_buffer_poll)
-#define iio_buffer_read_first_n_outer_addr (&iio_buffer_read_first_n_outer)
+#define iio_buffer_read_outer_addr (&iio_buffer_read_outer)
 
 void iio_disable_all_buffers(struct iio_dev *indio_dev);
 void iio_buffer_wakeup_poll(struct iio_dev *indio_dev);
@@ -57,7 +57,7 @@ void iio_buffer_wakeup_poll(struct iio_dev *indio_dev);
 #else
 
 #define iio_buffer_poll_addr NULL
-#define iio_buffer_read_first_n_outer_addr NULL
+#define iio_buffer_read_outer_addr NULL
 
 static inline int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev)
 {
index e14c853..022bb54 100644 (file)
 #define ADIS_MSC_CTRL_DATA_RDY_DIO2    BIT(0)
 #define ADIS_GLOB_CMD_SW_RESET         BIT(7)
 
-int adis_write_reg(struct adis *adis, unsigned int reg,
+/**
+ * __adis_write_reg() - write N bytes to register (unlocked version)
+ * @adis: The adis device
+ * @reg: The address of the lower of the two registers
+ * @value: The value to write to device (up to 4 bytes)
+ * @size: The size of the @value (in bytes)
+ */
+int __adis_write_reg(struct adis *adis, unsigned int reg,
        unsigned int value, unsigned int size)
 {
        unsigned int page = reg / ADIS_PAGE_SIZE;
@@ -38,7 +45,8 @@ int adis_write_reg(struct adis *adis, unsigned int reg,
                        .bits_per_word = 8,
                        .len = 2,
                        .cs_change = 1,
-                       .delay_usecs = adis->data->write_delay,
+                       .delay.value = adis->data->write_delay,
+                       .delay.unit = SPI_DELAY_UNIT_USECS,
                        .cs_change_delay.value = adis->data->cs_change_delay,
                        .cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
                }, {
@@ -46,7 +54,8 @@ int adis_write_reg(struct adis *adis, unsigned int reg,
                        .bits_per_word = 8,
                        .len = 2,
                        .cs_change = 1,
-                       .delay_usecs = adis->data->write_delay,
+                       .delay.value = adis->data->write_delay,
+                       .delay.unit = SPI_DELAY_UNIT_USECS,
                        .cs_change_delay.value = adis->data->cs_change_delay,
                        .cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
                }, {
@@ -54,24 +63,25 @@ int adis_write_reg(struct adis *adis, unsigned int reg,
                        .bits_per_word = 8,
                        .len = 2,
                        .cs_change = 1,
-                       .delay_usecs = adis->data->write_delay,
+                       .delay.value = adis->data->write_delay,
+                       .delay.unit = SPI_DELAY_UNIT_USECS,
                        .cs_change_delay.value = adis->data->cs_change_delay,
                        .cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
                }, {
                        .tx_buf = adis->tx + 6,
                        .bits_per_word = 8,
                        .len = 2,
-                       .delay_usecs = adis->data->write_delay,
+                       .delay.value = adis->data->write_delay,
+                       .delay.unit = SPI_DELAY_UNIT_USECS,
                }, {
                        .tx_buf = adis->tx + 8,
                        .bits_per_word = 8,
                        .len = 2,
-                       .delay_usecs = adis->data->write_delay,
+                       .delay.value = adis->data->write_delay,
+                       .delay.unit = SPI_DELAY_UNIT_USECS,
                },
        };
 
-       mutex_lock(&adis->txrx_lock);
-
        spi_message_init(&msg);
 
        if (adis->current_page != page) {
@@ -96,8 +106,7 @@ int adis_write_reg(struct adis *adis, unsigned int reg,
                adis->tx[3] = value & 0xff;
                break;
        default:
-               ret = -EINVAL;
-               goto out_unlock;
+               return -EINVAL;
        }
 
        xfers[size].cs_change = 0;
@@ -113,20 +122,18 @@ int adis_write_reg(struct adis *adis, unsigned int reg,
                adis->current_page = page;
        }
 
-out_unlock:
-       mutex_unlock(&adis->txrx_lock);
-
        return ret;
 }
-EXPORT_SYMBOL_GPL(adis_write_reg);
+EXPORT_SYMBOL_GPL(__adis_write_reg);
 
 /**
- * adis_read_reg() - read 2 bytes from a 16-bit register
+ * __adis_read_reg() - read N bytes from register (unlocked version)
  * @adis: The adis device
  * @reg: The address of the lower of the two registers
  * @val: The value read back from the device
+ * @size: The size of the @val buffer
  */
-int adis_read_reg(struct adis *adis, unsigned int reg,
+int __adis_read_reg(struct adis *adis, unsigned int reg,
        unsigned int *val, unsigned int size)
 {
        unsigned int page = reg / ADIS_PAGE_SIZE;
@@ -138,7 +145,8 @@ int adis_read_reg(struct adis *adis, unsigned int reg,
                        .bits_per_word = 8,
                        .len = 2,
                        .cs_change = 1,
-                       .delay_usecs = adis->data->write_delay,
+                       .delay.value = adis->data->write_delay,
+                       .delay.unit = SPI_DELAY_UNIT_USECS,
                        .cs_change_delay.value = adis->data->cs_change_delay,
                        .cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
                }, {
@@ -146,7 +154,8 @@ int adis_read_reg(struct adis *adis, unsigned int reg,
                        .bits_per_word = 8,
                        .len = 2,
                        .cs_change = 1,
-                       .delay_usecs = adis->data->read_delay,
+                       .delay.value = adis->data->read_delay,
+                       .delay.unit = SPI_DELAY_UNIT_USECS,
                        .cs_change_delay.value = adis->data->cs_change_delay,
                        .cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
                }, {
@@ -155,18 +164,19 @@ int adis_read_reg(struct adis *adis, unsigned int reg,
                        .bits_per_word = 8,
                        .len = 2,
                        .cs_change = 1,
-                       .delay_usecs = adis->data->read_delay,
+                       .delay.value = adis->data->read_delay,
+                       .delay.unit = SPI_DELAY_UNIT_USECS,
                        .cs_change_delay.value = adis->data->cs_change_delay,
                        .cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
                }, {
                        .rx_buf = adis->rx + 2,
                        .bits_per_word = 8,
                        .len = 2,
-                       .delay_usecs = adis->data->read_delay,
+                       .delay.value = adis->data->read_delay,
+                       .delay.unit = SPI_DELAY_UNIT_USECS,
                },
        };
 
-       mutex_lock(&adis->txrx_lock);
        spi_message_init(&msg);
 
        if (adis->current_page != page) {
@@ -188,15 +198,14 @@ int adis_read_reg(struct adis *adis, unsigned int reg,
                spi_message_add_tail(&xfers[3], &msg);
                break;
        default:
-               ret = -EINVAL;
-               goto out_unlock;
+               return -EINVAL;
        }
 
        ret = spi_sync(adis->spi, &msg);
        if (ret) {
                dev_err(&adis->spi->dev, "Failed to read register 0x%02X: %d\n",
                                reg, ret);
-               goto out_unlock;
+               return ret;
        } else {
                adis->current_page = page;
        }
@@ -210,12 +219,9 @@ int adis_read_reg(struct adis *adis, unsigned int reg,
                break;
        }
 
-out_unlock:
-       mutex_unlock(&adis->txrx_lock);
-
        return ret;
 }
-EXPORT_SYMBOL_GPL(adis_read_reg);
+EXPORT_SYMBOL_GPL(__adis_read_reg);
 
 #ifdef CONFIG_DEBUG_FS
 
@@ -253,12 +259,16 @@ int adis_enable_irq(struct adis *adis, bool enable)
        int ret = 0;
        uint16_t msc;
 
-       if (adis->data->enable_irq)
-               return adis->data->enable_irq(adis, enable);
+       mutex_lock(&adis->state_lock);
+
+       if (adis->data->enable_irq) {
+               ret = adis->data->enable_irq(adis, enable);
+               goto out_unlock;
+       }
 
-       ret = adis_read_reg_16(adis, adis->data->msc_ctrl_reg, &msc);
+       ret = __adis_read_reg_16(adis, adis->data->msc_ctrl_reg, &msc);
        if (ret)
-               goto error_ret;
+               goto out_unlock;
 
        msc |= ADIS_MSC_CTRL_DATA_RDY_POL_HIGH;
        msc &= ~ADIS_MSC_CTRL_DATA_RDY_DIO2;
@@ -267,26 +277,27 @@ int adis_enable_irq(struct adis *adis, bool enable)
        else
                msc &= ~ADIS_MSC_CTRL_DATA_RDY_EN;
 
-       ret = adis_write_reg_16(adis, adis->data->msc_ctrl_reg, msc);
+       ret = __adis_write_reg_16(adis, adis->data->msc_ctrl_reg, msc);
 
-error_ret:
+out_unlock:
+       mutex_unlock(&adis->state_lock);
        return ret;
 }
 EXPORT_SYMBOL(adis_enable_irq);
 
 /**
- * adis_check_status() - Check the device for error conditions
+ * __adis_check_status() - Check the device for error conditions (unlocked)
  * @adis: The adis device
  *
  * Returns 0 on success, a negative error code otherwise
  */
-int adis_check_status(struct adis *adis)
+int __adis_check_status(struct adis *adis)
 {
        uint16_t status;
        int ret;
        int i;
 
-       ret = adis_read_reg_16(adis, adis->data->diag_stat_reg, &status);
+       ret = __adis_read_reg_16(adis, adis->data->diag_stat_reg, &status);
        if (ret)
                return ret;
 
@@ -304,32 +315,38 @@ int adis_check_status(struct adis *adis)
 
        return -EIO;
 }
-EXPORT_SYMBOL_GPL(adis_check_status);
+EXPORT_SYMBOL_GPL(__adis_check_status);
 
 /**
- * adis_reset() - Reset the device
+ * __adis_reset() - Reset the device (unlocked version)
  * @adis: The adis device
  *
  * Returns 0 on success, a negative error code otherwise
  */
-int adis_reset(struct adis *adis)
+int __adis_reset(struct adis *adis)
 {
        int ret;
+       const struct adis_timeout *timeouts = adis->data->timeouts;
 
-       ret = adis_write_reg_8(adis, adis->data->glob_cmd_reg,
+       ret = __adis_write_reg_8(adis, adis->data->glob_cmd_reg,
                        ADIS_GLOB_CMD_SW_RESET);
-       if (ret)
+       if (ret) {
                dev_err(&adis->spi->dev, "Failed to reset device: %d\n", ret);
+               return ret;
+       }
 
-       return ret;
+       msleep(timeouts->sw_reset_ms);
+
+       return 0;
 }
-EXPORT_SYMBOL_GPL(adis_reset);
+EXPORT_SYMBOL_GPL(__adis_reset);
 
 static int adis_self_test(struct adis *adis)
 {
        int ret;
+       const struct adis_timeout *timeouts = adis->data->timeouts;
 
-       ret = adis_write_reg_16(adis, adis->data->msc_ctrl_reg,
+       ret = __adis_write_reg_16(adis, adis->data->msc_ctrl_reg,
                        adis->data->self_test_mask);
        if (ret) {
                dev_err(&adis->spi->dev, "Failed to initiate self test: %d\n",
@@ -337,12 +354,12 @@ static int adis_self_test(struct adis *adis)
                return ret;
        }
 
-       msleep(adis->data->startup_delay);
+       msleep(timeouts->self_test_ms);
 
-       ret = adis_check_status(adis);
+       ret = __adis_check_status(adis);
 
        if (adis->data->self_test_no_autoclear)
-               adis_write_reg_16(adis, adis->data->msc_ctrl_reg, 0x00);
+               __adis_write_reg_16(adis, adis->data->msc_ctrl_reg, 0x00);
 
        return ret;
 }
@@ -360,19 +377,22 @@ int adis_initial_startup(struct adis *adis)
 {
        int ret;
 
+       mutex_lock(&adis->state_lock);
+
        ret = adis_self_test(adis);
        if (ret) {
                dev_err(&adis->spi->dev, "Self-test failed, trying reset.\n");
-               adis_reset(adis);
-               msleep(adis->data->startup_delay);
+               __adis_reset(adis);
                ret = adis_self_test(adis);
                if (ret) {
                        dev_err(&adis->spi->dev, "Second self-test failed, giving up.\n");
-                       return ret;
+                       goto out_unlock;
                }
        }
 
-       return 0;
+out_unlock:
+       mutex_unlock(&adis->state_lock);
+       return ret;
 }
 EXPORT_SYMBOL_GPL(adis_initial_startup);
 
@@ -398,15 +418,15 @@ int adis_single_conversion(struct iio_dev *indio_dev,
        unsigned int uval;
        int ret;
 
-       mutex_lock(&indio_dev->mlock);
+       mutex_lock(&adis->state_lock);
 
-       ret = adis_read_reg(adis, chan->address, &uval,
+       ret = __adis_read_reg(adis, chan->address, &uval,
                        chan->scan_type.storagebits / 8);
        if (ret)
                goto err_unlock;
 
        if (uval & error_mask) {
-               ret = adis_check_status(adis);
+               ret = __adis_check_status(adis);
                if (ret)
                        goto err_unlock;
        }
@@ -418,7 +438,7 @@ int adis_single_conversion(struct iio_dev *indio_dev,
 
        ret = IIO_VAL_INT;
 err_unlock:
-       mutex_unlock(&indio_dev->mlock);
+       mutex_unlock(&adis->state_lock);
        return ret;
 }
 EXPORT_SYMBOL_GPL(adis_single_conversion);
@@ -438,7 +458,12 @@ EXPORT_SYMBOL_GPL(adis_single_conversion);
 int adis_init(struct adis *adis, struct iio_dev *indio_dev,
        struct spi_device *spi, const struct adis_data *data)
 {
-       mutex_init(&adis->txrx_lock);
+       if (!data || !data->timeouts) {
+               dev_err(&spi->dev, "No config data or timeouts not defined!\n");
+               return -EINVAL;
+       }
+
+       mutex_init(&adis->state_lock);
        adis->spi = spi;
        adis->data = data;
        iio_device_set_drvdata(indio_dev, adis);
index 44e46dc..cfb1c19 100644 (file)
@@ -156,12 +156,14 @@ struct adis16400_state;
 
 struct adis16400_chip_info {
        const struct iio_chan_spec *channels;
+       const struct adis_timeout *timeouts;
        const int num_channels;
        const long flags;
        unsigned int gyro_scale_micro;
        unsigned int accel_scale_micro;
        int temp_scale_nano;
        int temp_offset;
+       /* set_freq() & get_freq() need to avoid using ADIS lib's state lock */
        int (*set_freq)(struct adis16400_state *st, unsigned int freq);
        int (*get_freq)(struct adis16400_state *st);
 };
@@ -326,7 +328,7 @@ static int adis16334_get_freq(struct adis16400_state *st)
        int ret;
        uint16_t t;
 
-       ret = adis_read_reg_16(&st->adis, ADIS16400_SMPL_PRD, &t);
+       ret = __adis_read_reg_16(&st->adis, ADIS16400_SMPL_PRD, &t);
        if (ret)
                return ret;
 
@@ -350,7 +352,7 @@ static int adis16334_set_freq(struct adis16400_state *st, unsigned int freq)
        t <<= ADIS16334_RATE_DIV_SHIFT;
        t |= ADIS16334_RATE_INT_CLK;
 
-       return adis_write_reg_16(&st->adis, ADIS16400_SMPL_PRD, t);
+       return __adis_write_reg_16(&st->adis, ADIS16400_SMPL_PRD, t);
 }
 
 static int adis16400_get_freq(struct adis16400_state *st)
@@ -358,7 +360,7 @@ static int adis16400_get_freq(struct adis16400_state *st)
        int sps, ret;
        uint16_t t;
 
-       ret = adis_read_reg_16(&st->adis, ADIS16400_SMPL_PRD, &t);
+       ret = __adis_read_reg_16(&st->adis, ADIS16400_SMPL_PRD, &t);
        if (ret)
                return ret;
 
@@ -390,7 +392,7 @@ static int adis16400_set_freq(struct adis16400_state *st, unsigned int freq)
        else
                st->adis.spi->max_speed_hz = ADIS16400_SPI_FAST;
 
-       return adis_write_reg_8(&st->adis, ADIS16400_SMPL_PRD, val);
+       return __adis_write_reg_8(&st->adis, ADIS16400_SMPL_PRD, val);
 }
 
 static const unsigned int adis16400_3db_divisors[] = {
@@ -404,7 +406,7 @@ static const unsigned int adis16400_3db_divisors[] = {
        [7] = 200, /* Not a valid setting */
 };
 
-static int adis16400_set_filter(struct iio_dev *indio_dev, int sps, int val)
+static int __adis16400_set_filter(struct iio_dev *indio_dev, int sps, int val)
 {
        struct adis16400_state *st = iio_priv(indio_dev);
        uint16_t val16;
@@ -415,11 +417,11 @@ static int adis16400_set_filter(struct iio_dev *indio_dev, int sps, int val)
                        break;
        }
 
-       ret = adis_read_reg_16(&st->adis, ADIS16400_SENS_AVG, &val16);
+       ret = __adis_read_reg_16(&st->adis, ADIS16400_SENS_AVG, &val16);
        if (ret)
                return ret;
 
-       ret = adis_write_reg_16(&st->adis, ADIS16400_SENS_AVG,
+       ret = __adis_write_reg_16(&st->adis, ADIS16400_SENS_AVG,
                                         (val16 & ~0x07) | i);
        return ret;
 }
@@ -507,32 +509,31 @@ static int adis16400_write_raw(struct iio_dev *indio_dev,
        struct iio_chan_spec const *chan, int val, int val2, long info)
 {
        struct adis16400_state *st = iio_priv(indio_dev);
+       struct mutex *slock = &st->adis.state_lock;
        int ret, sps;
 
        switch (info) {
        case IIO_CHAN_INFO_CALIBBIAS:
-               mutex_lock(&indio_dev->mlock);
                ret = adis_write_reg_16(&st->adis,
                                adis16400_addresses[chan->scan_index], val);
-               mutex_unlock(&indio_dev->mlock);
                return ret;
        case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
                /*
                 * Need to cache values so we can update if the frequency
                 * changes.
                 */
-               mutex_lock(&indio_dev->mlock);
+               mutex_lock(slock);
                st->filt_int = val;
                /* Work out update to current value */
                sps = st->variant->get_freq(st);
                if (sps < 0) {
-                       mutex_unlock(&indio_dev->mlock);
+                       mutex_unlock(slock);
                        return sps;
                }
 
-               ret = adis16400_set_filter(indio_dev, sps,
+               ret = __adis16400_set_filter(indio_dev, sps,
                        val * 1000 + val2 / 1000);
-               mutex_unlock(&indio_dev->mlock);
+               mutex_unlock(slock);
                return ret;
        case IIO_CHAN_INFO_SAMP_FREQ:
                sps = val * 1000 + val2 / 1000;
@@ -540,9 +541,9 @@ static int adis16400_write_raw(struct iio_dev *indio_dev,
                if (sps <= 0)
                        return -EINVAL;
 
-               mutex_lock(&indio_dev->mlock);
+               mutex_lock(slock);
                ret = st->variant->set_freq(st, sps);
-               mutex_unlock(&indio_dev->mlock);
+               mutex_unlock(slock);
                return ret;
        default:
                return -EINVAL;
@@ -553,6 +554,7 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
        struct iio_chan_spec const *chan, int *val, int *val2, long info)
 {
        struct adis16400_state *st = iio_priv(indio_dev);
+       struct mutex *slock = &st->adis.state_lock;
        int16_t val16;
        int ret;
 
@@ -596,10 +598,8 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
                        return -EINVAL;
                }
        case IIO_CHAN_INFO_CALIBBIAS:
-               mutex_lock(&indio_dev->mlock);
                ret = adis_read_reg_16(&st->adis,
                                adis16400_addresses[chan->scan_index], &val16);
-               mutex_unlock(&indio_dev->mlock);
                if (ret)
                        return ret;
                val16 = sign_extend32(val16, 11);
@@ -610,27 +610,27 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
                *val = st->variant->temp_offset;
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
-               mutex_lock(&indio_dev->mlock);
+               mutex_lock(slock);
                /* Need both the number of taps and the sampling frequency */
-               ret = adis_read_reg_16(&st->adis,
+               ret = __adis_read_reg_16(&st->adis,
                                                ADIS16400_SENS_AVG,
                                                &val16);
                if (ret) {
-                       mutex_unlock(&indio_dev->mlock);
+                       mutex_unlock(slock);
                        return ret;
                }
                ret = st->variant->get_freq(st);
-               if (ret >= 0) {
-                       ret /= adis16400_3db_divisors[val16 & 0x07];
-                       *val = ret / 1000;
-                       *val2 = (ret % 1000) * 1000;
-               }
-               mutex_unlock(&indio_dev->mlock);
+               mutex_unlock(slock);
                if (ret)
                        return ret;
+               ret /= adis16400_3db_divisors[val16 & 0x07];
+               *val = ret / 1000;
+               *val2 = (ret % 1000) * 1000;
                return IIO_VAL_INT_PLUS_MICRO;
        case IIO_CHAN_INFO_SAMP_FREQ:
+               mutex_lock(slock);
                ret = st->variant->get_freq(st);
+               mutex_unlock(slock);
                if (ret)
                        return ret;
                *val = ret / 1000;
@@ -930,6 +930,36 @@ static const struct iio_chan_spec adis16334_channels[] = {
        IIO_CHAN_SOFT_TIMESTAMP(ADIS16400_SCAN_TIMESTAMP),
 };
 
+static const struct adis_timeout adis16300_timeouts = {
+       .reset_ms = ADIS16400_STARTUP_DELAY,
+       .sw_reset_ms = ADIS16400_STARTUP_DELAY,
+       .self_test_ms = ADIS16400_STARTUP_DELAY,
+};
+
+static const struct adis_timeout adis16362_timeouts = {
+       .reset_ms = 130,
+       .sw_reset_ms = 130,
+       .self_test_ms = 12,
+};
+
+static const struct adis_timeout adis16400_timeouts = {
+       .reset_ms = 170,
+       .sw_reset_ms = 170,
+       .self_test_ms = 12,
+};
+
+static const struct adis_timeout adis16445_timeouts = {
+       .reset_ms = 55,
+       .sw_reset_ms = 55,
+       .self_test_ms = 16,
+};
+
+static const struct adis_timeout adis16448_timeouts = {
+       .reset_ms = 90,
+       .sw_reset_ms = 90,
+       .self_test_ms = 45,
+};
+
 static struct adis16400_chip_info adis16400_chips[] = {
        [ADIS16300] = {
                .channels = adis16300_channels,
@@ -942,6 +972,7 @@ static struct adis16400_chip_info adis16400_chips[] = {
                .temp_offset = 25000000 / 140000, /* 25 C = 0x00 */
                .set_freq = adis16400_set_freq,
                .get_freq = adis16400_get_freq,
+               .timeouts = &adis16300_timeouts,
        },
        [ADIS16334] = {
                .channels = adis16334_channels,
@@ -965,6 +996,7 @@ static struct adis16400_chip_info adis16400_chips[] = {
                .flags = ADIS16400_NO_BURST | ADIS16400_HAS_SLOW_MODE,
                .set_freq = adis16400_set_freq,
                .get_freq = adis16400_get_freq,
+               .timeouts = &adis16300_timeouts,
        },
        [ADIS16360] = {
                .channels = adis16350_channels,
@@ -977,6 +1009,7 @@ static struct adis16400_chip_info adis16400_chips[] = {
                .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */
                .set_freq = adis16400_set_freq,
                .get_freq = adis16400_get_freq,
+               .timeouts = &adis16300_timeouts,
        },
        [ADIS16362] = {
                .channels = adis16350_channels,
@@ -989,6 +1022,7 @@ static struct adis16400_chip_info adis16400_chips[] = {
                .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */
                .set_freq = adis16400_set_freq,
                .get_freq = adis16400_get_freq,
+               .timeouts = &adis16362_timeouts,
        },
        [ADIS16364] = {
                .channels = adis16350_channels,
@@ -1001,6 +1035,7 @@ static struct adis16400_chip_info adis16400_chips[] = {
                .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */
                .set_freq = adis16400_set_freq,
                .get_freq = adis16400_get_freq,
+               .timeouts = &adis16362_timeouts,
        },
        [ADIS16367] = {
                .channels = adis16350_channels,
@@ -1013,6 +1048,7 @@ static struct adis16400_chip_info adis16400_chips[] = {
                .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */
                .set_freq = adis16400_set_freq,
                .get_freq = adis16400_get_freq,
+               .timeouts = &adis16300_timeouts,
        },
        [ADIS16400] = {
                .channels = adis16400_channels,
@@ -1024,6 +1060,7 @@ static struct adis16400_chip_info adis16400_chips[] = {
                .temp_offset = 25000000 / 140000, /* 25 C = 0x00 */
                .set_freq = adis16400_set_freq,
                .get_freq = adis16400_get_freq,
+               .timeouts = &adis16400_timeouts,
        },
        [ADIS16445] = {
                .channels = adis16445_channels,
@@ -1037,6 +1074,7 @@ static struct adis16400_chip_info adis16400_chips[] = {
                .temp_offset = 31000000 / 73860, /* 31 C = 0x00 */
                .set_freq = adis16334_set_freq,
                .get_freq = adis16334_get_freq,
+               .timeouts = &adis16445_timeouts,
        },
        [ADIS16448] = {
                .channels = adis16448_channels,
@@ -1050,6 +1088,7 @@ static struct adis16400_chip_info adis16400_chips[] = {
                .temp_offset = 31000000 / 73860, /* 31 C = 0x00 */
                .set_freq = adis16334_set_freq,
                .get_freq = adis16334_get_freq,
+               .timeouts = &adis16448_timeouts,
        }
 };
 
@@ -1087,7 +1126,6 @@ static const struct adis_data adis16400_data = {
        .write_delay = 50,
 
        .self_test_mask = ADIS16400_MSC_CTRL_MEM_TEST,
-       .startup_delay = ADIS16400_STARTUP_DELAY,
 
        .status_error_msgs = adis16400_status_error_msgs,
        .status_error_mask = BIT(ADIS16400_DIAG_STAT_ZACCL_FAIL) |
@@ -1121,11 +1159,28 @@ static void adis16400_setup_chan_mask(struct adis16400_state *st)
        }
 }
 
+static struct adis_data *adis16400_adis_data_alloc(struct adis16400_state *st,
+                                                  struct device *dev)
+{
+       struct adis_data *data;
+
+       data = devm_kmalloc(dev, sizeof(struct adis_data), GFP_KERNEL);
+       if (!data)
+               return ERR_PTR(-ENOMEM);
+
+       memcpy(data, &adis16400_data, sizeof(*data));
+
+       data->timeouts = st->variant->timeouts;
+
+       return data;
+}
+
 static int adis16400_probe(struct spi_device *spi)
 {
        struct adis16400_state *st;
        struct iio_dev *indio_dev;
        int ret;
+       const struct adis_data *adis16400_data;
 
        indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
        if (indio_dev == NULL)
@@ -1152,7 +1207,11 @@ static int adis16400_probe(struct spi_device *spi)
                        st->adis.burst->extra_len = sizeof(u16);
        }
 
-       ret = adis_init(&st->adis, indio_dev, spi, &adis16400_data);
+       adis16400_data = adis16400_adis_data_alloc(st, &spi->dev);
+       if (IS_ERR(adis16400_data))
+               return PTR_ERR(adis16400_data);
+
+       ret = adis_init(&st->adis, indio_dev, spi, adis16400_data);
        if (ret)
                return ret;
 
index b558125..9539cfe 100644 (file)
@@ -383,6 +383,12 @@ static const char * const adis16460_status_error_msgs[] = {
        [ADIS16460_DIAG_STAT_FLASH_UPT] = "Flash update failure",
 };
 
+static const struct adis_timeout adis16460_timeouts = {
+       .reset_ms = 225,
+       .sw_reset_ms = 225,
+       .self_test_ms = 10,
+};
+
 static const struct adis_data adis16460_data = {
        .diag_stat_reg = ADIS16460_REG_DIAG_STAT,
        .glob_cmd_reg = ADIS16460_REG_GLOB_CMD,
@@ -398,6 +404,7 @@ static const struct adis_data adis16460_data = {
                BIT(ADIS16460_DIAG_STAT_SPI_COMM) |
                BIT(ADIS16460_DIAG_STAT_FLASH_UPT),
        .enable_irq = adis16460_enable_irq,
+       .timeouts = &adis16460_timeouts,
 };
 
 static int adis16460_probe(struct spi_device *spi)
index 748f8bb..dac87f1 100644 (file)
@@ -138,6 +138,7 @@ struct adis16480_chip_info {
        unsigned int max_dec_rate;
        const unsigned int *filter_freqs;
        bool has_pps_clk_mode;
+       const struct adis_timeout *timeouts;
 };
 
 enum adis16480_int_pin {
@@ -555,6 +556,7 @@ static int adis16480_set_filter_freq(struct iio_dev *indio_dev,
        const struct iio_chan_spec *chan, unsigned int freq)
 {
        struct adis16480 *st = iio_priv(indio_dev);
+       struct mutex *slock = &st->adis.state_lock;
        unsigned int enable_mask, offset, reg;
        unsigned int diff, best_diff;
        unsigned int i, best_freq;
@@ -565,9 +567,11 @@ static int adis16480_set_filter_freq(struct iio_dev *indio_dev,
        offset = ad16480_filter_data[chan->scan_index][1];
        enable_mask = BIT(offset + 2);
 
-       ret = adis_read_reg_16(&st->adis, reg, &val);
+       mutex_lock(slock);
+
+       ret = __adis_read_reg_16(&st->adis, reg, &val);
        if (ret)
-               return ret;
+               goto out_unlock;
 
        if (freq == 0) {
                val &= ~enable_mask;
@@ -589,7 +593,11 @@ static int adis16480_set_filter_freq(struct iio_dev *indio_dev,
                val |= enable_mask;
        }
 
-       return adis_write_reg_16(&st->adis, reg, val);
+       ret = __adis_write_reg_16(&st->adis, reg, val);
+out_unlock:
+       mutex_unlock(slock);
+
+       return ret;
 }
 
 static int adis16480_read_raw(struct iio_dev *indio_dev,
@@ -779,6 +787,7 @@ enum adis16480_variant {
        ADIS16480,
        ADIS16485,
        ADIS16488,
+       ADIS16490,
        ADIS16495_1,
        ADIS16495_2,
        ADIS16495_3,
@@ -787,6 +796,30 @@ enum adis16480_variant {
        ADIS16497_3,
 };
 
+static const struct adis_timeout adis16485_timeouts = {
+       .reset_ms = 560,
+       .sw_reset_ms = 120,
+       .self_test_ms = 12,
+};
+
+static const struct adis_timeout adis16480_timeouts = {
+       .reset_ms = 560,
+       .sw_reset_ms = 560,
+       .self_test_ms = 12,
+};
+
+static const struct adis_timeout adis16495_timeouts = {
+       .reset_ms = 170,
+       .sw_reset_ms = 130,
+       .self_test_ms = 40,
+};
+
+static const struct adis_timeout adis16495_1_timeouts = {
+       .reset_ms = 250,
+       .sw_reset_ms = 210,
+       .self_test_ms = 20,
+};
+
 static const struct adis16480_chip_info adis16480_chip_info[] = {
        [ADIS16375] = {
                .channels = adis16485_channels,
@@ -805,6 +838,7 @@ static const struct adis16480_chip_info adis16480_chip_info[] = {
                .int_clk = 2460000,
                .max_dec_rate = 2048,
                .filter_freqs = adis16480_def_filter_freqs,
+               .timeouts = &adis16485_timeouts,
        },
        [ADIS16480] = {
                .channels = adis16480_channels,
@@ -817,6 +851,7 @@ static const struct adis16480_chip_info adis16480_chip_info[] = {
                .int_clk = 2460000,
                .max_dec_rate = 2048,
                .filter_freqs = adis16480_def_filter_freqs,
+               .timeouts = &adis16480_timeouts,
        },
        [ADIS16485] = {
                .channels = adis16485_channels,
@@ -829,6 +864,7 @@ static const struct adis16480_chip_info adis16480_chip_info[] = {
                .int_clk = 2460000,
                .max_dec_rate = 2048,
                .filter_freqs = adis16480_def_filter_freqs,
+               .timeouts = &adis16485_timeouts,
        },
        [ADIS16488] = {
                .channels = adis16480_channels,
@@ -841,6 +877,21 @@ static const struct adis16480_chip_info adis16480_chip_info[] = {
                .int_clk = 2460000,
                .max_dec_rate = 2048,
                .filter_freqs = adis16480_def_filter_freqs,
+               .timeouts = &adis16485_timeouts,
+       },
+       [ADIS16490] = {
+               .channels = adis16485_channels,
+               .num_channels = ARRAY_SIZE(adis16485_channels),
+               .gyro_max_val = 20000 << 16,
+               .gyro_max_scale = IIO_DEGREE_TO_RAD(100),
+               .accel_max_val = IIO_M_S_2_TO_G(16000 << 16),
+               .accel_max_scale = 8,
+               .temp_scale = 14285, /* 14.285 milli degree Celsius */
+               .int_clk = 4250000,
+               .max_dec_rate = 4250,
+               .filter_freqs = adis16495_def_filter_freqs,
+               .has_pps_clk_mode = true,
+               .timeouts = &adis16495_timeouts,
        },
        [ADIS16495_1] = {
                .channels = adis16485_channels,
@@ -854,6 +905,7 @@ static const struct adis16480_chip_info adis16480_chip_info[] = {
                .max_dec_rate = 4250,
                .filter_freqs = adis16495_def_filter_freqs,
                .has_pps_clk_mode = true,
+               .timeouts = &adis16495_1_timeouts,
        },
        [ADIS16495_2] = {
                .channels = adis16485_channels,
@@ -867,6 +919,7 @@ static const struct adis16480_chip_info adis16480_chip_info[] = {
                .max_dec_rate = 4250,
                .filter_freqs = adis16495_def_filter_freqs,
                .has_pps_clk_mode = true,
+               .timeouts = &adis16495_1_timeouts,
        },
        [ADIS16495_3] = {
                .channels = adis16485_channels,
@@ -880,6 +933,7 @@ static const struct adis16480_chip_info adis16480_chip_info[] = {
                .max_dec_rate = 4250,
                .filter_freqs = adis16495_def_filter_freqs,
                .has_pps_clk_mode = true,
+               .timeouts = &adis16495_1_timeouts,
        },
        [ADIS16497_1] = {
                .channels = adis16485_channels,
@@ -893,6 +947,7 @@ static const struct adis16480_chip_info adis16480_chip_info[] = {
                .max_dec_rate = 4250,
                .filter_freqs = adis16495_def_filter_freqs,
                .has_pps_clk_mode = true,
+               .timeouts = &adis16495_1_timeouts,
        },
        [ADIS16497_2] = {
                .channels = adis16485_channels,
@@ -906,6 +961,7 @@ static const struct adis16480_chip_info adis16480_chip_info[] = {
                .max_dec_rate = 4250,
                .filter_freqs = adis16495_def_filter_freqs,
                .has_pps_clk_mode = true,
+               .timeouts = &adis16495_1_timeouts,
        },
        [ADIS16497_3] = {
                .channels = adis16485_channels,
@@ -919,6 +975,7 @@ static const struct adis16480_chip_info adis16480_chip_info[] = {
                .max_dec_rate = 4250,
                .filter_freqs = adis16495_def_filter_freqs,
                .has_pps_clk_mode = true,
+               .timeouts = &adis16495_1_timeouts,
        },
 };
 
@@ -947,14 +1004,14 @@ static int adis16480_enable_irq(struct adis *adis, bool enable)
        uint16_t val;
        int ret;
 
-       ret = adis_read_reg_16(adis, ADIS16480_REG_FNCTIO_CTRL, &val);
+       ret = __adis_read_reg_16(adis, ADIS16480_REG_FNCTIO_CTRL, &val);
        if (ret)
                return ret;
 
        val &= ~ADIS16480_DRDY_EN_MSK;
        val |= ADIS16480_DRDY_EN(enable);
 
-       return adis_write_reg_16(adis, ADIS16480_REG_FNCTIO_CTRL, val);
+       return __adis_write_reg_16(adis, ADIS16480_REG_FNCTIO_CTRL, val);
 }
 
 static int adis16480_initial_setup(struct iio_dev *indio_dev)
@@ -1188,9 +1245,26 @@ static int adis16480_get_ext_clocks(struct adis16480 *st)
        return 0;
 }
 
+static struct adis_data *adis16480_adis_data_alloc(struct adis16480 *st,
+                                                  struct device *dev)
+{
+       struct adis_data *data;
+
+       data = devm_kmalloc(dev, sizeof(struct adis_data), GFP_KERNEL);
+       if (!data)
+               return ERR_PTR(-ENOMEM);
+
+       memcpy(data, &adis16480_data, sizeof(*data));
+
+       data->timeouts = st->chip_info->timeouts;
+
+       return data;
+}
+
 static int adis16480_probe(struct spi_device *spi)
 {
        const struct spi_device_id *id = spi_get_device_id(spi);
+       const struct adis_data *adis16480_data;
        struct iio_dev *indio_dev;
        struct adis16480 *st;
        int ret;
@@ -1211,7 +1285,11 @@ static int adis16480_probe(struct spi_device *spi)
        indio_dev->info = &adis16480_info;
        indio_dev->modes = INDIO_DIRECT_MODE;
 
-       ret = adis_init(&st->adis, indio_dev, spi, &adis16480_data);
+       adis16480_data = adis16480_adis_data_alloc(st, &spi->dev);
+       if (IS_ERR(adis16480_data))
+               return PTR_ERR(adis16480_data);
+
+       ret = adis_init(&st->adis, indio_dev, spi, adis16480_data);
        if (ret)
                return ret;
 
@@ -1278,6 +1356,7 @@ static const struct spi_device_id adis16480_ids[] = {
        { "adis16480", ADIS16480 },
        { "adis16485", ADIS16485 },
        { "adis16488", ADIS16488 },
+       { "adis16490", ADIS16490 },
        { "adis16495-1", ADIS16495_1 },
        { "adis16495-2", ADIS16495_2 },
        { "adis16495-3", ADIS16495_3 },
@@ -1293,6 +1372,7 @@ static const struct of_device_id adis16480_of_match[] = {
        { .compatible = "adi,adis16480" },
        { .compatible = "adi,adis16485" },
        { .compatible = "adi,adis16488" },
+       { .compatible = "adi,adis16490" },
        { .compatible = "adi,adis16495-1" },
        { .compatible = "adi,adis16495-2" },
        { .compatible = "adi,adis16495-3" },
index 4998a89..3f4dd5c 100644 (file)
@@ -129,7 +129,7 @@ static irqreturn_t adis_trigger_handler(int irq, void *p)
                return -ENOMEM;
 
        if (adis->data->has_paging) {
-               mutex_lock(&adis->txrx_lock);
+               mutex_lock(&adis->state_lock);
                if (adis->current_page != 0) {
                        adis->tx[0] = ADIS_WRITE_REG(ADIS_REG_PAGE_ID);
                        adis->tx[1] = 0;
@@ -144,7 +144,7 @@ static irqreturn_t adis_trigger_handler(int irq, void *p)
 
        if (adis->data->has_paging) {
                adis->current_page = 0;
-               mutex_unlock(&adis->txrx_lock);
+               mutex_unlock(&adis->state_lock);
        }
 
        iio_push_to_buffers_with_timestamp(indio_dev, adis->buffer,
index e4c4c12..017bc0f 100644 (file)
@@ -10,11 +10,12 @@ config INV_MPU6050_IIO
 
 config INV_MPU6050_I2C
        tristate "Invensense MPU6050 devices (I2C)"
-       depends on I2C_MUX
+       depends on I2C
+       select I2C_MUX
        select INV_MPU6050_IIO
        select REGMAP_I2C
        help
-         This driver supports the Invensense MPU6000/6050/6500/6515,
+         This driver supports the Invensense MPU6050/6500/6515,
          MPU9150/9250/9255 and ICM20608/20602 motion tracking devices
          over I2C.
          This driver can be built as a module. The module will be called
@@ -26,8 +27,8 @@ config INV_MPU6050_SPI
        select INV_MPU6050_IIO
        select REGMAP_SPI
        help
-         This driver supports the Invensense MPU6000/6050/6500/6515,
-         MPU9150/9250/9255 and ICM20608/20602 motion tracking devices
+         This driver supports the Invensense MPU6000/6500/6515,
+         MPU9250/9255 and ICM20608/20602 motion tracking devices
          over SPI.
          This driver can be built as a module. The module will be called
          inv-mpu6050-spi.
index 0686e41..5096fc4 100644 (file)
@@ -104,6 +104,7 @@ static const struct inv_mpu6050_chip_config chip_config_6050 = {
        .divider = INV_MPU6050_FIFO_RATE_TO_DIVIDER(INV_MPU6050_INIT_FIFO_RATE),
        .gyro_fifo_enable = false,
        .accl_fifo_enable = false,
+       .temp_fifo_enable = false,
        .magn_fifo_enable = false,
        .accl_fs = INV_MPU6050_FS_02G,
        .user_ctrl = 0,
@@ -856,19 +857,27 @@ static const struct iio_chan_spec_ext_info inv_ext_info[] = {
                .ext_info = inv_ext_info,                             \
        }
 
+#define INV_MPU6050_TEMP_CHAN(_index)                          \
+       {                                                       \
+               .type = IIO_TEMP,                               \
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW)    \
+                               | BIT(IIO_CHAN_INFO_OFFSET)     \
+                               | BIT(IIO_CHAN_INFO_SCALE),     \
+               .scan_index = _index,                           \
+               .scan_type = {                                  \
+                       .sign = 's',                            \
+                       .realbits = 16,                         \
+                       .storagebits = 16,                      \
+                       .shift = 0,                             \
+                       .endianness = IIO_BE,                   \
+               },                                              \
+       }
+
 static const struct iio_chan_spec inv_mpu_channels[] = {
        IIO_CHAN_SOFT_TIMESTAMP(INV_MPU6050_SCAN_TIMESTAMP),
-       /*
-        * Note that temperature should only be via polled reading only,
-        * not the final scan elements output.
-        */
-       {
-               .type = IIO_TEMP,
-               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW)
-                               | BIT(IIO_CHAN_INFO_OFFSET)
-                               | BIT(IIO_CHAN_INFO_SCALE),
-               .scan_index = -1,
-       },
+
+       INV_MPU6050_TEMP_CHAN(INV_MPU6050_SCAN_TEMP),
+
        INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_X, INV_MPU6050_SCAN_GYRO_X),
        INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Y, INV_MPU6050_SCAN_GYRO_Y),
        INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Z, INV_MPU6050_SCAN_GYRO_Z),
@@ -878,22 +887,29 @@ static const struct iio_chan_spec inv_mpu_channels[] = {
        INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Z, INV_MPU6050_SCAN_ACCL_Z),
 };
 
+#define INV_MPU6050_SCAN_MASK_3AXIS_ACCEL      \
+       (BIT(INV_MPU6050_SCAN_ACCL_X)           \
+       | BIT(INV_MPU6050_SCAN_ACCL_Y)          \
+       | BIT(INV_MPU6050_SCAN_ACCL_Z))
+
+#define INV_MPU6050_SCAN_MASK_3AXIS_GYRO       \
+       (BIT(INV_MPU6050_SCAN_GYRO_X)           \
+       | BIT(INV_MPU6050_SCAN_GYRO_Y)          \
+       | BIT(INV_MPU6050_SCAN_GYRO_Z))
+
+#define INV_MPU6050_SCAN_MASK_TEMP             (BIT(INV_MPU6050_SCAN_TEMP))
+
 static const unsigned long inv_mpu_scan_masks[] = {
        /* 3-axis accel */
-       BIT(INV_MPU6050_SCAN_ACCL_X)
-               | BIT(INV_MPU6050_SCAN_ACCL_Y)
-               | BIT(INV_MPU6050_SCAN_ACCL_Z),
+       INV_MPU6050_SCAN_MASK_3AXIS_ACCEL,
+       INV_MPU6050_SCAN_MASK_3AXIS_ACCEL | INV_MPU6050_SCAN_MASK_TEMP,
        /* 3-axis gyro */
-       BIT(INV_MPU6050_SCAN_GYRO_X)
-               | BIT(INV_MPU6050_SCAN_GYRO_Y)
-               | BIT(INV_MPU6050_SCAN_GYRO_Z),
+       INV_MPU6050_SCAN_MASK_3AXIS_GYRO,
+       INV_MPU6050_SCAN_MASK_3AXIS_GYRO | INV_MPU6050_SCAN_MASK_TEMP,
        /* 6-axis accel + gyro */
-       BIT(INV_MPU6050_SCAN_ACCL_X)
-               | BIT(INV_MPU6050_SCAN_ACCL_Y)
-               | BIT(INV_MPU6050_SCAN_ACCL_Z)
-               | BIT(INV_MPU6050_SCAN_GYRO_X)
-               | BIT(INV_MPU6050_SCAN_GYRO_Y)
-               | BIT(INV_MPU6050_SCAN_GYRO_Z),
+       INV_MPU6050_SCAN_MASK_3AXIS_ACCEL | INV_MPU6050_SCAN_MASK_3AXIS_GYRO,
+       INV_MPU6050_SCAN_MASK_3AXIS_ACCEL | INV_MPU6050_SCAN_MASK_3AXIS_GYRO
+               | INV_MPU6050_SCAN_MASK_TEMP,
        0,
 };
 
@@ -915,19 +931,30 @@ static const unsigned long inv_mpu_scan_masks[] = {
                .ext_info = inv_ext_info,                               \
        }
 
+static const struct iio_chan_spec inv_mpu9150_channels[] = {
+       IIO_CHAN_SOFT_TIMESTAMP(INV_MPU9X50_SCAN_TIMESTAMP),
+
+       INV_MPU6050_TEMP_CHAN(INV_MPU6050_SCAN_TEMP),
+
+       INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_X, INV_MPU6050_SCAN_GYRO_X),
+       INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Y, INV_MPU6050_SCAN_GYRO_Y),
+       INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Z, INV_MPU6050_SCAN_GYRO_Z),
+
+       INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_X, INV_MPU6050_SCAN_ACCL_X),
+       INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Y, INV_MPU6050_SCAN_ACCL_Y),
+       INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Z, INV_MPU6050_SCAN_ACCL_Z),
+
+       /* Magnetometer resolution is 13 bits */
+       INV_MPU9X50_MAGN_CHAN(IIO_MOD_X, 13, INV_MPU9X50_SCAN_MAGN_X),
+       INV_MPU9X50_MAGN_CHAN(IIO_MOD_Y, 13, INV_MPU9X50_SCAN_MAGN_Y),
+       INV_MPU9X50_MAGN_CHAN(IIO_MOD_Z, 13, INV_MPU9X50_SCAN_MAGN_Z),
+};
+
 static const struct iio_chan_spec inv_mpu9250_channels[] = {
        IIO_CHAN_SOFT_TIMESTAMP(INV_MPU9X50_SCAN_TIMESTAMP),
-       /*
-        * Note that temperature should only be via polled reading only,
-        * not the final scan elements output.
-        */
-       {
-               .type = IIO_TEMP,
-               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW)
-                               | BIT(IIO_CHAN_INFO_OFFSET)
-                               | BIT(IIO_CHAN_INFO_SCALE),
-               .scan_index = -1,
-       },
+
+       INV_MPU6050_TEMP_CHAN(INV_MPU6050_SCAN_TEMP),
+
        INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_X, INV_MPU6050_SCAN_GYRO_X),
        INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Y, INV_MPU6050_SCAN_GYRO_Y),
        INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Z, INV_MPU6050_SCAN_GYRO_Z),
@@ -942,98 +969,50 @@ static const struct iio_chan_spec inv_mpu9250_channels[] = {
        INV_MPU9X50_MAGN_CHAN(IIO_MOD_Z, 16, INV_MPU9X50_SCAN_MAGN_Z),
 };
 
+#define INV_MPU9X50_SCAN_MASK_3AXIS_MAGN       \
+       (BIT(INV_MPU9X50_SCAN_MAGN_X)           \
+       | BIT(INV_MPU9X50_SCAN_MAGN_Y)          \
+       | BIT(INV_MPU9X50_SCAN_MAGN_Z))
+
 static const unsigned long inv_mpu9x50_scan_masks[] = {
        /* 3-axis accel */
-       BIT(INV_MPU6050_SCAN_ACCL_X)
-               | BIT(INV_MPU6050_SCAN_ACCL_Y)
-               | BIT(INV_MPU6050_SCAN_ACCL_Z),
+       INV_MPU6050_SCAN_MASK_3AXIS_ACCEL,
+       INV_MPU6050_SCAN_MASK_3AXIS_ACCEL | INV_MPU6050_SCAN_MASK_TEMP,
        /* 3-axis gyro */
-       BIT(INV_MPU6050_SCAN_GYRO_X)
-               | BIT(INV_MPU6050_SCAN_GYRO_Y)
-               | BIT(INV_MPU6050_SCAN_GYRO_Z),
+       INV_MPU6050_SCAN_MASK_3AXIS_GYRO,
+       INV_MPU6050_SCAN_MASK_3AXIS_GYRO | INV_MPU6050_SCAN_MASK_TEMP,
        /* 3-axis magn */
-       BIT(INV_MPU9X50_SCAN_MAGN_X)
-               | BIT(INV_MPU9X50_SCAN_MAGN_Y)
-               | BIT(INV_MPU9X50_SCAN_MAGN_Z),
+       INV_MPU9X50_SCAN_MASK_3AXIS_MAGN,
+       INV_MPU9X50_SCAN_MASK_3AXIS_MAGN | INV_MPU6050_SCAN_MASK_TEMP,
        /* 6-axis accel + gyro */
-       BIT(INV_MPU6050_SCAN_ACCL_X)
-               | BIT(INV_MPU6050_SCAN_ACCL_Y)
-               | BIT(INV_MPU6050_SCAN_ACCL_Z)
-               | BIT(INV_MPU6050_SCAN_GYRO_X)
-               | BIT(INV_MPU6050_SCAN_GYRO_Y)
-               | BIT(INV_MPU6050_SCAN_GYRO_Z),
+       INV_MPU6050_SCAN_MASK_3AXIS_ACCEL | INV_MPU6050_SCAN_MASK_3AXIS_GYRO,
+       INV_MPU6050_SCAN_MASK_3AXIS_ACCEL | INV_MPU6050_SCAN_MASK_3AXIS_GYRO
+               | INV_MPU6050_SCAN_MASK_TEMP,
        /* 6-axis accel + magn */
-       BIT(INV_MPU6050_SCAN_ACCL_X)
-               | BIT(INV_MPU6050_SCAN_ACCL_Y)
-               | BIT(INV_MPU6050_SCAN_ACCL_Z)
-               | BIT(INV_MPU9X50_SCAN_MAGN_X)
-               | BIT(INV_MPU9X50_SCAN_MAGN_Y)
-               | BIT(INV_MPU9X50_SCAN_MAGN_Z),
+       INV_MPU6050_SCAN_MASK_3AXIS_ACCEL | INV_MPU9X50_SCAN_MASK_3AXIS_MAGN,
+       INV_MPU6050_SCAN_MASK_3AXIS_ACCEL | INV_MPU9X50_SCAN_MASK_3AXIS_MAGN
+               | INV_MPU6050_SCAN_MASK_TEMP,
        /* 6-axis gyro + magn */
-       BIT(INV_MPU6050_SCAN_GYRO_X)
-               | BIT(INV_MPU6050_SCAN_GYRO_Y)
-               | BIT(INV_MPU6050_SCAN_GYRO_Z)
-               | BIT(INV_MPU9X50_SCAN_MAGN_X)
-               | BIT(INV_MPU9X50_SCAN_MAGN_Y)
-               | BIT(INV_MPU9X50_SCAN_MAGN_Z),
+       INV_MPU6050_SCAN_MASK_3AXIS_GYRO | INV_MPU9X50_SCAN_MASK_3AXIS_MAGN,
+       INV_MPU6050_SCAN_MASK_3AXIS_GYRO | INV_MPU9X50_SCAN_MASK_3AXIS_MAGN
+               | INV_MPU6050_SCAN_MASK_TEMP,
        /* 9-axis accel + gyro + magn */
-       BIT(INV_MPU6050_SCAN_ACCL_X)
-               | BIT(INV_MPU6050_SCAN_ACCL_Y)
-               | BIT(INV_MPU6050_SCAN_ACCL_Z)
-               | BIT(INV_MPU6050_SCAN_GYRO_X)
-               | BIT(INV_MPU6050_SCAN_GYRO_Y)
-               | BIT(INV_MPU6050_SCAN_GYRO_Z)
-               | BIT(INV_MPU9X50_SCAN_MAGN_X)
-               | BIT(INV_MPU9X50_SCAN_MAGN_Y)
-               | BIT(INV_MPU9X50_SCAN_MAGN_Z),
+       INV_MPU6050_SCAN_MASK_3AXIS_ACCEL | INV_MPU6050_SCAN_MASK_3AXIS_GYRO
+               | INV_MPU9X50_SCAN_MASK_3AXIS_MAGN,
+       INV_MPU6050_SCAN_MASK_3AXIS_ACCEL | INV_MPU6050_SCAN_MASK_3AXIS_GYRO
+               | INV_MPU9X50_SCAN_MASK_3AXIS_MAGN
+               | INV_MPU6050_SCAN_MASK_TEMP,
        0,
 };
 
-static const struct iio_chan_spec inv_icm20602_channels[] = {
-       IIO_CHAN_SOFT_TIMESTAMP(INV_ICM20602_SCAN_TIMESTAMP),
-       {
-               .type = IIO_TEMP,
-               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW)
-                               | BIT(IIO_CHAN_INFO_OFFSET)
-                               | BIT(IIO_CHAN_INFO_SCALE),
-               .scan_index = INV_ICM20602_SCAN_TEMP,
-               .scan_type = {
-                               .sign = 's',
-                               .realbits = 16,
-                               .storagebits = 16,
-                               .shift = 0,
-                               .endianness = IIO_BE,
-                            },
-       },
-
-       INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_X, INV_ICM20602_SCAN_GYRO_X),
-       INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Y, INV_ICM20602_SCAN_GYRO_Y),
-       INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Z, INV_ICM20602_SCAN_GYRO_Z),
-
-       INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Y, INV_ICM20602_SCAN_ACCL_Y),
-       INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_X, INV_ICM20602_SCAN_ACCL_X),
-       INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Z, INV_ICM20602_SCAN_ACCL_Z),
-};
-
 static const unsigned long inv_icm20602_scan_masks[] = {
        /* 3-axis accel + temp (mandatory) */
-       BIT(INV_ICM20602_SCAN_ACCL_X)
-               | BIT(INV_ICM20602_SCAN_ACCL_Y)
-               | BIT(INV_ICM20602_SCAN_ACCL_Z)
-               | BIT(INV_ICM20602_SCAN_TEMP),
+       INV_MPU6050_SCAN_MASK_3AXIS_ACCEL | INV_MPU6050_SCAN_MASK_TEMP,
        /* 3-axis gyro + temp (mandatory) */
-       BIT(INV_ICM20602_SCAN_GYRO_X)
-               | BIT(INV_ICM20602_SCAN_GYRO_Y)
-               | BIT(INV_ICM20602_SCAN_GYRO_Z)
-               | BIT(INV_ICM20602_SCAN_TEMP),
+       INV_MPU6050_SCAN_MASK_3AXIS_GYRO | INV_MPU6050_SCAN_MASK_TEMP,
        /* 6-axis accel + gyro + temp (mandatory) */
-       BIT(INV_ICM20602_SCAN_ACCL_X)
-               | BIT(INV_ICM20602_SCAN_ACCL_Y)
-               | BIT(INV_ICM20602_SCAN_ACCL_Z)
-               | BIT(INV_ICM20602_SCAN_GYRO_X)
-               | BIT(INV_ICM20602_SCAN_GYRO_Y)
-               | BIT(INV_ICM20602_SCAN_GYRO_Z)
-               | BIT(INV_ICM20602_SCAN_TEMP),
+       INV_MPU6050_SCAN_MASK_3AXIS_ACCEL | INV_MPU6050_SCAN_MASK_3AXIS_GYRO
+               | INV_MPU6050_SCAN_MASK_TEMP,
        0,
 };
 
@@ -1241,7 +1220,7 @@ int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name,
        irq_type = irqd_get_trigger_type(desc);
        if (!irq_type)
                irq_type = IRQF_TRIGGER_RISING;
-       if (irq_type == IRQF_TRIGGER_RISING)
+       if (irq_type & IRQF_TRIGGER_RISING)     // rising or both-edge
                st->irq_mask = INV_MPU6050_ACTIVE_HIGH;
        else if (irq_type == IRQF_TRIGGER_FALLING)
                st->irq_mask = INV_MPU6050_ACTIVE_LOW;
@@ -1324,25 +1303,20 @@ int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name,
                inv_mpu_bus_setup(indio_dev);
 
        switch (chip_type) {
+       case INV_MPU9150:
+               indio_dev->channels = inv_mpu9150_channels;
+               indio_dev->num_channels = ARRAY_SIZE(inv_mpu9150_channels);
+               indio_dev->available_scan_masks = inv_mpu9x50_scan_masks;
+               break;
        case INV_MPU9250:
        case INV_MPU9255:
-               /*
-                * Use magnetometer inside the chip only if there is no i2c
-                * auxiliary device in use.
-                */
-               if (!st->magn_disabled) {
-                       indio_dev->channels = inv_mpu9250_channels;
-                       indio_dev->num_channels = ARRAY_SIZE(inv_mpu9250_channels);
-                       indio_dev->available_scan_masks = inv_mpu9x50_scan_masks;
-               } else {
-                       indio_dev->channels = inv_mpu_channels;
-                       indio_dev->num_channels = ARRAY_SIZE(inv_mpu_channels);
-                       indio_dev->available_scan_masks = inv_mpu_scan_masks;
-               }
+               indio_dev->channels = inv_mpu9250_channels;
+               indio_dev->num_channels = ARRAY_SIZE(inv_mpu9250_channels);
+               indio_dev->available_scan_masks = inv_mpu9x50_scan_masks;
                break;
        case INV_ICM20602:
-               indio_dev->channels = inv_icm20602_channels;
-               indio_dev->num_channels = ARRAY_SIZE(inv_icm20602_channels);
+               indio_dev->channels = inv_mpu_channels;
+               indio_dev->num_channels = ARRAY_SIZE(inv_mpu_channels);
                indio_dev->available_scan_masks = inv_icm20602_scan_masks;
                break;
        default:
@@ -1351,6 +1325,15 @@ int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name,
                indio_dev->available_scan_masks = inv_mpu_scan_masks;
                break;
        }
+       /*
+        * Use magnetometer inside the chip only if there is no i2c
+        * auxiliary device in use. Otherwise Going back to 6-axis only.
+        */
+       if (st->magn_disabled) {
+               indio_dev->channels = inv_mpu_channels;
+               indio_dev->num_channels = ARRAY_SIZE(inv_mpu_channels);
+               indio_dev->available_scan_masks = inv_mpu_scan_masks;
+       }
 
        indio_dev->info = &mpu_info;
        indio_dev->modes = INDIO_BUFFER_TRIGGERED;
index 389cc85..f47a28b 100644 (file)
@@ -77,6 +77,7 @@ static bool inv_mpu_i2c_aux_bus(struct device *dev)
        case INV_ICM20602:
                /* no i2c auxiliary bus on the chip */
                return false;
+       case INV_MPU9150:
        case INV_MPU9250:
        case INV_MPU9255:
                if (st->magn_disabled)
@@ -102,6 +103,7 @@ static int inv_mpu_magn_disable(struct iio_dev *indio_dev)
        struct device_node *mux_node;
 
        switch (st->chip_type) {
+       case INV_MPU9150:
        case INV_MPU9250:
        case INV_MPU9255:
                mux_node = of_get_child_by_name(dev->of_node, "i2c-gate");
index b096e01..6158fca 100644 (file)
@@ -86,6 +86,7 @@ enum inv_devices {
  *  @accl_fs:          accel full scale range.
  *  @accl_fifo_enable: enable accel data output
  *  @gyro_fifo_enable: enable gyro data output
+ *  @temp_fifo_enable: enable temp data output
  *  @magn_fifo_enable: enable magn data output
  *  @divider:          chip sample rate divider (sample rate divider - 1)
  */
@@ -95,6 +96,7 @@ struct inv_mpu6050_chip_config {
        unsigned int accl_fs:2;
        unsigned int accl_fifo_enable:1;
        unsigned int gyro_fifo_enable:1;
+       unsigned int temp_fifo_enable:1;
        unsigned int magn_fifo_enable:1;
        u8 divider;
        u8 user_ctrl;
@@ -184,6 +186,7 @@ struct inv_mpu6050_state {
 #define INV_MPU6050_BIT_SLAVE_2             0x04
 #define INV_MPU6050_BIT_ACCEL_OUT           0x08
 #define INV_MPU6050_BITS_GYRO_OUT           0x70
+#define INV_MPU6050_BIT_TEMP_OUT            0x80
 
 #define INV_MPU6050_REG_I2C_MST_CTRL        0x24
 #define INV_MPU6050_BITS_I2C_MST_CLK_400KHZ 0x0D
@@ -268,8 +271,8 @@ struct inv_mpu6050_state {
 /* MPU9X50 9-axis magnetometer */
 #define INV_MPU9X50_BYTES_MAGN               7
 
-/* ICM20602 FIFO samples include temperature readings */
-#define INV_ICM20602_BYTES_PER_TEMP_SENSOR   2
+/* FIFO temperature sample size */
+#define INV_MPU6050_BYTES_PER_TEMP_SENSOR   2
 
 /* mpu6500 registers */
 #define INV_MPU6500_REG_ACCEL_CONFIG_2      0x1D
@@ -298,7 +301,7 @@ struct inv_mpu6050_state {
 #define INV_ICM20608_TEMP_OFFSET            8170
 #define INV_ICM20608_TEMP_SCALE                     3059976
 
-/* 6 + 6 + 7 (for MPU9x50) = 19 round up to 24 and plus 8 */
+/* 6 + 6 + 2 + 7 (for MPU9x50) = 21 round up to 24 and plus 8 */
 #define INV_MPU6050_OUTPUT_DATA_SIZE         32
 
 #define INV_MPU6050_REG_INT_PIN_CFG    0x37
@@ -344,6 +347,7 @@ enum inv_mpu6050_scan {
        INV_MPU6050_SCAN_ACCL_X,
        INV_MPU6050_SCAN_ACCL_Y,
        INV_MPU6050_SCAN_ACCL_Z,
+       INV_MPU6050_SCAN_TEMP,
        INV_MPU6050_SCAN_GYRO_X,
        INV_MPU6050_SCAN_GYRO_Y,
        INV_MPU6050_SCAN_GYRO_Z,
@@ -355,18 +359,6 @@ enum inv_mpu6050_scan {
        INV_MPU9X50_SCAN_TIMESTAMP,
 };
 
-/* scan element definition for ICM20602, which includes temperature */
-enum inv_icm20602_scan {
-       INV_ICM20602_SCAN_ACCL_X,
-       INV_ICM20602_SCAN_ACCL_Y,
-       INV_ICM20602_SCAN_ACCL_Z,
-       INV_ICM20602_SCAN_TEMP,
-       INV_ICM20602_SCAN_GYRO_X,
-       INV_ICM20602_SCAN_GYRO_Y,
-       INV_ICM20602_SCAN_GYRO_Z,
-       INV_ICM20602_SCAN_TIMESTAMP,
-};
-
 enum inv_mpu6050_filter_e {
        INV_MPU6050_FILTER_256HZ_NOLPF2 = 0,
        INV_MPU6050_FILTER_188HZ,
index 02735af..4f19235 100644 (file)
@@ -12,7 +12,9 @@
 #include "inv_mpu_magn.h"
 
 /*
- * MPU9250 magnetometer is an AKM AK8963 chip on I2C aux bus
+ * MPU9xxx magnetometer are AKM chips on I2C aux bus
+ * MPU9150 is AK8975
+ * MPU9250 is AK8963
  */
 #define INV_MPU_MAGN_I2C_ADDR          0x0C
 
 #define INV_MPU_MAGN_BITS_MODE_PWDN    0x00
 #define INV_MPU_MAGN_BITS_MODE_SINGLE  0x01
 #define INV_MPU_MAGN_BITS_MODE_FUSE    0x0F
-#define INV_MPU_MAGN_BIT_OUTPUT_BIT    0x10
+#define INV_MPU9250_MAGN_BIT_OUTPUT_BIT        0x10
 
-#define INV_MPU_MAGN_REG_CNTL2         0x0B
-#define INV_MPU_MAGN_BIT_SRST          0x01
+#define INV_MPU9250_MAGN_REG_CNTL2     0x0B
+#define INV_MPU9250_MAGN_BIT_SRST      0x01
 
 #define INV_MPU_MAGN_REG_ASAX          0x10
 #define INV_MPU_MAGN_REG_ASAY          0x11
@@ -48,6 +50,7 @@
 static bool inv_magn_supported(const struct inv_mpu6050_state *st)
 {
        switch (st->chip_type) {
+       case INV_MPU9150:
        case INV_MPU9250:
        case INV_MPU9255:
                return true;
@@ -61,6 +64,7 @@ static int inv_magn_init(struct inv_mpu6050_state *st)
 {
        uint8_t val;
        uint8_t asa[3];
+       int32_t sensitivity;
        int ret;
 
        /* check whoami */
@@ -71,12 +75,19 @@ static int inv_magn_init(struct inv_mpu6050_state *st)
        if (val != INV_MPU_MAGN_BITS_WIA)
                return -ENODEV;
 
-       /* reset chip */
-       ret = inv_mpu_aux_write(st, INV_MPU_MAGN_I2C_ADDR,
-                               INV_MPU_MAGN_REG_CNTL2,
-                               INV_MPU_MAGN_BIT_SRST);
-       if (ret)
-               return ret;
+       /* software reset for MPU925x only */
+       switch (st->chip_type) {
+       case INV_MPU9250:
+       case INV_MPU9255:
+               ret = inv_mpu_aux_write(st, INV_MPU_MAGN_I2C_ADDR,
+                                       INV_MPU9250_MAGN_REG_CNTL2,
+                                       INV_MPU9250_MAGN_BIT_SRST);
+               if (ret)
+                       return ret;
+               break;
+       default:
+               break;
+       }
 
        /* read fuse ROM data */
        ret = inv_mpu_aux_write(st, INV_MPU_MAGN_I2C_ADDR,
@@ -97,6 +108,25 @@ static int inv_magn_init(struct inv_mpu6050_state *st)
        if (ret)
                return ret;
 
+       /*
+        * Sensor sentivity
+        * 1 uT = 0.01 G and value is in micron (1e6)
+        * sensitvity = x uT * 0.01 * 1e6
+        */
+       switch (st->chip_type) {
+       case INV_MPU9150:
+               /* sensor sensitivity is 0.3 uT */
+               sensitivity = 3000;
+               break;
+       case INV_MPU9250:
+       case INV_MPU9255:
+               /* sensor sensitivity in 16 bits mode: 0.15 uT */
+               sensitivity = 1500;
+               break;
+       default:
+               return -EINVAL;
+       }
+
        /*
         * Sensitivity adjustement and scale to Gauss
         *
@@ -104,16 +134,11 @@ static int inv_magn_init(struct inv_mpu6050_state *st)
         * Factor simplification:
         * Hadj = H * ((ASA + 128) / 256)
         *
-        * Sensor sentivity
-        * 0.15 uT in 16 bits mode
-        * 1 uT = 0.01 G and value is in micron (1e6)
-        * sensitvity = 0.15 uT * 0.01 * 1e6
-        *
-        * raw_to_gauss = Hadj * 1500
+        * raw_to_gauss = Hadj * sensitivity
         */
-       st->magn_raw_to_gauss[0] = (((int32_t)asa[0] + 128) * 1500) / 256;
-       st->magn_raw_to_gauss[1] = (((int32_t)asa[1] + 128) * 1500) / 256;
-       st->magn_raw_to_gauss[2] = (((int32_t)asa[2] + 128) * 1500) / 256;
+       st->magn_raw_to_gauss[0] = (((int32_t)asa[0] + 128) * sensitivity) / 256;
+       st->magn_raw_to_gauss[1] = (((int32_t)asa[1] + 128) * sensitivity) / 256;
+       st->magn_raw_to_gauss[2] = (((int32_t)asa[2] + 128) * sensitivity) / 256;
 
        return 0;
 }
@@ -129,6 +154,7 @@ static int inv_magn_init(struct inv_mpu6050_state *st)
  */
 int inv_mpu_magn_probe(struct inv_mpu6050_state *st)
 {
+       uint8_t val;
        int ret;
 
        /* quit if chip is not supported */
@@ -179,10 +205,17 @@ int inv_mpu_magn_probe(struct inv_mpu6050_state *st)
        if (ret)
                return ret;
 
-       /* add 16 bits mode */
-       ret = regmap_write(st->map, INV_MPU6050_REG_I2C_SLV_DO(1),
-                          INV_MPU_MAGN_BITS_MODE_SINGLE |
-                          INV_MPU_MAGN_BIT_OUTPUT_BIT);
+       /* add 16 bits mode for MPU925x */
+       val = INV_MPU_MAGN_BITS_MODE_SINGLE;
+       switch (st->chip_type) {
+       case INV_MPU9250:
+       case INV_MPU9255:
+               val |= INV_MPU9250_MAGN_BIT_OUTPUT_BIT;
+               break;
+       default:
+               break;
+       }
+       ret = regmap_write(st->map, INV_MPU6050_REG_I2C_SLV_DO(1), val);
        if (ret)
                return ret;
 
@@ -237,6 +270,7 @@ int inv_mpu_magn_set_orient(struct inv_mpu6050_state *st)
 
        /* fill magnetometer orientation */
        switch (st->chip_type) {
+       case INV_MPU9150:
        case INV_MPU9250:
        case INV_MPU9255:
                /* x <- y */
index 10d16ec..f9fdf43 100644 (file)
@@ -142,6 +142,8 @@ int inv_reset_fifo(struct iio_dev *indio_dev)
                d |= INV_MPU6050_BITS_GYRO_OUT;
        if (st->chip_config.accl_fifo_enable)
                d |= INV_MPU6050_BIT_ACCEL_OUT;
+       if (st->chip_config.temp_fifo_enable)
+               d |= INV_MPU6050_BIT_TEMP_OUT;
        if (st->chip_config.magn_fifo_enable)
                d |= INV_MPU6050_BIT_SLAVE_0;
        result = regmap_write(st->map, st->reg->fifo_en, d);
@@ -183,11 +185,8 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
                        "failed to ack interrupt\n");
                goto flush_fifo;
        }
-       if (!(int_status & INV_MPU6050_BIT_RAW_DATA_RDY_INT)) {
-               dev_warn(regmap_get_device(st->map),
-                       "spurious interrupt with status 0x%x\n", int_status);
+       if (!(int_status & INV_MPU6050_BIT_RAW_DATA_RDY_INT))
                goto end_session;
-       }
 
        if (!(st->chip_config.accl_fifo_enable |
                st->chip_config.gyro_fifo_enable |
@@ -200,8 +199,8 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
        if (st->chip_config.gyro_fifo_enable)
                bytes_per_datum += INV_MPU6050_BYTES_PER_3AXIS_SENSOR;
 
-       if (st->chip_type == INV_ICM20602)
-               bytes_per_datum += INV_ICM20602_BYTES_PER_TEMP_SENSOR;
+       if (st->chip_config.temp_fifo_enable)
+               bytes_per_datum += INV_MPU6050_BYTES_PER_TEMP_SENSOR;
 
        if (st->chip_config.magn_fifo_enable)
                bytes_per_datum += INV_MPU9X50_BYTES_MAGN;
index 142692f..ec102d5 100644 (file)
@@ -74,7 +74,6 @@ static int inv_mpu_probe(struct spi_device *spi)
 static const struct spi_device_id inv_mpu_id[] = {
        {"mpu6000", INV_MPU6000},
        {"mpu6500", INV_MPU6500},
-       {"mpu9150", INV_MPU9150},
        {"mpu9250", INV_MPU9250},
        {"mpu9255", INV_MPU9255},
        {"icm20608", INV_ICM20608},
index d7d9519..5199fe7 100644 (file)
@@ -24,6 +24,9 @@ static void inv_scan_query_mpu6050(struct iio_dev *indio_dev)
                         indio_dev->active_scan_mask) ||
                test_bit(INV_MPU6050_SCAN_ACCL_Z,
                         indio_dev->active_scan_mask);
+
+       st->chip_config.temp_fifo_enable =
+               test_bit(INV_MPU6050_SCAN_TEMP, indio_dev->active_scan_mask);
 }
 
 static void inv_scan_query_mpu9x50(struct iio_dev *indio_dev)
@@ -50,6 +53,7 @@ static void inv_scan_query(struct iio_dev *indio_dev)
        struct inv_mpu6050_state *st = iio_priv(indio_dev);
 
        switch (st->chip_type) {
+       case INV_MPU9150:
        case INV_MPU9250:
        case INV_MPU9255:
                return inv_scan_query_mpu9x50(indio_dev);
index dc55d7d..9c3486a 100644 (file)
@@ -76,6 +76,7 @@ enum st_lsm6dsx_hw_id {
                .endianness = IIO_LE,                                   \
        },                                                              \
        .event_spec = &st_lsm6dsx_event,                                \
+       .ext_info = st_lsm6dsx_accel_ext_info,                          \
        .num_event_specs = 1,                                           \
 }
 
@@ -176,21 +177,38 @@ struct st_lsm6dsx_hw_ts_settings {
  * @pullup_en: i2c controller pull-up register info (addr + mask).
  * @aux_sens: aux sensor register info (addr + mask).
  * @wr_once: write_once register info (addr + mask).
+ * @emb_func:  embedded function register info (addr + mask).
+ * @num_ext_dev: max number of slave devices.
  * @shub_out: sensor hub first output register info.
  * @slv0_addr: slave0 address in secondary page.
  * @dw_slv0_addr: slave0 write register address in secondary page.
  * @batch_en: Enable/disable FIFO batching.
+ * @pause: controller pause value.
  */
 struct st_lsm6dsx_shub_settings {
        struct st_lsm6dsx_reg page_mux;
-       struct st_lsm6dsx_reg master_en;
-       struct st_lsm6dsx_reg pullup_en;
+       struct {
+               bool sec_page;
+               u8 addr;
+               u8 mask;
+       } master_en;
+       struct {
+               bool sec_page;
+               u8 addr;
+               u8 mask;
+       } pullup_en;
        struct st_lsm6dsx_reg aux_sens;
        struct st_lsm6dsx_reg wr_once;
-       u8 shub_out;
+       struct st_lsm6dsx_reg emb_func;
+       u8 num_ext_dev;
+       struct {
+               bool sec_page;
+               u8 addr;
+       } shub_out;
        u8 slv0_addr;
        u8 dw_slv0_addr;
        u8 batch_en;
+       u8 pause;
 };
 
 struct st_lsm6dsx_event_settings {
@@ -361,6 +379,7 @@ struct st_lsm6dsx_sensor {
  * @enable_event: enabled event bitmask.
  * @iio_devs: Pointers to acc/gyro iio_dev instances.
  * @settings: Pointer to the specific sensor settings in use.
+ * @orientation: sensor chip orientation relative to main hardware.
  */
 struct st_lsm6dsx_hw {
        struct device *dev;
@@ -387,16 +406,21 @@ struct st_lsm6dsx_hw {
        struct iio_dev *iio_devs[ST_LSM6DSX_ID_MAX];
 
        const struct st_lsm6dsx_settings *settings;
+
+       struct iio_mount_matrix orientation;
 };
 
-static const struct iio_event_spec st_lsm6dsx_event = {
+static __maybe_unused const struct iio_event_spec st_lsm6dsx_event = {
        .type = IIO_EV_TYPE_THRESH,
        .dir = IIO_EV_DIR_EITHER,
        .mask_separate = BIT(IIO_EV_INFO_VALUE) |
                         BIT(IIO_EV_INFO_ENABLE)
 };
 
-static const unsigned long st_lsm6dsx_available_scan_masks[] = {0x7, 0x0};
+static __maybe_unused const unsigned long st_lsm6dsx_available_scan_masks[] = {
+       0x7, 0x0,
+};
+
 extern const struct dev_pm_ops st_lsm6dsx_pm_ops;
 
 int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id,
@@ -457,4 +481,19 @@ st_lsm6dsx_write_locked(struct st_lsm6dsx_hw *hw, unsigned int addr,
        return err;
 }
 
+static const inline struct iio_mount_matrix *
+st_lsm6dsx_get_mount_matrix(const struct iio_dev *iio_dev,
+                           const struct iio_chan_spec *chan)
+{
+       struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
+       struct st_lsm6dsx_hw *hw = sensor->hw;
+
+       return &hw->orientation;
+}
+
+static const struct iio_chan_spec_ext_info st_lsm6dsx_accel_ext_info[] = {
+       IIO_MOUNT_MATRIX(IIO_SHARED_BY_ALL, st_lsm6dsx_get_mount_matrix),
+       { }
+};
+
 #endif /* ST_LSM6DSX_H */
index cb536b8..bb89934 100644 (file)
@@ -336,12 +336,13 @@ static inline int st_lsm6dsx_read_block(struct st_lsm6dsx_hw *hw, u8 addr,
  */
 int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
 {
+       struct st_lsm6dsx_sensor *acc_sensor, *gyro_sensor, *ext_sensor = NULL;
+       int err, acc_sip, gyro_sip, ts_sip, ext_sip, read_len, offset;
        u16 fifo_len, pattern_len = hw->sip * ST_LSM6DSX_SAMPLE_SIZE;
        u16 fifo_diff_mask = hw->settings->fifo_ops.fifo_diff.mask;
-       int err, acc_sip, gyro_sip, ts_sip, read_len, offset;
-       struct st_lsm6dsx_sensor *acc_sensor, *gyro_sensor;
        u8 gyro_buff[ST_LSM6DSX_IIO_BUFF_SIZE];
        u8 acc_buff[ST_LSM6DSX_IIO_BUFF_SIZE];
+       u8 ext_buff[ST_LSM6DSX_IIO_BUFF_SIZE];
        bool reset_ts = false;
        __le16 fifo_status;
        s64 ts = 0;
@@ -364,6 +365,8 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
 
        acc_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]);
        gyro_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_GYRO]);
+       if (hw->iio_devs[ST_LSM6DSX_ID_EXT0])
+               ext_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_EXT0]);
 
        for (read_len = 0; read_len < fifo_len; read_len += pattern_len) {
                err = st_lsm6dsx_read_block(hw, ST_LSM6DSX_REG_FIFO_OUTL_ADDR,
@@ -391,12 +394,13 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
                 * following pattern is repeated every 9 samples:
                 *   - Gx, Gy, Gz, Ax, Ay, Az, Ts, Gx, Gy, Gz, Ts, Gx, ..
                 */
+               ext_sip = ext_sensor ? ext_sensor->sip : 0;
                gyro_sip = gyro_sensor->sip;
                acc_sip = acc_sensor->sip;
                ts_sip = hw->ts_sip;
                offset = 0;
 
-               while (acc_sip > 0 || gyro_sip > 0) {
+               while (acc_sip > 0 || gyro_sip > 0 || ext_sip > 0) {
                        if (gyro_sip > 0) {
                                memcpy(gyro_buff, &hw->buff[offset],
                                       ST_LSM6DSX_SAMPLE_SIZE);
@@ -407,6 +411,11 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
                                       ST_LSM6DSX_SAMPLE_SIZE);
                                offset += ST_LSM6DSX_SAMPLE_SIZE;
                        }
+                       if (ext_sip > 0) {
+                               memcpy(ext_buff, &hw->buff[offset],
+                                      ST_LSM6DSX_SAMPLE_SIZE);
+                               offset += ST_LSM6DSX_SAMPLE_SIZE;
+                       }
 
                        if (ts_sip-- > 0) {
                                u8 data[ST_LSM6DSX_SAMPLE_SIZE];
@@ -440,6 +449,10 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
                                iio_push_to_buffers_with_timestamp(
                                        hw->iio_devs[ST_LSM6DSX_ID_ACC],
                                        acc_buff, acc_sensor->ts_ref + ts);
+                       if (ext_sip-- > 0)
+                               iio_push_to_buffers_with_timestamp(
+                                       hw->iio_devs[ST_LSM6DSX_ID_EXT0],
+                                       ext_buff, ext_sensor->ts_ref + ts);
                }
        }
 
@@ -638,12 +651,12 @@ int st_lsm6dsx_update_fifo(struct st_lsm6dsx_sensor *sensor, bool enable)
                err = st_lsm6dsx_sensor_set_enable(sensor, enable);
                if (err < 0)
                        goto out;
-
-               err = st_lsm6dsx_set_fifo_odr(sensor, enable);
-               if (err < 0)
-                       goto out;
        }
 
+       err = st_lsm6dsx_set_fifo_odr(sensor, enable);
+       if (err < 0)
+               goto out;
+
        err = st_lsm6dsx_update_decimators(hw);
        if (err < 0)
                goto out;
index b921dd9..84d219a 100644 (file)
@@ -54,6 +54,7 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/pm.h>
+#include <linux/property.h>
 #include <linux/regmap.h>
 #include <linux/bitfield.h>
 
@@ -655,6 +656,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
                                .addr = 0x08,
                                .mask = GENMASK(5, 3),
                        },
+                       [ST_LSM6DSX_ID_EXT0] = {
+                               .addr = 0x09,
+                               .mask = GENMASK(2, 0),
+                       },
                },
                .fifo_ops = {
                        .update_fifo = st_lsm6dsx_update_fifo,
@@ -687,6 +692,39 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
                                .mask = GENMASK(5, 3),
                        },
                },
+               .shub_settings = {
+                       .page_mux = {
+                               .addr = 0x01,
+                               .mask = BIT(7),
+                       },
+                       .master_en = {
+                               .addr = 0x1a,
+                               .mask = BIT(0),
+                       },
+                       .pullup_en = {
+                               .addr = 0x1a,
+                               .mask = BIT(3),
+                       },
+                       .aux_sens = {
+                               .addr = 0x04,
+                               .mask = GENMASK(5, 4),
+                       },
+                       .wr_once = {
+                               .addr = 0x07,
+                               .mask = BIT(5),
+                       },
+                       .emb_func = {
+                               .addr = 0x19,
+                               .mask = BIT(2),
+                       },
+                       .num_ext_dev = 1,
+                       .shub_out = {
+                               .addr = 0x2e,
+                       },
+                       .slv0_addr = 0x02,
+                       .dw_slv0_addr = 0x0e,
+                       .pause = 0x7,
+               },
                .event_settings = {
                        .enable_reg = {
                                .addr = 0x58,
@@ -867,10 +905,12 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
                                .mask = BIT(6),
                        },
                        .master_en = {
+                               .sec_page = true,
                                .addr = 0x14,
                                .mask = BIT(2),
                        },
                        .pullup_en = {
+                               .sec_page = true,
                                .addr = 0x14,
                                .mask = BIT(3),
                        },
@@ -882,7 +922,11 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
                                .addr = 0x14,
                                .mask = BIT(6),
                        },
-                       .shub_out = 0x02,
+                       .num_ext_dev = 3,
+                       .shub_out = {
+                               .sec_page = true,
+                               .addr = 0x02,
+                       },
                        .slv0_addr = 0x15,
                        .dw_slv0_addr = 0x21,
                        .batch_en = BIT(3),
@@ -1241,10 +1285,12 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
                                .mask = BIT(6),
                        },
                        .master_en = {
+                               .sec_page = true,
                                .addr = 0x14,
                                .mask = BIT(2),
                        },
                        .pullup_en = {
+                               .sec_page = true,
                                .addr = 0x14,
                                .mask = BIT(3),
                        },
@@ -1256,7 +1302,11 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
                                .addr = 0x14,
                                .mask = BIT(6),
                        },
-                       .shub_out = 0x02,
+                       .num_ext_dev = 3,
+                       .shub_out = {
+                               .sec_page = true,
+                               .addr = 0x02,
+                       },
                        .slv0_addr = 0x15,
                        .dw_slv0_addr = 0x21,
                        .batch_en = BIT(3),
@@ -1506,8 +1556,11 @@ static int st_lsm6dsx_read_oneshot(struct st_lsm6dsx_sensor *sensor,
        if (err < 0)
                return err;
 
-       if (!hw->enable_event)
-               st_lsm6dsx_sensor_set_enable(sensor, false);
+       if (!hw->enable_event) {
+               err = st_lsm6dsx_sensor_set_enable(sensor, false);
+               if (err < 0)
+                       return err;
+       }
 
        *val = (s16)le16_to_cpu(data);
 
@@ -1609,11 +1662,11 @@ static int st_lsm6dsx_event_setup(struct st_lsm6dsx_hw *hw, int state)
 }
 
 static int st_lsm6dsx_read_event(struct iio_dev *iio_dev,
-                                  const struct iio_chan_spec *chan,
-                                  enum iio_event_type type,
-                                  enum iio_event_direction dir,
-                                  enum iio_event_info info,
-                                  int *val, int *val2)
+                                const struct iio_chan_spec *chan,
+                                enum iio_event_type type,
+                                enum iio_event_direction dir,
+                                enum iio_event_info info,
+                                int *val, int *val2)
 {
        struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
        struct st_lsm6dsx_hw *hw = sensor->hw;
@@ -1827,14 +1880,14 @@ static const struct iio_info st_lsm6dsx_gyro_info = {
        .hwfifo_set_watermark = st_lsm6dsx_set_watermark,
 };
 
-static int st_lsm6dsx_of_get_drdy_pin(struct st_lsm6dsx_hw *hw, int *drdy_pin)
+static int st_lsm6dsx_get_drdy_pin(struct st_lsm6dsx_hw *hw, int *drdy_pin)
 {
-       struct device_node *np = hw->dev->of_node;
+       struct device *dev = hw->dev;
 
-       if (!np)
+       if (!dev_fwnode(dev))
                return -EINVAL;
 
-       return of_property_read_u32(np, "st,drdy-int-pin", drdy_pin);
+       return device_property_read_u32(dev, "st,drdy-int-pin", drdy_pin);
 }
 
 static int
@@ -1843,7 +1896,7 @@ st_lsm6dsx_get_drdy_reg(struct st_lsm6dsx_hw *hw,
 {
        int err = 0, drdy_pin;
 
-       if (st_lsm6dsx_of_get_drdy_pin(hw, &drdy_pin) < 0) {
+       if (st_lsm6dsx_get_drdy_pin(hw, &drdy_pin) < 0) {
                struct st_sensors_platform_data *pdata;
                struct device *dev = hw->dev;
 
@@ -1872,26 +1925,29 @@ st_lsm6dsx_get_drdy_reg(struct st_lsm6dsx_hw *hw,
 static int st_lsm6dsx_init_shub(struct st_lsm6dsx_hw *hw)
 {
        const struct st_lsm6dsx_shub_settings *hub_settings;
-       struct device_node *np = hw->dev->of_node;
        struct st_sensors_platform_data *pdata;
+       struct device *dev = hw->dev;
        unsigned int data;
        int err = 0;
 
        hub_settings = &hw->settings->shub_settings;
 
-       pdata = (struct st_sensors_platform_data *)hw->dev->platform_data;
-       if ((np && of_property_read_bool(np, "st,pullups")) ||
+       pdata = (struct st_sensors_platform_data *)dev->platform_data;
+       if ((dev_fwnode(dev) && device_property_read_bool(dev, "st,pullups")) ||
            (pdata && pdata->pullups)) {
-               err = st_lsm6dsx_set_page(hw, true);
-               if (err < 0)
-                       return err;
+               if (hub_settings->pullup_en.sec_page) {
+                       err = st_lsm6dsx_set_page(hw, true);
+                       if (err < 0)
+                               return err;
+               }
 
                data = ST_LSM6DSX_SHIFT_VAL(1, hub_settings->pullup_en.mask);
                err = regmap_update_bits(hw->regmap,
                                         hub_settings->pullup_en.addr,
                                         hub_settings->pullup_en.mask, data);
 
-               st_lsm6dsx_set_page(hw, false);
+               if (hub_settings->pullup_en.sec_page)
+                       st_lsm6dsx_set_page(hw, false);
 
                if (err < 0)
                        return err;
@@ -1909,6 +1965,16 @@ static int st_lsm6dsx_init_shub(struct st_lsm6dsx_hw *hw)
                                         hub_settings->aux_sens.mask, data);
 
                st_lsm6dsx_set_page(hw, false);
+
+               if (err < 0)
+                       return err;
+       }
+
+       if (hub_settings->emb_func.addr) {
+               data = ST_LSM6DSX_SHIFT_VAL(1, hub_settings->emb_func.mask);
+               err = regmap_update_bits(hw->regmap,
+                                        hub_settings->emb_func.addr,
+                                        hub_settings->emb_func.mask, data);
        }
 
        return err;
@@ -2158,9 +2224,9 @@ static irqreturn_t st_lsm6dsx_handler_thread(int irq, void *private)
 
 static int st_lsm6dsx_irq_setup(struct st_lsm6dsx_hw *hw)
 {
-       struct device_node *np = hw->dev->of_node;
        struct st_sensors_platform_data *pdata;
        const struct st_lsm6dsx_reg *reg;
+       struct device *dev = hw->dev;
        unsigned long irq_type;
        bool irq_active_low;
        int err;
@@ -2188,8 +2254,8 @@ static int st_lsm6dsx_irq_setup(struct st_lsm6dsx_hw *hw)
        if (err < 0)
                return err;
 
-       pdata = (struct st_sensors_platform_data *)hw->dev->platform_data;
-       if ((np && of_property_read_bool(np, "drive-open-drain")) ||
+       pdata = (struct st_sensors_platform_data *)dev->platform_data;
+       if ((dev_fwnode(dev) && device_property_read_bool(dev, "drive-open-drain")) ||
            (pdata && pdata->open_drain)) {
                reg = &hw->settings->irq_config.od;
                err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
@@ -2219,7 +2285,6 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id,
 {
        struct st_sensors_platform_data *pdata = dev->platform_data;
        const struct st_lsm6dsx_shub_settings *hub_settings;
-       struct device_node *np = dev->of_node;
        struct st_lsm6dsx_hw *hw;
        const char *name = NULL;
        int i, err;
@@ -2273,6 +2338,10 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id,
                        return err;
        }
 
+       err = iio_read_mount_matrix(hw->dev, "mount-matrix", &hw->orientation);
+       if (err)
+               return err;
+
        for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
                if (!hw->iio_devs[i])
                        continue;
@@ -2282,7 +2351,7 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id,
                        return err;
        }
 
-       if ((np && of_property_read_bool(np, "wakeup-source")) ||
+       if ((dev_fwnode(dev) && device_property_read_bool(dev, "wakeup-source")) ||
            (pdata && pdata->wakeup_source))
                device_init_wakeup(dev, true);
 
index cd47ec1..0fb3213 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/module.h>
 #include <linux/i2c.h>
 #include <linux/slab.h>
-#include <linux/of.h>
 #include <linux/regmap.h>
 
 #include "st_lsm6dsx.h"
@@ -122,7 +121,7 @@ static struct i2c_driver st_lsm6dsx_driver = {
        .driver = {
                .name = "st_lsm6dsx_i2c",
                .pm = &st_lsm6dsx_pm_ops,
-               .of_match_table = of_match_ptr(st_lsm6dsx_i2c_of_match),
+               .of_match_table = st_lsm6dsx_i2c_of_match,
        },
        .probe = st_lsm6dsx_i2c_probe,
        .id_table = st_lsm6dsx_i2c_id_table,
index fa5d100..eea5556 100644 (file)
@@ -30,7 +30,6 @@
 
 #include "st_lsm6dsx.h"
 
-#define ST_LSM6DSX_MAX_SLV_NUM                 3
 #define ST_LSM6DSX_SLV_ADDR(n, base)           ((base) + (n) * 3)
 #define ST_LSM6DSX_SLV_SUB_ADDR(n, base)       ((base) + 1 + (n) * 3)
 #define ST_LSM6DSX_SLV_CONFIG(n, base)         ((base) + 2 + (n) * 3)
@@ -102,24 +101,31 @@ static void st_lsm6dsx_shub_wait_complete(struct st_lsm6dsx_hw *hw)
 }
 
 /**
- * st_lsm6dsx_shub_read_reg - read i2c controller register
+ * st_lsm6dsx_shub_read_output - read i2c controller register
  *
  * Read st_lsm6dsx i2c controller register
  */
-static int st_lsm6dsx_shub_read_reg(struct st_lsm6dsx_hw *hw, u8 addr,
-                                   u8 *data, int len)
+static int
+st_lsm6dsx_shub_read_output(struct st_lsm6dsx_hw *hw, u8 *data,
+                           int len)
 {
+       const struct st_lsm6dsx_shub_settings *hub_settings;
        int err;
 
        mutex_lock(&hw->page_lock);
 
-       err = st_lsm6dsx_set_page(hw, true);
-       if (err < 0)
-               goto out;
+       hub_settings = &hw->settings->shub_settings;
+       if (hub_settings->shub_out.sec_page) {
+               err = st_lsm6dsx_set_page(hw, true);
+               if (err < 0)
+                       goto out;
+       }
 
-       err = regmap_bulk_read(hw->regmap, addr, data, len);
+       err = regmap_bulk_read(hw->regmap, hub_settings->shub_out.addr,
+                              data, len);
 
-       st_lsm6dsx_set_page(hw, false);
+       if (hub_settings->shub_out.sec_page)
+               st_lsm6dsx_set_page(hw, false);
 out:
        mutex_unlock(&hw->page_lock);
 
@@ -186,15 +192,18 @@ static int st_lsm6dsx_shub_master_enable(struct st_lsm6dsx_sensor *sensor,
        mutex_lock(&hw->page_lock);
 
        hub_settings = &hw->settings->shub_settings;
-       err = st_lsm6dsx_set_page(hw, true);
-       if (err < 0)
-               goto out;
+       if (hub_settings->master_en.sec_page) {
+               err = st_lsm6dsx_set_page(hw, true);
+               if (err < 0)
+                       goto out;
+       }
 
        data = ST_LSM6DSX_SHIFT_VAL(enable, hub_settings->master_en.mask);
        err = regmap_update_bits(hw->regmap, hub_settings->master_en.addr,
                                 hub_settings->master_en.mask, data);
 
-       st_lsm6dsx_set_page(hw, false);
+       if (hub_settings->master_en.sec_page)
+               st_lsm6dsx_set_page(hw, false);
 out:
        mutex_unlock(&hw->page_lock);
 
@@ -212,16 +221,21 @@ st_lsm6dsx_shub_read(struct st_lsm6dsx_sensor *sensor, u8 addr,
                     u8 *data, int len)
 {
        const struct st_lsm6dsx_shub_settings *hub_settings;
+       u8 config[3], slv_addr, slv_config = 0;
        struct st_lsm6dsx_hw *hw = sensor->hw;
-       u8 config[3], slv_addr;
+       const struct st_lsm6dsx_reg *aux_sens;
        int err;
 
        hub_settings = &hw->settings->shub_settings;
        slv_addr = ST_LSM6DSX_SLV_ADDR(0, hub_settings->slv0_addr);
+       aux_sens = &hw->settings->shub_settings.aux_sens;
+       /* do not overwrite aux_sens */
+       if (slv_addr + 2 == aux_sens->addr)
+               slv_config = ST_LSM6DSX_SHIFT_VAL(3, aux_sens->mask);
 
        config[0] = (sensor->ext_info.addr << 1) | 1;
        config[1] = addr;
-       config[2] = len & ST_LS6DSX_READ_OP_MASK;
+       config[2] = (len & ST_LS6DSX_READ_OP_MASK) | slv_config;
 
        err = st_lsm6dsx_shub_write_reg(hw, slv_addr, config,
                                        sizeof(config));
@@ -234,12 +248,14 @@ st_lsm6dsx_shub_read(struct st_lsm6dsx_sensor *sensor, u8 addr,
 
        st_lsm6dsx_shub_wait_complete(hw);
 
-       err = st_lsm6dsx_shub_read_reg(hw, hub_settings->shub_out, data,
-                                      len & ST_LS6DSX_READ_OP_MASK);
+       err = st_lsm6dsx_shub_read_output(hw, data,
+                                         len & ST_LS6DSX_READ_OP_MASK);
 
        st_lsm6dsx_shub_master_enable(sensor, false);
 
-       memset(config, 0, sizeof(config));
+       config[0] = hub_settings->pause;
+       config[1] = 0;
+       config[2] = slv_config;
        return st_lsm6dsx_shub_write_reg(hw, slv_addr, config,
                                         sizeof(config));
 }
@@ -296,7 +312,8 @@ st_lsm6dsx_shub_write(struct st_lsm6dsx_sensor *sensor, u8 addr,
                st_lsm6dsx_shub_master_enable(sensor, false);
        }
 
-       memset(config, 0, sizeof(config));
+       config[0] = hub_settings->pause;
+       config[1] = 0;
        return st_lsm6dsx_shub_write_reg(hw, slv_addr, config, sizeof(config));
 }
 
@@ -688,14 +705,19 @@ st_lsm6dsx_shub_check_wai(struct st_lsm6dsx_hw *hw, u8 *i2c_addr,
                          const struct st_lsm6dsx_ext_dev_settings *settings)
 {
        const struct st_lsm6dsx_shub_settings *hub_settings;
+       u8 config[3], data, slv_addr, slv_config = 0;
+       const struct st_lsm6dsx_reg *aux_sens;
        struct st_lsm6dsx_sensor *sensor;
-       u8 config[3], data, slv_addr;
        bool found = false;
        int i, err;
 
+       sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]);
        hub_settings = &hw->settings->shub_settings;
+       aux_sens = &hw->settings->shub_settings.aux_sens;
        slv_addr = ST_LSM6DSX_SLV_ADDR(0, hub_settings->slv0_addr);
-       sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]);
+       /* do not overwrite aux_sens */
+       if (slv_addr + 2 == aux_sens->addr)
+               slv_config = ST_LSM6DSX_SHIFT_VAL(3, aux_sens->mask);
 
        for (i = 0; i < ARRAY_SIZE(settings->i2c_addr); i++) {
                if (!settings->i2c_addr[i])
@@ -704,7 +726,7 @@ st_lsm6dsx_shub_check_wai(struct st_lsm6dsx_hw *hw, u8 *i2c_addr,
                /* read wai slave register */
                config[0] = (settings->i2c_addr[i] << 1) | 0x1;
                config[1] = settings->wai.addr;
-               config[2] = 0x1;
+               config[2] = 0x1 | slv_config;
 
                err = st_lsm6dsx_shub_write_reg(hw, slv_addr, config,
                                                sizeof(config));
@@ -717,9 +739,7 @@ st_lsm6dsx_shub_check_wai(struct st_lsm6dsx_hw *hw, u8 *i2c_addr,
 
                st_lsm6dsx_shub_wait_complete(hw);
 
-               err = st_lsm6dsx_shub_read_reg(hw,
-                                              hub_settings->shub_out,
-                                              &data, sizeof(data));
+               err = st_lsm6dsx_shub_read_output(hw, &data, sizeof(data));
 
                st_lsm6dsx_shub_master_enable(sensor, false);
 
@@ -735,7 +755,9 @@ st_lsm6dsx_shub_check_wai(struct st_lsm6dsx_hw *hw, u8 *i2c_addr,
        }
 
        /* reset SLV0 channel */
-       memset(config, 0, sizeof(config));
+       config[0] = hub_settings->pause;
+       config[1] = 0;
+       config[2] = slv_config;
        err = st_lsm6dsx_shub_write_reg(hw, slv_addr, config,
                                        sizeof(config));
        if (err < 0)
@@ -770,7 +792,7 @@ int st_lsm6dsx_shub_probe(struct st_lsm6dsx_hw *hw, const char *name)
                if (err < 0)
                        return err;
 
-               if (++num_ext_dev >= ST_LSM6DSX_MAX_SLV_NUM)
+               if (++num_ext_dev >= hw->settings->shub_settings.num_ext_dev)
                        break;
                id++;
        }
index 67ff36e..eb1086e 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/module.h>
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
-#include <linux/of.h>
 #include <linux/regmap.h>
 
 #include "st_lsm6dsx.h"
@@ -122,7 +121,7 @@ static struct spi_driver st_lsm6dsx_driver = {
        .driver = {
                .name = "st_lsm6dsx_spi",
                .pm = &st_lsm6dsx_pm_ops,
-               .of_match_table = of_match_ptr(st_lsm6dsx_spi_of_match),
+               .of_match_table = st_lsm6dsx_spi_of_match,
        },
        .probe = st_lsm6dsx_spi_probe,
        .id_table = st_lsm6dsx_spi_id_table,
index 112225c..4ada559 100644 (file)
@@ -87,7 +87,7 @@ static bool iio_buffer_ready(struct iio_dev *indio_dev, struct iio_buffer *buf,
 }
 
 /**
- * iio_buffer_read_first_n_outer() - chrdev read for buffer access
+ * iio_buffer_read_outer() - chrdev read for buffer access
  * @filp:      File structure pointer for the char device
  * @buf:       Destination buffer for iio buffer read
  * @n:         First n bytes to read
@@ -99,8 +99,8 @@ static bool iio_buffer_ready(struct iio_dev *indio_dev, struct iio_buffer *buf,
  * Return: negative values corresponding to error codes or ret != 0
  *        for ending the reading activity
  **/
-ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf,
-                                     size_t n, loff_t *f_ps)
+ssize_t iio_buffer_read_outer(struct file *filp, char __user *buf,
+                             size_t n, loff_t *f_ps)
 {
        struct iio_dev *indio_dev = filp->private_data;
        struct iio_buffer *rb = indio_dev->buffer;
@@ -112,7 +112,7 @@ ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf,
        if (!indio_dev->info)
                return -ENODEV;
 
-       if (!rb || !rb->access->read_first_n)
+       if (!rb || !rb->access->read)
                return -EINVAL;
 
        datum_size = rb->bytes_per_datum;
@@ -147,7 +147,7 @@ ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf,
                        continue;
                }
 
-               ret = rb->access->read_first_n(rb, n, buf);
+               ret = rb->access->read(rb, n, buf);
                if (ret == 0 && (filp->f_flags & O_NONBLOCK))
                        ret = -EAGAIN;
        } while (ret == 0);
index a46cdf2..65ff0d0 100644 (file)
@@ -161,6 +161,7 @@ static const char * const iio_chan_info_postfix[] = {
        [IIO_CHAN_INFO_DEBOUNCE_TIME] = "debounce_time",
        [IIO_CHAN_INFO_CALIBEMISSIVITY] = "calibemissivity",
        [IIO_CHAN_INFO_OVERSAMPLING_RATIO] = "oversampling_ratio",
+       [IIO_CHAN_INFO_THERMOCOUPLE_TYPE] = "thermocouple_type",
 };
 
 /**
@@ -596,6 +597,8 @@ static ssize_t __iio_format_value(char *buf, size_t len, unsigned int type,
                }
                return l;
        }
+       case IIO_VAL_CHAR:
+               return snprintf(buf, len, "%c", (char)vals[0]);
        default:
                return 0;
        }
@@ -837,7 +840,8 @@ static ssize_t iio_write_channel_info(struct device *dev,
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
        int ret, fract_mult = 100000;
-       int integer, fract;
+       int integer, fract = 0;
+       bool is_char = false;
 
        /* Assumes decimal - precision based on number of digits */
        if (!indio_dev->info->write_raw)
@@ -855,13 +859,24 @@ static ssize_t iio_write_channel_info(struct device *dev,
                case IIO_VAL_INT_PLUS_NANO:
                        fract_mult = 100000000;
                        break;
+               case IIO_VAL_CHAR:
+                       is_char = true;
+                       break;
                default:
                        return -EINVAL;
                }
 
-       ret = iio_str_to_fixpoint(buf, fract_mult, &integer, &fract);
-       if (ret)
-               return ret;
+       if (is_char) {
+               char ch;
+
+               if (sscanf(buf, "%c", &ch) != 1)
+                       return -EINVAL;
+               integer = ch;
+       } else {
+               ret = iio_str_to_fixpoint(buf, fract_mult, &integer, &fract);
+               if (ret)
+                       return ret;
+       }
 
        ret = indio_dev->info->write_raw(indio_dev, this_attr->c,
                                         integer, fract, this_attr->address);
@@ -1617,7 +1632,7 @@ static long iio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 }
 
 static const struct file_operations iio_buffer_fileops = {
-       .read = iio_buffer_read_first_n_outer_addr,
+       .read = iio_buffer_read_outer_addr,
        .release = iio_chrdev_release,
        .open = iio_chrdev_open,
        .poll = iio_buffer_poll_addr,
index c5dfb9a..52f86bc 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/mutex.h>
 #include <linux/err.h>
 #include <linux/irq.h>
-#include <linux/gpio.h>
 #include <linux/i2c.h>
 #include <linux/pm_runtime.h>
 #include <linux/regmap.h>
@@ -24,7 +23,6 @@
 #include <linux/iio/events.h>
 #include <linux/iio/kfifo_buf.h>
 #include <linux/iio/sysfs.h>
-#include <linux/of_gpio.h>
 
 #define APDS9960_REGMAP_NAME   "apds9960_regmap"
 #define APDS9960_DRV_NAME      "apds9960"
index 6733b52..bc196c2 100644 (file)
@@ -742,7 +742,7 @@ static int lm3533_als_set_resistor(struct lm3533_als *als, u8 val)
        if (val < LM3533_ALS_RESISTOR_MIN || val > LM3533_ALS_RESISTOR_MAX) {
                dev_err(&als->pdev->dev, "invalid resistor value\n");
                return -EINVAL;
-       };
+       }
 
        ret = lm3533_write(als->lm3533, LM3533_REG_ALS_RESISTOR_SELECT, val);
        if (ret) {
index 982bba0..0476c2b 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/irq.h>
-#include <linux/gpio.h>
 
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
index dacbac6..4889bbe 100644 (file)
@@ -9,7 +9,6 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/acpi.h>
 #include <linux/i2c.h>
 #include <linux/slab.h>
 #include <linux/regmap.h>
index 893bec5..3c88154 100644 (file)
@@ -16,8 +16,7 @@
 #include <linux/mutex.h>
 #include <linux/delay.h>
 #include <linux/bitops.h>
-#include <linux/gpio.h>
-#include <linux/of_gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/acpi.h>
 #include <linux/regulator/consumer.h>
 #include <linux/pm_runtime.h>
@@ -29,8 +28,6 @@
 #include <linux/iio/trigger_consumer.h>
 #include <linux/iio/triggered_buffer.h>
 
-#include <linux/iio/magnetometer/ak8975.h>
-
 /*
  * Register definitions, as well as various shifts and masks to get at the
  * individual fields of the registers.
@@ -206,11 +203,11 @@ static long ak09912_raw_to_gauss(u16 data)
 
 /* Compatible Asahi Kasei Compass parts */
 enum asahi_compass_chipset {
+       AKXXXX          = 0,
        AK8975,
        AK8963,
        AK09911,
        AK09912,
-       AK_MAX_TYPE
 };
 
 enum ak_ctrl_reg_addr {
@@ -248,7 +245,7 @@ struct ak_def {
        u8 data_regs[3];
 };
 
-static const struct ak_def ak_def_array[AK_MAX_TYPE] = {
+static const struct ak_def ak_def_array[] = {
        {
                .type = AK8975,
                .raw_to_gauss = ak8975_raw_to_gauss,
@@ -360,7 +357,7 @@ struct ak8975_data {
        struct mutex            lock;
        u8                      asa[3];
        long                    raw_to_gauss[3];
-       int                     eoc_gpio;
+       struct gpio_desc        *eoc_gpiod;
        int                     eoc_irq;
        wait_queue_head_t       data_ready_queue;
        unsigned long           flags;
@@ -498,15 +495,13 @@ static int ak8975_setup_irq(struct ak8975_data *data)
        if (client->irq)
                irq = client->irq;
        else
-               irq = gpio_to_irq(data->eoc_gpio);
+               irq = gpiod_to_irq(data->eoc_gpiod);
 
        rc = devm_request_irq(&client->dev, irq, ak8975_irq_handler,
                              IRQF_TRIGGER_RISING | IRQF_ONESHOT,
                              dev_name(&client->dev), data);
        if (rc < 0) {
-               dev_err(&client->dev,
-                       "irq %d request failed, (gpio %d): %d\n",
-                       irq, data->eoc_gpio, rc);
+               dev_err(&client->dev, "irq %d request failed: %d\n", irq, rc);
                return rc;
        }
 
@@ -549,7 +544,7 @@ static int ak8975_setup(struct i2c_client *client)
                return ret;
        }
 
-       if (data->eoc_gpio > 0 || client->irq > 0) {
+       if (data->eoc_gpiod || client->irq > 0) {
                ret = ak8975_setup_irq(data);
                if (ret < 0) {
                        dev_err(&client->dev,
@@ -574,7 +569,7 @@ static int wait_conversion_complete_gpio(struct ak8975_data *data)
        /* Wait for the conversion to complete. */
        while (timeout_ms) {
                msleep(AK8975_CONVERSION_DONE_POLL_TIME);
-               if (gpio_get_value(data->eoc_gpio))
+               if (gpiod_get_value(data->eoc_gpiod))
                        break;
                timeout_ms -= AK8975_CONVERSION_DONE_POLL_TIME;
        }
@@ -646,7 +641,7 @@ static int ak8975_start_read_axis(struct ak8975_data *data,
        /* Wait for the conversion to complete. */
        if (data->eoc_irq)
                ret = wait_conversion_complete_interrupt(data);
-       else if (gpio_is_valid(data->eoc_gpio))
+       else if (data->eoc_gpiod)
                ret = wait_conversion_complete_gpio(data);
        else
                ret = wait_conversion_complete_polled(data);
@@ -786,19 +781,6 @@ static const struct acpi_device_id ak_acpi_match[] = {
 MODULE_DEVICE_TABLE(acpi, ak_acpi_match);
 #endif
 
-static const char *ak8975_match_acpi_device(struct device *dev,
-                                           enum asahi_compass_chipset *chipset)
-{
-       const struct acpi_device_id *id;
-
-       id = acpi_match_device(dev->driver->acpi_match_table, dev);
-       if (!id)
-               return NULL;
-       *chipset = (int)id->driver_data;
-
-       return dev_name(dev);
-}
-
 static void ak8975_fill_buffer(struct iio_dev *indio_dev)
 {
        struct ak8975_data *data = iio_priv(indio_dev);
@@ -856,36 +838,23 @@ static int ak8975_probe(struct i2c_client *client,
 {
        struct ak8975_data *data;
        struct iio_dev *indio_dev;
-       int eoc_gpio;
+       struct gpio_desc *eoc_gpiod;
+       const void *match;
+       unsigned int i;
        int err;
+       enum asahi_compass_chipset chipset;
        const char *name = NULL;
-       enum asahi_compass_chipset chipset = AK_MAX_TYPE;
-       const struct ak8975_platform_data *pdata =
-               dev_get_platdata(&client->dev);
-
-       /* Grab and set up the supplied GPIO. */
-       if (pdata)
-               eoc_gpio = pdata->eoc_gpio;
-       else if (client->dev.of_node)
-               eoc_gpio = of_get_gpio(client->dev.of_node, 0);
-       else
-               eoc_gpio = -1;
 
-       if (eoc_gpio == -EPROBE_DEFER)
-               return -EPROBE_DEFER;
-
-       /* We may not have a GPIO based IRQ to scan, that is fine, we will
-          poll if so */
-       if (gpio_is_valid(eoc_gpio)) {
-               err = devm_gpio_request_one(&client->dev, eoc_gpio,
-                                                       GPIOF_IN, "ak_8975");
-               if (err < 0) {
-                       dev_err(&client->dev,
-                               "failed to request GPIO %d, error %d\n",
-                                                       eoc_gpio, err);
-                       return err;
-               }
-       }
+       /*
+        * Grab and set up the supplied GPIO.
+        * We may not have a GPIO based IRQ to scan, that is fine, we will
+        * poll if so.
+        */
+       eoc_gpiod = devm_gpiod_get_optional(&client->dev, NULL, GPIOD_IN);
+       if (IS_ERR(eoc_gpiod))
+               return PTR_ERR(eoc_gpiod);
+       if (eoc_gpiod)
+               gpiod_set_consumer_name(eoc_gpiod, "ak_8975");
 
        /* Register with IIO */
        indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
@@ -896,35 +865,35 @@ static int ak8975_probe(struct i2c_client *client,
        i2c_set_clientdata(client, indio_dev);
 
        data->client = client;
-       data->eoc_gpio = eoc_gpio;
+       data->eoc_gpiod = eoc_gpiod;
        data->eoc_irq = 0;
 
-       if (!pdata) {
-               err = iio_read_mount_matrix(&client->dev, "mount-matrix",
-                                           &data->orientation);
-               if (err)
-                       return err;
-       } else
-               data->orientation = pdata->orientation;
+       err = iio_read_mount_matrix(&client->dev, "mount-matrix", &data->orientation);
+       if (err)
+               return err;
 
        /* id will be NULL when enumerated via ACPI */
-       if (id) {
+       match = device_get_match_data(&client->dev);
+       if (match) {
+               chipset = (enum asahi_compass_chipset)(match);
+               name = dev_name(&client->dev);
+       } else if (id) {
                chipset = (enum asahi_compass_chipset)(id->driver_data);
                name = id->name;
-       } else if (ACPI_HANDLE(&client->dev)) {
-               name = ak8975_match_acpi_device(&client->dev, &chipset);
-               if (!name)
-                       return -ENODEV;
        } else
                return -ENOSYS;
 
-       if (chipset >= AK_MAX_TYPE) {
+       for (i = 0; i < ARRAY_SIZE(ak_def_array); i++)
+               if (ak_def_array[i].type == chipset)
+                       break;
+
+       if (i == ARRAY_SIZE(ak_def_array)) {
                dev_err(&client->dev, "AKM device type unsupported: %d\n",
                        chipset);
                return -ENODEV;
        }
 
-       data->def = &ak_def_array[chipset];
+       data->def = &ak_def_array[i];
 
        /* Fetch the regulators */
        data->vdd = devm_regulator_get(&client->dev, "vdd");
index fdba480..c6bb4ce 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/iio/common/st_sensors_i2c.h>
 #include "st_magn.h"
 
-#ifdef CONFIG_OF
 static const struct of_device_id st_magn_of_match[] = {
        {
                .compatible = "st,lsm303dlh-magn",
@@ -50,9 +49,6 @@ static const struct of_device_id st_magn_of_match[] = {
        {},
 };
 MODULE_DEVICE_TABLE(of, st_magn_of_match);
-#else
-#define st_magn_of_match NULL
-#endif
 
 static int st_magn_i2c_probe(struct i2c_client *client,
                             const struct i2c_device_id *id)
@@ -62,8 +58,7 @@ static int st_magn_i2c_probe(struct i2c_client *client,
        struct iio_dev *indio_dev;
        int err;
 
-       st_sensors_of_name_probe(&client->dev, st_magn_of_match,
-                                client->name, sizeof(client->name));
+       st_sensors_dev_name_probe(&client->dev, client->name, sizeof(client->name));
 
        settings = st_magn_get_settings(client->name);
        if (!settings) {
@@ -113,7 +108,7 @@ MODULE_DEVICE_TABLE(i2c, st_magn_id_table);
 static struct i2c_driver st_magn_driver = {
        .driver = {
                .name = "st-magn-i2c",
-               .of_match_table = of_match_ptr(st_magn_of_match),
+               .of_match_table = st_magn_of_match,
        },
        .probe = st_magn_i2c_probe,
        .remove = st_magn_i2c_remove,
index fbf909b..3d08d74 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/iio/common/st_sensors_spi.h>
 #include "st_magn.h"
 
-#ifdef CONFIG_OF
 /*
  * For new single-chip sensors use <device_name> as compatible string.
  * For old single-chip devices keep <device_name>-magn to maintain
@@ -45,9 +44,6 @@ static const struct of_device_id st_magn_of_match[] = {
        {}
 };
 MODULE_DEVICE_TABLE(of, st_magn_of_match);
-#else
-#define st_magn_of_match       NULL
-#endif
 
 static int st_magn_spi_probe(struct spi_device *spi)
 {
@@ -56,8 +52,7 @@ static int st_magn_spi_probe(struct spi_device *spi)
        struct iio_dev *indio_dev;
        int err;
 
-       st_sensors_of_name_probe(&spi->dev, st_magn_of_match,
-                                spi->modalias, sizeof(spi->modalias));
+       st_sensors_dev_name_probe(&spi->dev, spi->modalias, sizeof(spi->modalias));
 
        settings = st_magn_get_settings(spi->modalias);
        if (!settings) {
@@ -104,7 +99,7 @@ MODULE_DEVICE_TABLE(spi, st_magn_id_table);
 static struct spi_driver st_magn_driver = {
        .driver = {
                .name = "st-magn-spi",
-               .of_match_table = of_match_ptr(st_magn_of_match),
+               .of_match_table = st_magn_of_match,
        },
        .probe = st_magn_spi_probe,
        .remove = st_magn_spi_remove,
index ba420e4..9c2d9bf 100644 (file)
@@ -53,6 +53,18 @@ config IIO_CROS_EC_BARO
          To compile this driver as a module, choose M here: the module
          will be called cros_ec_baro.
 
+config DLHL60D
+       tristate "All Sensors DLHL60D and DLHL60G low voltage digital pressure sensors"
+       depends on I2C
+       select IIO_BUFFER
+       select IIO_TRIGGERED_BUFFER
+       help
+         Say yes here to build support for the All Sensors DLH series
+         pressure sensors driver.
+
+         To compile this driver as a module, choose M here: the module
+         will be called dlhl60d.
+
 config DPS310
        tristate "Infineon DPS310 pressure and temperature sensor"
        depends on I2C
index d8f5ace..5a79192 100644 (file)
@@ -9,6 +9,7 @@ obj-$(CONFIG_BMP280) += bmp280.o
 bmp280-objs := bmp280-core.o bmp280-regmap.o
 obj-$(CONFIG_BMP280_I2C) += bmp280-i2c.o
 obj-$(CONFIG_BMP280_SPI) += bmp280-spi.o
+obj-$(CONFIG_DLHL60D) += dlhl60d.o
 obj-$(CONFIG_DPS310) += dps310.o
 obj-$(CONFIG_IIO_CROS_EC_BARO) += cros_ec_baro.o
 obj-$(CONFIG_HID_SENSOR_PRESS)   += hid-sensor-press.o
index 3109c8e..8b03ea1 100644 (file)
@@ -1,8 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 #include <linux/module.h>
 #include <linux/i2c.h>
-#include <linux/acpi.h>
-#include <linux/of.h>
 #include <linux/regmap.h>
 
 #include "bmp280.h"
@@ -38,16 +36,6 @@ static int bmp280_i2c_probe(struct i2c_client *client,
                                   client->irq);
 }
 
-static const struct acpi_device_id bmp280_acpi_i2c_match[] = {
-       {"BMP0280", BMP280_CHIP_ID },
-       {"BMP0180", BMP180_CHIP_ID },
-       {"BMP0085", BMP180_CHIP_ID },
-       {"BME0280", BME280_CHIP_ID },
-       { },
-};
-MODULE_DEVICE_TABLE(acpi, bmp280_acpi_i2c_match);
-
-#ifdef CONFIG_OF
 static const struct of_device_id bmp280_of_i2c_match[] = {
        { .compatible = "bosch,bme280", .data = (void *)BME280_CHIP_ID },
        { .compatible = "bosch,bmp280", .data = (void *)BMP280_CHIP_ID },
@@ -56,9 +44,6 @@ static const struct of_device_id bmp280_of_i2c_match[] = {
        { },
 };
 MODULE_DEVICE_TABLE(of, bmp280_of_i2c_match);
-#else
-#define bmp280_of_i2c_match NULL
-#endif
 
 static const struct i2c_device_id bmp280_i2c_id[] = {
        {"bmp280", BMP280_CHIP_ID },
@@ -72,8 +57,7 @@ MODULE_DEVICE_TABLE(i2c, bmp280_i2c_id);
 static struct i2c_driver bmp280_i2c_driver = {
        .driver = {
                .name   = "bmp280",
-               .acpi_match_table = ACPI_PTR(bmp280_acpi_i2c_match),
-               .of_match_table = of_match_ptr(bmp280_of_i2c_match),
+               .of_match_table = bmp280_of_i2c_match,
                .pm = &bmp280_dev_pm_ops,
        },
        .probe          = bmp280_i2c_probe,
diff --git a/drivers/iio/pressure/dlhl60d.c b/drivers/iio/pressure/dlhl60d.c
new file mode 100644 (file)
index 0000000..b8c99e7
--- /dev/null
@@ -0,0 +1,375 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * All Sensors DLH series low voltage digital pressure sensors
+ *
+ * Copyright (c) 2019 AVL DiTEST GmbH
+ *   Tomislav Denis <tomislav.denis@avl.com>
+ *
+ * Datasheet: http://www.allsensors.com/cad/DS-0355_Rev_B.PDF
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+#include <asm/unaligned.h>
+
+/* Commands */
+#define DLH_START_SINGLE    0xAA
+
+/* Status bits */
+#define DLH_STATUS_OK       0x40
+
+/* DLH  data format */
+#define DLH_NUM_READ_BYTES  7
+#define DLH_NUM_DATA_BYTES  3
+#define DLH_NUM_PR_BITS     24
+#define DLH_NUM_TEMP_BITS   24
+
+/* DLH  timings */
+#define DLH_SINGLE_DUT_MS   5
+
+enum dhl_ids {
+       dlhl60d,
+       dlhl60g,
+};
+
+struct dlh_info {
+       u8 osdig;           /* digital offset factor */
+       unsigned int fss;   /* full scale span (inch H2O) */
+};
+
+struct dlh_state {
+       struct i2c_client *client;
+       struct dlh_info info;
+       bool use_interrupt;
+       struct completion completion;
+       u8 rx_buf[DLH_NUM_READ_BYTES] ____cacheline_aligned;
+};
+
+static struct dlh_info dlh_info_tbl[] = {
+       [dlhl60d] = {
+               .osdig = 2,
+               .fss = 120,
+       },
+       [dlhl60g] = {
+               .osdig = 10,
+               .fss = 60,
+       },
+};
+
+
+static int dlh_cmd_start_single(struct dlh_state *st)
+{
+       int ret;
+
+       ret = i2c_smbus_write_byte(st->client, DLH_START_SINGLE);
+       if (ret)
+               dev_err(&st->client->dev,
+                       "%s: I2C write byte failed\n", __func__);
+
+       return ret;
+}
+
+static int dlh_cmd_read_data(struct dlh_state *st)
+{
+       int ret;
+
+       ret = i2c_master_recv(st->client, st->rx_buf, DLH_NUM_READ_BYTES);
+       if (ret < 0) {
+               dev_err(&st->client->dev,
+                       "%s: I2C read block failed\n", __func__);
+               return ret;
+       }
+
+       if (st->rx_buf[0] != DLH_STATUS_OK) {
+               dev_err(&st->client->dev,
+                       "%s: invalid status 0x%02x\n", __func__, st->rx_buf[0]);
+               return -EBUSY;
+       }
+
+       return 0;
+}
+
+static int dlh_start_capture_and_read(struct dlh_state *st)
+{
+       int ret;
+
+       if (st->use_interrupt)
+               reinit_completion(&st->completion);
+
+       ret = dlh_cmd_start_single(st);
+       if (ret)
+               return ret;
+
+       if (st->use_interrupt) {
+               ret = wait_for_completion_timeout(&st->completion,
+                       msecs_to_jiffies(DLH_SINGLE_DUT_MS));
+               if (!ret) {
+                       dev_err(&st->client->dev,
+                               "%s: conversion timed out\n", __func__);
+                       return -ETIMEDOUT;
+               }
+       } else {
+               mdelay(DLH_SINGLE_DUT_MS);
+       }
+
+       return dlh_cmd_read_data(st);
+}
+
+static int dlh_read_direct(struct dlh_state *st,
+       unsigned int *pressure, unsigned int *temperature)
+{
+       int ret;
+
+       ret = dlh_start_capture_and_read(st);
+       if (ret)
+               return ret;
+
+       *pressure = get_unaligned_be32(&st->rx_buf[1]) >> 8;
+       *temperature = get_unaligned_be32(&st->rx_buf[3]) &
+               GENMASK(DLH_NUM_TEMP_BITS - 1, 0);
+
+       return 0;
+}
+
+static int dlh_read_raw(struct iio_dev *indio_dev,
+       struct iio_chan_spec const *channel, int *value,
+       int *value2, long mask)
+{
+       struct dlh_state *st = iio_priv(indio_dev);
+       unsigned int pressure, temperature;
+       int ret;
+       s64 tmp;
+       s32 rem;
+
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               ret = iio_device_claim_direct_mode(indio_dev);
+               if (ret)
+                       return ret;
+
+               ret = dlh_read_direct(st, &pressure, &temperature);
+               iio_device_release_direct_mode(indio_dev);
+               if (ret)
+                       return ret;
+
+               switch (channel->type) {
+               case IIO_PRESSURE:
+                       *value = pressure;
+                       return IIO_VAL_INT;
+
+               case IIO_TEMP:
+                       *value = temperature;
+                       return IIO_VAL_INT;
+
+               default:
+                       return -EINVAL;
+               }
+       case IIO_CHAN_INFO_SCALE:
+               switch (channel->type) {
+               case IIO_PRESSURE:
+                       tmp = div_s64(125LL * st->info.fss * 24909 * 100,
+                               1 << DLH_NUM_PR_BITS);
+                       tmp = div_s64_rem(tmp, 1000000000LL, &rem);
+                       *value = tmp;
+                       *value2 = rem;
+                       return IIO_VAL_INT_PLUS_NANO;
+
+               case IIO_TEMP:
+                       *value = 125 * 1000;
+                       *value2 = DLH_NUM_TEMP_BITS;
+                       return IIO_VAL_FRACTIONAL_LOG2;
+
+               default:
+                       return -EINVAL;
+               }
+       case IIO_CHAN_INFO_OFFSET:
+               switch (channel->type) {
+               case IIO_PRESSURE:
+                       *value = -125 * st->info.fss * 24909;
+                       *value2 = 100 * st->info.osdig * 100000;
+                       return IIO_VAL_FRACTIONAL;
+
+               case IIO_TEMP:
+                       *value = -40 * 1000;
+                       return IIO_VAL_INT;
+
+               default:
+                       return -EINVAL;
+               }
+       }
+
+       return -EINVAL;
+}
+
+static const struct iio_info dlh_info = {
+       .read_raw = dlh_read_raw,
+};
+
+static const struct iio_chan_spec dlh_channels[] = {
+       {
+               .type = IIO_PRESSURE,
+               .indexed = 1,
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+               .info_mask_shared_by_type =
+                       BIT(IIO_CHAN_INFO_SCALE) |
+                       BIT(IIO_CHAN_INFO_OFFSET),
+               .scan_index = 0,
+               .scan_type = {
+                       .sign = 'u',
+                       .realbits = DLH_NUM_PR_BITS,
+                       .storagebits = 32,
+                       .shift = 8,
+                       .endianness = IIO_BE,
+               },
+       }, {
+               .type = IIO_TEMP,
+               .indexed = 1,
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+               .info_mask_shared_by_type =
+                       BIT(IIO_CHAN_INFO_SCALE) |
+                       BIT(IIO_CHAN_INFO_OFFSET),
+               .scan_index = 1,
+               .scan_type = {
+                       .sign = 'u',
+                       .realbits = DLH_NUM_TEMP_BITS,
+                       .storagebits = 32,
+                       .shift = 8,
+                       .endianness = IIO_BE,
+               },
+       }
+};
+
+static irqreturn_t dlh_trigger_handler(int irq, void *private)
+{
+       struct iio_poll_func *pf = private;
+       struct iio_dev *indio_dev = pf->indio_dev;
+       struct dlh_state *st = iio_priv(indio_dev);
+       int ret;
+       unsigned int chn, i = 0;
+       __be32 tmp_buf[2];
+
+       ret = dlh_start_capture_and_read(st);
+       if (ret)
+               goto out;
+
+       for_each_set_bit(chn, indio_dev->active_scan_mask,
+               indio_dev->masklength) {
+               memcpy(tmp_buf + i,
+                       &st->rx_buf[1] + chn * DLH_NUM_DATA_BYTES,
+                       DLH_NUM_DATA_BYTES);
+               i++;
+       }
+
+       iio_push_to_buffers(indio_dev, tmp_buf);
+
+out:
+       iio_trigger_notify_done(indio_dev->trig);
+
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t dlh_interrupt(int irq, void *private)
+{
+       struct iio_dev *indio_dev = private;
+       struct dlh_state *st = iio_priv(indio_dev);
+
+       complete(&st->completion);
+
+       return IRQ_HANDLED;
+};
+
+static int dlh_probe(struct i2c_client *client,
+       const struct i2c_device_id *id)
+{
+       struct dlh_state *st;
+       struct iio_dev *indio_dev;
+       int ret;
+
+       if (!i2c_check_functionality(client->adapter,
+               I2C_FUNC_I2C | I2C_FUNC_SMBUS_WRITE_BYTE)) {
+               dev_err(&client->dev,
+                       "adapter doesn't support required i2c functionality\n");
+               return -EOPNOTSUPP;
+       }
+
+       indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));
+       if (!indio_dev) {
+               dev_err(&client->dev, "failed to allocate iio device\n");
+               return -ENOMEM;
+       }
+
+       i2c_set_clientdata(client, indio_dev);
+
+       st = iio_priv(indio_dev);
+       st->info = dlh_info_tbl[id->driver_data];
+       st->client = client;
+       st->use_interrupt = false;
+
+       indio_dev->name = id->name;
+       indio_dev->dev.parent = &client->dev;
+       indio_dev->dev.of_node = client->dev.of_node;
+       indio_dev->info = &dlh_info;
+       indio_dev->modes = INDIO_DIRECT_MODE;
+       indio_dev->channels =  dlh_channels;
+       indio_dev->num_channels = ARRAY_SIZE(dlh_channels);
+
+       if (client->irq > 0) {
+               ret = devm_request_threaded_irq(&client->dev, client->irq,
+                       dlh_interrupt, NULL,
+                       IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+                       id->name, indio_dev);
+               if (ret) {
+                       dev_err(&client->dev, "failed to allocate threaded irq");
+                       return ret;
+               }
+
+               st->use_interrupt = true;
+               init_completion(&st->completion);
+       }
+
+       ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev,
+               NULL, &dlh_trigger_handler, NULL);
+       if (ret) {
+               dev_err(&client->dev, "failed to setup iio buffer\n");
+               return ret;
+       }
+
+       ret = devm_iio_device_register(&client->dev, indio_dev);
+       if (ret)
+               dev_err(&client->dev, "failed to register iio device\n");
+
+       return ret;
+}
+
+static const struct of_device_id dlh_of_match[] = {
+       { .compatible = "asc,dlhl60d" },
+       { .compatible = "asc,dlhl60g" },
+       {}
+};
+MODULE_DEVICE_TABLE(of, dlh_of_match);
+
+static const struct i2c_device_id dlh_id[] = {
+       { "dlhl60d",    dlhl60d },
+       { "dlhl60g",    dlhl60g },
+       {}
+};
+MODULE_DEVICE_TABLE(i2c, dlh_id);
+
+static struct i2c_driver dlh_driver = {
+       .driver = {
+               .name = "dlhl60d",
+               .of_match_table = dlh_of_match,
+       },
+       .probe = dlh_probe,
+       .id_table = dlh_id,
+};
+module_i2c_driver(dlh_driver);
+
+MODULE_AUTHOR("Tomislav Denis <tomislav.denis@avl.com>");
+MODULE_DESCRIPTION("Driver for All Sensors DLH series pressure sensors");
+MODULE_LICENSE("GPL v2");
index c2e47a6..5c746ff 100644 (file)
@@ -37,7 +37,7 @@ enum st_press_type {
  * struct st_sensors_platform_data - default press platform data
  * @drdy_int_pin: default press DRDY is available on INT1 pin.
  */
-static const struct st_sensors_platform_data default_press_pdata = {
+static __maybe_unused const struct st_sensors_platform_data default_press_pdata = {
        .drdy_int_pin = 1,
 };
 
index 71d2ed6..09c6903 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/slab.h>
-#include <linux/acpi.h>
 #include <linux/i2c.h>
 #include <linux/iio/iio.h>
 
@@ -18,7 +17,6 @@
 #include <linux/iio/common/st_sensors_i2c.h>
 #include "st_pressure.h"
 
-#ifdef CONFIG_OF
 static const struct of_device_id st_press_of_match[] = {
        {
                .compatible = "st,lps001wp-press",
@@ -51,9 +49,6 @@ static const struct of_device_id st_press_of_match[] = {
        {},
 };
 MODULE_DEVICE_TABLE(of, st_press_of_match);
-#else
-#define st_press_of_match NULL
-#endif
 
 #ifdef CONFIG_ACPI
 static const struct acpi_device_id st_press_acpi_match[] = {
@@ -61,8 +56,6 @@ static const struct acpi_device_id st_press_acpi_match[] = {
        { },
 };
 MODULE_DEVICE_TABLE(acpi, st_press_acpi_match);
-#else
-#define st_press_acpi_match NULL
 #endif
 
 static const struct i2c_device_id st_press_id_table[] = {
@@ -85,18 +78,7 @@ static int st_press_i2c_probe(struct i2c_client *client,
        struct iio_dev *indio_dev;
        int ret;
 
-       if (client->dev.of_node) {
-               st_sensors_of_name_probe(&client->dev, st_press_of_match,
-                                        client->name, sizeof(client->name));
-       } else if (ACPI_HANDLE(&client->dev)) {
-               ret = st_sensors_match_acpi_device(&client->dev);
-               if ((ret < 0) || (ret >= ST_PRESS_MAX))
-                       return -ENODEV;
-
-               strlcpy(client->name, st_press_id_table[ret].name,
-                       sizeof(client->name));
-       } else if (!id)
-               return -ENODEV;
+       st_sensors_dev_name_probe(&client->dev, client->name, sizeof(client->name));
 
        settings = st_press_get_settings(client->name);
        if (!settings) {
@@ -133,7 +115,7 @@ static int st_press_i2c_remove(struct i2c_client *client)
 static struct i2c_driver st_press_driver = {
        .driver = {
                .name = "st-press-i2c",
-               .of_match_table = of_match_ptr(st_press_of_match),
+               .of_match_table = st_press_of_match,
                .acpi_match_table = ACPI_PTR(st_press_acpi_match),
        },
        .probe = st_press_i2c_probe,
index 7c8b702..b5ee3ec 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/iio/common/st_sensors_spi.h>
 #include "st_pressure.h"
 
-#ifdef CONFIG_OF
 /*
  * For new single-chip sensors use <device_name> as compatible string.
  * For old single-chip devices keep <device_name>-press to maintain
@@ -55,9 +54,6 @@ static const struct of_device_id st_press_of_match[] = {
        {},
 };
 MODULE_DEVICE_TABLE(of, st_press_of_match);
-#else
-#define st_press_of_match      NULL
-#endif
 
 static int st_press_spi_probe(struct spi_device *spi)
 {
@@ -66,8 +62,7 @@ static int st_press_spi_probe(struct spi_device *spi)
        struct iio_dev *indio_dev;
        int err;
 
-       st_sensors_of_name_probe(&spi->dev, st_press_of_match,
-                                spi->modalias, sizeof(spi->modalias));
+       st_sensors_dev_name_probe(&spi->dev, spi->modalias, sizeof(spi->modalias));
 
        settings = st_press_get_settings(spi->modalias);
        if (!settings) {
@@ -116,7 +111,7 @@ MODULE_DEVICE_TABLE(spi, st_press_id_table);
 static struct spi_driver st_press_driver = {
        .driver = {
                .name = "st-press-spi",
-               .of_match_table = of_match_ptr(st_press_of_match),
+               .of_match_table = st_press_of_match,
        },
        .probe = st_press_spi_probe,
        .remove = st_press_spi_remove,
index d536014..37606d4 100644 (file)
@@ -58,6 +58,21 @@ config MB1232
          To compile this driver as a module, choose M here: the
          module will be called mb1232.
 
+config PING
+       tristate "Parallax GPIO bitbanged ranger sensors"
+       depends on GPIOLIB
+       help
+         Say Y here to build a driver for GPIO bitbanged ranger sensors
+         with just one GPIO for the trigger and echo. This driver can be
+         used to measure the distance of objects.
+
+         Actually supported are:
+         - Parallax PING))) (ultrasonic)
+         - Parallax LaserPING (time-of-flight)
+
+         To compile this driver as a module, choose M here: the
+         module will be called ping.
+
 config RFD77402
        tristate "RFD77402 ToF sensor"
        depends on I2C
index 0bb5f9d..c591b01 100644 (file)
@@ -8,6 +8,7 @@ obj-$(CONFIG_AS3935)            += as3935.o
 obj-$(CONFIG_ISL29501)         += isl29501.o
 obj-$(CONFIG_LIDAR_LITE_V2)    += pulsedlight-lidar-lite-v2.o
 obj-$(CONFIG_MB1232)           += mb1232.o
+obj-$(CONFIG_PING)             += ping.o
 obj-$(CONFIG_RFD77402)         += rfd77402.o
 obj-$(CONFIG_SRF04)            += srf04.o
 obj-$(CONFIG_SRF08)            += srf08.o
index b591c63..bac9a43 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/mutex.h>
 #include <linux/err.h>
 #include <linux/irq.h>
-#include <linux/gpio.h>
 #include <linux/spi/spi.h>
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
@@ -22,8 +21,6 @@
 #include <linux/iio/trigger_consumer.h>
 #include <linux/iio/buffer.h>
 #include <linux/iio/triggered_buffer.h>
-#include <linux/of_gpio.h>
-
 
 #define AS3935_AFE_GAIN                0x00
 #define AS3935_AFE_MASK                0x3F
diff --git a/drivers/iio/proximity/ping.c b/drivers/iio/proximity/ping.c
new file mode 100644 (file)
index 0000000..34aff10
--- /dev/null
@@ -0,0 +1,335 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * PING: ultrasonic sensor for distance measuring by using only one GPIOs
+ *
+ * Copyright (c) 2019 Andreas Klinger <ak@it-klinger.de>
+ *
+ * For details about the devices see:
+ * http://parallax.com/sites/default/files/downloads/28041-LaserPING-2m-Rangefinder-Guide.pdf
+ * http://parallax.com/sites/default/files/downloads/28015-PING-Documentation-v1.6.pdf
+ *
+ * the measurement cycle as timing diagram looks like:
+ *
+ * GPIO      ___              ________________________
+ * ping:  __/   \____________/                        \________________
+ *          ^   ^            ^                        ^
+ *          |<->|            interrupt                interrupt
+ *         udelay(5)         (ts_rising)              (ts_falling)
+ *                           |<---------------------->|
+ *                           .  pulse time measured   .
+ *                           .  --> one round trip of ultra sonic waves
+ * ultra                     .                        .
+ * sonic            _   _   _.                        .
+ * burst: _________/ \_/ \_/ \_________________________________________
+ *                                                    .
+ * ultra                                              .
+ * sonic                                     _   _   _.
+ * echo:  __________________________________/ \_/ \_/ \________________
+ */
+#include <linux/err.h>
+#include <linux/gpio/consumer.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+
+struct ping_cfg {
+       unsigned long   trigger_pulse_us;       /* length of trigger pulse */
+       int             laserping_error;        /* support error code in */
+                                               /*   pulse width of laser */
+                                               /*   ping sensors */
+       s64             timeout_ns;             /* timeout in ns */
+};
+
+struct ping_data {
+       struct device           *dev;
+       struct gpio_desc        *gpiod_ping;
+       struct mutex            lock;
+       int                     irqnr;
+       ktime_t                 ts_rising;
+       ktime_t                 ts_falling;
+       struct completion       rising;
+       struct completion       falling;
+       const struct ping_cfg   *cfg;
+};
+
+static const struct ping_cfg pa_ping_cfg = {
+       .trigger_pulse_us       = 5,
+       .laserping_error        = 0,
+       .timeout_ns             = 18500000,     /* 3 meters */
+};
+
+static const struct ping_cfg pa_laser_ping_cfg = {
+       .trigger_pulse_us       = 5,
+       .laserping_error        = 1,
+       .timeout_ns             = 15500000,     /* 2 meters plus error codes */
+};
+
+static irqreturn_t ping_handle_irq(int irq, void *dev_id)
+{
+       struct iio_dev *indio_dev = dev_id;
+       struct ping_data *data = iio_priv(indio_dev);
+       ktime_t now = ktime_get();
+
+       if (gpiod_get_value(data->gpiod_ping)) {
+               data->ts_rising = now;
+               complete(&data->rising);
+       } else {
+               data->ts_falling = now;
+               complete(&data->falling);
+       }
+
+       return IRQ_HANDLED;
+}
+
+static int ping_read(struct ping_data *data)
+{
+       int ret;
+       ktime_t ktime_dt;
+       s64 dt_ns;
+       u32 time_ns, distance_mm;
+       struct platform_device *pdev = to_platform_device(data->dev);
+       struct iio_dev *indio_dev = iio_priv_to_dev(data);
+
+       /*
+        * just one read-echo-cycle can take place at a time
+        * ==> lock against concurrent reading calls
+        */
+       mutex_lock(&data->lock);
+
+       reinit_completion(&data->rising);
+       reinit_completion(&data->falling);
+
+       gpiod_set_value(data->gpiod_ping, 1);
+       udelay(data->cfg->trigger_pulse_us);
+       gpiod_set_value(data->gpiod_ping, 0);
+
+       ret = gpiod_direction_input(data->gpiod_ping);
+       if (ret < 0) {
+               mutex_unlock(&data->lock);
+               return ret;
+       }
+
+       data->irqnr = gpiod_to_irq(data->gpiod_ping);
+       if (data->irqnr < 0) {
+               dev_err(data->dev, "gpiod_to_irq: %d\n", data->irqnr);
+               mutex_unlock(&data->lock);
+               return data->irqnr;
+       }
+
+       ret = request_irq(data->irqnr, ping_handle_irq,
+                               IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+                                                       pdev->name, indio_dev);
+       if (ret < 0) {
+               dev_err(data->dev, "request_irq: %d\n", ret);
+               mutex_unlock(&data->lock);
+               return ret;
+       }
+
+       /* it should not take more than 20 ms until echo is rising */
+       ret = wait_for_completion_killable_timeout(&data->rising, HZ/50);
+       if (ret < 0)
+               goto err_reset_direction;
+       else if (ret == 0) {
+               ret = -ETIMEDOUT;
+               goto err_reset_direction;
+       }
+
+       /* it cannot take more than 50 ms until echo is falling */
+       ret = wait_for_completion_killable_timeout(&data->falling, HZ/20);
+       if (ret < 0)
+               goto err_reset_direction;
+       else if (ret == 0) {
+               ret = -ETIMEDOUT;
+               goto err_reset_direction;
+       }
+
+       ktime_dt = ktime_sub(data->ts_falling, data->ts_rising);
+
+       free_irq(data->irqnr, indio_dev);
+
+       ret = gpiod_direction_output(data->gpiod_ping, GPIOD_OUT_LOW);
+       if (ret < 0) {
+               mutex_unlock(&data->lock);
+               return ret;
+       }
+
+       mutex_unlock(&data->lock);
+
+       dt_ns = ktime_to_ns(ktime_dt);
+       if (dt_ns > data->cfg->timeout_ns) {
+               dev_dbg(data->dev, "distance out of range: dt=%lldns\n",
+                                                               dt_ns);
+               return -EIO;
+       }
+
+       time_ns = dt_ns;
+
+       /*
+        * read error code of laser ping sensor and give users chance to
+        * figure out error by using dynamic debuggging
+        */
+       if (data->cfg->laserping_error) {
+               if ((time_ns > 12500000) && (time_ns <= 13500000)) {
+                       dev_dbg(data->dev, "target too close or to far\n");
+                       return -EIO;
+               }
+               if ((time_ns > 13500000) && (time_ns <= 14500000)) {
+                       dev_dbg(data->dev, "internal sensor error\n");
+                       return -EIO;
+               }
+               if ((time_ns > 14500000) && (time_ns <= 15500000)) {
+                       dev_dbg(data->dev, "internal sensor timeout\n");
+                       return -EIO;
+               }
+       }
+
+       /*
+        * the speed as function of the temperature is approximately:
+        *
+        * speed = 331,5 + 0,6 * Temp
+        *   with Temp in Â°C
+        *   and speed in m/s
+        *
+        * use 343,5 m/s as ultrasonic speed at 20 Â°C here in absence of the
+        * temperature
+        *
+        * therefore:
+        *             time     343,5     time * 232
+        * distance = ------ * ------- = ------------
+        *             10^6         2        1350800
+        *   with time in ns
+        *   and distance in mm (one way)
+        *
+        * because we limit to 3 meters the multiplication with 232 just
+        * fits into 32 bit
+        */
+       distance_mm = time_ns * 232 / 1350800;
+
+       return distance_mm;
+
+err_reset_direction:
+       free_irq(data->irqnr, indio_dev);
+       mutex_unlock(&data->lock);
+
+       if (gpiod_direction_output(data->gpiod_ping, GPIOD_OUT_LOW))
+               dev_dbg(data->dev, "error in gpiod_direction_output\n");
+       return ret;
+}
+
+static int ping_read_raw(struct iio_dev *indio_dev,
+                           struct iio_chan_spec const *channel, int *val,
+                           int *val2, long info)
+{
+       struct ping_data *data = iio_priv(indio_dev);
+       int ret;
+
+       if (channel->type != IIO_DISTANCE)
+               return -EINVAL;
+
+       switch (info) {
+       case IIO_CHAN_INFO_RAW:
+               ret = ping_read(data);
+               if (ret < 0)
+                       return ret;
+               *val = ret;
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_SCALE:
+               /*
+                * maximum resolution in datasheet is 1 mm
+                * 1 LSB is 1 mm
+                */
+               *val = 0;
+               *val2 = 1000;
+               return IIO_VAL_INT_PLUS_MICRO;
+       default:
+               return -EINVAL;
+       }
+}
+
+static const struct iio_info ping_iio_info = {
+       .read_raw               = ping_read_raw,
+};
+
+static const struct iio_chan_spec ping_chan_spec[] = {
+       {
+               .type = IIO_DISTANCE,
+               .info_mask_separate =
+                               BIT(IIO_CHAN_INFO_RAW) |
+                               BIT(IIO_CHAN_INFO_SCALE),
+       },
+};
+
+static const struct of_device_id of_ping_match[] = {
+       { .compatible = "parallax,ping", .data = &pa_ping_cfg},
+       { .compatible = "parallax,laserping", .data = &pa_ping_cfg},
+       {},
+};
+
+MODULE_DEVICE_TABLE(of, of_ping_match);
+
+static int ping_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct ping_data *data;
+       struct iio_dev *indio_dev;
+
+       indio_dev = devm_iio_device_alloc(dev, sizeof(struct ping_data));
+       if (!indio_dev) {
+               dev_err(dev, "failed to allocate IIO device\n");
+               return -ENOMEM;
+       }
+
+       data = iio_priv(indio_dev);
+       data->dev = dev;
+       data->cfg = of_device_get_match_data(dev);
+
+       mutex_init(&data->lock);
+       init_completion(&data->rising);
+       init_completion(&data->falling);
+
+       data->gpiod_ping = devm_gpiod_get(dev, "ping", GPIOD_OUT_LOW);
+       if (IS_ERR(data->gpiod_ping)) {
+               dev_err(dev, "failed to get ping-gpios: err=%ld\n",
+                                               PTR_ERR(data->gpiod_ping));
+               return PTR_ERR(data->gpiod_ping);
+       }
+
+       if (gpiod_cansleep(data->gpiod_ping)) {
+               dev_err(data->dev, "cansleep-GPIOs not supported\n");
+               return -ENODEV;
+       }
+
+       platform_set_drvdata(pdev, indio_dev);
+
+       indio_dev->name = "ping";
+       indio_dev->dev.parent = &pdev->dev;
+       indio_dev->info = &ping_iio_info;
+       indio_dev->modes = INDIO_DIRECT_MODE;
+       indio_dev->channels = ping_chan_spec;
+       indio_dev->num_channels = ARRAY_SIZE(ping_chan_spec);
+
+       return devm_iio_device_register(dev, indio_dev);
+}
+
+static struct platform_driver ping_driver = {
+       .probe          = ping_probe,
+       .driver         = {
+               .name           = "ping-gpio",
+               .of_match_table = of_ping_match,
+       },
+};
+
+module_platform_driver(ping_driver);
+
+MODULE_AUTHOR("Andreas Klinger <ak@it-klinger.de>");
+MODULE_DESCRIPTION("PING sensors for distance measuring using one GPIOs");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:ping");
index 17b8962..a391f46 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/bitops.h>
 #include <linux/delay.h>
 #include <linux/device.h>
-#include <linux/gpio.h>
 #include <linux/gpio/consumer.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
index 73ed550..b4cb21a 100644 (file)
@@ -6,12 +6,14 @@
  * Copyright (C) 2018-2019 Rockwell Collins
  */
 
+#include <linux/ctype.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/err.h>
 #include <linux/spi/spi.h>
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
+#include <linux/util_macros.h>
 #include <dt-bindings/iio/temperature/thermocouple.h>
 /*
  * The MSB of the register value determines whether the following byte will
@@ -23,6 +25,9 @@
 #define MAX31856_CR0_1SHOT         BIT(6)
 #define MAX31856_CR0_OCFAULT       BIT(4)
 #define MAX31856_CR0_OCFAULT_MASK  GENMASK(5, 4)
+#define MAX31856_CR0_FILTER_50HZ   BIT(0)
+#define MAX31856_AVERAGING_MASK    GENMASK(6, 4)
+#define MAX31856_AVERAGING_SHIFT   4
 #define MAX31856_TC_TYPE_MASK      GENMASK(3, 0)
 #define MAX31856_FAULT_OVUV        BIT(1)
 #define MAX31856_FAULT_OPEN        BIT(0)
@@ -49,7 +54,10 @@ static const struct iio_chan_spec max31856_channels[] = {
        {       /* Thermocouple Temperature */
                .type = IIO_TEMP,
                .info_mask_separate =
-                       BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+                       BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) |
+                       BIT(IIO_CHAN_INFO_THERMOCOUPLE_TYPE),
+               .info_mask_shared_by_type =
+                       BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO)
        },
        {       /* Cold Junction Temperature */
                .type = IIO_TEMP,
@@ -57,12 +65,20 @@ static const struct iio_chan_spec max31856_channels[] = {
                .modified = 1,
                .info_mask_separate =
                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+               .info_mask_shared_by_type =
+                       BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO)
        },
 };
 
 struct max31856_data {
        struct spi_device *spi;
        u32 thermocouple_type;
+       bool filter_50hz;
+       int averaging;
+};
+
+static const char max31856_tc_types[] = {
+       'B', 'E', 'J', 'K', 'N', 'R', 'S', 'T'
 };
 
 static int max31856_read(struct max31856_data *data, u8 reg,
@@ -107,6 +123,10 @@ static int max31856_init(struct max31856_data *data)
 
        reg_cr1_val &= ~MAX31856_TC_TYPE_MASK;
        reg_cr1_val |= data->thermocouple_type;
+
+       reg_cr1_val &= ~MAX31856_AVERAGING_MASK;
+       reg_cr1_val |= data->averaging << MAX31856_AVERAGING_SHIFT;
+
        ret = max31856_write(data, MAX31856_CR1_REG, reg_cr1_val);
        if (ret)
                return ret;
@@ -123,6 +143,11 @@ static int max31856_init(struct max31856_data *data)
        reg_cr0_val &= ~MAX31856_CR0_1SHOT;
        reg_cr0_val |= MAX31856_CR0_AUTOCONVERT;
 
+       if (data->filter_50hz)
+               reg_cr0_val |= MAX31856_CR0_FILTER_50HZ;
+       else
+               reg_cr0_val &= ~MAX31856_CR0_FILTER_50HZ;
+
        return max31856_write(data, MAX31856_CR0_REG, reg_cr0_val);
 }
 
@@ -210,6 +235,12 @@ static int max31856_read_raw(struct iio_dev *indio_dev,
                        return IIO_VAL_INT_PLUS_MICRO;
                }
                break;
+       case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
+               *val = 1 << data->averaging;
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_THERMOCOUPLE_TYPE:
+               *val = max31856_tc_types[data->thermocouple_type];
+               return IIO_VAL_CHAR;
        default:
                ret = -EINVAL;
                break;
@@ -218,6 +249,62 @@ static int max31856_read_raw(struct iio_dev *indio_dev,
        return ret;
 }
 
+static int max31856_write_raw_get_fmt(struct iio_dev *indio_dev,
+                                     struct iio_chan_spec const *chan,
+                                     long mask)
+{
+       switch (mask) {
+       case IIO_CHAN_INFO_THERMOCOUPLE_TYPE:
+               return IIO_VAL_CHAR;
+       default:
+               return IIO_VAL_INT;
+       }
+}
+
+static int max31856_write_raw(struct iio_dev *indio_dev,
+                             struct iio_chan_spec const *chan,
+                             int val, int val2, long mask)
+{
+       struct max31856_data *data = iio_priv(indio_dev);
+       int msb;
+
+       switch (mask) {
+       case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
+               if (val > 16 || val < 1)
+                       return -EINVAL;
+               msb = fls(val) - 1;
+               /* Round up to next 2pow if needed */
+               if (BIT(msb) < val)
+                       msb++;
+
+               data->averaging = msb;
+               max31856_init(data);
+               break;
+       case IIO_CHAN_INFO_THERMOCOUPLE_TYPE:
+       {
+               int tc_type = -1;
+               int i;
+
+               for (i = 0; i < ARRAY_SIZE(max31856_tc_types); i++) {
+                       if (max31856_tc_types[i] == toupper(val)) {
+                               tc_type = i;
+                               break;
+                       }
+               }
+               if (tc_type < 0)
+                       return -EINVAL;
+
+               data->thermocouple_type = tc_type;
+               max31856_init(data);
+               break;
+       }
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 static ssize_t show_fault(struct device *dev, u8 faultbit, char *buf)
 {
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
@@ -249,12 +336,54 @@ static ssize_t show_fault_oc(struct device *dev,
        return show_fault(dev, MAX31856_FAULT_OPEN, buf);
 }
 
+static ssize_t show_filter(struct device *dev,
+                          struct device_attribute *attr,
+                          char *buf)
+{
+       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+       struct max31856_data *data = iio_priv(indio_dev);
+
+       return sprintf(buf, "%d\n", data->filter_50hz ? 50 : 60);
+}
+
+static ssize_t set_filter(struct device *dev,
+                         struct device_attribute *attr,
+                         const char *buf,
+                         size_t len)
+{
+       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+       struct max31856_data *data = iio_priv(indio_dev);
+       unsigned int freq;
+       int ret;
+
+       ret = kstrtouint(buf, 10, &freq);
+       if (ret)
+               return ret;
+
+       switch (freq) {
+       case 50:
+               data->filter_50hz = true;
+               break;
+       case 60:
+               data->filter_50hz = false;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       max31856_init(data);
+       return len;
+}
+
 static IIO_DEVICE_ATTR(fault_ovuv, 0444, show_fault_ovuv, NULL, 0);
 static IIO_DEVICE_ATTR(fault_oc, 0444, show_fault_oc, NULL, 0);
+static IIO_DEVICE_ATTR(in_temp_filter_notch_center_frequency, 0644,
+                      show_filter, set_filter, 0);
 
 static struct attribute *max31856_attributes[] = {
        &iio_dev_attr_fault_ovuv.dev_attr.attr,
        &iio_dev_attr_fault_oc.dev_attr.attr,
+       &iio_dev_attr_in_temp_filter_notch_center_frequency.dev_attr.attr,
        NULL,
 };
 
@@ -264,6 +393,8 @@ static const struct attribute_group max31856_group = {
 
 static const struct iio_info max31856_info = {
        .read_raw = max31856_read_raw,
+       .write_raw = max31856_write_raw,
+       .write_raw_get_fmt = max31856_write_raw_get_fmt,
        .attrs = &max31856_group,
 };
 
@@ -280,6 +411,7 @@ static int max31856_probe(struct spi_device *spi)
 
        data = iio_priv(indio_dev);
        data->spi = spi;
+       data->filter_50hz = false;
 
        spi_set_drvdata(spi, indio_dev);
 
index d136060..8d21116 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/of_device.h>
 #include <linux/spi/spi.h>
 #include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
 #include <linux/iio/trigger.h>
 #include <linux/iio/buffer.h>
 #include <linux/iio/triggered_buffer.h>
 enum {
        MAX6675,
        MAX31855,
+       MAX31855K,
+       MAX31855J,
+       MAX31855N,
+       MAX31855S,
+       MAX31855T,
+       MAX31855E,
+       MAX31855R,
+};
+
+static const char maxim_tc_types[] = {
+       'K', '?', 'K', 'J', 'N', 'S', 'T', 'E', 'R'
 };
 
 static const struct iio_chan_spec max6675_channels[] = {
        {       /* thermocouple temperature */
                .type = IIO_TEMP,
                .info_mask_separate =
-                       BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+                       BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) |
+                       BIT(IIO_CHAN_INFO_THERMOCOUPLE_TYPE),
                .scan_index = 0,
                .scan_type = {
                        .sign = 's',
@@ -48,7 +61,8 @@ static const struct iio_chan_spec max31855_channels[] = {
                .type = IIO_TEMP,
                .address = 2,
                .info_mask_separate =
-                       BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+                       BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) |
+                       BIT(IIO_CHAN_INFO_THERMOCOUPLE_TYPE),
                .scan_index = 0,
                .scan_type = {
                        .sign = 's',
@@ -110,6 +124,7 @@ struct maxim_thermocouple_data {
        const struct maxim_thermocouple_chip *chip;
 
        u8 buffer[16] ____cacheline_aligned;
+       char tc_type;
 };
 
 static int maxim_thermocouple_read(struct maxim_thermocouple_data *data,
@@ -196,6 +211,10 @@ static int maxim_thermocouple_read_raw(struct iio_dev *indio_dev,
                        ret = IIO_VAL_INT;
                }
                break;
+       case IIO_CHAN_INFO_THERMOCOUPLE_TYPE:
+               *val = data->tc_type;
+               ret = IIO_VAL_CHAR;
+               break;
        }
 
        return ret;
@@ -210,8 +229,9 @@ static int maxim_thermocouple_probe(struct spi_device *spi)
        const struct spi_device_id *id = spi_get_device_id(spi);
        struct iio_dev *indio_dev;
        struct maxim_thermocouple_data *data;
+       const int chip_type = (id->driver_data == MAX6675) ? MAX6675 : MAX31855;
        const struct maxim_thermocouple_chip *chip =
-                       &maxim_thermocouple_chips[id->driver_data];
+               &maxim_thermocouple_chips[chip_type];
        int ret;
 
        indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*data));
@@ -229,6 +249,7 @@ static int maxim_thermocouple_probe(struct spi_device *spi)
        data = iio_priv(indio_dev);
        data->spi = spi;
        data->chip = chip;
+       data->tc_type = maxim_tc_types[id->driver_data];
 
        ret = devm_iio_triggered_buffer_setup(&spi->dev,
                                indio_dev, NULL,
@@ -236,12 +257,22 @@ static int maxim_thermocouple_probe(struct spi_device *spi)
        if (ret)
                return ret;
 
+       if (id->driver_data == MAX31855)
+               dev_warn(&spi->dev, "generic max31855 ID is deprecated\nplease use more specific part type");
+
        return devm_iio_device_register(&spi->dev, indio_dev);
 }
 
 static const struct spi_device_id maxim_thermocouple_id[] = {
        {"max6675", MAX6675},
        {"max31855", MAX31855},
+       {"max31855k", MAX31855K},
+       {"max31855j", MAX31855J},
+       {"max31855n", MAX31855N},
+       {"max31855s", MAX31855S},
+       {"max31855t", MAX31855T},
+       {"max31855e", MAX31855E},
+       {"max31855r", MAX31855R},
        {},
 };
 MODULE_DEVICE_TABLE(spi, maxim_thermocouple_id);
@@ -249,6 +280,13 @@ MODULE_DEVICE_TABLE(spi, maxim_thermocouple_id);
 static const struct of_device_id maxim_thermocouple_of_match[] = {
         { .compatible = "maxim,max6675" },
         { .compatible = "maxim,max31855" },
+       { .compatible = "maxim,max31855k" },
+       { .compatible = "maxim,max31855j" },
+       { .compatible = "maxim,max31855n" },
+       { .compatible = "maxim,max31855s" },
+       { .compatible = "maxim,max31855t" },
+       { .compatible = "maxim,max31855e" },
+       { .compatible = "maxim,max31855r" },
         { },
 };
 MODULE_DEVICE_TABLE(of, maxim_thermocouple_of_match);
index a5dfe65..2e0d32a 100644 (file)
@@ -297,9 +297,6 @@ static ssize_t stm32_tt_store_master_mode(struct device *dev,
                             strlen(master_mode_table[i]))) {
                        regmap_update_bits(priv->regmap, TIM_CR2, mask,
                                           i << shift);
-                       /* Make sure that registers are updated */
-                       regmap_update_bits(priv->regmap, TIM_EGR,
-                                          TIM_EGR_UG, TIM_EGR_UG);
                        return len;
                }
        }
index 63baf27..d14334f 100644 (file)
@@ -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/
index 573fea5..cc408ad 100644 (file)
@@ -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
index d299f3e..352217e 100644 (file)
@@ -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
index 1675da3..85767f5 100644 (file)
@@ -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 (file)
index a39ad37..0000000
+++ /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);
index 9846d82..f26bf3c 100644 (file)
@@ -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);
index a4ceb61..7168778 100644 (file)
@@ -10,8 +10,6 @@
  *
  */
 
-#define AVMB1_COMPAT
-
 #include "kcapi.h"
 #include <linux/module.h>
 #include <linux/mm.h>
 #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);
index 6d439f9..479623e 100644 (file)
@@ -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);
index c94bd12..eadbe59 100644 (file)
@@ -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);
index eaf753b..baccd7c 100644 (file)
@@ -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"
 
index 0a4396c..fdd03fd 100644 (file)
@@ -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,10 +46,9 @@ 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/
+obj-$(CONFIG_STAGING_EXFAT_FS) += exfat/
 obj-$(CONFIG_QLGE)             += qlge/
 obj-$(CONFIG_NET_VENDOR_HP)    += hp/
 obj-$(CONFIG_WFX)              += wfx/
index 74d497d..5891d07 100644 (file)
@@ -537,14 +537,14 @@ static int set_name(struct ashmem_area *asma, void __user *name)
        len = strncpy_from_user(local_name, name, ASHMEM_NAME_LEN);
        if (len < 0)
                return len;
-       if (len == ASHMEM_NAME_LEN)
-               local_name[ASHMEM_NAME_LEN - 1] = '\0';
+
        mutex_lock(&ashmem_mutex);
        /* cannot change an existing mapping's name */
        if (asma->file)
                ret = -EINVAL;
        else
-               strcpy(asma->name + ASHMEM_NAME_PREFIX_LEN, local_name);
+               strscpy(asma->name + ASHMEM_NAME_PREFIX_LEN, local_name,
+                       ASHMEM_NAME_LEN);
 
        mutex_unlock(&ashmem_mutex);
        return ret;
index 39e6c59..5801067 100644 (file)
@@ -16,7 +16,7 @@
 
 #include <linux/kernel.h>
 #include <linux/wait.h>
-#include <linux/spinlock_types.h>
+#include <linux/mutex.h>
 #include <linux/device.h>
 #include <linux/cdev.h>
 #include <linux/init.h>
@@ -133,9 +133,9 @@ struct axis_fifo {
        int has_tx_fifo; /* whether the IP has the tx fifo enabled */
 
        wait_queue_head_t read_queue; /* wait queue for asynchronos read */
-       spinlock_t read_queue_lock; /* lock for reading waitqueue */
+       struct mutex read_lock; /* lock for reading */
        wait_queue_head_t write_queue; /* wait queue for asynchronos write */
-       spinlock_t write_queue_lock; /* lock for writing waitqueue */
+       struct mutex write_lock; /* lock for writing */
        unsigned int write_flags; /* write file flags */
        unsigned int read_flags; /* read file flags */
 
@@ -336,7 +336,21 @@ static void reset_ip_core(struct axis_fifo *fifo)
        iowrite32(XLLF_INT_ALL_MASK, fifo->base_addr + XLLF_ISR_OFFSET);
 }
 
-/* reads a single packet from the fifo as dictated by the tlast signal */
+/**
+ * axis_fifo_write() - Read a packet from AXIS-FIFO character device.
+ * @f Open file.
+ * @buf User space buffer to read to.
+ * @len User space buffer length.
+ * @off Buffer offset.
+ *
+ * As defined by the device's documentation, we need to check the device's
+ * occupancy before reading the length register and then the data. All these
+ * operations must be executed atomically, in order and one after the other
+ * without missing any.
+ *
+ * Returns the number of bytes read from the device or negative error code
+ *     on failure.
+ */
 static ssize_t axis_fifo_read(struct file *f, char __user *buf,
                              size_t len, loff_t *off)
 {
@@ -350,36 +364,37 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf,
        u32 tmp_buf[READ_BUF_SIZE];
 
        if (fifo->read_flags & O_NONBLOCK) {
-               /* opened in non-blocking mode
-                * return if there are no packets available
+               /*
+                * Device opened in non-blocking mode. Try to lock it and then
+                * check if any packet is available.
                 */
-               if (!ioread32(fifo->base_addr + XLLF_RDFO_OFFSET))
+               if (!mutex_trylock(&fifo->read_lock))
                        return -EAGAIN;
+
+               if (!ioread32(fifo->base_addr + XLLF_RDFO_OFFSET)) {
+                       ret = -EAGAIN;
+                       goto end_unlock;
+               }
        } else {
                /* opened in blocking mode
                 * wait for a packet available interrupt (or timeout)
                 * if nothing is currently available
                 */
-               spin_lock_irq(&fifo->read_queue_lock);
-               ret = wait_event_interruptible_lock_irq_timeout
-                       (fifo->read_queue,
-                        ioread32(fifo->base_addr + XLLF_RDFO_OFFSET),
-                        fifo->read_queue_lock,
-                        (read_timeout >= 0) ? msecs_to_jiffies(read_timeout) :
+               mutex_lock(&fifo->read_lock);
+               ret = wait_event_interruptible_timeout(fifo->read_queue,
+                       ioread32(fifo->base_addr + XLLF_RDFO_OFFSET),
+                       (read_timeout >= 0) ? msecs_to_jiffies(read_timeout) :
                                MAX_SCHEDULE_TIMEOUT);
-               spin_unlock_irq(&fifo->read_queue_lock);
 
-               if (ret == 0) {
-                       /* timeout occurred */
-                       dev_dbg(fifo->dt_device, "read timeout");
-                       return -EAGAIN;
-               } else if (ret == -ERESTARTSYS) {
-                       /* signal received */
-                       return -ERESTARTSYS;
-               } else if (ret < 0) {
-                       dev_err(fifo->dt_device, "wait_event_interruptible_timeout() error in read (ret=%i)\n",
-                               ret);
-                       return ret;
+               if (ret <= 0) {
+                       if (ret == 0) {
+                               ret = -EAGAIN;
+                       } else if (ret != -ERESTARTSYS) {
+                               dev_err(fifo->dt_device, "wait_event_interruptible_timeout() error in read (ret=%i)\n",
+                                       ret);
+                       }
+
+                       goto end_unlock;
                }
        }
 
@@ -387,14 +402,16 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf,
        if (!bytes_available) {
                dev_err(fifo->dt_device, "received a packet of length 0 - fifo core will be reset\n");
                reset_ip_core(fifo);
-               return -EIO;
+               ret = -EIO;
+               goto end_unlock;
        }
 
        if (bytes_available > len) {
                dev_err(fifo->dt_device, "user read buffer too small (available bytes=%zu user buffer bytes=%zu) - fifo core will be reset\n",
                        bytes_available, len);
                reset_ip_core(fifo);
-               return -EINVAL;
+               ret = -EINVAL;
+               goto end_unlock;
        }
 
        if (bytes_available % sizeof(u32)) {
@@ -403,7 +420,8 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf,
                 */
                dev_err(fifo->dt_device, "received a packet that isn't word-aligned - fifo core will be reset\n");
                reset_ip_core(fifo);
-               return -EIO;
+               ret = -EIO;
+               goto end_unlock;
        }
 
        words_available = bytes_available / sizeof(u32);
@@ -423,16 +441,37 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf,
                if (copy_to_user(buf + copied * sizeof(u32), tmp_buf,
                                 copy * sizeof(u32))) {
                        reset_ip_core(fifo);
-                       return -EFAULT;
+                       ret = -EFAULT;
+                       goto end_unlock;
                }
 
                copied += copy;
                words_available -= copy;
        }
 
-       return bytes_available;
+       ret = bytes_available;
+
+end_unlock:
+       mutex_unlock(&fifo->read_lock);
+
+       return ret;
 }
 
+/**
+ * axis_fifo_write() - Write buffer to AXIS-FIFO character device.
+ * @f Open file.
+ * @buf User space buffer to write to the device.
+ * @len User space buffer length.
+ * @off Buffer offset.
+ *
+ * As defined by the device's documentation, we need to write to the device's
+ * data buffer then to the device's packet length register atomically. Also,
+ * we need to lock before checking if the device has available space to avoid
+ * any concurrency issue.
+ *
+ * Returns the number of bytes written to the device or negative error code
+ *     on failure.
+ */
 static ssize_t axis_fifo_write(struct file *f, const char __user *buf,
                               size_t len, loff_t *off)
 {
@@ -465,12 +504,17 @@ static ssize_t axis_fifo_write(struct file *f, const char __user *buf,
        }
 
        if (fifo->write_flags & O_NONBLOCK) {
-               /* opened in non-blocking mode
-                * return if there is not enough room available in the fifo
+               /*
+                * Device opened in non-blocking mode. Try to lock it and then
+                * check if there is any room to write the given buffer.
                 */
+               if (!mutex_trylock(&fifo->write_lock))
+                       return -EAGAIN;
+
                if (words_to_write > ioread32(fifo->base_addr +
                                              XLLF_TDFV_OFFSET)) {
-                       return -EAGAIN;
+                       ret = -EAGAIN;
+                       goto end_unlock;
                }
        } else {
                /* opened in blocking mode */
@@ -478,30 +522,22 @@ static ssize_t axis_fifo_write(struct file *f, const char __user *buf,
                /* wait for an interrupt (or timeout) if there isn't
                 * currently enough room in the fifo
                 */
-               spin_lock_irq(&fifo->write_queue_lock);
-               ret = wait_event_interruptible_lock_irq_timeout
-                       (fifo->write_queue,
-                        ioread32(fifo->base_addr + XLLF_TDFV_OFFSET)
+               mutex_lock(&fifo->write_lock);
+               ret = wait_event_interruptible_timeout(fifo->write_queue,
+                       ioread32(fifo->base_addr + XLLF_TDFV_OFFSET)
                                >= words_to_write,
-                        fifo->write_queue_lock,
-                        (write_timeout >= 0) ?
-                               msecs_to_jiffies(write_timeout) :
+                       (write_timeout >= 0) ? msecs_to_jiffies(write_timeout) :
                                MAX_SCHEDULE_TIMEOUT);
-               spin_unlock_irq(&fifo->write_queue_lock);
 
-               if (ret == 0) {
-                       /* timeout occurred */
-                       dev_dbg(fifo->dt_device, "write timeout\n");
-                       return -EAGAIN;
-               } else if (ret == -ERESTARTSYS) {
-                       /* signal received */
-                       return -ERESTARTSYS;
-               } else if (ret < 0) {
-                       /* unknown error */
-                       dev_err(fifo->dt_device,
-                               "wait_event_interruptible_timeout() error in write (ret=%i)\n",
-                               ret);
-                       return ret;
+               if (ret <= 0) {
+                       if (ret == 0) {
+                               ret = -EAGAIN;
+                       } else if (ret != -ERESTARTSYS) {
+                               dev_err(fifo->dt_device, "wait_event_interruptible_timeout() error in write (ret=%i)\n",
+                                       ret);
+                       }
+
+                       goto end_unlock;
                }
        }
 
@@ -515,7 +551,8 @@ static ssize_t axis_fifo_write(struct file *f, const char __user *buf,
                if (copy_from_user(tmp_buf, buf + copied * sizeof(u32),
                                   copy * sizeof(u32))) {
                        reset_ip_core(fifo);
-                       return -EFAULT;
+                       ret = -EFAULT;
+                       goto end_unlock;
                }
 
                for (i = 0; i < copy; i++)
@@ -526,10 +563,15 @@ static ssize_t axis_fifo_write(struct file *f, const char __user *buf,
                words_to_write -= copy;
        }
 
+       ret = copied * sizeof(u32);
+
        /* write packet size to fifo */
-       iowrite32(copied * sizeof(u32), fifo->base_addr + XLLF_TLR_OFFSET);
+       iowrite32(ret, fifo->base_addr + XLLF_TLR_OFFSET);
+
+end_unlock:
+       mutex_unlock(&fifo->write_lock);
 
-       return (ssize_t)copied * sizeof(u32);
+       return ret;
 }
 
 static irqreturn_t axis_fifo_irq(int irq, void *dw)
@@ -789,8 +831,8 @@ static int axis_fifo_probe(struct platform_device *pdev)
        init_waitqueue_head(&fifo->read_queue);
        init_waitqueue_head(&fifo->write_queue);
 
-       spin_lock_init(&fifo->read_queue_lock);
-       spin_lock_init(&fifo->write_queue_lock);
+       mutex_init(&fifo->read_lock);
+       mutex_init(&fifo->write_lock);
 
        /* ----------------------------
         *   init device memory space
index f99211e..04e224f 100644 (file)
@@ -279,7 +279,7 @@ static int das6402_ai_check_chanlist(struct comedi_device *dev,
 
                if (aref0 == AREF_DIFF && chan > (s->n_chan / 2)) {
                        dev_dbg(dev->class_dev,
-                               "chanlist differential channel to large\n");
+                               "chanlist differential channel too large\n");
                        return -EINVAL;
                }
        }
index 0130019..292a19d 100644 (file)
@@ -1,41 +1,41 @@
 # SPDX-License-Identifier: GPL-2.0
-config EXFAT_FS
+config STAGING_EXFAT_FS
        tristate "exFAT fs support"
        depends on BLOCK
        select NLS
        help
          This adds support for the exFAT file system.
 
-config EXFAT_DISCARD
+config STAGING_EXFAT_DISCARD
        bool "enable discard support"
-       depends on EXFAT_FS
+       depends on STAGING_EXFAT_FS
        default y
 
-config EXFAT_DELAYED_SYNC
+config STAGING_EXFAT_DELAYED_SYNC
        bool "enable delayed sync"
-       depends on EXFAT_FS
+       depends on STAGING_EXFAT_FS
        default n
 
-config EXFAT_KERNEL_DEBUG
+config STAGING_EXFAT_KERNEL_DEBUG
        bool "enable kernel debug features via ioctl"
-       depends on EXFAT_FS
+       depends on STAGING_EXFAT_FS
        default n
 
-config EXFAT_DEBUG_MSG
+config STAGING_EXFAT_DEBUG_MSG
        bool "print debug messages"
-       depends on EXFAT_FS
+       depends on STAGING_EXFAT_FS
        default n
 
-config EXFAT_DEFAULT_CODEPAGE
+config STAGING_EXFAT_DEFAULT_CODEPAGE
        int "Default codepage for exFAT"
        default 437
-       depends on EXFAT_FS
+       depends on STAGING_EXFAT_FS
        help
          This option should be set to the codepage of your exFAT filesystems.
 
-config EXFAT_DEFAULT_IOCHARSET
+config STAGING_EXFAT_DEFAULT_IOCHARSET
        string "Default iocharset for exFAT"
        default "utf8"
-       depends on EXFAT_FS
+       depends on STAGING_EXFAT_FS
        help
          Set this to the default input/output character set you'd like exFAT to use.
index 6c90aec..057556e 100644 (file)
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-or-later
 
-obj-$(CONFIG_EXFAT_FS) += exfat.o
+obj-$(CONFIG_STAGING_EXFAT_FS) += exfat.o
 
 exfat-y :=     exfat_core.o    \
                exfat_super.o   \
index 51c665a..4d87360 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/types.h>
 #include <linux/buffer_head.h>
 
-#ifdef CONFIG_EXFAT_KERNEL_DEBUG
+#ifdef CONFIG_STAGING_EXFAT_KERNEL_DEBUG
   /* For Debugging Purpose */
        /* IOCTL code 'f' used by
         *   - file systems typically #0~0x1F
@@ -22,9 +22,9 @@
 
 #define EXFAT_DEBUGFLAGS_INVALID_UMOUNT        0x01
 #define EXFAT_DEBUGFLAGS_ERROR_RW      0x02
-#endif /* CONFIG_EXFAT_KERNEL_DEBUG */
+#endif /* CONFIG_STAGING_EXFAT_KERNEL_DEBUG */
 
-#ifdef CONFIG_EXFAT_DEBUG_MSG
+#ifdef CONFIG_STAGING_EXFAT_DEBUG_MSG
 #define DEBUG  1
 #else
 #undef DEBUG
@@ -516,49 +516,6 @@ struct buf_cache_t {
        struct buffer_head   *buf_bh;
 };
 
-struct fs_func {
-       s32     (*alloc_cluster)(struct super_block *sb, s32 num_alloc,
-                                struct chain_t *p_chain);
-       void    (*free_cluster)(struct super_block *sb, struct chain_t *p_chain,
-                               s32 do_relse);
-       s32     (*count_used_clusters)(struct super_block *sb);
-
-       s32     (*init_dir_entry)(struct super_block *sb, struct chain_t *p_dir,
-                                 s32 entry, u32 type, u32 start_clu, u64 size);
-       s32     (*init_ext_entry)(struct super_block *sb, struct chain_t *p_dir,
-                                 s32 entry, s32 num_entries,
-                                 struct uni_name_t *p_uniname,
-                                 struct dos_name_t *p_dosname);
-       s32     (*find_dir_entry)(struct super_block *sb, struct chain_t *p_dir,
-                                 struct uni_name_t *p_uniname, s32 num_entries,
-                                 struct dos_name_t *p_dosname, u32 type);
-       void    (*delete_dir_entry)(struct super_block *sb,
-                                   struct chain_t *p_dir, s32 entry,
-                                   s32 offset, s32 num_entries);
-       void    (*get_uni_name_from_ext_entry)(struct super_block *sb,
-                                              struct chain_t *p_dir, s32 entry,
-                                              u16 *uniname);
-       s32     (*count_ext_entries)(struct super_block *sb,
-                                    struct chain_t *p_dir, s32 entry,
-                                    struct dentry_t *p_entry);
-       s32     (*calc_num_entries)(struct uni_name_t *p_uniname);
-
-       u32     (*get_entry_type)(struct dentry_t *p_entry);
-       void    (*set_entry_type)(struct dentry_t *p_entry, u32 type);
-       u32     (*get_entry_attr)(struct dentry_t *p_entry);
-       void    (*set_entry_attr)(struct dentry_t *p_entry, u32 attr);
-       u8      (*get_entry_flag)(struct dentry_t *p_entry);
-       void    (*set_entry_flag)(struct dentry_t *p_entry, u8 flag);
-       u32     (*get_entry_clu0)(struct dentry_t *p_entry);
-       void    (*set_entry_clu0)(struct dentry_t *p_entry, u32 clu0);
-       u64     (*get_entry_size)(struct dentry_t *p_entry);
-       void    (*set_entry_size)(struct dentry_t *p_entry, u64 size);
-       void    (*get_entry_time)(struct dentry_t *p_entry,
-                                 struct timestamp_t *tp, u8 mode);
-       void    (*set_entry_time)(struct dentry_t *p_entry,
-                                 struct timestamp_t *tp, u8 mode);
-};
-
 struct fs_info_t {
        u32      drv;                    /* drive ID */
        u32      vol_type;               /* volume FAT type */
@@ -597,7 +554,6 @@ struct fs_info_t {
 
        u32 dev_ejected;        /* block device operation error flag */
 
-       struct fs_func *fs_func;
        struct mutex v_mutex;
 
        /* FAT cache */
@@ -661,10 +617,10 @@ struct exfat_mount_options {
 
        /* on error: continue, panic, remount-ro */
        unsigned char errors;
-#ifdef CONFIG_EXFAT_DISCARD
+#ifdef CONFIG_STAGING_EXFAT_DISCARD
        /* flag on if -o dicard specified and device support discard() */
        unsigned char discard;
-#endif /* CONFIG_EXFAT_DISCARD */
+#endif /* CONFIG_STAGING_EXFAT_DISCARD */
 };
 
 #define EXFAT_HASH_BITS                8
@@ -700,9 +656,9 @@ struct exfat_sb_info {
 
        spinlock_t inode_hash_lock;
        struct hlist_head inode_hashtable[EXFAT_HASH_SIZE];
-#ifdef CONFIG_EXFAT_KERNEL_DEBUG
+#ifdef CONFIG_STAGING_EXFAT_KERNEL_DEBUG
        long debug_flags;
-#endif /* CONFIG_EXFAT_KERNEL_DEBUG */
+#endif /* CONFIG_STAGING_EXFAT_KERNEL_DEBUG */
 };
 
 /*
@@ -829,5 +785,40 @@ int exfat_bdev_write(struct super_block *sb, sector_t secno,
               struct buffer_head *bh, u32 num_secs, bool sync);
 int exfat_bdev_sync(struct super_block *sb);
 
+/* cluster operation functions */
+s32 exfat_alloc_cluster(struct super_block *sb, s32 num_alloc,
+                       struct chain_t *p_chain);
+void exfat_free_cluster(struct super_block *sb, struct chain_t *p_chain,
+                       s32 do_relse);
+s32 exfat_count_used_clusters(struct super_block *sb);
+
+/* dir operation functions */
+s32 exfat_find_dir_entry(struct super_block *sb, struct chain_t *p_dir,
+                        struct uni_name_t *p_uniname, s32 num_entries,
+                        struct dos_name_t *p_dosname, u32 type);
+void exfat_delete_dir_entry(struct super_block *sb, struct chain_t *p_dir,
+                           s32 entry, s32 order, s32 num_entries);
+void exfat_get_uni_name_from_ext_entry(struct super_block *sb,
+                                      struct chain_t *p_dir, s32 entry,
+                                      u16 *uniname);
+s32 exfat_count_ext_entries(struct super_block *sb, struct chain_t *p_dir,
+                           s32 entry, struct dentry_t *p_entry);
+s32 exfat_calc_num_entries(struct uni_name_t *p_uniname);
+
+/* dir entry getter/setter */
+u32 exfat_get_entry_type(struct dentry_t *p_entry);
+u32 exfat_get_entry_attr(struct dentry_t *p_entry);
+void exfat_set_entry_attr(struct dentry_t *p_entry, u32 attr);
+u8 exfat_get_entry_flag(struct dentry_t *p_entry);
+void exfat_set_entry_flag(struct dentry_t *p_entry, u8 flags);
+u32 exfat_get_entry_clu0(struct dentry_t *p_entry);
+void exfat_set_entry_clu0(struct dentry_t *p_entry, u32 start_clu);
+u64 exfat_get_entry_size(struct dentry_t *p_entry);
+void exfat_set_entry_size(struct dentry_t *p_entry, u64 size);
+void exfat_get_entry_time(struct dentry_t *p_entry, struct timestamp_t *tp,
+                         u8 mode);
+void exfat_set_entry_time(struct dentry_t *p_entry, struct timestamp_t *tp,
+                         u8 mode);
+
 extern const u8 uni_upcase[];
 #endif /* _EXFAT_H */
index 7bcd98b..0a3dc35 100644 (file)
@@ -31,17 +31,17 @@ void exfat_bdev_close(struct super_block *sb)
 }
 
 int exfat_bdev_read(struct super_block *sb, sector_t secno, struct buffer_head **bh,
-             u32 num_secs, bool read)
+                   u32 num_secs, bool read)
 {
        struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
        struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-#ifdef CONFIG_EXFAT_KERNEL_DEBUG
+#ifdef CONFIG_STAGING_EXFAT_KERNEL_DEBUG
        struct exfat_sb_info *sbi = EXFAT_SB(sb);
        long flags = sbi->debug_flags;
 
        if (flags & EXFAT_DEBUGFLAGS_ERROR_RW)
                return -EIO;
-#endif /* CONFIG_EXFAT_KERNEL_DEBUG */
+#endif /* CONFIG_STAGING_EXFAT_KERNEL_DEBUG */
 
        if (!p_bd->opened)
                return -ENODEV;
@@ -66,19 +66,19 @@ int exfat_bdev_read(struct super_block *sb, sector_t secno, struct buffer_head *
 }
 
 int exfat_bdev_write(struct super_block *sb, sector_t secno, struct buffer_head *bh,
-              u32 num_secs, bool sync)
+                    u32 num_secs, bool sync)
 {
        s32 count;
        struct buffer_head *bh2;
        struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
        struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-#ifdef CONFIG_EXFAT_KERNEL_DEBUG
+#ifdef CONFIG_STAGING_EXFAT_KERNEL_DEBUG
        struct exfat_sb_info *sbi = EXFAT_SB(sb);
        long flags = sbi->debug_flags;
 
        if (flags & EXFAT_DEBUGFLAGS_ERROR_RW)
                return -EIO;
-#endif /* CONFIG_EXFAT_KERNEL_DEBUG */
+#endif /* CONFIG_STAGING_EXFAT_KERNEL_DEBUG */
 
        if (!p_bd->opened)
                return -ENODEV;
@@ -121,13 +121,13 @@ no_bh:
 int exfat_bdev_sync(struct super_block *sb)
 {
        struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
-#ifdef CONFIG_EXFAT_KERNEL_DEBUG
+#ifdef CONFIG_STAGING_EXFAT_KERNEL_DEBUG
        struct exfat_sb_info *sbi = EXFAT_SB(sb);
        long flags = sbi->debug_flags;
 
        if (flags & EXFAT_DEBUGFLAGS_ERROR_RW)
                return -EIO;
-#endif /* CONFIG_EXFAT_KERNEL_DEBUG */
+#endif /* CONFIG_STAGING_EXFAT_KERNEL_DEBUG */
 
        if (!p_bd->opened)
                return -ENODEV;
index 794000e..07b460d 100644 (file)
@@ -177,11 +177,11 @@ static s32 clr_alloc_bitmap(struct super_block *sb, u32 clu)
 {
        int i, b;
        sector_t sector;
-#ifdef CONFIG_EXFAT_DISCARD
+#ifdef CONFIG_STAGING_EXFAT_DISCARD
        struct exfat_sb_info *sbi = EXFAT_SB(sb);
        struct exfat_mount_options *opts = &sbi->options;
        int ret;
-#endif /* CONFIG_EXFAT_DISCARD */
+#endif /* CONFIG_STAGING_EXFAT_DISCARD */
        struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
        struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
 
@@ -192,7 +192,7 @@ static s32 clr_alloc_bitmap(struct super_block *sb, u32 clu)
 
        exfat_bitmap_clear((u8 *)p_fs->vol_amap[i]->b_data, b);
 
-#ifdef CONFIG_EXFAT_DISCARD
+#ifdef CONFIG_STAGING_EXFAT_DISCARD
        if (opts->discard) {
                ret = sb_issue_discard(sb, START_SECTOR(clu),
                                       (1 << p_fs->sectors_per_clu_bits),
@@ -204,7 +204,7 @@ static s32 clr_alloc_bitmap(struct super_block *sb, u32 clu)
                        return ret;
                }
        }
-#endif /* CONFIG_EXFAT_DISCARD */
+#endif /* CONFIG_STAGING_EXFAT_DISCARD */
 
        return sector_write(sb, sector, p_fs->vol_amap[i], 0);
 }
@@ -249,7 +249,7 @@ static u32 test_alloc_bitmap(struct super_block *sb, u32 clu)
        return CLUSTER_32(~0);
 }
 
-static s32 exfat_alloc_cluster(struct super_block *sb, s32 num_alloc,
+s32 exfat_alloc_cluster(struct super_block *sb, s32 num_alloc,
                        struct chain_t *p_chain)
 {
        s32 num_clusters = 0;
@@ -328,7 +328,7 @@ static s32 exfat_alloc_cluster(struct super_block *sb, s32 num_alloc,
        return num_clusters;
 }
 
-static void exfat_free_cluster(struct super_block *sb, struct chain_t *p_chain,
+void exfat_free_cluster(struct super_block *sb, struct chain_t *p_chain,
                        s32 do_relse)
 {
        s32 num_clusters = 0;
@@ -434,7 +434,7 @@ s32 count_num_clusters(struct super_block *sb, struct chain_t *p_chain)
        return count;
 }
 
-static s32 exfat_count_used_clusters(struct super_block *sb)
+s32 exfat_count_used_clusters(struct super_block *sb)
 {
        int i, map_i, map_b, count = 0;
        u8 k;
@@ -499,7 +499,7 @@ s32 load_alloc_bitmap(struct super_block *sb)
                        if (!ep)
                                return -ENOENT;
 
-                       type = p_fs->fs_func->get_entry_type((struct dentry_t *)ep);
+                       type = exfat_get_entry_type((struct dentry_t *)ep);
 
                        if (type == TYPE_UNUSED)
                                break;
@@ -745,7 +745,7 @@ s32 load_upcase_table(struct super_block *sb)
                        if (!ep)
                                return -ENOENT;
 
-                       type = p_fs->fs_func->get_entry_type((struct dentry_t *)ep);
+                       type = exfat_get_entry_type((struct dentry_t *)ep);
 
                        if (type == TYPE_UNUSED)
                                break;
@@ -787,7 +787,7 @@ void free_upcase_table(struct super_block *sb)
  *  Directory Entry Management Functions
  */
 
-static u32 exfat_get_entry_type(struct dentry_t *p_entry)
+u32 exfat_get_entry_type(struct dentry_t *p_entry)
 {
        struct file_dentry_t *ep = (struct file_dentry_t *)p_entry;
 
@@ -862,56 +862,56 @@ static void exfat_set_entry_type(struct dentry_t *p_entry, u32 type)
        }
 }
 
-static u32 exfat_get_entry_attr(struct dentry_t *p_entry)
+u32 exfat_get_entry_attr(struct dentry_t *p_entry)
 {
        struct file_dentry_t *ep = (struct file_dentry_t *)p_entry;
 
        return (u32)GET16_A(ep->attr);
 }
 
-static void exfat_set_entry_attr(struct dentry_t *p_entry, u32 attr)
+void exfat_set_entry_attr(struct dentry_t *p_entry, u32 attr)
 {
        struct file_dentry_t *ep = (struct file_dentry_t *)p_entry;
 
        SET16_A(ep->attr, (u16)attr);
 }
 
-static u8 exfat_get_entry_flag(struct dentry_t *p_entry)
+u8 exfat_get_entry_flag(struct dentry_t *p_entry)
 {
        struct strm_dentry_t *ep = (struct strm_dentry_t *)p_entry;
 
        return ep->flags;
 }
 
-static void exfat_set_entry_flag(struct dentry_t *p_entry, u8 flags)
+void exfat_set_entry_flag(struct dentry_t *p_entry, u8 flags)
 {
        struct strm_dentry_t *ep = (struct strm_dentry_t *)p_entry;
 
        ep->flags = flags;
 }
 
-static u32 exfat_get_entry_clu0(struct dentry_t *p_entry)
+u32 exfat_get_entry_clu0(struct dentry_t *p_entry)
 {
        struct strm_dentry_t *ep = (struct strm_dentry_t *)p_entry;
 
        return GET32_A(ep->start_clu);
 }
 
-static void exfat_set_entry_clu0(struct dentry_t *p_entry, u32 start_clu)
+void exfat_set_entry_clu0(struct dentry_t *p_entry, u32 start_clu)
 {
        struct strm_dentry_t *ep = (struct strm_dentry_t *)p_entry;
 
        SET32_A(ep->start_clu, start_clu);
 }
 
-static u64 exfat_get_entry_size(struct dentry_t *p_entry)
+u64 exfat_get_entry_size(struct dentry_t *p_entry)
 {
        struct strm_dentry_t *ep = (struct strm_dentry_t *)p_entry;
 
        return GET64_A(ep->valid_size);
 }
 
-static void exfat_set_entry_size(struct dentry_t *p_entry, u64 size)
+void exfat_set_entry_size(struct dentry_t *p_entry, u64 size)
 {
        struct strm_dentry_t *ep = (struct strm_dentry_t *)p_entry;
 
@@ -919,7 +919,7 @@ static void exfat_set_entry_size(struct dentry_t *p_entry, u64 size)
        SET64_A(ep->size, size);
 }
 
-static void exfat_get_entry_time(struct dentry_t *p_entry, struct timestamp_t *tp,
+void exfat_get_entry_time(struct dentry_t *p_entry, struct timestamp_t *tp,
                          u8 mode)
 {
        u16 t = 0x00, d = 0x21;
@@ -948,7 +948,7 @@ static void exfat_get_entry_time(struct dentry_t *p_entry, struct timestamp_t *t
        tp->year = (d >> 9);
 }
 
-static void exfat_set_entry_time(struct dentry_t *p_entry, struct timestamp_t *tp,
+void exfat_set_entry_time(struct dentry_t *p_entry, struct timestamp_t *tp,
                          u8 mode)
 {
        u16 t, d;
@@ -1013,7 +1013,7 @@ static void init_name_entry(struct name_dentry_t *ep, u16 *uniname)
 }
 
 static s32 exfat_init_dir_entry(struct super_block *sb, struct chain_t *p_dir,
-                        s32 entry, u32 type, u32 start_clu, u64 size)
+                               s32 entry, u32 type, u32 start_clu, u64 size)
 {
        sector_t sector;
        u8 flags;
@@ -1088,20 +1088,19 @@ static s32 exfat_init_ext_entry(struct super_block *sb, struct chain_t *p_dir,
        return 0;
 }
 
-static void exfat_delete_dir_entry(struct super_block *sb, struct chain_t *p_dir,
+void exfat_delete_dir_entry(struct super_block *sb, struct chain_t *p_dir,
                            s32 entry, s32 order, s32 num_entries)
 {
        int i;
        sector_t sector;
        struct dentry_t *ep;
-       struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
 
        for (i = order; i < num_entries; i++) {
                ep = get_entry_in_dir(sb, p_dir, entry + i, &sector);
                if (!ep)
                        return;
 
-               p_fs->fs_func->set_entry_type(ep, TYPE_DELETED);
+               exfat_set_entry_type(ep, TYPE_DELETED);
                exfat_buf_modify(sb, sector);
        }
 }
@@ -1256,7 +1255,7 @@ static s32 _walk_fat_chain(struct super_block *sb, struct chain_t *p_dir,
 }
 
 static s32 find_location(struct super_block *sb, struct chain_t *p_dir, s32 entry,
-                 sector_t *sector, s32 *offset)
+                        sector_t *sector, s32 *offset)
 {
        s32 off, ret;
        u32 clu = 0;
@@ -1366,7 +1365,7 @@ struct entry_set_cache_t *get_entry_set_in_dir(struct super_block *sb,
                goto err_out;
 
        ep = (struct dentry_t *)(buf + off);
-       entry_type = p_fs->fs_func->get_entry_type(ep);
+       entry_type = exfat_get_entry_type(ep);
 
        if ((entry_type != TYPE_FILE) && (entry_type != TYPE_DIR))
                goto err_out;
@@ -1396,7 +1395,7 @@ struct entry_set_cache_t *get_entry_set_in_dir(struct super_block *sb,
                 * instead of copying whole sector, we will check every entry.
                 * this will provide minimum stablity and consistency.
                 */
-               entry_type = p_fs->fs_func->get_entry_type(ep);
+               entry_type = exfat_get_entry_type(ep);
 
                if ((entry_type == TYPE_UNUSED) || (entry_type == TYPE_DELETED))
                        goto err_out;
@@ -1492,7 +1491,8 @@ void release_entry_set(struct entry_set_cache_t *es)
 
 /* search EMPTY CONTINUOUS "num_entries" entries */
 static s32 search_deleted_or_unused_entry(struct super_block *sb,
-                                  struct chain_t *p_dir, s32 num_entries)
+                                         struct chain_t *p_dir,
+                                         s32 num_entries)
 {
        int i, dentry, num_empty = 0;
        s32 dentries_per_clu;
@@ -1539,7 +1539,7 @@ static s32 search_deleted_or_unused_entry(struct super_block *sb,
                        if (!ep)
                                return -1;
 
-                       type = p_fs->fs_func->get_entry_type(ep);
+                       type = exfat_get_entry_type(ep);
 
                        if (type == TYPE_UNUSED) {
                                num_empty++;
@@ -1613,7 +1613,7 @@ static s32 find_empty_entry(struct inode *inode, struct chain_t *p_dir, s32 num_
                clu.flags = p_dir->flags;
 
                /* (1) allocate a cluster */
-               ret = p_fs->fs_func->alloc_cluster(sb, 1, &clu);
+               ret = exfat_alloc_cluster(sb, 1, &clu);
                if (ret < 1)
                        return -EIO;
 
@@ -1649,8 +1649,8 @@ static s32 find_empty_entry(struct inode *inode, struct chain_t *p_dir, s32 num_
                                              fid->entry + 1, &sector);
                        if (!ep)
                                return -ENOENT;
-                       p_fs->fs_func->set_entry_size(ep, size);
-                       p_fs->fs_func->set_entry_flag(ep, p_dir->flags);
+                       exfat_set_entry_size(ep, size);
+                       exfat_set_entry_flag(ep, p_dir->flags);
                        exfat_buf_modify(sb, sector);
 
                        update_dir_checksum(sb, &fid->dir,
@@ -1668,7 +1668,7 @@ static s32 find_empty_entry(struct inode *inode, struct chain_t *p_dir, s32 num_
 }
 
 static s32 extract_uni_name_from_name_entry(struct name_dentry_t *ep, u16 *uniname,
-                                    s32 order)
+                                           s32 order)
 {
        int i, len = 0;
 
@@ -1689,7 +1689,7 @@ static s32 extract_uni_name_from_name_entry(struct name_dentry_t *ep, u16 *unina
  * -1 : (root dir, ".") it is the root dir itself
  * -2 : entry with the name does not exist
  */
-static s32 exfat_find_dir_entry(struct super_block *sb, struct chain_t *p_dir,
+s32 exfat_find_dir_entry(struct super_block *sb, struct chain_t *p_dir,
                         struct uni_name_t *p_uniname, s32 num_entries,
                         struct dos_name_t *p_dosname, u32 type)
 {
@@ -1735,7 +1735,7 @@ static s32 exfat_find_dir_entry(struct super_block *sb, struct chain_t *p_dir,
                        if (!ep)
                                return -2;
 
-                       entry_type = p_fs->fs_func->get_entry_type(ep);
+                       entry_type = exfat_get_entry_type(ep);
                        step = 1;
 
                        if ((entry_type == TYPE_UNUSED) || (entry_type == TYPE_DELETED)) {
@@ -1832,21 +1832,20 @@ static s32 exfat_find_dir_entry(struct super_block *sb, struct chain_t *p_dir,
        return -2;
 }
 
-static s32 exfat_count_ext_entries(struct super_block *sb, struct chain_t *p_dir,
+s32 exfat_count_ext_entries(struct super_block *sb, struct chain_t *p_dir,
                            s32 entry, struct dentry_t *p_entry)
 {
        int i, count = 0;
        u32 type;
        struct file_dentry_t *file_ep = (struct file_dentry_t *)p_entry;
        struct dentry_t *ext_ep;
-       struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
 
        for (i = 0, entry++; i < file_ep->num_ext; i++, entry++) {
                ext_ep = get_entry_in_dir(sb, p_dir, entry, NULL);
                if (!ext_ep)
                        return -1;
 
-               type = p_fs->fs_func->get_entry_type(ext_ep);
+               type = exfat_get_entry_type(ext_ep);
                if ((type == TYPE_EXTEND) || (type == TYPE_STREAM))
                        count++;
                else
@@ -1884,7 +1883,7 @@ s32 count_dos_name_entries(struct super_block *sb, struct chain_t *p_dir,
                        if (!ep)
                                return -ENOENT;
 
-                       entry_type = p_fs->fs_func->get_entry_type(ep);
+                       entry_type = exfat_get_entry_type(ep);
 
                        if (entry_type == TYPE_UNUSED)
                                return count;
@@ -1940,7 +1939,7 @@ bool is_dir_empty(struct super_block *sb, struct chain_t *p_dir)
                        if (!ep)
                                break;
 
-                       type = p_fs->fs_func->get_entry_type(ep);
+                       type = exfat_get_entry_type(ep);
 
                        if (type == TYPE_UNUSED)
                                return true;
@@ -1984,9 +1983,8 @@ s32 get_num_entries_and_dos_name(struct super_block *sb, struct chain_t *p_dir,
                                 struct dos_name_t *p_dosname)
 {
        s32 num_entries;
-       struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
 
-       num_entries = p_fs->fs_func->calc_num_entries(p_uniname);
+       num_entries = exfat_calc_num_entries(p_uniname);
        if (num_entries == 0)
                return -EINVAL;
 
@@ -1995,14 +1993,13 @@ s32 get_num_entries_and_dos_name(struct super_block *sb, struct chain_t *p_dir,
        return 0;
 }
 
-static void exfat_get_uni_name_from_ext_entry(struct super_block *sb,
+void exfat_get_uni_name_from_ext_entry(struct super_block *sb,
                                       struct chain_t *p_dir, s32 entry,
                                       u16 *uniname)
 {
        int i;
        struct dentry_t *ep;
        struct entry_set_cache_t *es;
-       struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
 
        es = get_entry_set_in_dir(sb, p_dir, entry, ES_ALL_ENTRIES, &ep);
        if (!es || es->num_entries < 3) {
@@ -2020,7 +2017,7 @@ static void exfat_get_uni_name_from_ext_entry(struct super_block *sb,
         * So, the index of first file-name dentry should start from 2.
         */
        for (i = 2; i < es->num_entries; i++, ep++) {
-               if (p_fs->fs_func->get_entry_type(ep) == TYPE_EXTEND)
+               if (exfat_get_entry_type(ep) == TYPE_EXTEND)
                        extract_uni_name_from_name_entry((struct name_dentry_t *)
                                                         ep, uniname, i);
                else
@@ -2032,7 +2029,7 @@ out:
        release_entry_set(es);
 }
 
-static s32 exfat_calc_num_entries(struct uni_name_t *p_uniname)
+s32 exfat_calc_num_entries(struct uni_name_t *p_uniname)
 {
        s32 len;
 
@@ -2100,36 +2097,6 @@ s32 resolve_path(struct inode *inode, char *path, struct chain_t *p_dir,
        return 0;
 }
 
-/*
- *  File Operation Functions
- */
-static struct fs_func exfat_fs_func = {
-       .alloc_cluster = exfat_alloc_cluster,
-       .free_cluster = exfat_free_cluster,
-       .count_used_clusters = exfat_count_used_clusters,
-
-       .init_dir_entry = exfat_init_dir_entry,
-       .init_ext_entry = exfat_init_ext_entry,
-       .find_dir_entry = exfat_find_dir_entry,
-       .delete_dir_entry = exfat_delete_dir_entry,
-       .get_uni_name_from_ext_entry = exfat_get_uni_name_from_ext_entry,
-       .count_ext_entries = exfat_count_ext_entries,
-       .calc_num_entries = exfat_calc_num_entries,
-
-       .get_entry_type = exfat_get_entry_type,
-       .set_entry_type = exfat_set_entry_type,
-       .get_entry_attr = exfat_get_entry_attr,
-       .set_entry_attr = exfat_set_entry_attr,
-       .get_entry_flag = exfat_get_entry_flag,
-       .set_entry_flag = exfat_set_entry_flag,
-       .get_entry_clu0 = exfat_get_entry_clu0,
-       .set_entry_clu0 = exfat_set_entry_clu0,
-       .get_entry_size = exfat_get_entry_size,
-       .set_entry_size = exfat_set_entry_size,
-       .get_entry_time = exfat_get_entry_time,
-       .set_entry_time = exfat_set_entry_time,
-};
-
 s32 exfat_mount(struct super_block *sb, struct pbr_sector_t *p_pbr)
 {
        struct bpbex_t *p_bpb = (struct bpbex_t *)p_pbr->bpb;
@@ -2173,8 +2140,6 @@ s32 exfat_mount(struct super_block *sb, struct pbr_sector_t *p_pbr)
        p_fs->clu_srch_ptr = 2;
        p_fs->used_clusters = UINT_MAX;
 
-       p_fs->fs_func = &exfat_fs_func;
-
        return 0;
 }
 
@@ -2187,7 +2152,6 @@ s32 create_dir(struct inode *inode, struct chain_t *p_dir,
        struct dos_name_t dos_name;
        struct super_block *sb = inode->i_sb;
        struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-       struct fs_func *fs_func = p_fs->fs_func;
 
        ret = get_num_entries_and_dos_name(sb, p_dir, p_uniname, &num_entries,
                                           &dos_name);
@@ -2204,7 +2168,7 @@ s32 create_dir(struct inode *inode, struct chain_t *p_dir,
        clu.flags = (p_fs->vol_type == EXFAT) ? 0x03 : 0x01;
 
        /* (1) allocate a cluster */
-       ret = fs_func->alloc_cluster(sb, 1, &clu);
+       ret = exfat_alloc_cluster(sb, 1, &clu);
        if (ret < 0)
                return ret;
        else if (ret == 0)
@@ -2218,13 +2182,13 @@ s32 create_dir(struct inode *inode, struct chain_t *p_dir,
 
        /* (2) update the directory entry */
        /* make sub-dir entry in parent directory */
-       ret = fs_func->init_dir_entry(sb, p_dir, dentry, TYPE_DIR, clu.dir,
-                                     size);
+       ret = exfat_init_dir_entry(sb, p_dir, dentry, TYPE_DIR, clu.dir,
+                                  size);
        if (ret != 0)
                return ret;
 
-       ret = fs_func->init_ext_entry(sb, p_dir, dentry, num_entries, p_uniname,
-                                     &dos_name);
+       ret = exfat_init_ext_entry(sb, p_dir, dentry, num_entries, p_uniname,
+                                  &dos_name);
        if (ret != 0)
                return ret;
 
@@ -2252,7 +2216,6 @@ s32 create_file(struct inode *inode, struct chain_t *p_dir,
        struct dos_name_t dos_name;
        struct super_block *sb = inode->i_sb;
        struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-       struct fs_func *fs_func = p_fs->fs_func;
 
        ret = get_num_entries_and_dos_name(sb, p_dir, p_uniname, &num_entries,
                                           &dos_name);
@@ -2268,13 +2231,13 @@ s32 create_file(struct inode *inode, struct chain_t *p_dir,
        /* fill the dos name directory entry information of the created file.
         * the first cluster is not determined yet. (0)
         */
-       ret = fs_func->init_dir_entry(sb, p_dir, dentry, TYPE_FILE | mode,
-                                     CLUSTER_32(0), 0);
+       ret = exfat_init_dir_entry(sb, p_dir, dentry, TYPE_FILE | mode,
+                                  CLUSTER_32(0), 0);
        if (ret != 0)
                return ret;
 
-       ret = fs_func->init_ext_entry(sb, p_dir, dentry, num_entries, p_uniname,
-                                     &dos_name);
+       ret = exfat_init_ext_entry(sb, p_dir, dentry, num_entries, p_uniname,
+                                  &dos_name);
        if (ret != 0)
                return ret;
 
@@ -2301,8 +2264,6 @@ void remove_file(struct inode *inode, struct chain_t *p_dir, s32 entry)
        sector_t sector;
        struct dentry_t *ep;
        struct super_block *sb = inode->i_sb;
-       struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-       struct fs_func *fs_func = p_fs->fs_func;
 
        ep = get_entry_in_dir(sb, p_dir, entry, &sector);
        if (!ep)
@@ -2311,7 +2272,7 @@ void remove_file(struct inode *inode, struct chain_t *p_dir, s32 entry)
        exfat_buf_lock(sb, sector);
 
        /* exfat_buf_lock() before call count_ext_entries() */
-       num_entries = fs_func->count_ext_entries(sb, p_dir, entry, ep);
+       num_entries = exfat_count_ext_entries(sb, p_dir, entry, ep);
        if (num_entries < 0) {
                exfat_buf_unlock(sb, sector);
                return;
@@ -2321,7 +2282,7 @@ void remove_file(struct inode *inode, struct chain_t *p_dir, s32 entry)
        exfat_buf_unlock(sb, sector);
 
        /* (1) update the directory entry */
-       fs_func->delete_dir_entry(sb, p_dir, entry, 0, num_entries);
+       exfat_delete_dir_entry(sb, p_dir, entry, 0, num_entries);
 }
 
 s32 exfat_rename_file(struct inode *inode, struct chain_t *p_dir, s32 oldentry,
@@ -2332,8 +2293,6 @@ s32 exfat_rename_file(struct inode *inode, struct chain_t *p_dir, s32 oldentry,
        struct dos_name_t dos_name;
        struct dentry_t *epold, *epnew;
        struct super_block *sb = inode->i_sb;
-       struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-       struct fs_func *fs_func = p_fs->fs_func;
 
        epold = get_entry_in_dir(sb, p_dir, oldentry, &sector_old);
        if (!epold)
@@ -2342,8 +2301,8 @@ s32 exfat_rename_file(struct inode *inode, struct chain_t *p_dir, s32 oldentry,
        exfat_buf_lock(sb, sector_old);
 
        /* exfat_buf_lock() before call count_ext_entries() */
-       num_old_entries = fs_func->count_ext_entries(sb, p_dir, oldentry,
-                                                    epold);
+       num_old_entries = exfat_count_ext_entries(sb, p_dir, oldentry,
+                                                 epold);
        if (num_old_entries < 0) {
                exfat_buf_unlock(sb, sector_old);
                return -ENOENT;
@@ -2371,10 +2330,10 @@ s32 exfat_rename_file(struct inode *inode, struct chain_t *p_dir, s32 oldentry,
                }
 
                memcpy((void *)epnew, (void *)epold, DENTRY_SIZE);
-               if (fs_func->get_entry_type(epnew) == TYPE_FILE) {
-                       fs_func->set_entry_attr(epnew,
-                                               fs_func->get_entry_attr(epnew) |
-                                               ATTR_ARCHIVE);
+               if (exfat_get_entry_type(epnew) == TYPE_FILE) {
+                       exfat_set_entry_attr(epnew,
+                                            exfat_get_entry_attr(epnew) |
+                                            ATTR_ARCHIVE);
                        fid->attr |= ATTR_ARCHIVE;
                }
                exfat_buf_modify(sb, sector_new);
@@ -2395,33 +2354,33 @@ s32 exfat_rename_file(struct inode *inode, struct chain_t *p_dir, s32 oldentry,
                exfat_buf_modify(sb, sector_new);
                exfat_buf_unlock(sb, sector_old);
 
-               ret = fs_func->init_ext_entry(sb, p_dir, newentry,
-                                             num_new_entries, p_uniname,
-                                             &dos_name);
+               ret = exfat_init_ext_entry(sb, p_dir, newentry,
+                                          num_new_entries, p_uniname,
+                                          &dos_name);
                if (ret != 0)
                        return ret;
 
-               fs_func->delete_dir_entry(sb, p_dir, oldentry, 0,
-                                         num_old_entries);
+               exfat_delete_dir_entry(sb, p_dir, oldentry, 0,
+                                      num_old_entries);
                fid->entry = newentry;
        } else {
-               if (fs_func->get_entry_type(epold) == TYPE_FILE) {
-                       fs_func->set_entry_attr(epold,
-                                               fs_func->get_entry_attr(epold) |
-                                               ATTR_ARCHIVE);
+               if (exfat_get_entry_type(epold) == TYPE_FILE) {
+                       exfat_set_entry_attr(epold,
+                                            exfat_get_entry_attr(epold) |
+                                            ATTR_ARCHIVE);
                        fid->attr |= ATTR_ARCHIVE;
                }
                exfat_buf_modify(sb, sector_old);
                exfat_buf_unlock(sb, sector_old);
 
-               ret = fs_func->init_ext_entry(sb, p_dir, oldentry,
-                                             num_new_entries, p_uniname,
-                                             &dos_name);
+               ret = exfat_init_ext_entry(sb, p_dir, oldentry,
+                                          num_new_entries, p_uniname,
+                                          &dos_name);
                if (ret != 0)
                        return ret;
 
-               fs_func->delete_dir_entry(sb, p_dir, oldentry, num_new_entries,
-                                         num_old_entries);
+               exfat_delete_dir_entry(sb, p_dir, oldentry, num_new_entries,
+                                      num_old_entries);
        }
 
        return 0;
@@ -2436,23 +2395,21 @@ s32 move_file(struct inode *inode, struct chain_t *p_olddir, s32 oldentry,
        struct dos_name_t dos_name;
        struct dentry_t *epmov, *epnew;
        struct super_block *sb = inode->i_sb;
-       struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-       struct fs_func *fs_func = p_fs->fs_func;
 
        epmov = get_entry_in_dir(sb, p_olddir, oldentry, &sector_mov);
        if (!epmov)
                return -ENOENT;
 
        /* check if the source and target directory is the same */
-       if (fs_func->get_entry_type(epmov) == TYPE_DIR &&
-           fs_func->get_entry_clu0(epmov) == p_newdir->dir)
+       if (exfat_get_entry_type(epmov) == TYPE_DIR &&
+           exfat_get_entry_clu0(epmov) == p_newdir->dir)
                return -EINVAL;
 
        exfat_buf_lock(sb, sector_mov);
 
        /* exfat_buf_lock() before call count_ext_entries() */
-       num_old_entries = fs_func->count_ext_entries(sb, p_olddir, oldentry,
-                                                    epmov);
+       num_old_entries = exfat_count_ext_entries(sb, p_olddir, oldentry,
+                                                 epmov);
        if (num_old_entries < 0) {
                exfat_buf_unlock(sb, sector_mov);
                return -ENOENT;
@@ -2479,9 +2436,9 @@ s32 move_file(struct inode *inode, struct chain_t *p_olddir, s32 oldentry,
        }
 
        memcpy((void *)epnew, (void *)epmov, DENTRY_SIZE);
-       if (fs_func->get_entry_type(epnew) == TYPE_FILE) {
-               fs_func->set_entry_attr(epnew, fs_func->get_entry_attr(epnew) |
-                                       ATTR_ARCHIVE);
+       if (exfat_get_entry_type(epnew) == TYPE_FILE) {
+               exfat_set_entry_attr(epnew, exfat_get_entry_attr(epnew) |
+                                    ATTR_ARCHIVE);
                fid->attr |= ATTR_ARCHIVE;
        }
        exfat_buf_modify(sb, sector_new);
@@ -2501,12 +2458,12 @@ s32 move_file(struct inode *inode, struct chain_t *p_olddir, s32 oldentry,
        exfat_buf_modify(sb, sector_new);
        exfat_buf_unlock(sb, sector_mov);
 
-       ret = fs_func->init_ext_entry(sb, p_newdir, newentry, num_new_entries,
-                                     p_uniname, &dos_name);
+       ret = exfat_init_ext_entry(sb, p_newdir, newentry, num_new_entries,
+                                  p_uniname, &dos_name);
        if (ret != 0)
                return ret;
 
-       fs_func->delete_dir_entry(sb, p_olddir, oldentry, 0, num_old_entries);
+       exfat_delete_dir_entry(sb, p_olddir, oldentry, 0, num_old_entries);
 
        fid->dir.dir = p_newdir->dir;
        fid->dir.size = p_newdir->size;
index 9f91853..b81d2a8 100644 (file)
@@ -38,8 +38,8 @@
 
 static struct kmem_cache *exfat_inode_cachep;
 
-static int exfat_default_codepage = CONFIG_EXFAT_DEFAULT_CODEPAGE;
-static char exfat_default_iocharset[] = CONFIG_EXFAT_DEFAULT_IOCHARSET;
+static int exfat_default_codepage = CONFIG_STAGING_EXFAT_DEFAULT_CODEPAGE;
+static char exfat_default_iocharset[] = CONFIG_STAGING_EXFAT_DEFAULT_IOCHARSET;
 
 #define INC_IVERSION(x) (inode_inc_iversion(x))
 #define GET_IVERSION(x) (inode_peek_iversion_raw(x))
@@ -365,7 +365,7 @@ static int ffsMountVol(struct super_block *sb)
 
        if (p_bd->sector_size < sb->s_blocksize) {
                printk(KERN_INFO "EXFAT: mount failed - sector size %d less than blocksize %ld\n",
-                       p_bd->sector_size,  sb->s_blocksize);
+                      p_bd->sector_size,  sb->s_blocksize);
                ret = -EINVAL;
                goto out;
        }
@@ -492,7 +492,7 @@ static int ffsGetVolInfo(struct super_block *sb, struct vol_info_t *info)
        mutex_lock(&p_fs->v_mutex);
 
        if (p_fs->used_clusters == UINT_MAX)
-               p_fs->used_clusters = p_fs->fs_func->count_used_clusters(sb);
+               p_fs->used_clusters = exfat_count_used_clusters(sb);
 
        info->FatType = p_fs->vol_type;
        info->ClusterSize = p_fs->cluster_size;
@@ -565,8 +565,8 @@ static int ffsLookupFile(struct inode *inode, char *path, struct file_id_t *fid)
                goto out;
 
        /* search the file name for directories */
-       dentry = p_fs->fs_func->find_dir_entry(sb, &dir, &uni_name, num_entries,
-                                              &dos_name, TYPE_ALL);
+       dentry = exfat_find_dir_entry(sb, &dir, &uni_name, num_entries,
+                                     &dos_name, TYPE_ALL);
        if (dentry < -1) {
                ret = -ENOENT;
                goto out;
@@ -595,18 +595,18 @@ static int ffsLookupFile(struct inode *inode, char *path, struct file_id_t *fid)
                }
                ep2 = ep + 1;
 
-               fid->type = p_fs->fs_func->get_entry_type(ep);
+               fid->type = exfat_get_entry_type(ep);
                fid->rwoffset = 0;
                fid->hint_last_off = -1;
-               fid->attr = p_fs->fs_func->get_entry_attr(ep);
+               fid->attr = exfat_get_entry_attr(ep);
 
-               fid->size = p_fs->fs_func->get_entry_size(ep2);
+               fid->size = exfat_get_entry_size(ep2);
                if ((fid->type == TYPE_FILE) && (fid->size == 0)) {
                        fid->flags = (p_fs->vol_type == EXFAT) ? 0x03 : 0x01;
                        fid->start_clu = CLUSTER_32(~0);
                } else {
-                       fid->flags = p_fs->fs_func->get_entry_flag(ep2);
-                       fid->start_clu = p_fs->fs_func->get_entry_clu0(ep2);
+                       fid->flags = exfat_get_entry_flag(ep2);
+                       fid->start_clu = exfat_get_entry_clu0(ep2);
                }
 
                release_entry_set(es);
@@ -647,7 +647,7 @@ static int ffsCreateFile(struct inode *inode, char *path, u8 mode,
        /* create a new file */
        ret = create_file(inode, &dir, &uni_name, mode, fid);
 
-#ifndef CONFIG_EXFAT_DELAYED_SYNC
+#ifndef CONFIG_STAGING_EXFAT_DELAYED_SYNC
        fs_sync(sb, true);
        fs_set_vol_flags(sb, VOL_CLEAN);
 #endif
@@ -886,9 +886,9 @@ static int ffsWriteFile(struct inode *inode, struct file_id_t *fid,
                        new_clu.flags = fid->flags;
 
                        /* (1) allocate a chain of clusters */
-                       num_alloced = p_fs->fs_func->alloc_cluster(sb,
-                                                                  num_alloc,
-                                                                  &new_clu);
+                       num_alloced = exfat_alloc_cluster(sb,
+                                                         num_alloc,
+                                                         &new_clu);
                        if (num_alloced == 0)
                                break;
                        if (num_alloced < 0) {
@@ -991,24 +991,24 @@ static int ffsWriteFile(struct inode *inode, struct file_id_t *fid,
                goto err_out;
        ep2 = ep + 1;
 
-       p_fs->fs_func->set_entry_time(ep, tm_current(&tm), TM_MODIFY);
-       p_fs->fs_func->set_entry_attr(ep, fid->attr);
+       exfat_set_entry_time(ep, tm_current(&tm), TM_MODIFY);
+       exfat_set_entry_attr(ep, fid->attr);
 
        if (modified) {
-               if (p_fs->fs_func->get_entry_flag(ep2) != fid->flags)
-                       p_fs->fs_func->set_entry_flag(ep2, fid->flags);
+               if (exfat_get_entry_flag(ep2) != fid->flags)
+                       exfat_set_entry_flag(ep2, fid->flags);
 
-               if (p_fs->fs_func->get_entry_size(ep2) != fid->size)
-                       p_fs->fs_func->set_entry_size(ep2, fid->size);
+               if (exfat_get_entry_size(ep2) != fid->size)
+                       exfat_set_entry_size(ep2, fid->size);
 
-               if (p_fs->fs_func->get_entry_clu0(ep2) != fid->start_clu)
-                       p_fs->fs_func->set_entry_clu0(ep2, fid->start_clu);
+               if (exfat_get_entry_clu0(ep2) != fid->start_clu)
+                       exfat_set_entry_clu0(ep2, fid->start_clu);
        }
 
        update_dir_checksum_with_entry_set(sb, es);
        release_entry_set(es);
 
-#ifndef CONFIG_EXFAT_DELAYED_SYNC
+#ifndef CONFIG_STAGING_EXFAT_DELAYED_SYNC
        fs_sync(sb, true);
        fs_set_vol_flags(sb, VOL_CLEAN);
 #endif
@@ -1108,13 +1108,13 @@ static int ffsTruncateFile(struct inode *inode, u64 old_size, u64 new_size)
                }
        ep2 = ep + 1;
 
-       p_fs->fs_func->set_entry_time(ep, tm_current(&tm), TM_MODIFY);
-       p_fs->fs_func->set_entry_attr(ep, fid->attr);
+       exfat_set_entry_time(ep, tm_current(&tm), TM_MODIFY);
+       exfat_set_entry_attr(ep, fid->attr);
 
-       p_fs->fs_func->set_entry_size(ep2, new_size);
+       exfat_set_entry_size(ep2, new_size);
        if (new_size == 0) {
-               p_fs->fs_func->set_entry_flag(ep2, 0x01);
-               p_fs->fs_func->set_entry_clu0(ep2, CLUSTER_32(0));
+               exfat_set_entry_flag(ep2, 0x01);
+               exfat_set_entry_clu0(ep2, CLUSTER_32(0));
        }
 
        update_dir_checksum_with_entry_set(sb, es);
@@ -1127,14 +1127,14 @@ static int ffsTruncateFile(struct inode *inode, u64 old_size, u64 new_size)
        }
 
        /* (3) free the clusters */
-       p_fs->fs_func->free_cluster(sb, &clu, 0);
+       exfat_free_cluster(sb, &clu, 0);
 
        /* hint information */
        fid->hint_last_off = -1;
        if (fid->rwoffset > fid->size)
                fid->rwoffset = fid->size;
 
-#ifndef CONFIG_EXFAT_DELAYED_SYNC
+#ifndef CONFIG_STAGING_EXFAT_DELAYED_SYNC
        fs_sync(sb, true);
        fs_set_vol_flags(sb, VOL_CLEAN);
 #endif
@@ -1217,7 +1217,7 @@ static int ffsMoveFile(struct inode *old_parent_inode, struct file_id_t *fid,
                goto out2;
        }
 
-       if (p_fs->fs_func->get_entry_attr(ep) & ATTR_READONLY) {
+       if (exfat_get_entry_attr(ep) & ATTR_READONLY) {
                ret = -EPERM;
                goto out2;
        }
@@ -1237,7 +1237,7 @@ static int ffsMoveFile(struct inode *old_parent_inode, struct file_id_t *fid,
                if (!ep)
                        goto out;
 
-               entry_type = p_fs->fs_func->get_entry_type(ep);
+               entry_type = exfat_get_entry_type(ep);
 
                if (entry_type == TYPE_DIR) {
                        struct chain_t new_clu;
@@ -1274,15 +1274,15 @@ static int ffsMoveFile(struct inode *old_parent_inode, struct file_id_t *fid,
                if (!ep)
                        goto out;
 
-               num_entries = p_fs->fs_func->count_ext_entries(sb, p_dir,
-                                                              new_entry, ep);
+               num_entries = exfat_count_ext_entries(sb, p_dir,
+                                                     new_entry, ep);
                if (num_entries < 0)
                        goto out;
-               p_fs->fs_func->delete_dir_entry(sb, p_dir, new_entry, 0,
-                                               num_entries + 1);
+               exfat_delete_dir_entry(sb, p_dir, new_entry, 0,
+                                      num_entries + 1);
        }
 out:
-#ifndef CONFIG_EXFAT_DELAYED_SYNC
+#ifndef CONFIG_STAGING_EXFAT_DELAYED_SYNC
        fs_sync(sb, true);
        fs_set_vol_flags(sb, VOL_CLEAN);
 #endif
@@ -1324,7 +1324,7 @@ static int ffsRemoveFile(struct inode *inode, struct file_id_t *fid)
                goto out;
        }
 
-       if (p_fs->fs_func->get_entry_attr(ep) & ATTR_READONLY) {
+       if (exfat_get_entry_attr(ep) & ATTR_READONLY) {
                ret = -EPERM;
                goto out;
        }
@@ -1338,13 +1338,13 @@ static int ffsRemoveFile(struct inode *inode, struct file_id_t *fid)
        clu_to_free.flags = fid->flags;
 
        /* (2) free the clusters */
-       p_fs->fs_func->free_cluster(sb, &clu_to_free, 0);
+       exfat_free_cluster(sb, &clu_to_free, 0);
 
        fid->size = 0;
        fid->start_clu = CLUSTER_32(~0);
        fid->flags = (p_fs->vol_type == EXFAT) ? 0x03 : 0x01;
 
-#ifndef CONFIG_EXFAT_DELAYED_SYNC
+#ifndef CONFIG_STAGING_EXFAT_DELAYED_SYNC
        fs_sync(sb, true);
        fs_set_vol_flags(sb, VOL_CLEAN);
 #endif
@@ -1398,7 +1398,7 @@ static int ffsSetAttr(struct inode *inode, u32 attr)
                goto out;
        }
 
-       type = p_fs->fs_func->get_entry_type(ep);
+       type = exfat_get_entry_type(ep);
 
        if (((type == TYPE_FILE) && (attr & ATTR_SUBDIR)) ||
            ((type == TYPE_DIR) && (!(attr & ATTR_SUBDIR)))) {
@@ -1415,12 +1415,12 @@ static int ffsSetAttr(struct inode *inode, u32 attr)
 
        /* set the file attribute */
        fid->attr = attr;
-       p_fs->fs_func->set_entry_attr(ep, attr);
+       exfat_set_entry_attr(ep, attr);
 
        update_dir_checksum_with_entry_set(sb, es);
        release_entry_set(es);
 
-#ifndef CONFIG_EXFAT_DELAYED_SYNC
+#ifndef CONFIG_STAGING_EXFAT_DELAYED_SYNC
        fs_sync(sb, true);
        fs_set_vol_flags(sb, VOL_CLEAN);
 #endif
@@ -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;
@@ -1502,9 +1502,9 @@ static int ffsReadStat(struct inode *inode, struct dir_entry_t *info)
        ep2 = ep + 1;
 
        /* set FILE_INFO structure using the acquired struct dentry_t */
-       info->Attr = p_fs->fs_func->get_entry_attr(ep);
+       info->Attr = exfat_get_entry_attr(ep);
 
-       p_fs->fs_func->get_entry_time(ep, &tm, TM_CREATE);
+       exfat_get_entry_time(ep, &tm, TM_CREATE);
        info->CreateTimestamp.Year = tm.year;
        info->CreateTimestamp.Month = tm.mon;
        info->CreateTimestamp.Day = tm.day;
@@ -1513,7 +1513,7 @@ static int ffsReadStat(struct inode *inode, struct dir_entry_t *info)
        info->CreateTimestamp.Second = tm.sec;
        info->CreateTimestamp.MilliSecond = 0;
 
-       p_fs->fs_func->get_entry_time(ep, &tm, TM_MODIFY);
+       exfat_get_entry_time(ep, &tm, TM_MODIFY);
        info->ModifyTimestamp.Year = tm.year;
        info->ModifyTimestamp.Month = tm.mon;
        info->ModifyTimestamp.Day = tm.day;
@@ -1528,13 +1528,13 @@ static int ffsReadStat(struct inode *inode, struct dir_entry_t *info)
        /* XXX this is very bad for exfat cuz name is already included in es.
         * API should be revised
         */
-       p_fs->fs_func->get_uni_name_from_ext_entry(sb, &fid->dir, fid->entry,
-                                                  uni_name.name);
+       exfat_get_uni_name_from_ext_entry(sb, &fid->dir, fid->entry,
+                                         uni_name.name);
        nls_uniname_to_cstring(sb, info->Name, &uni_name);
 
        info->NumSubdirs = 2;
 
-       info->Size = p_fs->fs_func->get_entry_size(ep2);
+       info->Size = exfat_get_entry_size(ep2);
 
        release_entry_set(es);
 
@@ -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;
@@ -1602,7 +1602,7 @@ static int ffsWriteStat(struct inode *inode, struct dir_entry_t *info)
        }
        ep2 = ep + 1;
 
-       p_fs->fs_func->set_entry_attr(ep, info->Attr);
+       exfat_set_entry_attr(ep, info->Attr);
 
        /* set FILE_INFO structure using the acquired struct dentry_t */
        tm.sec  = info->CreateTimestamp.Second;
@@ -1611,7 +1611,7 @@ static int ffsWriteStat(struct inode *inode, struct dir_entry_t *info)
        tm.day  = info->CreateTimestamp.Day;
        tm.mon  = info->CreateTimestamp.Month;
        tm.year = info->CreateTimestamp.Year;
-       p_fs->fs_func->set_entry_time(ep, &tm, TM_CREATE);
+       exfat_set_entry_time(ep, &tm, TM_CREATE);
 
        tm.sec  = info->ModifyTimestamp.Second;
        tm.min  = info->ModifyTimestamp.Minute;
@@ -1619,9 +1619,9 @@ static int ffsWriteStat(struct inode *inode, struct dir_entry_t *info)
        tm.day  = info->ModifyTimestamp.Day;
        tm.mon  = info->ModifyTimestamp.Month;
        tm.year = info->ModifyTimestamp.Year;
-       p_fs->fs_func->set_entry_time(ep, &tm, TM_MODIFY);
+       exfat_set_entry_time(ep, &tm, TM_MODIFY);
 
-       p_fs->fs_func->set_entry_size(ep2, info->Size);
+       exfat_set_entry_size(ep2, info->Size);
 
        update_dir_checksum_with_entry_set(sb, es);
        release_entry_set(es);
@@ -1704,7 +1704,7 @@ static int ffsMapCluster(struct inode *inode, s32 clu_offset, u32 *clu)
                new_clu.flags = fid->flags;
 
                /* (1) allocate a cluster */
-               num_alloced = p_fs->fs_func->alloc_cluster(sb, 1, &new_clu);
+               num_alloced = exfat_alloc_cluster(sb, 1, &new_clu);
                if (num_alloced < 0) {
                        ret = -EIO;
                        goto out;
@@ -1744,13 +1744,11 @@ static int ffsMapCluster(struct inode *inode, s32 clu_offset, u32 *clu)
 
                /* (3) update directory entry */
                if (modified) {
-                       if (p_fs->fs_func->get_entry_flag(ep) != fid->flags)
-                               p_fs->fs_func->set_entry_flag(ep, fid->flags);
-
-                       if (p_fs->fs_func->get_entry_clu0(ep) != fid->start_clu)
-                               p_fs->fs_func->set_entry_clu0(ep,
-                                                             fid->start_clu);
+                       if (exfat_get_entry_flag(ep) != fid->flags)
+                               exfat_set_entry_flag(ep, fid->flags);
 
+                       if (exfat_get_entry_clu0(ep) != fid->start_clu)
+                               exfat_set_entry_clu0(ep, fid->start_clu);
                }
 
                update_dir_checksum_with_entry_set(sb, es);
@@ -1804,7 +1802,7 @@ static int ffsCreateDir(struct inode *inode, char *path, struct file_id_t *fid)
 
        ret = create_dir(inode, &dir, &uni_name, fid);
 
-#ifndef CONFIG_EXFAT_DELAYED_SYNC
+#ifndef CONFIG_STAGING_EXFAT_DELAYED_SYNC
        fs_sync(sb, true);
        fs_set_vol_flags(sb, VOL_CLEAN);
 #endif
@@ -1831,7 +1829,6 @@ static int ffsReadDir(struct inode *inode, struct dir_entry_t *dir_entry)
        struct dentry_t *ep;
        struct super_block *sb = inode->i_sb;
        struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-       struct fs_func *fs_func = p_fs->fs_func;
        struct file_id_t *fid = &(EXFAT_I(inode)->fid);
 
        /* check the validity of pointer parameters */
@@ -1913,7 +1910,7 @@ static int ffsReadDir(struct inode *inode, struct dir_entry_t *dir_entry)
                                ret = -ENOENT;
                                goto out;
                        }
-                       type = fs_func->get_entry_type(ep);
+                       type = exfat_get_entry_type(ep);
 
                        if (type == TYPE_UNUSED)
                                break;
@@ -1922,9 +1919,9 @@ static int ffsReadDir(struct inode *inode, struct dir_entry_t *dir_entry)
                                continue;
 
                        exfat_buf_lock(sb, sector);
-                       dir_entry->Attr = fs_func->get_entry_attr(ep);
+                       dir_entry->Attr = exfat_get_entry_attr(ep);
 
-                       fs_func->get_entry_time(ep, &tm, TM_CREATE);
+                       exfat_get_entry_time(ep, &tm, TM_CREATE);
                        dir_entry->CreateTimestamp.Year = tm.year;
                        dir_entry->CreateTimestamp.Month = tm.mon;
                        dir_entry->CreateTimestamp.Day = tm.day;
@@ -1933,7 +1930,7 @@ static int ffsReadDir(struct inode *inode, struct dir_entry_t *dir_entry)
                        dir_entry->CreateTimestamp.Second = tm.sec;
                        dir_entry->CreateTimestamp.MilliSecond = 0;
 
-                       fs_func->get_entry_time(ep, &tm, TM_MODIFY);
+                       exfat_get_entry_time(ep, &tm, TM_MODIFY);
                        dir_entry->ModifyTimestamp.Year = tm.year;
                        dir_entry->ModifyTimestamp.Month = tm.mon;
                        dir_entry->ModifyTimestamp.Day = tm.day;
@@ -1946,8 +1943,8 @@ static int ffsReadDir(struct inode *inode, struct dir_entry_t *dir_entry)
                               sizeof(struct date_time_t));
 
                        *uni_name.name = 0x0;
-                       fs_func->get_uni_name_from_ext_entry(sb, &dir, dentry,
-                                                            uni_name.name);
+                       exfat_get_uni_name_from_ext_entry(sb, &dir, dentry,
+                                                         uni_name.name);
                        nls_uniname_to_cstring(sb, dir_entry->Name, &uni_name);
                        exfat_buf_unlock(sb, sector);
 
@@ -1957,7 +1954,7 @@ static int ffsReadDir(struct inode *inode, struct dir_entry_t *dir_entry)
                                goto out;
                        }
 
-                       dir_entry->Size = fs_func->get_entry_size(ep);
+                       dir_entry->Size = exfat_get_entry_size(ep);
 
                        /* hint information */
                        if (dir.dir == CLUSTER_32(0)) { /* FAT16 root_dir */
@@ -2047,13 +2044,13 @@ static int ffsRemoveDir(struct inode *inode, struct file_id_t *fid)
        remove_file(inode, &dir, dentry);
 
        /* (2) free the clusters */
-       p_fs->fs_func->free_cluster(sb, &clu_to_free, 1);
+       exfat_free_cluster(sb, &clu_to_free, 1);
 
        fid->size = 0;
        fid->start_clu = CLUSTER_32(~0);
        fid->flags = (p_fs->vol_type == EXFAT) ? 0x03 : 0x01;
 
-#ifndef CONFIG_EXFAT_DELAYED_SYNC
+#ifndef CONFIG_STAGING_EXFAT_DELAYED_SYNC
        fs_sync(sb, true);
        fs_set_vol_flags(sb, VOL_CLEAN);
 #endif
@@ -2176,14 +2173,14 @@ static long exfat_generic_ioctl(struct file *filp, unsigned int cmd,
                                unsigned long arg)
 {
        struct inode *inode = filp->f_path.dentry->d_inode;
-#ifdef CONFIG_EXFAT_KERNEL_DEBUG
+#ifdef CONFIG_STAGING_EXFAT_KERNEL_DEBUG
        unsigned int flags;
-#endif /* CONFIG_EXFAT_KERNEL_DEBUG */
+#endif /* CONFIG_STAGING_EXFAT_KERNEL_DEBUG */
 
        switch (cmd) {
        case EXFAT_IOCTL_GET_VOLUME_ID:
                return exfat_ioctl_volume_id(inode);
-#ifdef CONFIG_EXFAT_KERNEL_DEBUG
+#ifdef CONFIG_STAGING_EXFAT_KERNEL_DEBUG
        case EXFAT_IOC_GET_DEBUGFLAGS: {
                struct super_block *sb = inode->i_sb;
                struct exfat_sb_info *sbi = EXFAT_SB(sb);
@@ -2207,7 +2204,7 @@ static long exfat_generic_ioctl(struct file *filp, unsigned int cmd,
 
                return 0;
        }
-#endif /* CONFIG_EXFAT_KERNEL_DEBUG */
+#endif /* CONFIG_STAGING_EXFAT_KERNEL_DEBUG */
        default:
                return -ENOTTY; /* Inappropriate ioctl for device */
        }
@@ -3400,7 +3397,7 @@ static int exfat_show_options(struct seq_file *m, struct dentry *root)
                seq_puts(m, ",errors=panic");
        else
                seq_puts(m, ",errors=remount-ro");
-#ifdef CONFIG_EXFAT_DISCARD
+#ifdef CONFIG_STAGING_EXFAT_DISCARD
        if (opts->discard)
                seq_puts(m, ",discard");
 #endif
@@ -3481,7 +3478,7 @@ enum {
        Opt_err_ro,
        Opt_utf8_hack,
        Opt_err,
-#ifdef CONFIG_EXFAT_DISCARD
+#ifdef CONFIG_STAGING_EXFAT_DISCARD
        Opt_discard,
 #endif /* EXFAT_CONFIG_DISCARD */
 };
@@ -3501,9 +3498,9 @@ static const match_table_t exfat_tokens = {
        {Opt_err_panic, "errors=panic"},
        {Opt_err_ro, "errors=remount-ro"},
        {Opt_utf8_hack, "utf8"},
-#ifdef CONFIG_EXFAT_DISCARD
+#ifdef CONFIG_STAGING_EXFAT_DISCARD
        {Opt_discard, "discard"},
-#endif /* CONFIG_EXFAT_DISCARD */
+#endif /* CONFIG_STAGING_EXFAT_DISCARD */
        {Opt_err, NULL}
 };
 
@@ -3524,7 +3521,7 @@ static int parse_options(char *options, int silent, int *debug,
        opts->iocharset = exfat_default_iocharset;
        opts->casesensitive = 0;
        opts->errors = EXFAT_ERRORS_RO;
-#ifdef CONFIG_EXFAT_DISCARD
+#ifdef CONFIG_STAGING_EXFAT_DISCARD
        opts->discard = 0;
 #endif
        *debug = 0;
@@ -3595,11 +3592,11 @@ static int parse_options(char *options, int silent, int *debug,
                case Opt_debug:
                        *debug = 1;
                        break;
-#ifdef CONFIG_EXFAT_DISCARD
+#ifdef CONFIG_STAGING_EXFAT_DISCARD
                case Opt_discard:
                        opts->discard = 1;
                        break;
-#endif /* CONFIG_EXFAT_DISCARD */
+#endif /* CONFIG_STAGING_EXFAT_DISCARD */
                case Opt_utf8_hack:
                        break;
                default:
@@ -3803,7 +3800,7 @@ static void __exit exfat_destroy_inodecache(void)
        kmem_cache_destroy(exfat_inode_cachep);
 }
 
-#ifdef CONFIG_EXFAT_KERNEL_DEBUG
+#ifdef CONFIG_STAGING_EXFAT_KERNEL_DEBUG
 static void exfat_debug_kill_sb(struct super_block *sb)
 {
        struct exfat_sb_info *sbi = EXFAT_SB(sb);
@@ -3831,17 +3828,17 @@ static void exfat_debug_kill_sb(struct super_block *sb)
 
        kill_block_super(sb);
 }
-#endif /* CONFIG_EXFAT_KERNEL_DEBUG */
+#endif /* CONFIG_STAGING_EXFAT_KERNEL_DEBUG */
 
 static struct file_system_type exfat_fs_type = {
        .owner       = THIS_MODULE,
        .name        = "exfat",
        .mount       = exfat_fs_mount,
-#ifdef CONFIG_EXFAT_KERNEL_DEBUG
+#ifdef CONFIG_STAGING_EXFAT_KERNEL_DEBUG
        .kill_sb    = exfat_debug_kill_sb,
 #else
        .kill_sb    = kill_block_super,
-#endif /* CONFIG_EXFAT_KERNEL_DEBUG */
+#endif /* CONFIG_STAGING_EXFAT_KERNEL_DEBUG */
        .fs_flags    = FS_REQUIRES_DEV,
 };
 
index 6ec78f5..e2f0b58 100644 (file)
@@ -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;
 
index 3968713..39dfe3f 100644 (file)
@@ -237,6 +237,12 @@ static const char * const adis16203_status_error_msgs[] = {
        [ADIS16203_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 2.975V",
 };
 
+static const struct adis_timeout adis16203_timeouts = {
+       .reset_ms = ADIS16203_STARTUP_DELAY,
+       .sw_reset_ms = ADIS16203_STARTUP_DELAY,
+       .self_test_ms = ADIS16203_STARTUP_DELAY
+};
+
 static const struct adis_data adis16203_data = {
        .read_delay = 20,
        .msc_ctrl_reg = ADIS16203_MSC_CTRL,
@@ -245,7 +251,7 @@ static const struct adis_data adis16203_data = {
 
        .self_test_mask = ADIS16203_MSC_CTRL_SELF_TEST_EN,
        .self_test_no_autoclear = true,
-       .startup_delay = ADIS16203_STARTUP_DELAY,
+       .timeouts = &adis16203_timeouts,
 
        .status_error_msgs = adis16203_status_error_msgs,
        .status_error_mask = BIT(ADIS16203_DIAG_STAT_SELFTEST_FAIL_BIT) |
index a480409..39eb836 100644 (file)
@@ -359,6 +359,12 @@ static const char * const adis16240_status_error_msgs[] = {
        [ADIS16240_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 2.225V",
 };
 
+static const struct adis_timeout adis16240_timeouts = {
+       .reset_ms = ADIS16240_STARTUP_DELAY,
+       .sw_reset_ms = ADIS16240_STARTUP_DELAY,
+       .self_test_ms = ADIS16240_STARTUP_DELAY,
+};
+
 static const struct adis_data adis16240_data = {
        .write_delay = 35,
        .read_delay = 35,
@@ -368,7 +374,7 @@ static const struct adis_data adis16240_data = {
 
        .self_test_mask = ADIS16240_MSC_CTRL_SELF_TEST_EN,
        .self_test_no_autoclear = true,
-       .startup_delay = ADIS16240_STARTUP_DELAY,
+       .timeouts = &adis16240_timeouts,
 
        .status_error_msgs = adis16240_status_error_msgs,
        .status_error_mask = BIT(ADIS16240_DIAG_STAT_PWRON_FAIL_BIT) |
@@ -399,6 +405,13 @@ static int adis16240_probe(struct spi_device *spi)
        indio_dev->num_channels = ARRAY_SIZE(adis16240_channels);
        indio_dev->modes = INDIO_DIRECT_MODE;
 
+       spi->mode = SPI_MODE_3;
+       ret = spi_setup(spi);
+       if (ret) {
+               dev_err(&spi->dev, "spi_setup failed!\n");
+               return ret;
+       }
+
        ret = adis_init(st, indio_dev, spi, &adis16240_data);
        if (ret)
                return ret;
diff --git a/drivers/staging/isdn/Kconfig b/drivers/staging/isdn/Kconfig
deleted file mode 100644 (file)
index faaf638..0000000
+++ /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 (file)
index 025504b..0000000
+++ /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 (file)
index 9210d11..0000000
+++ /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 (file)
index 81483db..0000000
+++ /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 (file)
index 3830a05..0000000
+++ /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 (file)
index 62b8030..0000000
+++ /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 (file)
index cdfa89c..0000000
+++ /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 (file)
index 32ec8cf..0000000
+++ /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 (file)
index 6a3dc99..0000000
+++ /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 (file)
index cdfea72..0000000
+++ /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 (file)
index b76b57a..0000000
+++ /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 (file)
index 3aca16e..0000000
+++ /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 (file)
index ac72cd2..0000000
+++ /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 (file)
index 2153619..0000000
+++ /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 (file)
index f5ed1d5..0000000
+++ /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 (file)
index c593105..0000000
+++ /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 (file)
index 9c01089..0000000
+++ /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 (file)
index a34b3c9..0000000
+++ /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 (file)
index c334525..0000000
+++ /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 (file)
index 83d7dd4..0000000
+++ /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 (file)
index 3bb8092..0000000
+++ /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 (file)
index 4b9637e..0000000
+++ /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 (file)
index f8bb186..0000000
+++ /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 (file)
index 0ecc2b5..0000000
+++ /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 (file)
index 9ddadd0..0000000
+++ /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 (file)
index 3ecf6e3..0000000
+++ /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 (file)
index 8914439..0000000
+++ /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 (file)
index 5587e9e..0000000
+++ /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 (file)
index a20c0bf..0000000
+++ /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 (file)
index 4c8a928..0000000
+++ /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 (file)
index e01f17f..0000000
+++ /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 (file)
index 2aa2a0e..0000000
+++ /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 (file)
index e99bd81..0000000
+++ /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 (file)
index a2c15cd..0000000
+++ /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 (file)
index ba177c3..0000000
+++ /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 (file)
index cdac46a..0000000
+++ /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 (file)
index 0db2f75..0000000
+++ /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 (file)
index dcb9ef7..0000000
+++ /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 (file)
index f63f5fa..0000000
+++ /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 (file)
index 48afd9f..0000000
+++ /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 (file)
index 6e898b9..0000000
+++ /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 (file)
index 31d7c14..0000000
+++ /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 (file)
index cab6836..0000000
+++ /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__ */
index 592099a..25bb5c9 100644 (file)
@@ -32,7 +32,7 @@
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Matt.Sickler@Daktronics.com");
 
-struct i2c_device {
+struct kpc_i2c {
        unsigned long           smba;
        struct i2c_adapter      adapter;
        unsigned int            features;
@@ -131,7 +131,7 @@ struct i2c_device {
 /* Make sure the SMBus host is ready to start transmitting.
  * Return 0 if it is, -EBUSY if it is not.
  */
-static int i801_check_pre(struct i2c_device *priv)
+static int i801_check_pre(struct kpc_i2c *priv)
 {
        int status;
 
@@ -156,7 +156,7 @@ static int i801_check_pre(struct i2c_device *priv)
 }
 
 /* Convert the status register to an error code, and clear it. */
-static int i801_check_post(struct i2c_device *priv, int status, int timeout)
+static int i801_check_post(struct kpc_i2c *priv, int status, int timeout)
 {
        int result = 0;
 
@@ -206,7 +206,7 @@ static int i801_check_post(struct i2c_device *priv, int status, int timeout)
        return result;
 }
 
-static int i801_transaction(struct i2c_device *priv, int xact)
+static int i801_transaction(struct kpc_i2c *priv, int xact)
 {
        int status;
        int result;
@@ -235,7 +235,7 @@ static int i801_transaction(struct i2c_device *priv, int xact)
 }
 
 /* wait for INTR bit as advised by Intel */
-static void i801_wait_hwpec(struct i2c_device *priv)
+static void i801_wait_hwpec(struct kpc_i2c *priv)
 {
        int timeout = 0;
        int status;
@@ -251,7 +251,7 @@ static void i801_wait_hwpec(struct i2c_device *priv)
        outb_p(status, SMBHSTSTS(priv));
 }
 
-static int i801_block_transaction_by_block(struct i2c_device *priv,
+static int i801_block_transaction_by_block(struct kpc_i2c *priv,
                                           union i2c_smbus_data *data,
                                           char read_write, int hwpec)
 {
@@ -285,7 +285,7 @@ static int i801_block_transaction_by_block(struct i2c_device *priv,
        return 0;
 }
 
-static int i801_block_transaction_byte_by_byte(struct i2c_device *priv,
+static int i801_block_transaction_byte_by_byte(struct kpc_i2c *priv,
                                               union i2c_smbus_data *data,
                                               char read_write, int command,
                                               int hwpec)
@@ -367,7 +367,7 @@ static int i801_block_transaction_byte_by_byte(struct i2c_device *priv,
        return 0;
 }
 
-static int i801_set_block_buffer_mode(struct i2c_device *priv)
+static int i801_set_block_buffer_mode(struct kpc_i2c *priv)
 {
        outb_p(inb_p(SMBAUXCTL(priv)) | SMBAUXCTL_E32B, SMBAUXCTL(priv));
        if ((inb_p(SMBAUXCTL(priv)) & SMBAUXCTL_E32B) == 0)
@@ -376,7 +376,7 @@ static int i801_set_block_buffer_mode(struct i2c_device *priv)
 }
 
 /* Block transaction function */
-static int i801_block_transaction(struct i2c_device *priv,
+static int i801_block_transaction(struct kpc_i2c *priv,
                                  union i2c_smbus_data *data, char read_write,
                                  int command, int hwpec)
 {
@@ -440,7 +440,7 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
        int hwpec;
        int block = 0;
        int ret, xact = 0;
-       struct i2c_device *priv = i2c_get_adapdata(adap);
+       struct kpc_i2c *priv = i2c_get_adapdata(adap);
 
        hwpec = (priv->features & FEATURE_SMBUS_PEC) &&
                (flags & I2C_CLIENT_PEC) &&
@@ -572,9 +572,13 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
        return 0;
 }
 
+#define enable_flag(x) (x)
+#define disable_flag(x) 0
+#define enable_flag_if(x, cond) ((cond) ? (x) : 0)
+
 static u32 i801_func(struct i2c_adapter *adapter)
 {
-       struct i2c_device *priv = i2c_get_adapdata(adapter);
+       struct kpc_i2c *priv = i2c_get_adapdata(adapter);
 
        /* original settings
         * u32 f = I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
@@ -588,42 +592,42 @@ static u32 i801_func(struct i2c_adapter *adapter)
        // http://lxr.free-electrons.com/source/include/uapi/linux/i2c.h#L85
 
        u32 f =
-               I2C_FUNC_I2C                     | /* 0x00000001(I enabled this
-                                                   * one)
-                                                   */
-               !I2C_FUNC_10BIT_ADDR             |              /* 0x00000002 */
-               !I2C_FUNC_PROTOCOL_MANGLING      |              /* 0x00000004 */
-               ((priv->features & FEATURE_SMBUS_PEC) ?
-                       I2C_FUNC_SMBUS_PEC : 0)  |              /* 0x00000008 */
-               !I2C_FUNC_SMBUS_BLOCK_PROC_CALL  |              /* 0x00008000 */
-               I2C_FUNC_SMBUS_QUICK             |              /* 0x00010000 */
-               !I2C_FUNC_SMBUS_READ_BYTE        |              /* 0x00020000 */
-               !I2C_FUNC_SMBUS_WRITE_BYTE       |              /* 0x00040000 */
-               !I2C_FUNC_SMBUS_READ_BYTE_DATA   |              /* 0x00080000 */
-               !I2C_FUNC_SMBUS_WRITE_BYTE_DATA  |              /* 0x00100000 */
-               !I2C_FUNC_SMBUS_READ_WORD_DATA   |              /* 0x00200000 */
-               !I2C_FUNC_SMBUS_WRITE_WORD_DATA  |              /* 0x00400000 */
-               !I2C_FUNC_SMBUS_PROC_CALL        |              /* 0x00800000 */
-               !I2C_FUNC_SMBUS_READ_BLOCK_DATA  |              /* 0x01000000 */
-               !I2C_FUNC_SMBUS_WRITE_BLOCK_DATA |              /* 0x02000000 */
-               ((priv->features & FEATURE_I2C_BLOCK_READ) ?
-                       I2C_FUNC_SMBUS_READ_I2C_BLOCK : 0) |    /* 0x04000000 */
-               I2C_FUNC_SMBUS_WRITE_I2C_BLOCK   |              /* 0x08000000 */
-
-               I2C_FUNC_SMBUS_BYTE              | /* _READ_BYTE  _WRITE_BYTE */
-               I2C_FUNC_SMBUS_BYTE_DATA         | /* _READ_BYTE_DATA
-                                                   * _WRITE_BYTE_DATA
-                                                   */
-               I2C_FUNC_SMBUS_WORD_DATA         | /* _READ_WORD_DATA
-                                                   * _WRITE_WORD_DATA
-                                                   */
-               I2C_FUNC_SMBUS_BLOCK_DATA        | /* _READ_BLOCK_DATA
-                                                   * _WRITE_BLOCK_DATA
-                                                   */
-               !I2C_FUNC_SMBUS_I2C_BLOCK        | /* _READ_I2C_BLOCK
-                                                   * _WRITE_I2C_BLOCK
-                                                   */
-               !I2C_FUNC_SMBUS_EMUL;              /* _QUICK  _BYTE
+               enable_flag(I2C_FUNC_I2C) | /* 0x00000001(I enabled this one) */
+               disable_flag(I2C_FUNC_10BIT_ADDR)             | /* 0x00000002 */
+               disable_flag(I2C_FUNC_PROTOCOL_MANGLING)      | /* 0x00000004 */
+               enable_flag_if(I2C_FUNC_SMBUS_PEC,
+                              priv->features & FEATURE_SMBUS_PEC) |
+                                                               /* 0x00000008 */
+               disable_flag(I2C_FUNC_SMBUS_BLOCK_PROC_CALL)  | /* 0x00008000 */
+               enable_flag(I2C_FUNC_SMBUS_QUICK)             | /* 0x00010000 */
+               disable_flag(I2C_FUNC_SMBUS_READ_BYTE)        | /* 0x00020000 */
+               disable_flag(I2C_FUNC_SMBUS_WRITE_BYTE)       | /* 0x00040000 */
+               disable_flag(I2C_FUNC_SMBUS_READ_BYTE_DATA)   | /* 0x00080000 */
+               disable_flag(I2C_FUNC_SMBUS_WRITE_BYTE_DATA)  | /* 0x00100000 */
+               disable_flag(I2C_FUNC_SMBUS_READ_WORD_DATA)   | /* 0x00200000 */
+               disable_flag(I2C_FUNC_SMBUS_WRITE_WORD_DATA)  | /* 0x00400000 */
+               disable_flag(I2C_FUNC_SMBUS_PROC_CALL)        | /* 0x00800000 */
+               disable_flag(I2C_FUNC_SMBUS_READ_BLOCK_DATA)  | /* 0x01000000 */
+               disable_flag(I2C_FUNC_SMBUS_WRITE_BLOCK_DATA) | /* 0x02000000 */
+               enable_flag_if(I2C_FUNC_SMBUS_READ_I2C_BLOCK,
+                              priv->features & FEATURE_I2C_BLOCK_READ) |
+                                                               /* 0x04000000 */
+               enable_flag(I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)   | /* 0x08000000 */
+
+               enable_flag(I2C_FUNC_SMBUS_BYTE) | /* _READ_BYTE  _WRITE_BYTE */
+               enable_flag(I2C_FUNC_SMBUS_BYTE_DATA)  | /* _READ_BYTE_DATA
+                                                         * _WRITE_BYTE_DATA
+                                                         */
+               enable_flag(I2C_FUNC_SMBUS_WORD_DATA)  | /* _READ_WORD_DATA
+                                                         * _WRITE_WORD_DATA
+                                                         */
+               enable_flag(I2C_FUNC_SMBUS_BLOCK_DATA) | /* _READ_BLOCK_DATA
+                                                         * _WRITE_BLOCK_DATA
+                                                         */
+               disable_flag(I2C_FUNC_SMBUS_I2C_BLOCK) | /* _READ_I2C_BLOCK
+                                                         * _WRITE_I2C_BLOCK
+                                                         */
+               disable_flag(I2C_FUNC_SMBUS_EMUL); /* _QUICK  _BYTE
                                                    * _BYTE_DATA  _WORD_DATA
                                                    * _PROC_CALL
                                                    * _WRITE_BLOCK_DATA
@@ -632,6 +636,10 @@ static u32 i801_func(struct i2c_adapter *adapter)
        return f;
 }
 
+#undef enable_flag
+#undef disable_flag
+#undef enable_flag_if
+
 static const struct i2c_algorithm smbus_algorithm = {
        .smbus_xfer     = i801_access,
        .functionality  = i801_func,
@@ -640,10 +648,10 @@ static const struct i2c_algorithm smbus_algorithm = {
 /********************************
  *** Part 2 - Driver Handlers ***
  ********************************/
-static int pi2c_probe(struct platform_device *pldev)
+static int kpc_i2c_probe(struct platform_device *pldev)
 {
        int err;
-       struct i2c_device *priv;
+       struct kpc_i2c *priv;
        struct resource *res;
 
        priv = devm_kzalloc(&pldev->dev, sizeof(*priv), GFP_KERNEL);
@@ -692,11 +700,11 @@ static int pi2c_probe(struct platform_device *pldev)
        return 0;
 }
 
-static int pi2c_remove(struct platform_device *pldev)
+static int kpc_i2c_remove(struct platform_device *pldev)
 {
-       struct i2c_device *lddev;
+       struct kpc_i2c *lddev;
 
-       lddev = (struct i2c_device *)platform_get_drvdata(pldev);
+       lddev = (struct kpc_i2c *)platform_get_drvdata(pldev);
 
        i2c_del_adapter(&lddev->adapter);
 
@@ -710,12 +718,12 @@ static int pi2c_remove(struct platform_device *pldev)
        return 0;
 }
 
-static struct platform_driver i2c_plat_driver_i = {
-       .probe      = pi2c_probe,
-       .remove     = pi2c_remove,
+static struct platform_driver kpc_i2c_driver = {
+       .probe      = kpc_i2c_probe,
+       .remove     = kpc_i2c_remove,
        .driver     = {
                .name   = KP_DRIVER_NAME_I2C,
        },
 };
 
-module_platform_driver(i2c_plat_driver_i);
+module_platform_driver(kpc_i2c_driver);
index cb52bd9..4052554 100644 (file)
@@ -49,9 +49,7 @@ static int kpc_dma_transfer(struct dev_private_data *priv,
        u64 dma_addr;
        u64 user_ctl;
 
-       BUG_ON(priv == NULL);
        ldev = priv->ldev;
-       BUG_ON(ldev == NULL);
 
        acd = kzalloc(sizeof(*acd), GFP_KERNEL);
        if (!acd) {
index 85ea5a4..20a99ec 100644 (file)
@@ -2,7 +2,6 @@
 obj-$(CONFIG_MOST) += most_core.o
 most_core-y := core.o
 most_core-y += configfs.o
-ccflags-y += -I $(srctree)/drivers/staging/
 
 obj-$(CONFIG_MOST_CDEV)        += cdev/
 obj-$(CONFIG_MOST_NET) += net/
index 9f4a8b8..ef90cd7 100644 (file)
@@ -2,4 +2,3 @@
 obj-$(CONFIG_MOST_CDEV) += most_cdev.o
 
 most_cdev-objs := cdev.o
-ccflags-y += -I $(srctree)/drivers/staging/
index f880147..71943d1 100644 (file)
@@ -16,7 +16,8 @@
 #include <linux/kfifo.h>
 #include <linux/uaccess.h>
 #include <linux/idr.h>
-#include "most/core.h"
+
+#include "../most.h"
 
 #define CHRDEV_REGION_SIZE 50
 
@@ -25,7 +26,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 {
index 34a9fb5..9a96122 100644 (file)
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/configfs.h>
-#include <most/core.h>
+
+#include "most.h"
+
+#define MAX_STRING_SIZE 80
 
 struct mdev_link {
        struct config_item item;
@@ -22,13 +25,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;
@@ -125,6 +128,8 @@ static ssize_t mdev_link_create_link_store(struct config_item *item,
                return ret;
        list_add_tail(&mdev_link->list, &mdev_link_list);
        mdev_link->create_link = tmp;
+       mdev_link->destroy_link = false;
+
        return count;
 }
 
@@ -140,13 +145,16 @@ static ssize_t mdev_link_destroy_link_store(struct config_item *item,
                return ret;
        if (!tmp)
                return count;
-       mdev_link->destroy_link = tmp;
+
        ret = most_remove_link(mdev_link->device, mdev_link->channel,
                               mdev_link->comp);
        if (ret)
                return ret;
        if (!list_empty(&mdev_link_list))
                list_del(&mdev_link->list);
+
+       mdev_link->destroy_link = tmp;
+
        return count;
 }
 
@@ -197,7 +205,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 +220,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 +235,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 +251,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;
 }
 
@@ -373,13 +383,20 @@ static void mdev_link_release(struct config_item *item)
        struct mdev_link *mdev_link = to_mdev_link(item);
        int ret;
 
-       if (!list_empty(&mdev_link_list)) {
-               ret = most_remove_link(mdev_link->device, mdev_link->channel,
-                                      mdev_link->comp);
-               if (ret && (ret != -ENODEV))
-                       pr_err("Removing link failed.\n");
-               list_del(&mdev_link->list);
+       if (mdev_link->destroy_link)
+               goto free_item;
+
+       ret = most_remove_link(mdev_link->device, mdev_link->channel,
+                              mdev_link->comp);
+       if (ret) {
+               pr_err("Removing link failed.\n");
+               goto free_item;
        }
+
+       if (!list_empty(&mdev_link_list))
+               list_del(&mdev_link->list);
+
+free_item:
        kfree(to_mdev_link(item));
 }
 
@@ -630,7 +647,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 +691,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);
index 51a6b41..0c4ae69 100644 (file)
@@ -2,10 +2,9 @@
 /*
  * core.c - Implementation of core module of MOST Linux driver stack
  *
- * Copyright (C) 2013-2015 Microchip Technology Germany II GmbH & Co. KG
+ * Copyright (C) 2013-2020 Microchip Technology Germany II GmbH & Co. KG
  */
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/slab.h>
 #include <linux/kthread.h>
 #include <linux/dma-mapping.h>
 #include <linux/idr.h>
-#include <most/core.h>
+
+#include "most.h"
 
 #define MAX_CHANNELS   64
 #define STRING_SIZE    80
 
 static struct ida mdev_id;
 static int dummy_num_buffers;
-
-static struct mostcore {
-       struct device dev;
-       struct device_driver drv;
-       struct bus_type bus;
-       struct list_head comp_list;
-} mc;
-
-#define to_driver(d) container_of(d, struct mostcore, drv)
+static struct list_head comp_list;
 
 struct pipe {
-       struct core_component *comp;
+       struct most_component *comp;
        int refs;
        int num_buffers;
 };
@@ -151,7 +143,7 @@ static void flush_channel_fifos(struct most_channel *c)
        spin_unlock_irqrestore(&c->fifo_lock, hf_flags);
 
        if (unlikely((!list_empty(&c->fifo) || !list_empty(&c->halt_fifo))))
-               pr_info("WARN: fifo | trash fifo not empty\n");
+               dev_warn(&c->dev, "Channel or trash fifo not empty\n");
 }
 
 /**
@@ -402,7 +394,7 @@ static ssize_t description_show(struct device *dev,
                                struct device_attribute *attr,
                                char *buf)
 {
-       struct most_interface *iface = to_most_interface(dev);
+       struct most_interface *iface = dev_get_drvdata(dev);
 
        return snprintf(buf, PAGE_SIZE, "%s\n", iface->description);
 }
@@ -411,7 +403,7 @@ static ssize_t interface_show(struct device *dev,
                              struct device_attribute *attr,
                              char *buf)
 {
-       struct most_interface *iface = to_most_interface(dev);
+       struct most_interface *iface = dev_get_drvdata(dev);
 
        switch (iface->interface) {
        case ITYPE_LOOPBACK:
@@ -454,11 +446,11 @@ 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) {
+       list_for_each_entry(comp, &comp_list, list) {
                if (!strcmp(comp->name, name))
                        return comp;
        }
@@ -476,7 +468,7 @@ static int print_links(struct device *dev, void *data)
        int offs = d->offs;
        char *buf = d->buf;
        struct most_channel *c;
-       struct most_interface *iface = to_most_interface(dev);
+       struct most_interface *iface = dev_get_drvdata(dev);
 
        list_for_each_entry(c, &iface->p->channel_list, list) {
                if (c->pipe0.comp) {
@@ -484,7 +476,7 @@ static int print_links(struct device *dev, void *data)
                                         PAGE_SIZE - offs,
                                         "%s:%s:%s\n",
                                         c->pipe0.comp->name,
-                                        dev_name(&iface->dev),
+                                        dev_name(iface->dev),
                                         dev_name(&c->dev));
                }
                if (c->pipe1.comp) {
@@ -492,7 +484,7 @@ static int print_links(struct device *dev, void *data)
                                         PAGE_SIZE - offs,
                                         "%s:%s:%s\n",
                                         c->pipe1.comp->name,
-                                        dev_name(&iface->dev),
+                                        dev_name(iface->dev),
                                         dev_name(&c->dev));
                }
        }
@@ -500,20 +492,33 @@ static int print_links(struct device *dev, void *data)
        return 0;
 }
 
+static int most_match(struct device *dev, struct device_driver *drv)
+{
+       if (!strcmp(dev_name(dev), "most"))
+               return 0;
+       else
+               return 1;
+}
+
+static struct bus_type mostbus = {
+       .name = "most",
+       .match = most_match,
+};
+
 static ssize_t links_show(struct device_driver *drv, char *buf)
 {
        struct show_links_data d = { .buf = buf };
 
-       bus_for_each_dev(&mc.bus, NULL, &d, print_links);
+       bus_for_each_dev(&mostbus, NULL, &d, print_links);
        return d.offs;
 }
 
 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) {
+       list_for_each_entry(comp, &comp_list, list) {
                offs += snprintf(buf + offs, PAGE_SIZE - offs, "%s\n",
                                 comp->name);
        }
@@ -531,10 +536,11 @@ static struct most_channel *get_channel(char *mdev, char *mdev_ch)
        struct most_interface *iface;
        struct most_channel *c, *tmp;
 
-       dev = bus_find_device_by_name(&mc.bus, NULL, mdev);
+       dev = bus_find_device_by_name(&mostbus, NULL, mdev);
        if (!dev)
                return NULL;
-       iface = to_most_interface(dev);
+       put_device(dev);
+       iface = dev_get_drvdata(dev);
        list_for_each_entry_safe(c, tmp, &iface->p->channel_list, list) {
                if (!strcmp(dev_name(&c->dev), mdev_ch))
                        return c;
@@ -544,12 +550,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;
@@ -623,7 +629,7 @@ int most_set_cfg_datatype(char *mdev, char *mdev_ch, char *buf)
        }
 
        if (i == ARRAY_SIZE(ch_data_type))
-               pr_info("WARN: invalid attribute settings\n");
+               dev_warn(&c->dev, "Invalid attribute settings\n");
        return 0;
 }
 
@@ -642,7 +648,7 @@ int most_set_cfg_direction(char *mdev, char *mdev_ch, char *buf)
        } else if (!strcmp(buf, "tx")) {
                c->cfg.direction = MOST_CH_TX;
        } else {
-               pr_info("Invalid direction\n");
+               dev_err(&c->dev, "Invalid direction\n");
                return -ENODATA;
        }
        return 0;
@@ -660,7 +666,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 +679,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 +690,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)
@@ -722,13 +728,11 @@ static const struct attribute_group *mc_attr_groups[] = {
        NULL,
 };
 
-static int most_match(struct device *dev, struct device_driver *drv)
-{
-       if (!strcmp(dev_name(dev), "most"))
-               return 0;
-       else
-               return 1;
-}
+static struct device_driver mostbus_driver = {
+       .name = "most_core",
+       .bus = &mostbus,
+       .groups = mc_attr_groups,
+};
 
 static inline void trash_mbo(struct mbo *mbo)
 {
@@ -795,7 +799,7 @@ static int hdm_enqueue_thread(void *data)
                mutex_unlock(&c->nq_mutex);
 
                if (unlikely(ret)) {
-                       pr_err("hdm enqueue failed\n");
+                       dev_err(&c->dev, "Buffer enqueue failed\n");
                        nq_hdm_mbo(mbo);
                        c->hdm_enqueue_task = NULL;
                        return 0;
@@ -922,7 +926,7 @@ flush_fifos:
 void most_submit_mbo(struct mbo *mbo)
 {
        if (WARN_ONCE(!mbo || !mbo->context,
-                     "bad mbo or missing channel reference\n"))
+                     "Bad buffer or missing channel reference\n"))
                return;
 
        nq_hdm_mbo(mbo);
@@ -941,8 +945,6 @@ static void most_write_completion(struct mbo *mbo)
        struct most_channel *c;
 
        c = mbo->context;
-       if (mbo->status == MBO_E_INVAL)
-               pr_info("WARN: Tx MBO status: invalid\n");
        if (unlikely(c->is_poisoned || (mbo->status == MBO_E_CLOSE)))
                trash_mbo(mbo);
        else
@@ -950,7 +952,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 +983,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 +1089,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;
@@ -1101,14 +1103,14 @@ int most_start_channel(struct most_interface *iface, int id,
                goto out; /* already started by another component */
 
        if (!try_module_get(iface->mod)) {
-               pr_info("failed to acquire HDM lock\n");
+               dev_err(&c->dev, "Failed to acquire HDM lock\n");
                mutex_unlock(&c->start_mutex);
                return -ENOLCK;
        }
 
        c->cfg.extra_len = 0;
        if (c->iface->configure(c->iface, c->channel_id, &c->cfg)) {
-               pr_info("channel configuration failed. Go check settings...\n");
+               dev_err(&c->dev, "Channel configuration failed. Go check settings...\n");
                ret = -EINVAL;
                goto err_put_module;
        }
@@ -1157,7 +1159,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;
 
@@ -1182,8 +1184,8 @@ int most_stop_channel(struct most_interface *iface, int id,
 
        c->is_poisoned = true;
        if (c->iface->poison_channel(c->iface, c->channel_id)) {
-               pr_err("Cannot stop channel %d of mdev %s\n", c->channel_id,
-                      c->iface->description);
+               dev_err(&c->dev, "Failed to stop channel %d of interface %s\n", c->channel_id,
+                       c->iface->description);
                mutex_unlock(&c->start_mutex);
                return -EAGAIN;
        }
@@ -1192,7 +1194,7 @@ int most_stop_channel(struct most_interface *iface, int id,
 
 #ifdef CMPL_INTERRUPTIBLE
        if (wait_for_completion_interruptible(&c->cleanup)) {
-               pr_info("Interrupted while clean up ch %d\n", c->channel_id);
+               dev_err(&c->dev, "Interrupted while cleaning up channel %d\n", c->channel_id);
                mutex_unlock(&c->start_mutex);
                return -EINTR;
        }
@@ -1215,14 +1217,13 @@ 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");
                return -EINVAL;
        }
-       list_add_tail(&comp->list, &mc.comp_list);
-       pr_info("registered new core component %s\n", comp->name);
+       list_add_tail(&comp->list, &comp_list);
        return 0;
 }
 EXPORT_SYMBOL_GPL(most_register_component);
@@ -1231,9 +1232,9 @@ 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);
+       iface = dev_get_drvdata(dev);
        list_for_each_entry_safe(c, tmp, &iface->p->channel_list, list) {
                if (c->pipe0.comp == comp || c->pipe1.comp == comp)
                        comp->disconnect_channel(c->iface, c->channel_id);
@@ -1249,28 +1250,24 @@ 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");
                return -EINVAL;
        }
 
-       bus_for_each_dev(&mc.bus, NULL, comp, disconnect_channels);
+       bus_for_each_dev(&mostbus, NULL, comp, disconnect_channels);
        list_del(&comp->list);
-       pr_info("deregistering component %s\n", comp->name);
        return 0;
 }
 EXPORT_SYMBOL_GPL(most_deregister_component);
 
-static void release_interface(struct device *dev)
-{
-       pr_info("releasing interface dev %s...\n", dev_name(dev));
-}
-
 static void release_channel(struct device *dev)
 {
-       pr_info("releasing channel dev %s...\n", dev_name(dev));
+       struct most_channel *c = to_channel(dev);
+
+       kfree(c);
 }
 
 /**
@@ -1288,13 +1285,13 @@ int most_register_interface(struct most_interface *iface)
 
        if (!iface || !iface->enqueue || !iface->configure ||
            !iface->poison_channel || (iface->num_channels > MAX_CHANNELS)) {
-               pr_err("Bad interface or channel overflow\n");
+               dev_err(iface->dev, "Bad interface or channel overflow\n");
                return -EINVAL;
        }
 
        id = ida_simple_get(&mdev_id, 0, 0, GFP_KERNEL);
        if (id < 0) {
-               pr_info("Failed to alloc mdev ID\n");
+               dev_err(iface->dev, "Failed to allocate device ID\n");
                return id;
        }
 
@@ -1307,14 +1304,13 @@ int most_register_interface(struct most_interface *iface)
        INIT_LIST_HEAD(&iface->p->channel_list);
        iface->p->dev_id = id;
        strscpy(iface->p->name, iface->description, sizeof(iface->p->name));
-       iface->dev.init_name = iface->p->name;
-       iface->dev.bus = &mc.bus;
-       iface->dev.parent = &mc.dev;
-       iface->dev.groups = interface_attr_groups;
-       iface->dev.release = release_interface;
-       if (device_register(&iface->dev)) {
-               pr_err("registering iface->dev failed\n");
+       iface->dev->bus = &mostbus;
+       iface->dev->groups = interface_attr_groups;
+       dev_set_drvdata(iface->dev, iface);
+       if (device_register(iface->dev)) {
+               dev_err(iface->dev, "Failed to register interface device\n");
                kfree(iface->p);
+               put_device(iface->dev);
                ida_simple_remove(&mdev_id, id);
                return -ENOMEM;
        }
@@ -1330,7 +1326,7 @@ int most_register_interface(struct most_interface *iface)
                else
                        snprintf(c->name, STRING_SIZE, "%s", name_suffix);
                c->dev.init_name = c->name;
-               c->dev.parent = &iface->dev;
+               c->dev.parent = iface->dev;
                c->dev.groups = channel_attr_groups;
                c->dev.release = release_channel;
                iface->p->channel[i] = c;
@@ -1356,26 +1352,23 @@ int most_register_interface(struct most_interface *iface)
                mutex_init(&c->nq_mutex);
                list_add_tail(&c->list, &iface->p->channel_list);
                if (device_register(&c->dev)) {
-                       pr_err("registering c->dev failed\n");
+                       dev_err(&c->dev, "Failed to register channel device\n");
                        goto err_free_most_channel;
                }
        }
-       pr_info("registered new device mdev%d (%s)\n",
-               id, iface->description);
        most_interface_register_notify(iface->description);
        return 0;
 
 err_free_most_channel:
-       kfree(c);
+       put_device(&c->dev);
 
 err_free_resources:
        while (i > 0) {
                c = iface->p->channel[--i];
                device_unregister(&c->dev);
-               kfree(c);
        }
        kfree(iface->p);
-       device_unregister(&iface->dev);
+       device_unregister(iface->dev);
        ida_simple_remove(&mdev_id, id);
        return -ENOMEM;
 }
@@ -1393,8 +1386,6 @@ void most_deregister_interface(struct most_interface *iface)
        int i;
        struct most_channel *c;
 
-       pr_info("deregistering device %s (%s)\n", dev_name(&iface->dev),
-               iface->description);
        for (i = 0; i < iface->num_channels; i++) {
                c = iface->p->channel[i];
                if (c->pipe0.comp)
@@ -1407,12 +1398,11 @@ void most_deregister_interface(struct most_interface *iface)
                c->pipe1.comp = NULL;
                list_del(&c->list);
                device_unregister(&c->dev);
-               kfree(c);
        }
 
        ida_simple_remove(&mdev_id, iface->p->dev_id);
        kfree(iface->p);
-       device_unregister(&iface->dev);
+       device_unregister(iface->dev);
 }
 EXPORT_SYMBOL_GPL(most_deregister_interface);
 
@@ -1462,57 +1452,35 @@ void most_resume_enqueue(struct most_interface *iface, int id)
 }
 EXPORT_SYMBOL_GPL(most_resume_enqueue);
 
-static void release_most_sub(struct device *dev)
-{
-       pr_info("releasing most_subsystem\n");
-}
-
 static int __init most_init(void)
 {
        int err;
 
-       pr_info("init()\n");
-       INIT_LIST_HEAD(&mc.comp_list);
+       INIT_LIST_HEAD(&comp_list);
        ida_init(&mdev_id);
 
-       mc.bus.name = "most",
-       mc.bus.match = most_match,
-       mc.drv.name = "most_core",
-       mc.drv.bus = &mc.bus,
-       mc.drv.groups = mc_attr_groups;
-
-       err = bus_register(&mc.bus);
+       err = bus_register(&mostbus);
        if (err) {
-               pr_info("Cannot register most bus\n");
+               pr_err("Failed to register most bus\n");
                return err;
        }
-       err = driver_register(&mc.drv);
+       err = driver_register(&mostbus_driver);
        if (err) {
-               pr_info("Cannot register core driver\n");
+               pr_err("Failed to register core driver\n");
                goto err_unregister_bus;
        }
-       mc.dev.init_name = "most_bus";
-       mc.dev.release = release_most_sub;
-       if (device_register(&mc.dev)) {
-               err = -ENOMEM;
-               goto err_unregister_driver;
-       }
        configfs_init();
        return 0;
 
-err_unregister_driver:
-       driver_unregister(&mc.drv);
 err_unregister_bus:
-       bus_unregister(&mc.bus);
+       bus_unregister(&mostbus);
        return err;
 }
 
 static void __exit most_exit(void)
 {
-       pr_info("exit core module\n");
-       device_unregister(&mc.dev);
-       driver_unregister(&mc.drv);
-       bus_unregister(&mc.bus);
+       driver_unregister(&mostbus_driver);
+       bus_unregister(&mostbus);
        ida_destroy(&mdev_id);
 }
 
diff --git a/drivers/staging/most/core.h b/drivers/staging/most/core.h
deleted file mode 100644 (file)
index 49859ae..0000000
+++ /dev/null
@@ -1,339 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * most.h - API for component and adapter drivers
- *
- * Copyright (C) 2013-2015, Microchip Technology Germany II GmbH & Co. KG
- */
-
-#ifndef __MOST_CORE_H__
-#define __MOST_CORE_H__
-
-#include <linux/types.h>
-#include <linux/device.h>
-
-struct module;
-struct interface_private;
-
-/**
- * Interface type
- */
-enum most_interface_type {
-       ITYPE_LOOPBACK = 1,
-       ITYPE_I2C,
-       ITYPE_I2S,
-       ITYPE_TSI,
-       ITYPE_HBI,
-       ITYPE_MEDIALB_DIM,
-       ITYPE_MEDIALB_DIM2,
-       ITYPE_USB,
-       ITYPE_PCIE
-};
-
-/**
- * Channel direction.
- */
-enum most_channel_direction {
-       MOST_CH_RX = 1 << 0,
-       MOST_CH_TX = 1 << 1,
-};
-
-/**
- * Channel data type.
- */
-enum most_channel_data_type {
-       MOST_CH_CONTROL = 1 << 0,
-       MOST_CH_ASYNC = 1 << 1,
-       MOST_CH_ISOC = 1 << 2,
-       MOST_CH_SYNC = 1 << 5,
-};
-
-enum mbo_status_flags {
-       /* MBO was processed successfully (data was send or received )*/
-       MBO_SUCCESS = 0,
-       /* The MBO contains wrong or missing information.  */
-       MBO_E_INVAL,
-       /* MBO was completed as HDM Channel will be closed */
-       MBO_E_CLOSE,
-};
-
-/**
- * struct most_channel_capability - Channel capability
- * @direction: Supported channel directions.
- * The value is bitwise OR-combination of the values from the
- * enumeration most_channel_direction. Zero is allowed value and means
- * "channel may not be used".
- * @data_type: Supported channel data types.
- * The value is bitwise OR-combination of the values from the
- * enumeration most_channel_data_type. Zero is allowed value and means
- * "channel may not be used".
- * @num_buffers_packet: Maximum number of buffers supported by this channel
- * for packet data types (Async,Control,QoS)
- * @buffer_size_packet: Maximum buffer size supported by this channel
- * for packet data types (Async,Control,QoS)
- * @num_buffers_streaming: Maximum number of buffers supported by this channel
- * for streaming data types (Sync,AV Packetized)
- * @buffer_size_streaming: Maximum buffer size supported by this channel
- * for streaming data types (Sync,AV Packetized)
- * @name_suffix: Optional suffix providean by an HDM that is attached to the
- * regular channel name.
- *
- * Describes the capabilities of a MOST channel like supported Data Types
- * and directions. This information is provided by an HDM for the MostCore.
- *
- * The Core creates read only sysfs attribute files in
- * /sys/devices/most/mdev#/<channel>/ with the
- * following attributes:
- *     -available_directions
- *     -available_datatypes
- *     -number_of_packet_buffers
- *     -number_of_stream_buffers
- *     -size_of_packet_buffer
- *     -size_of_stream_buffer
- * where content of each file is a string with all supported properties of this
- * very channel attribute.
- */
-struct most_channel_capability {
-       u16 direction;
-       u16 data_type;
-       u16 num_buffers_packet;
-       u16 buffer_size_packet;
-       u16 num_buffers_streaming;
-       u16 buffer_size_streaming;
-       const char *name_suffix;
-};
-
-/**
- * struct most_channel_config - stores channel configuration
- * @direction: direction of the channel
- * @data_type: data type travelling over this channel
- * @num_buffers: number of buffers
- * @buffer_size: size of a buffer for AIM.
- * Buffer size may be cutted down by HDM in a configure callback
- * to match to a given interface and channel type.
- * @extra_len: additional buffer space for internal HDM purposes like padding.
- * May be set by HDM in a configure callback if needed.
- * @subbuffer_size: size of a subbuffer
- * @packets_per_xact: number of MOST frames that are packet inside one USB
- *                   packet. This is USB specific
- *
- * Describes the configuration for a MOST channel. This information is
- * provided from the MostCore to a HDM (like the Medusa PCIe Interface) as a
- * parameter of the "configure" function call.
- */
-struct most_channel_config {
-       enum most_channel_direction direction;
-       enum most_channel_data_type data_type;
-       u16 num_buffers;
-       u16 buffer_size;
-       u16 extra_len;
-       u16 subbuffer_size;
-       u16 packets_per_xact;
-       u16 dbr_size;
-};
-
-/*
- * struct mbo - MOST Buffer Object.
- * @context: context for core completion handler
- * @priv: private data for HDM
- *
- *     public: documented fields that are used for the communications
- *     between MostCore and HDMs
- *
- * @list: list head for use by the mbo's current owner
- * @ifp: (in) associated interface instance
- * @num_buffers_ptr: amount of pool buffers
- * @hdm_channel_id: (in) HDM channel instance
- * @virt_address: (in) kernel virtual address of the buffer
- * @bus_address: (in) bus address of the buffer
- * @buffer_length: (in) buffer payload length
- * @processed_length: (out) processed length
- * @status: (out) transfer status
- * @complete: (in) completion routine
- *
- * The core allocates and initializes the MBO.
- *
- * The HDM receives MBO for transfer from the core with the call to enqueue().
- * The HDM copies the data to- or from the buffer depending on configured
- * channel direction, set "processed_length" and "status" and completes
- * the transfer procedure by calling the completion routine.
- *
- * Finally, the MBO is being deallocated or recycled for further
- * transfers of the same or a different HDM.
- *
- * Directions of usage:
- * The core driver should never access any MBO fields (even if marked
- * as "public") while the MBO is owned by an HDM. The ownership starts with
- * the call of enqueue() and ends with the call of its complete() routine.
- *
- *                                     II.
- * Every HDM attached to the core driver _must_ ensure that it returns any MBO
- * it owns (due to a previous call to enqueue() by the core driver) before it
- * de-registers an interface or gets unloaded from the kernel. If this direction
- * is violated memory leaks will occur, since the core driver does _not_ track
- * MBOs it is currently not in control of.
- *
- */
-struct mbo {
-       void *context;
-       void *priv;
-       struct list_head list;
-       struct most_interface *ifp;
-       int *num_buffers_ptr;
-       u16 hdm_channel_id;
-       void *virt_address;
-       dma_addr_t bus_address;
-       u16 buffer_length;
-       u16 processed_length;
-       enum mbo_status_flags status;
-       void (*complete)(struct mbo *mbo);
-};
-
-/**
- * Interface instance description.
- *
- * Describes an interface of a MOST device the core driver is bound to.
- * This structure is allocated and initialized in the HDM. MostCore may not
- * modify this structure.
- *
- * @dev: the actual device
- * @mod: module
- * @interface Interface type. \sa most_interface_type.
- * @description PRELIMINARY.
- *   Unique description of the device instance from point of view of the
- *   interface in free text form (ASCII).
- *   It may be a hexadecimal presentation of the memory address for the MediaLB
- *   IP or USB device ID with USB properties for USB interface, etc.
- * @num_channels Number of channels and size of the channel_vector.
- * @channel_vector Properties of the channels.
- *   Array index represents channel ID by the driver.
- * @configure Callback to change data type for the channel of the
- *   interface instance. May be zero if the instance of the interface is not
- *   configurable. Parameter channel_config describes direction and data
- *   type for the channel, configured by the higher level. The content of
- * @enqueue Delivers MBO to the HDM for processing.
- *   After HDM completes Rx- or Tx- operation the processed MBO shall
- *   be returned back to the MostCore using completion routine.
- *   The reason to get the MBO delivered from the MostCore after the channel
- *   is poisoned is the re-opening of the channel by the application.
- *   In this case the HDM shall hold MBOs and service the channel as usual.
- *   The HDM must be able to hold at least one MBO for each channel.
- *   The callback returns a negative value on error, otherwise 0.
- * @poison_channel Informs HDM about closing the channel. The HDM shall
- *   cancel all transfers and synchronously or asynchronously return
- *   all enqueued for this channel MBOs using the completion routine.
- *   The callback returns a negative value on error, otherwise 0.
- * @request_netinfo: triggers retrieving of network info from the HDM by
- *   means of "Message exchange over MDP/MEP"
- *   The call of the function request_netinfo with the parameter on_netinfo as
- *   NULL prohibits use of the previously obtained function pointer.
- * @priv Private field used by mostcore to store context information.
- */
-struct most_interface {
-       struct device dev;
-       struct device *driver_dev;
-       struct module *mod;
-       enum most_interface_type interface;
-       const char *description;
-       unsigned int num_channels;
-       struct most_channel_capability *channel_vector;
-       void *(*dma_alloc)(struct mbo *mbo, u32 size);
-       void (*dma_free)(struct mbo *mbo, u32 size);
-       int (*configure)(struct most_interface *iface, int channel_idx,
-                        struct most_channel_config *channel_config);
-       int (*enqueue)(struct most_interface *iface, int channel_idx,
-                      struct mbo *mbo);
-       int (*poison_channel)(struct most_interface *iface, int channel_idx);
-       void (*request_netinfo)(struct most_interface *iface, int channel_idx,
-                               void (*on_netinfo)(struct most_interface *iface,
-                                                  unsigned char link_stat,
-                                                  unsigned char *mac_addr));
-       void *priv;
-       struct interface_private *p;
-};
-
-#define to_most_interface(d) container_of(d, struct most_interface, dev)
-
-/**
- * struct core_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
- * @disconnect_channel: callback function to disconnect a certain channel
- * @rx_completion: completion handler for received packets
- * @tx_completion: completion handler for transmitted packets
- */
-struct core_component {
-       struct list_head list;
-       const char *name;
-       struct module *mod;
-       int (*probe_channel)(struct most_interface *iface, int channel_idx,
-                            struct most_channel_config *cfg, char *name,
-                            char *param);
-       int (*disconnect_channel)(struct most_interface *iface,
-                                 int channel_idx);
-       int (*rx_completion)(struct mbo *mbo);
-       int (*tx_completion)(struct most_interface *iface, int channel_idx);
-       int (*cfg_complete)(void);
-};
-
-/**
- * most_register_interface - Registers instance of the interface.
- * @iface: Pointer to the interface instance description.
- *
- * Returns a pointer to the kobject of the generated instance.
- *
- * Note: HDM has to ensure that any reference held on the kobj is
- * released before deregistering the interface.
- */
-int most_register_interface(struct most_interface *iface);
-
-/**
- * Deregisters instance of the interface.
- * @intf_instance Pointer to the interface instance description.
- */
-void most_deregister_interface(struct most_interface *iface);
-void most_submit_mbo(struct mbo *mbo);
-
-/**
- * most_stop_enqueue - prevents core from enqueing MBOs
- * @iface: pointer to interface
- * @channel_idx: channel index
- */
-void most_stop_enqueue(struct most_interface *iface, int channel_idx);
-
-/**
- * most_resume_enqueue - allow core to enqueue MBOs again
- * @iface: pointer to interface
- * @channel_idx: channel index
- *
- * This clears the enqueue halt flag and enqueues all MBOs currently
- * 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);
-struct mbo *most_get_mbo(struct most_interface *iface, int channel_idx,
-                        struct core_component *comp);
-void most_put_mbo(struct mbo *mbo);
-int channel_has_mbo(struct most_interface *iface, int channel_idx,
-                   struct core_component *comp);
-int most_start_channel(struct most_interface *iface, int channel_idx,
-                      struct core_component *comp);
-int most_stop_channel(struct most_interface *iface, int channel_idx,
-                     struct core_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_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);
-int most_set_cfg_buffer_size(char *mdev, char *mdev_ch, u16 val);
-int most_set_cfg_subbuffer_size(char *mdev, char *mdev_ch, u16 val);
-int most_set_cfg_dbr_size(char *mdev, char *mdev_ch, u16 val);
-int most_set_cfg_num_buffers(char *mdev, char *mdev_ch, u16 val);
-int most_set_cfg_datatype(char *mdev, char *mdev_ch, char *buf);
-int most_set_cfg_direction(char *mdev, char *mdev_ch, char *buf);
-int most_set_cfg_packets_xact(char *mdev, char *mdev_ch, u16 val);
-int most_cfg_complete(char *comp_name);
-void most_interface_register_notify(const char *mdev_name);
-#endif /* MOST_CORE_H_ */
index 116f04d..861adac 100644 (file)
@@ -2,4 +2,3 @@
 obj-$(CONFIG_MOST_DIM2) += most_dim2.o
 
 most_dim2-objs := dim2.o hal.o sysfs.o
-ccflags-y += -I $(srctree)/drivers/staging/
index 64c9791..1659328 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/sched.h>
 #include <linux/kthread.h>
 
-#include "most/core.h"
+#include "../most.h"
 #include "hal.h"
 #include "errors.h"
 #include "sysfs.h"
@@ -854,8 +854,9 @@ static int dim2_probe(struct platform_device *pdev)
        dev->most_iface.poison_channel = poison_channel;
        dev->most_iface.request_netinfo = request_netinfo;
        dev->most_iface.driver_dev = &pdev->dev;
+       dev->most_iface.dev = &dev->dev;
        dev->dev.init_name = "dim2_state";
-       dev->dev.parent = &dev->most_iface.dev;
+       dev->dev.parent = &pdev->dev;
 
        ret = most_register_interface(&dev->most_iface);
        if (ret) {
index 2b3769d..71099dd 100644 (file)
@@ -2,4 +2,3 @@
 obj-$(CONFIG_MOST_I2C) += most_i2c.o
 
 most_i2c-objs := i2c.o
-ccflags-y += -I $(srctree)/drivers/staging/
index 4a4fc10..2980f70 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/interrupt.h>
 #include <linux/err.h>
 
-#include "most/core.h"
+#include "../most.h"
 
 enum { CH_RX, CH_TX, NUM_CHANNELS };
 
diff --git a/drivers/staging/most/most.h b/drivers/staging/most/most.h
new file mode 100644 (file)
index 0000000..232e01b
--- /dev/null
@@ -0,0 +1,337 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * most.h - API for component and adapter drivers
+ *
+ * Copyright (C) 2013-2015, Microchip Technology Germany II GmbH & Co. KG
+ */
+
+#ifndef __MOST_CORE_H__
+#define __MOST_CORE_H__
+
+#include <linux/types.h>
+#include <linux/device.h>
+
+struct module;
+struct interface_private;
+
+/**
+ * Interface type
+ */
+enum most_interface_type {
+       ITYPE_LOOPBACK = 1,
+       ITYPE_I2C,
+       ITYPE_I2S,
+       ITYPE_TSI,
+       ITYPE_HBI,
+       ITYPE_MEDIALB_DIM,
+       ITYPE_MEDIALB_DIM2,
+       ITYPE_USB,
+       ITYPE_PCIE
+};
+
+/**
+ * Channel direction.
+ */
+enum most_channel_direction {
+       MOST_CH_RX = 1 << 0,
+       MOST_CH_TX = 1 << 1,
+};
+
+/**
+ * Channel data type.
+ */
+enum most_channel_data_type {
+       MOST_CH_CONTROL = 1 << 0,
+       MOST_CH_ASYNC = 1 << 1,
+       MOST_CH_ISOC = 1 << 2,
+       MOST_CH_SYNC = 1 << 5,
+};
+
+enum most_status_flags {
+       /* MBO was processed successfully (data was send or received )*/
+       MBO_SUCCESS = 0,
+       /* The MBO contains wrong or missing information.  */
+       MBO_E_INVAL,
+       /* MBO was completed as HDM Channel will be closed */
+       MBO_E_CLOSE,
+};
+
+/**
+ * struct most_channel_capability - Channel capability
+ * @direction: Supported channel directions.
+ * The value is bitwise OR-combination of the values from the
+ * enumeration most_channel_direction. Zero is allowed value and means
+ * "channel may not be used".
+ * @data_type: Supported channel data types.
+ * The value is bitwise OR-combination of the values from the
+ * enumeration most_channel_data_type. Zero is allowed value and means
+ * "channel may not be used".
+ * @num_buffers_packet: Maximum number of buffers supported by this channel
+ * for packet data types (Async,Control,QoS)
+ * @buffer_size_packet: Maximum buffer size supported by this channel
+ * for packet data types (Async,Control,QoS)
+ * @num_buffers_streaming: Maximum number of buffers supported by this channel
+ * for streaming data types (Sync,AV Packetized)
+ * @buffer_size_streaming: Maximum buffer size supported by this channel
+ * for streaming data types (Sync,AV Packetized)
+ * @name_suffix: Optional suffix providean by an HDM that is attached to the
+ * regular channel name.
+ *
+ * Describes the capabilities of a MOST channel like supported Data Types
+ * and directions. This information is provided by an HDM for the MostCore.
+ *
+ * The Core creates read only sysfs attribute files in
+ * /sys/devices/most/mdev#/<channel>/ with the
+ * following attributes:
+ *     -available_directions
+ *     -available_datatypes
+ *     -number_of_packet_buffers
+ *     -number_of_stream_buffers
+ *     -size_of_packet_buffer
+ *     -size_of_stream_buffer
+ * where content of each file is a string with all supported properties of this
+ * very channel attribute.
+ */
+struct most_channel_capability {
+       u16 direction;
+       u16 data_type;
+       u16 num_buffers_packet;
+       u16 buffer_size_packet;
+       u16 num_buffers_streaming;
+       u16 buffer_size_streaming;
+       const char *name_suffix;
+};
+
+/**
+ * struct most_channel_config - stores channel configuration
+ * @direction: direction of the channel
+ * @data_type: data type travelling over this channel
+ * @num_buffers: number of buffers
+ * @buffer_size: size of a buffer for AIM.
+ * Buffer size may be cutted down by HDM in a configure callback
+ * to match to a given interface and channel type.
+ * @extra_len: additional buffer space for internal HDM purposes like padding.
+ * May be set by HDM in a configure callback if needed.
+ * @subbuffer_size: size of a subbuffer
+ * @packets_per_xact: number of MOST frames that are packet inside one USB
+ *                   packet. This is USB specific
+ *
+ * Describes the configuration for a MOST channel. This information is
+ * provided from the MostCore to a HDM (like the Medusa PCIe Interface) as a
+ * parameter of the "configure" function call.
+ */
+struct most_channel_config {
+       enum most_channel_direction direction;
+       enum most_channel_data_type data_type;
+       u16 num_buffers;
+       u16 buffer_size;
+       u16 extra_len;
+       u16 subbuffer_size;
+       u16 packets_per_xact;
+       u16 dbr_size;
+};
+
+/*
+ * struct mbo - MOST Buffer Object.
+ * @context: context for core completion handler
+ * @priv: private data for HDM
+ *
+ *     public: documented fields that are used for the communications
+ *     between MostCore and HDMs
+ *
+ * @list: list head for use by the mbo's current owner
+ * @ifp: (in) associated interface instance
+ * @num_buffers_ptr: amount of pool buffers
+ * @hdm_channel_id: (in) HDM channel instance
+ * @virt_address: (in) kernel virtual address of the buffer
+ * @bus_address: (in) bus address of the buffer
+ * @buffer_length: (in) buffer payload length
+ * @processed_length: (out) processed length
+ * @status: (out) transfer status
+ * @complete: (in) completion routine
+ *
+ * The core allocates and initializes the MBO.
+ *
+ * The HDM receives MBO for transfer from the core with the call to enqueue().
+ * The HDM copies the data to- or from the buffer depending on configured
+ * channel direction, set "processed_length" and "status" and completes
+ * the transfer procedure by calling the completion routine.
+ *
+ * Finally, the MBO is being deallocated or recycled for further
+ * transfers of the same or a different HDM.
+ *
+ * Directions of usage:
+ * The core driver should never access any MBO fields (even if marked
+ * as "public") while the MBO is owned by an HDM. The ownership starts with
+ * the call of enqueue() and ends with the call of its complete() routine.
+ *
+ *                                     II.
+ * Every HDM attached to the core driver _must_ ensure that it returns any MBO
+ * it owns (due to a previous call to enqueue() by the core driver) before it
+ * de-registers an interface or gets unloaded from the kernel. If this direction
+ * is violated memory leaks will occur, since the core driver does _not_ track
+ * MBOs it is currently not in control of.
+ *
+ */
+struct mbo {
+       void *context;
+       void *priv;
+       struct list_head list;
+       struct most_interface *ifp;
+       int *num_buffers_ptr;
+       u16 hdm_channel_id;
+       void *virt_address;
+       dma_addr_t bus_address;
+       u16 buffer_length;
+       u16 processed_length;
+       enum most_status_flags status;
+       void (*complete)(struct mbo *mbo);
+};
+
+/**
+ * Interface instance description.
+ *
+ * Describes an interface of a MOST device the core driver is bound to.
+ * This structure is allocated and initialized in the HDM. MostCore may not
+ * modify this structure.
+ *
+ * @dev: the actual device
+ * @mod: module
+ * @interface Interface type. \sa most_interface_type.
+ * @description PRELIMINARY.
+ *   Unique description of the device instance from point of view of the
+ *   interface in free text form (ASCII).
+ *   It may be a hexadecimal presentation of the memory address for the MediaLB
+ *   IP or USB device ID with USB properties for USB interface, etc.
+ * @num_channels Number of channels and size of the channel_vector.
+ * @channel_vector Properties of the channels.
+ *   Array index represents channel ID by the driver.
+ * @configure Callback to change data type for the channel of the
+ *   interface instance. May be zero if the instance of the interface is not
+ *   configurable. Parameter channel_config describes direction and data
+ *   type for the channel, configured by the higher level. The content of
+ * @enqueue Delivers MBO to the HDM for processing.
+ *   After HDM completes Rx- or Tx- operation the processed MBO shall
+ *   be returned back to the MostCore using completion routine.
+ *   The reason to get the MBO delivered from the MostCore after the channel
+ *   is poisoned is the re-opening of the channel by the application.
+ *   In this case the HDM shall hold MBOs and service the channel as usual.
+ *   The HDM must be able to hold at least one MBO for each channel.
+ *   The callback returns a negative value on error, otherwise 0.
+ * @poison_channel Informs HDM about closing the channel. The HDM shall
+ *   cancel all transfers and synchronously or asynchronously return
+ *   all enqueued for this channel MBOs using the completion routine.
+ *   The callback returns a negative value on error, otherwise 0.
+ * @request_netinfo: triggers retrieving of network info from the HDM by
+ *   means of "Message exchange over MDP/MEP"
+ *   The call of the function request_netinfo with the parameter on_netinfo as
+ *   NULL prohibits use of the previously obtained function pointer.
+ * @priv Private field used by mostcore to store context information.
+ */
+struct most_interface {
+       struct device *dev;
+       struct device *driver_dev;
+       struct module *mod;
+       enum most_interface_type interface;
+       const char *description;
+       unsigned int num_channels;
+       struct most_channel_capability *channel_vector;
+       void *(*dma_alloc)(struct mbo *mbo, u32 size);
+       void (*dma_free)(struct mbo *mbo, u32 size);
+       int (*configure)(struct most_interface *iface, int channel_idx,
+                        struct most_channel_config *channel_config);
+       int (*enqueue)(struct most_interface *iface, int channel_idx,
+                      struct mbo *mbo);
+       int (*poison_channel)(struct most_interface *iface, int channel_idx);
+       void (*request_netinfo)(struct most_interface *iface, int channel_idx,
+                               void (*on_netinfo)(struct most_interface *iface,
+                                                  unsigned char link_stat,
+                                                  unsigned char *mac_addr));
+       void *priv;
+       struct interface_private *p;
+};
+
+/**
+ * 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
+ * @disconnect_channel: callback function to disconnect a certain channel
+ * @rx_completion: completion handler for received packets
+ * @tx_completion: completion handler for transmitted packets
+ */
+struct most_component {
+       struct list_head list;
+       const char *name;
+       struct module *mod;
+       int (*probe_channel)(struct most_interface *iface, int channel_idx,
+                            struct most_channel_config *cfg, char *name,
+                            char *param);
+       int (*disconnect_channel)(struct most_interface *iface,
+                                 int channel_idx);
+       int (*rx_completion)(struct mbo *mbo);
+       int (*tx_completion)(struct most_interface *iface, int channel_idx);
+       int (*cfg_complete)(void);
+};
+
+/**
+ * most_register_interface - Registers instance of the interface.
+ * @iface: Pointer to the interface instance description.
+ *
+ * Returns a pointer to the kobject of the generated instance.
+ *
+ * Note: HDM has to ensure that any reference held on the kobj is
+ * released before deregistering the interface.
+ */
+int most_register_interface(struct most_interface *iface);
+
+/**
+ * Deregisters instance of the interface.
+ * @intf_instance Pointer to the interface instance description.
+ */
+void most_deregister_interface(struct most_interface *iface);
+void most_submit_mbo(struct mbo *mbo);
+
+/**
+ * most_stop_enqueue - prevents core from enqueing MBOs
+ * @iface: pointer to interface
+ * @channel_idx: channel index
+ */
+void most_stop_enqueue(struct most_interface *iface, int channel_idx);
+
+/**
+ * most_resume_enqueue - allow core to enqueue MBOs again
+ * @iface: pointer to interface
+ * @channel_idx: channel index
+ *
+ * This clears the enqueue halt flag and enqueues all MBOs currently
+ * in wait fifo.
+ */
+void most_resume_enqueue(struct most_interface *iface, int channel_idx);
+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 most_component *comp);
+void most_put_mbo(struct mbo *mbo);
+int channel_has_mbo(struct most_interface *iface, int channel_idx,
+                   struct most_component *comp);
+int most_start_channel(struct most_interface *iface, int channel_idx,
+                      struct most_component *comp);
+int most_stop_channel(struct most_interface *iface, int channel_idx,
+                     struct most_component *comp);
+int __init configfs_init(void);
+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);
+int most_set_cfg_buffer_size(char *mdev, char *mdev_ch, u16 val);
+int most_set_cfg_subbuffer_size(char *mdev, char *mdev_ch, u16 val);
+int most_set_cfg_dbr_size(char *mdev, char *mdev_ch, u16 val);
+int most_set_cfg_num_buffers(char *mdev, char *mdev_ch, u16 val);
+int most_set_cfg_datatype(char *mdev, char *mdev_ch, char *buf);
+int most_set_cfg_direction(char *mdev, char *mdev_ch, char *buf);
+int most_set_cfg_packets_xact(char *mdev, char *mdev_ch, u16 val);
+int most_cfg_complete(char *comp_name);
+void most_interface_register_notify(const char *mdev_name);
+#endif /* MOST_CORE_H_ */
index f0ac64d..1582c97 100644 (file)
@@ -2,4 +2,3 @@
 obj-$(CONFIG_MOST_NET) += most_net.o
 
 most_net-objs := net.o
-ccflags-y += -I $(srctree)/drivers/staging/
index 6cab1bb..5547e36 100644 (file)
@@ -15,7 +15,8 @@
 #include <linux/list.h>
 #include <linux/wait.h>
 #include <linux/kobject.h>
-#include "most/core.h"
+
+#include "../most.h"
 
 #define MEP_HDR_LEN 8
 #define MDP_HDR_LEN 16
@@ -70,7 +71,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)
 {
@@ -81,6 +82,11 @@ static int skb_to_mamac(const struct sk_buff *skb, struct mbo *mbo)
        unsigned int payload_len = skb->len - ETH_HLEN;
        unsigned int mdp_len = payload_len + MDP_HDR_LEN;
 
+       if (mdp_len < skb->len) {
+               pr_err("drop: too large packet! (%u)\n", skb->len);
+               return -EINVAL;
+       }
+
        if (mbo->buffer_length < mdp_len) {
                pr_err("drop: too small buffer! (%d for %d)\n",
                       mbo->buffer_length, mdp_len);
@@ -128,6 +134,11 @@ static int skb_to_mep(const struct sk_buff *skb, struct mbo *mbo)
        u8 *buff = mbo->virt_address;
        unsigned int mep_len = skb->len + MEP_HDR_LEN;
 
+       if (mep_len < skb->len) {
+               pr_err("drop: too large packet! (%u)\n", skb->len);
+               return -EINVAL;
+       }
+
        if (mbo->buffer_length < mep_len) {
                pr_err("drop: too small buffer! (%d for %d)\n",
                       mbo->buffer_length, mep_len);
@@ -497,7 +508,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,
index a3d086c..f0cd9d8 100644 (file)
@@ -2,4 +2,3 @@
 obj-$(CONFIG_MOST_SOUND) += most_sound.o
 
 most_sound-objs := sound.o
-ccflags-y += -I $(srctree)/drivers/staging/
index 723d0bd..44cf233 100644 (file)
 #include <sound/pcm_params.h>
 #include <linux/sched.h>
 #include <linux/kthread.h>
-#include <most/core.h>
+
+#include "../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
@@ -322,45 +323,6 @@ static int pcm_close(struct snd_pcm_substream *substream)
        return 0;
 }
 
-/**
- * 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 +424,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 +620,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 +737,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,
index 83cf2ea..c2b2073 100644 (file)
@@ -2,4 +2,3 @@
 obj-$(CONFIG_MOST_USB) += most_usb.o
 
 most_usb-objs := usb.o
-ccflags-y += -I $(srctree)/drivers/staging/
index 360cb5b..0bda88c 100644 (file)
@@ -23,7 +23,8 @@
 #include <linux/dma-mapping.h>
 #include <linux/etherdevice.h>
 #include <linux/uaccess.h>
-#include "most/core.h"
+
+#include "../most.h"
 
 #define USB_MTU                        512
 #define NO_ISOCHRONOUS_URB     0
@@ -101,6 +102,7 @@ struct clear_hold_work {
  * @poll_work_obj: work for polling link status
  */
 struct most_dev {
+       struct device dev;
        struct usb_device *usb_device;
        struct most_interface iface;
        struct most_channel_capability *cap;
@@ -122,6 +124,7 @@ struct most_dev {
 };
 
 #define to_mdev(d) container_of(d, struct most_dev, iface)
+#define to_mdev_from_dev(d) container_of(d, struct most_dev, dev)
 #define to_mdev_from_work(w) container_of(w, struct most_dev, poll_work_obj)
 
 static void wq_clear_halt(struct work_struct *wq_obj);
@@ -1022,6 +1025,12 @@ static void release_dci(struct device *dev)
        kfree(dci);
 }
 
+static void release_mdev(struct device *dev)
+{
+       struct most_dev *mdev = to_mdev_from_dev(dev);
+
+       kfree(mdev);
+}
 /**
  * hdm_probe - probe function of USB device driver
  * @interface: Interface of the attached USB device
@@ -1060,6 +1069,7 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
        mdev->link_stat_timer.expires = jiffies + (2 * HZ);
 
        mdev->iface.mod = hdm_usb_fops.owner;
+       mdev->iface.dev = &mdev->dev;
        mdev->iface.driver_dev = &interface->dev;
        mdev->iface.interface = ITYPE_USB;
        mdev->iface.configure = hdm_configure_channel;
@@ -1078,6 +1088,9 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
                 usb_dev->config->desc.bConfigurationValue,
                 usb_iface_desc->desc.bInterfaceNumber);
 
+       mdev->dev.init_name = mdev->description;
+       mdev->dev.parent = &interface->dev;
+       mdev->dev.release = release_mdev;
        mdev->conf = kcalloc(num_endpoints, sizeof(*mdev->conf), GFP_KERNEL);
        if (!mdev->conf)
                goto err_free_mdev;
@@ -1151,7 +1164,7 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
                }
 
                mdev->dci->dev.init_name = "dci";
-               mdev->dci->dev.parent = &mdev->iface.dev;
+               mdev->dci->dev.parent = get_device(mdev->iface.dev);
                mdev->dci->dev.groups = dci_attr_groups;
                mdev->dci->dev.release = release_dci;
                if (device_register(&mdev->dci->dev)) {
@@ -1165,7 +1178,7 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
        mutex_unlock(&mdev->io_mutex);
        return 0;
 err_free_dci:
-       kfree(mdev->dci);
+       put_device(&mdev->dci->dev);
 err_free_busy_urbs:
        kfree(mdev->busy_urbs);
 err_free_ep_address:
@@ -1175,7 +1188,7 @@ err_free_cap:
 err_free_conf:
        kfree(mdev->conf);
 err_free_mdev:
-       kfree(mdev);
+       put_device(&mdev->dev);
 err_out_of_memory:
        if (ret == 0 || ret == -ENOMEM) {
                ret = -ENOMEM;
@@ -1205,14 +1218,15 @@ static void hdm_disconnect(struct usb_interface *interface)
        del_timer_sync(&mdev->link_stat_timer);
        cancel_work_sync(&mdev->poll_work_obj);
 
-       device_unregister(&mdev->dci->dev);
+       if (mdev->dci)
+               device_unregister(&mdev->dci->dev);
        most_deregister_interface(&mdev->iface);
 
        kfree(mdev->busy_urbs);
        kfree(mdev->cap);
        kfree(mdev->conf);
        kfree(mdev->ep_address);
-       kfree(mdev);
+       put_device(&mdev->dev);
 }
 
 static struct usb_driver hdm_usb = {
index 2d857d3..856175f 100644 (file)
@@ -2,4 +2,3 @@
 obj-$(CONFIG_MOST_VIDEO) += most_video.o
 
 most_video-objs := video.o
-ccflags-y += -I $(srctree)/drivers/staging/
index 10c1ef7..d32ae49 100644 (file)
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-fh.h>
 
-#include "most/core.h"
+#include "../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,
index a4c0811..d89d68f 100644 (file)
 
                memc: memc@5000 {
                        compatible = "mtk,mt7621-memc";
-                       reg = <0x300 0x100>;
+                       reg = <0x5000 0x1000>;
                };
 
                cpc: cpc@1fbf0000 {
index 01dbb66..386d619 100644 (file)
@@ -123,6 +123,8 @@ static int nvec_kbd_probe(struct platform_device *pdev)
                keycodes[j++] = extcode_tab_us102[i];
 
        idev = devm_input_allocate_device(&pdev->dev);
+       if (!idev)
+               return -ENOMEM;
        idev->name = "nvec keyboard";
        idev->phys = "nvec";
        idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | BIT_MASK(EV_LED);
diff --git a/drivers/staging/octeon-usb/Kconfig b/drivers/staging/octeon-usb/Kconfig
deleted file mode 100644 (file)
index 6a5d842..0000000
+++ /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 (file)
index 9873a01..0000000
+++ /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 (file)
index 2b29acc..0000000
+++ /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 (file)
index 582c918..0000000
+++ /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 (file)
index 9ed619c..0000000
+++ /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 (file)
index e7f4ddc..0000000
+++ /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 (file)
index 3887cf5..0000000
+++ /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 (file)
index 67a0a1f..0000000
+++ /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 (file)
index ef9e767..0000000
+++ /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 (file)
index c798672..0000000
+++ /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 (file)
index e3771d4..0000000
+++ /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 (file)
index 5325949..0000000
+++ /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 (file)
index 692dcdb..0000000
+++ /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 (file)
index 0c4fac3..0000000
+++ /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 (file)
index 2c16230..0000000
+++ /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 (file)
index ff6482f..0000000
+++ /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 (file)
index d7fbd91..0000000
+++ /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 (file)
index c582403..0000000
+++ /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 (file)
index b334cf8..0000000
+++ /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 (file)
index 78936e9..0000000
+++ /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 (file)
index 2af83a1..0000000
+++ /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 (file)
index f42c381..0000000
+++ /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 (file)
index a614070..0000000
+++ /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 (file)
index 79213c0..0000000
+++ /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)
index 6ec7e3c..4bc5d5f 100644 (file)
@@ -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];
 };
index 83f34ca..8cf3961 100644 (file)
@@ -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,
index 56d116d..790997a 100644 (file)
@@ -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;
 }
 
index ed5440d..ef8037d 100644 (file)
@@ -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;
 
index 9e422bb..bb03b2f 100644 (file)
@@ -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);
 }
index 88e42cc..93283c7 100644 (file)
@@ -429,7 +429,7 @@ static void update_bmc_sta(struct adapter *padapter)
 
                /* prepare for add_RATid */
                supportRateNum = rtw_get_rateset_len((u8 *)&pcur_network->SupportedRates);
-               network_type = rtw_check_network_type((u8 *)&pcur_network->SupportedRates, supportRateNum, 1);
+               network_type = rtw_check_network_type((u8 *)&pcur_network->SupportedRates);
 
                memcpy(psta->bssrateset, &pcur_network->SupportedRates, supportRateNum);
                psta->bssratelen = supportRateNum;
@@ -802,7 +802,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf,  int len)
                supportRateNum += ie_len;
        }
 
-       network_type = rtw_check_network_type(supportRate, supportRateNum, channel);
+       network_type = rtw_check_network_type(supportRate);
 
        rtw_set_supported_rate(pbss_network->SupportedRates, network_type);
 
index d9b0f9e..c525682 100644 (file)
@@ -402,7 +402,6 @@ static u16 Efuse_GetCurrentSize(struct adapter *pAdapter)
 int Efuse_PgPacketRead(struct adapter *pAdapter, u8 offset, u8 *data)
 {
        u8 ReadState = PG_STATE_HEADER;
-       int     bContinual = true;
        int     bDataEmpty = true;
        u8 efuse_data, word_cnts = 0;
        u16     efuse_addr = 0;
@@ -422,7 +421,7 @@ int Efuse_PgPacketRead(struct adapter *pAdapter, u8 offset, u8 *data)
        /*  <Roger_TODO> Efuse has been pre-programmed dummy 5Bytes at the end of Efuse by CP. */
        /*  Skip dummy parts to prevent unexpected data read from Efuse. */
        /*  By pass right now. 2009.02.19. */
-       while (bContinual && AVAILABLE_EFUSE_ADDR(efuse_addr)) {
+       while (AVAILABLE_EFUSE_ADDR(efuse_addr)) {
                /*   Header Read ------------- */
                if (ReadState & PG_STATE_HEADER) {
                        if (efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data) && (efuse_data != 0xFF)) {
@@ -464,7 +463,7 @@ int Efuse_PgPacketRead(struct adapter *pAdapter, u8 offset, u8 *data)
                                        ReadState = PG_STATE_HEADER;
                                }
                        } else {
-                               bContinual = false;
+                               break;
                        }
                } else if (ReadState & PG_STATE_DATA) {
                        /*   Data section Read ------------- */
@@ -498,8 +497,8 @@ static bool hal_EfuseFixHeaderProcess(struct adapter *pAdapter, u8 efuseType, st
 
                        if (!PgWriteSuccess)
                                return false;
-                       else
-                               efuse_addr = Efuse_GetCurrentSize(pAdapter);
+
+                       efuse_addr = Efuse_GetCurrentSize(pAdapter);
                } else {
                        efuse_addr = efuse_addr + (pFixPkt->word_cnts * 2) + 1;
                }
@@ -714,10 +713,9 @@ static bool hal_EfusePartialWriteCheck(struct adapter *pAdapter, u8 efuseType, u
                                if (ALL_WORDS_DISABLED(efuse_data)) {
                                        ret = false;
                                        break;
-                               } else {
-                                       curPkt.offset = ((cur_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
-                                       curPkt.word_en = efuse_data & 0x0F;
                                }
+                               curPkt.offset = ((cur_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
+                               curPkt.word_en = efuse_data & 0x0F;
                        } else {
                                cur_header  =  efuse_data;
                                curPkt.offset = (cur_header >> 4) & 0x0F;
index cc1b543..29f6154 100644 (file)
@@ -98,7 +98,7 @@ bool rtw_is_cckratesonly_included(u8 *rate)
        return true;
 }
 
-int rtw_check_network_type(unsigned char *rate, int ratelen, int channel)
+int rtw_check_network_type(unsigned char *rate)
 {
        /*  could be pure B, pure G, or B/G */
        if (rtw_is_cckratesonly_included(rate))
@@ -157,11 +157,10 @@ u8 *rtw_get_ie(u8 *pbuf, int index, uint *len, int limit)
                if (*p == index) {
                        *len = *(p + 1);
                        return p;
-               } else {
-                       tmp = *(p + 1);
-                       p += (tmp + 2);
-                       i += (tmp + 2);
                }
+               tmp = *(p + 1);
+               p += (tmp + 2);
+               i += (tmp + 2);
                if (i >= limit)
                        break;
        }
@@ -295,10 +294,9 @@ unsigned char *rtw_get_wpa_ie(unsigned char *pie, uint *wpa_ie_len, int limit)
                                goto check_next_ie;
                        *wpa_ie_len = *(pbuf + 1);
                        return pbuf;
-               } else {
-                       *wpa_ie_len = 0;
-                       return NULL;
                }
+               *wpa_ie_len = 0;
+               return NULL;
 
 check_next_ie:
                limit_new = limit - (pbuf - pie) - 2 - len;
@@ -596,9 +594,8 @@ u8 *rtw_get_wps_ie(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen)
                        cnt += in_ie[cnt + 1] + 2;
 
                        break;
-               } else {
-                       cnt += in_ie[cnt + 1] + 2; /* goto next */
                }
+               cnt += in_ie[cnt + 1] + 2; /* goto next */
        }
        return wpsie_ptr;
 }
@@ -642,9 +639,8 @@ u8 *rtw_get_wps_attr(u8 *wps_ie, uint wps_ielen, u16 target_attr_id, u8 *buf_att
                        if (len_attr)
                                *len_attr = attr_len;
                        break;
-               } else {
-                       attr_ptr += attr_len; /* goto next */
                }
+               attr_ptr += attr_len; /* goto next */
        }
        return target_attr_ptr;
 }
index e984b46..36841d2 100644 (file)
@@ -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 */
@@ -1865,6 +1865,7 @@ unsigned int send_beacon(struct adapter *padapter)
        int issue = 0;
        int poll = 0;
        unsigned long start = jiffies;
+       u32 passing_time;
 
        rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
        do {
@@ -1874,7 +1875,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)
@@ -1883,15 +1884,14 @@ unsigned int send_beacon(struct adapter *padapter)
                DBG_88E("%s fail! %u ms\n", __func__,
                        jiffies_to_msecs(jiffies - start));
                return _FAIL;
-       } else {
-               u32 passing_time = jiffies_to_msecs(jiffies - start);
-
-               if (passing_time > 100 || issue > 3)
-                       DBG_88E("%s success, issue:%d, poll:%d, %u ms\n",
-                               __func__, issue, poll,
-                               jiffies_to_msecs(jiffies - start));
-               return _SUCCESS;
        }
+       passing_time = jiffies_to_msecs(jiffies - start);
+
+       if (passing_time > 100 || issue > 3)
+               DBG_88E("%s success, issue:%d, poll:%d, %u ms\n",
+                       __func__, issue, poll,
+                       jiffies_to_msecs(jiffies - start));
+       return _SUCCESS;
 }
 
 /****************************************************************************
@@ -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);
@@ -2864,10 +2864,9 @@ static unsigned int OnAuthClient(struct adapter *padapter,
                        set_link_timer(pmlmeext, REAUTH_TO);
 
                        return _SUCCESS;
-               } else {
-                       /*  open system */
-                       go2asoc = 1;
                }
+               /*  open system */
+               go2asoc = 1;
        } else if (seq == 4) {
                if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
                        go2asoc = 1;
@@ -2975,7 +2974,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 +2986,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 +2995,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 +3031,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 +3052,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 +3094,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 +3131,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 +3146,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 +3162,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 +3245,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) { */
@@ -3452,14 +3452,13 @@ static unsigned int OnDeAuth(struct adapter *padapter,
                }
 
                return _SUCCESS;
-       } else
+       }
 #endif
-       {
-               DBG_88E_LEVEL(_drv_always_, "sta recv deauth reason code(%d) sta:%pM\n",
-                             reason, GetAddr3Ptr(pframe));
+       DBG_88E_LEVEL(_drv_always_, "sta recv deauth reason code(%d) sta:%pM\n",
+                     reason, GetAddr3Ptr(pframe));
+
+       receive_disconnect(padapter, GetAddr3Ptr(pframe), reason);
 
-               receive_disconnect(padapter, GetAddr3Ptr(pframe), reason);
-       }
        pmlmepriv->LinkDetectInfo.bBusyTraffic = false;
        return _SUCCESS;
 }
@@ -3506,14 +3505,13 @@ static unsigned int OnDisassoc(struct adapter *padapter,
                }
 
                return _SUCCESS;
-       } else
+       }
 #endif
-       {
-               DBG_88E_LEVEL(_drv_always_, "ap recv disassoc reason code(%d) sta:%pM\n",
-                             reason, GetAddr3Ptr(pframe));
+       DBG_88E_LEVEL(_drv_always_, "ap recv disassoc reason code(%d) sta:%pM\n",
+                     reason, GetAddr3Ptr(pframe));
+
+       receive_disconnect(padapter, GetAddr3Ptr(pframe), reason);
 
-               receive_disconnect(padapter, GetAddr3Ptr(pframe), reason);
-       }
        pmlmepriv->LinkDetectInfo.bBusyTraffic = false;
        return _SUCCESS;
 }
@@ -3958,7 +3956,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 +4513,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 +4842,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 +5038,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 +5082,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 +5261,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;
                        }
@@ -5276,10 +5274,10 @@ u8 set_stakey_hdl(struct adapter *padapter, u8 *pbuf)
                        write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key);
 
                        return H2C_SUCCESS_RSP;
-               } else {
-                       DBG_88E("r871x_set_stakey_hdl(): sta has been free\n");
-                       return H2C_REJECTED;
                }
+
+               DBG_88E("r871x_set_stakey_hdl(): sta has been free\n");
+               return H2C_REJECTED;
        }
 
        /* below for sta mode */
@@ -5333,14 +5331,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 +5359,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) {
index 03dc7e5..c4f5850 100644 (file)
@@ -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) {
index af8a79c..6df873e 100644 (file)
@@ -1247,9 +1247,8 @@ unsigned char check_assoc_AP(u8 *pframe, uint len)
                                if (ralink_vendor_flag) {
                                        DBG_88E("link to Tenda W311R AP\n");
                                        return HT_IOT_PEER_TENDA;
-                               } else {
-                                       DBG_88E("Capture EPIGRAM_OUI\n");
                                }
+                               DBG_88E("Capture EPIGRAM_OUI\n");
                        } else {
                                break;
                        }
@@ -1266,10 +1265,9 @@ unsigned char check_assoc_AP(u8 *pframe, uint len)
        } else if (ralink_vendor_flag && epigram_vendor_flag) {
                DBG_88E("link to Tenda W311R AP\n");
                return HT_IOT_PEER_TENDA;
-       } else {
-               DBG_88E("link to new AP\n");
-               return HT_IOT_PEER_UNKNOWN;
        }
+       DBG_88E("link to new AP\n");
+       return HT_IOT_PEER_UNKNOWN;
 }
 
 void update_IOT_info(struct adapter *padapter)
index c375916..258531b 100644 (file)
@@ -1022,10 +1022,10 @@ s32 rtw_xmitframe_coalesce(struct adapter *padapter, struct sk_buff *pkt, struct
                        ClearMFrag(mem_start);
 
                        break;
-               } else {
-                       RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("%s: There're still something in packet!\n", __func__));
                }
 
+               RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("%s: There're still something in packet!\n", __func__));
+
                addr = (size_t)(pframe);
 
                mem_start = (unsigned char *)round_up(addr, 4) + hw_hdr_offset;
index 4e2f6cb..7489491 100644 (file)
@@ -967,10 +967,11 @@ void ODM_TXPowerTrackingCheck(struct odm_dm_struct *pDM_Odm)
 
                pDM_Odm->RFCalibrateInfo.TM_Trigger = 1;
                return;
-       } else {
-               rtl88eu_dm_txpower_tracking_callback_thermalmeter(Adapter);
-               pDM_Odm->RFCalibrateInfo.TM_Trigger = 0;
        }
+
+       rtl88eu_dm_txpower_tracking_callback_thermalmeter(Adapter);
+       pDM_Odm->RFCalibrateInfo.TM_Trigger = 0;
+
 }
 
 /* 3============================================================ */
index 251bd8a..a55a0d8 100644 (file)
@@ -154,35 +154,37 @@ void rtl88eu_dm_update_rx_idle_ant(struct odm_dm_struct *dm_odm, u8 ant)
        struct adapter *adapter = dm_odm->Adapter;
        u32 default_ant, optional_ant;
 
-       if (dm_fat_tbl->RxIdleAnt != ant) {
-               if (ant == MAIN_ANT) {
-                       default_ant = (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) ?
-                                      MAIN_ANT_CG_TRX : MAIN_ANT_CGCS_RX;
-                       optional_ant = (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) ?
-                                       AUX_ANT_CG_TRX : AUX_ANT_CGCS_RX;
-               } else {
-                       default_ant = (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) ?
-                                      AUX_ANT_CG_TRX : AUX_ANT_CGCS_RX;
-                       optional_ant = (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) ?
-                                       MAIN_ANT_CG_TRX : MAIN_ANT_CGCS_RX;
-               }
+       if (dm_fat_tbl->RxIdleAnt == ant)
+               return;
 
-               if (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) {
-                       phy_set_bb_reg(adapter, ODM_REG_RX_ANT_CTRL_11N,
-                                      BIT(5) | BIT(4) | BIT(3), default_ant);
-                       phy_set_bb_reg(adapter, ODM_REG_RX_ANT_CTRL_11N,
-                                      BIT(8) | BIT(7) | BIT(6), optional_ant);
-                       phy_set_bb_reg(adapter, ODM_REG_ANTSEL_CTRL_11N,
-                                      BIT(14) | BIT(13) | BIT(12), default_ant);
-                       phy_set_bb_reg(adapter, ODM_REG_RESP_TX_11N,
-                                      BIT(6) | BIT(7), default_ant);
-               } else if (dm_odm->AntDivType == CGCS_RX_HW_ANTDIV) {
-                       phy_set_bb_reg(adapter, ODM_REG_RX_ANT_CTRL_11N,
-                                      BIT(5) | BIT(4) | BIT(3), default_ant);
-                       phy_set_bb_reg(adapter, ODM_REG_RX_ANT_CTRL_11N,
-                                      BIT(8) | BIT(7) | BIT(6), optional_ant);
-               }
+       if (ant == MAIN_ANT) {
+               default_ant = (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) ?
+                              MAIN_ANT_CG_TRX : MAIN_ANT_CGCS_RX;
+               optional_ant = (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) ?
+                               AUX_ANT_CG_TRX : AUX_ANT_CGCS_RX;
+       } else {
+               default_ant = (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) ?
+                              AUX_ANT_CG_TRX : AUX_ANT_CGCS_RX;
+               optional_ant = (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) ?
+                               MAIN_ANT_CG_TRX : MAIN_ANT_CGCS_RX;
+       }
+
+       if (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) {
+               phy_set_bb_reg(adapter, ODM_REG_RX_ANT_CTRL_11N,
+                              BIT(5) | BIT(4) | BIT(3), default_ant);
+               phy_set_bb_reg(adapter, ODM_REG_RX_ANT_CTRL_11N,
+                              BIT(8) | BIT(7) | BIT(6), optional_ant);
+               phy_set_bb_reg(adapter, ODM_REG_ANTSEL_CTRL_11N,
+                              BIT(14) | BIT(13) | BIT(12), default_ant);
+               phy_set_bb_reg(adapter, ODM_REG_RESP_TX_11N,
+                              BIT(6) | BIT(7), default_ant);
+       } else if (dm_odm->AntDivType == CGCS_RX_HW_ANTDIV) {
+               phy_set_bb_reg(adapter, ODM_REG_RX_ANT_CTRL_11N,
+                              BIT(5) | BIT(4) | BIT(3), default_ant);
+               phy_set_bb_reg(adapter, ODM_REG_RX_ANT_CTRL_11N,
+                              BIT(8) | BIT(7) | BIT(6), optional_ant);
        }
+
        dm_fat_tbl->RxIdleAnt = ant;
 }
 
@@ -303,6 +305,7 @@ void rtl88eu_dm_antenna_diversity(struct odm_dm_struct *dm_odm)
 
        if (!(dm_odm->SupportAbility & ODM_BB_ANT_DIV))
                return;
+
        if (!dm_odm->bLinked) {
                ODM_RT_TRACE(dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD,
                             ("ODM_AntennaDiversity_88E(): No Link.\n"));
@@ -318,19 +321,20 @@ void rtl88eu_dm_antenna_diversity(struct odm_dm_struct *dm_odm)
                        dm_fat_tbl->bBecomeLinked = dm_odm->bLinked;
                }
                return;
-       } else {
-               if (!dm_fat_tbl->bBecomeLinked) {
-                       ODM_RT_TRACE(dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD,
-                                    ("Need to Turn on HW AntDiv\n"));
-                       phy_set_bb_reg(adapter, ODM_REG_IGI_A_11N, BIT(7), 1);
-                       phy_set_bb_reg(adapter, ODM_REG_CCK_ANTDIV_PARA1_11N,
-                                      BIT(15), 1);
-                       if (dm_odm->AntDivType == CG_TRX_HW_ANTDIV)
-                               phy_set_bb_reg(adapter, ODM_REG_TX_ANT_CTRL_11N,
-                                              BIT(21), 1);
-                       dm_fat_tbl->bBecomeLinked = dm_odm->bLinked;
-               }
        }
+
+       if (!dm_fat_tbl->bBecomeLinked) {
+               ODM_RT_TRACE(dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD,
+                            ("Need to Turn on HW AntDiv\n"));
+               phy_set_bb_reg(adapter, ODM_REG_IGI_A_11N, BIT(7), 1);
+               phy_set_bb_reg(adapter, ODM_REG_CCK_ANTDIV_PARA1_11N,
+                              BIT(15), 1);
+               if (dm_odm->AntDivType == CG_TRX_HW_ANTDIV)
+                       phy_set_bb_reg(adapter, ODM_REG_TX_ANT_CTRL_11N,
+                                      BIT(21), 1);
+               dm_fat_tbl->bBecomeLinked = dm_odm->bLinked;
+       }
+
        if ((dm_odm->AntDivType == CG_TRX_HW_ANTDIV) ||
            (dm_odm->AntDivType == CGCS_RX_HW_ANTDIV))
                rtl88eu_dm_hw_ant_div(dm_odm);
index 51c40ab..afaf9e5 100644 (file)
@@ -923,27 +923,27 @@ static bool simularity_compare(struct adapter *adapt, s32 resulta[][8],
                        }
                }
                return result;
-       } else {
-               if (!(sim_bitmap & 0x03)) {                /* path A TX OK */
-                       for (i = 0; i < 2; i++)
-                               resulta[3][i] = resulta[c1][i];
-               }
-               if (!(sim_bitmap & 0x0c)) {                /* path A RX OK */
-                       for (i = 2; i < 4; i++)
-                               resulta[3][i] = resulta[c1][i];
-               }
+       }
 
-               if (!(sim_bitmap & 0x30)) { /* path B TX OK */
-                       for (i = 4; i < 6; i++)
-                               resulta[3][i] = resulta[c1][i];
-               }
+       if (!(sim_bitmap & 0x03)) {                /* path A TX OK */
+               for (i = 0; i < 2; i++)
+                       resulta[3][i] = resulta[c1][i];
+       }
+       if (!(sim_bitmap & 0x0c)) {                /* path A RX OK */
+               for (i = 2; i < 4; i++)
+                       resulta[3][i] = resulta[c1][i];
+       }
 
-               if (!(sim_bitmap & 0xc0)) { /* path B RX OK */
-                       for (i = 6; i < 8; i++)
-                               resulta[3][i] = resulta[c1][i];
-               }
-               return false;
+       if (!(sim_bitmap & 0x30)) { /* path B TX OK */
+               for (i = 4; i < 6; i++)
+                       resulta[3][i] = resulta[c1][i];
+       }
+
+       if (!(sim_bitmap & 0xc0)) { /* path B RX OK */
+               for (i = 6; i < 8; i++)
+                       resulta[3][i] = resulta[c1][i];
        }
+       return false;
 }
 
 static void phy_iq_calibrate(struct adapter *adapt, s32 result[][8],
@@ -1053,10 +1053,9 @@ static void phy_iq_calibrate(struct adapter *adapt, s32 result[][8],
                                result[t][3] = (phy_query_bb_reg(adapt, rRx_Power_After_IQK_A_2,
                                                                 bMaskDWord)&0x3FF0000)>>16;
                        break;
-               } else {
-                       ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
-                                    ("Path A Rx IQK Fail!!\n"));
                }
+               ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
+                            ("Path A Rx IQK Fail!!\n"));
        }
 
        if (path_a_ok == 0x00) {
index 545d6a6..241f55b 100644 (file)
@@ -21,7 +21,7 @@
 /*  Initialize GPIO setting registers */
 static void dm_InitGPIOSetting(struct adapter *Adapter)
 {
-       u8      tmp1byte;
+       u8 tmp1byte;
 
        tmp1byte = usb_read8(Adapter, REG_GPIO_MUXCFG);
        tmp1byte &= (GPIOSEL_GPIO | ~GPIOSEL_ENBT);
@@ -35,8 +35,8 @@ static void dm_InitGPIOSetting(struct adapter *Adapter)
 static void Init_ODM_ComInfo_88E(struct adapter *Adapter)
 {
        struct hal_data_8188e *hal_data = Adapter->HalData;
-       struct dm_priv  *pdmpriv = &hal_data->dmpriv;
-       struct odm_dm_struct *dm_odm = &(hal_data->odmpriv);
+       struct dm_priv *pdmpriv = &hal_data->dmpriv;
+       struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
 
        /*  Init Value */
        memset(dm_odm, 0, sizeof(*dm_odm));
@@ -51,44 +51,46 @@ static void Init_ODM_ComInfo_88E(struct adapter *Adapter)
 
        dm_odm->AntDivType = hal_data->TRxAntDivType;
 
-       /*  Tx power tracking BB swing table. */
-       /*  The base index = 12. +((12-n)/2)dB 13~?? = decrease tx pwr by -((n-12)/2)dB */
+       /* Tx power tracking BB swing table.
+        * The base index =
+        * 12. +((12-n)/2)dB 13~?? = decrease tx pwr by -((n-12)/2)dB
+        */
        dm_odm->BbSwingIdxOfdm = 12; /*  Set defalut value as index 12. */
        dm_odm->BbSwingIdxOfdmCurrent = 12;
        dm_odm->BbSwingFlagOfdm = false;
 
-       pdmpriv->InitODMFlag =  ODM_RF_CALIBRATION |
-                               ODM_RF_TX_PWR_TRACK;
+       pdmpriv->InitODMFlag = ODM_RF_CALIBRATION |
+                              ODM_RF_TX_PWR_TRACK;
 
        dm_odm->SupportAbility = pdmpriv->InitODMFlag;
 }
 
 static void Update_ODM_ComInfo_88E(struct adapter *Adapter)
 {
-       struct mlme_ext_priv    *pmlmeext = &Adapter->mlmeextpriv;
-       struct mlme_priv        *pmlmepriv = &Adapter->mlmepriv;
+       struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
+       struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
        struct pwrctrl_priv *pwrctrlpriv = &Adapter->pwrctrlpriv;
        struct hal_data_8188e *hal_data = Adapter->HalData;
-       struct odm_dm_struct *dm_odm = &(hal_data->odmpriv);
-       struct dm_priv  *pdmpriv = &hal_data->dmpriv;
+       struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
+       struct dm_priv *pdmpriv = &hal_data->dmpriv;
        int i;
 
-       pdmpriv->InitODMFlag =  ODM_BB_DIG |
-                               ODM_BB_RA_MASK |
-                               ODM_BB_DYNAMIC_TXPWR |
-                               ODM_BB_FA_CNT |
-                               ODM_BB_RSSI_MONITOR |
-                               ODM_BB_CCK_PD |
-                               ODM_BB_PWR_SAVE |
-                               ODM_MAC_EDCA_TURBO |
-                               ODM_RF_CALIBRATION |
-                               ODM_RF_TX_PWR_TRACK;
+       pdmpriv->InitODMFlag = ODM_BB_DIG |
+                              ODM_BB_RA_MASK |
+                              ODM_BB_DYNAMIC_TXPWR |
+                              ODM_BB_FA_CNT |
+                              ODM_BB_RSSI_MONITOR |
+                              ODM_BB_CCK_PD |
+                              ODM_BB_PWR_SAVE |
+                              ODM_MAC_EDCA_TURBO |
+                              ODM_RF_CALIBRATION |
+                              ODM_RF_TX_PWR_TRACK;
        if (hal_data->AntDivCfg)
                pdmpriv->InitODMFlag |= ODM_BB_ANT_DIV;
 
        if (Adapter->registrypriv.mp_mode == 1) {
-               pdmpriv->InitODMFlag =  ODM_RF_CALIBRATION |
-                                       ODM_RF_TX_PWR_TRACK;
+               pdmpriv->InitODMFlag = ODM_RF_CALIBRATION |
+                                      ODM_RF_TX_PWR_TRACK;
        }
 
        dm_odm->SupportAbility = pdmpriv->InitODMFlag;
@@ -106,20 +108,23 @@ static void Update_ODM_ComInfo_88E(struct adapter *Adapter)
        dm_odm->pbPowerSaving = (bool *)&pwrctrlpriv->bpower_saving;
        dm_odm->AntDivType = hal_data->TRxAntDivType;
 
-       /*  Tx power tracking BB swing table. */
-       /*  The base index = 12. +((12-n)/2)dB 13~?? = decrease tx pwr by -((n-12)/2)dB */
+       /* Tx power tracking BB swing table.
+        * The base index =
+        * 12. +((12-n)/2)dB 13~?? = decrease tx pwr by -((n-12)/2)dB
+        */
        dm_odm->BbSwingIdxOfdm = 12; /*  Set defalut value as index 12. */
        dm_odm->BbSwingIdxOfdmCurrent = 12;
        dm_odm->BbSwingFlagOfdm = false;
 
        for (i = 0; i < NUM_STA; i++)
-               ODM_CmnInfoPtrArrayHook(dm_odm, ODM_CMNINFO_STA_STATUS, i, NULL);
+               ODM_CmnInfoPtrArrayHook(dm_odm, ODM_CMNINFO_STA_STATUS, i,
+                                       NULL);
 }
 
 void rtl8188e_InitHalDm(struct adapter *Adapter)
 {
-       struct dm_priv  *pdmpriv = &Adapter->HalData->dmpriv;
-       struct odm_dm_struct *dm_odm = &(Adapter->HalData->odmpriv);
+       struct dm_priv *pdmpriv = &Adapter->HalData->dmpriv;
+       struct odm_dm_struct *dm_odm = &Adapter->HalData->odmpriv;
 
        dm_InitGPIOSetting(Adapter);
        pdmpriv->DM_Type = DM_Type_ByDriver;
@@ -162,7 +167,7 @@ skip_dm:
 
 void rtw_hal_dm_init(struct adapter *Adapter)
 {
-       struct dm_priv  *pdmpriv = &Adapter->HalData->dmpriv;
+       struct dm_priv *pdmpriv = &Adapter->HalData->dmpriv;
        struct odm_dm_struct *podmpriv = &Adapter->HalData->odmpriv;
 
        memset(pdmpriv, 0, sizeof(struct dm_priv));
@@ -172,23 +177,28 @@ void rtw_hal_dm_init(struct adapter *Adapter)
 
 /*  Add new function to reset the state of antenna diversity before link. */
 /*  Compare RSSI for deciding antenna */
-void rtw_hal_antdiv_rssi_compared(struct adapter *Adapter, struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src)
+void rtw_hal_antdiv_rssi_compared(struct adapter *Adapter,
+                                 struct wlan_bssid_ex *dst,
+                                 struct wlan_bssid_ex *src)
 {
        if (Adapter->HalData->AntDivCfg != 0) {
-               /* select optimum_antenna for before linked =>For antenna diversity */
-               if (dst->Rssi >=  src->Rssi) {/* keep org parameter */
+               /* select optimum_antenna for before linked => For antenna
+                * diversity
+                */
+               if (dst->Rssi >= src->Rssi) {/* keep org parameter */
                        src->Rssi = dst->Rssi;
-                       src->PhyInfo.Optimum_antenna = dst->PhyInfo.Optimum_antenna;
+                       src->PhyInfo.Optimum_antenna =
+                               dst->PhyInfo.Optimum_antenna;
                }
        }
 }
 
 /*  Add new function to reset the state of antenna diversity before link. */
-u8 rtw_hal_antdiv_before_linked(struct adapter *Adapter)
+bool rtw_hal_antdiv_before_linked(struct adapter *Adapter)
 {
        struct odm_dm_struct *dm_odm = &Adapter->HalData->odmpriv;
        struct sw_ant_switch *dm_swat_tbl = &dm_odm->DM_SWAT_Table;
-       struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv);
+       struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
 
        /*  Condition that does not need to use antenna diversity. */
        if (Adapter->HalData->AntDivCfg == 0)
@@ -197,15 +207,16 @@ u8 rtw_hal_antdiv_before_linked(struct adapter *Adapter)
        if (check_fwstate(pmlmepriv, _FW_LINKED))
                return false;
 
-       if (dm_swat_tbl->SWAS_NoLink_State == 0) {
-               /* switch channel */
-               dm_swat_tbl->SWAS_NoLink_State = 1;
-               dm_swat_tbl->CurAntenna = (dm_swat_tbl->CurAntenna == Antenna_A) ? Antenna_B : Antenna_A;
-
-               rtw_antenna_select_cmd(Adapter, dm_swat_tbl->CurAntenna, false);
-               return true;
-       } else {
+       if (dm_swat_tbl->SWAS_NoLink_State != 0) {
                dm_swat_tbl->SWAS_NoLink_State = 0;
                return false;
        }
+
+       /* switch channel */
+       dm_swat_tbl->SWAS_NoLink_State = 1;
+       dm_swat_tbl->CurAntenna = (dm_swat_tbl->CurAntenna == Antenna_A) ?
+                                 Antenna_B : Antenna_A;
+
+       rtw_antenna_select_cmd(Adapter, dm_swat_tbl->CurAntenna, false);
+       return true;
 }
index da66695..0c5b2b0 100644 (file)
 #define MAX_TXPWR_IDX_NMODE_92S                63
 #define Reset_Cnt_Limit                        3
 
-#define IQK_MAC_REG_NUM                        4
-#define IQK_ADDA_REG_NUM               16
-#define IQK_BB_REG_NUM                 9
-#define HP_THERMAL_NUM                 8
-
 #define MAX_AGGR_NUM                   0x07
 
 
index 516a896..39df305 100644 (file)
@@ -209,7 +209,7 @@ void        rtw_hal_set_bwmode(struct adapter *padapter,
 void   rtw_hal_set_chan(struct adapter *padapter, u8 channel);
 void   rtw_hal_dm_watchdog(struct adapter *padapter);
 
-u8     rtw_hal_antdiv_before_linked(struct adapter *padapter);
+bool rtw_hal_antdiv_before_linked(struct adapter *padapter);
 void   rtw_hal_antdiv_rssi_compared(struct adapter *padapter,
                                     struct wlan_bssid_ex *dst,
                                     struct wlan_bssid_ex *src);
index d569fe5..75f0ebe 100644 (file)
@@ -765,7 +765,7 @@ bool rtw_is_cckrates_included(u8 *rate);
 
 bool rtw_is_cckratesonly_included(u8 *rate);
 
-int rtw_check_network_type(unsigned char *rate, int ratelen, int channel);
+int rtw_check_network_type(unsigned char *rate);
 
 void rtw_get_bcn_info(struct wlan_network *pnetwork);
 
index 8245cea..9d39fe1 100644 (file)
@@ -239,7 +239,6 @@ struct odm_rate_adapt {
 
 #define IQK_MAC_REG_NUM                4
 #define IQK_ADDA_REG_NUM       16
-#define IQK_BB_REG_NUM_MAX     10
 #define IQK_BB_REG_NUM         9
 #define HP_THERMAL_NUM         8
 
index 1920433..910b982 100644 (file)
@@ -10,12 +10,7 @@ enum{
        UP_LINK,
        DOWN_LINK,
 };
-/*  duplicate code,will move to ODM ######### */
-#define IQK_MAC_REG_NUM                4
-#define IQK_ADDA_REG_NUM               16
-#define IQK_BB_REG_NUM                 9
-#define HP_THERMAL_NUM         8
-/*  duplicate code,will move to ODM ######### */
+
 struct dm_priv {
        u8      DM_Type;
        u8      DMFlag;
index b5dfb22..c3847cf 100644 (file)
@@ -19,9 +19,6 @@
 #define SHORT_SLOT_TIME                        9
 #define NON_SHORT_SLOT_TIME            20
 
-#define RTL8711_RF_MAX_SENS            6
-#define RTL8711_RF_DEF_SENS            4
-
 /*  We now define the following channels as the max channels in each
  * channel plan.
  */
@@ -30,8 +27,6 @@
 #define        MAX_CHANNEL_NUM_2G              14
 #define        MAX_CHANNEL_NUM                 14      /* 2.4 GHz only */
 
-#define NUM_REGULATORYS        1
-
 /* Country codes */
 #define USA                            0x555320
 #define EUROPE                         0x1 /* temp, should be provided later */
@@ -74,17 +69,6 @@ enum _REG_PREAMBLE_MODE {
        PREAMBLE_SHORT  = 3,
 };
 
-enum _RTL8712_RF_MIMO_CONFIG_ {
-       RTL8712_RFCONFIG_1T = 0x10,
-       RTL8712_RFCONFIG_2T = 0x20,
-       RTL8712_RFCONFIG_1R = 0x01,
-       RTL8712_RFCONFIG_2R = 0x02,
-       RTL8712_RFCONFIG_1T1R = 0x11,
-       RTL8712_RFCONFIG_1T2R = 0x12,
-       RTL8712_RFCONFIG_TURBO = 0x92,
-       RTL8712_RFCONFIG_2T2R = 0x22
-};
-
 enum rf90_radio_path {
        RF90_PATH_A = 0,                /* Radio Path A */
        RF90_PATH_B = 1,                /* Radio Path B */
index 710c33f..9b6ea86 100644 (file)
@@ -222,18 +222,21 @@ static char *translate_scan(struct adapter *padapter,
 
        /* parsing WPA/WPA2 IE */
        {
-               u8 buf[MAX_WPA_IE_LEN];
+               u8 *buf;
                u8 wpa_ie[255], rsn_ie[255];
                u16 wpa_len = 0, rsn_len = 0;
                u8 *p;
 
+               buf = kzalloc(MAX_WPA_IE_LEN, GFP_ATOMIC);
+               if (!buf)
+                       return start;
+
                rtw_get_sec_ie(pnetwork->network.ies, pnetwork->network.ie_length, rsn_ie, &rsn_len, wpa_ie, &wpa_len);
                RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan: ssid =%s\n", pnetwork->network.ssid.ssid));
                RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan: wpa_len =%d rsn_len =%d\n", wpa_len, rsn_len));
 
                if (wpa_len > 0) {
                        p = buf;
-                       memset(buf, 0, MAX_WPA_IE_LEN);
                        p += sprintf(p, "wpa_ie=");
                        for (i = 0; i < wpa_len; i++)
                                p += sprintf(p, "%02x", wpa_ie[i]);
@@ -250,7 +253,6 @@ static char *translate_scan(struct adapter *padapter,
                }
                if (rsn_len > 0) {
                        p = buf;
-                       memset(buf, 0, MAX_WPA_IE_LEN);
                        p += sprintf(p, "rsn_ie=");
                        for (i = 0; i < rsn_len; i++)
                                p += sprintf(p, "%02x", rsn_ie[i]);
@@ -264,6 +266,7 @@ static char *translate_scan(struct adapter *padapter,
                        iwe.u.data.length = rsn_len;
                        start = iwe_stream_add_point(info, start, stop, &iwe, rsn_ie);
                }
+               kfree(buf);
        }
 
        {/* parsing WPS IE */
@@ -593,9 +596,8 @@ static int rtw_set_wpa_ie(struct adapter *padapter, char *pie, unsigned short ie
                                        set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
                                        cnt += buf[cnt+1]+2;
                                        break;
-                               } else {
-                                       cnt += buf[cnt+1]+2; /* goto next */
                                }
+                               cnt += buf[cnt+1]+2; /* goto next */
                        }
                }
        }
@@ -770,8 +772,7 @@ static int rtw_wx_set_pmkid(struct net_device *dev,
                DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_ADD!\n");
                if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN))
                        return ret;
-               else
-                       ret = true;
+               ret = true;
                blInserted = false;
 
                /* overwrite PMKID */
index 60c6527..11183b9 100644 (file)
@@ -1973,18 +1973,11 @@ u8 rtl92e_rx_db_to_percent(s8 antpower)
 
 u8 rtl92e_evm_db_to_percent(s8 value)
 {
-       s8 ret_val;
+       s8 ret_val = clamp(-value, 0, 33) * 3;
 
-       ret_val = value;
-
-       if (ret_val >= 0)
-               ret_val = 0;
-       if (ret_val <= -33)
-               ret_val = -33;
-       ret_val = 0 - ret_val;
-       ret_val *= 3;
        if (ret_val == 99)
                ret_val = 100;
+
        return ret_val;
 }
 
index dcd51bf..0be7426 100644 (file)
@@ -1,13 +1,9 @@
 # SPDX-License-Identifier: GPL-2.0
 NIC_SELECT = RTL8192U
 
-ccflags-y := -std=gnu89
-ccflags-y += -O2
-
 ccflags-y += -DCONFIG_FORCE_HARD_FLOAT=y
 ccflags-y += -DJACKSON_NEW_8187 -DJACKSON_NEW_RX
 ccflags-y += -DTHOMAS_BEACON -DTHOMAS_TASKLET -DTHOMAS_SKB -DTHOMAS_TURBO
-ccflags-y += -I $(srctree)/$(src)/ieee80211
 
 r8192u_usb-y := r8192U_core.o r8180_93cx6.o r8192U_wx.o                \
                  r8190_rtl8256.o r819xU_phy.o r819xU_firmware.o        \
diff --git a/drivers/staging/rtl8192u/ieee80211/Makefile b/drivers/staging/rtl8192u/ieee80211/Makefile
deleted file mode 100644 (file)
index 0d4d648..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-NIC_SELECT = RTL8192U
-
-ccflags-y := -O2
-ccflags-y += -DJACKSON_NEW_8187 -DJACKSON_NEW_RX
-
-ieee80211-rsl-objs := ieee80211_rx.o \
-                     ieee80211_softmac.o \
-                     ieee80211_tx.o \
-                     ieee80211_wx.o \
-                     ieee80211_module.o \
-                     ieee80211_softmac_wx.o\
-                     rtl819x_HTProc.o\
-                     rtl819x_TSProc.o\
-                     rtl819x_BAProc.o\
-                     dot11d.o
-
-ieee80211_crypt-rsl-objs := ieee80211_crypt.o
-ieee80211_crypt_tkip-rsl-objs := ieee80211_crypt_tkip.o
-ieee80211_crypt_ccmp-rsl-objs := ieee80211_crypt_ccmp.o
-ieee80211_crypt_wep-rsl-objs := ieee80211_crypt_wep.o
-
-obj-m +=ieee80211-rsl.o
-obj-m +=ieee80211_crypt-rsl.o
-obj-m +=ieee80211_crypt_wep-rsl.o
-obj-m +=ieee80211_crypt_tkip-rsl.o
-obj-m +=ieee80211_crypt_ccmp-rsl.o
index 00fea12..e101f7b 100644 (file)
@@ -232,8 +232,7 @@ ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
 
        #ifdef NOT_YET
        if (ieee->iw_mode == IW_MODE_MASTER) {
-               printk(KERN_DEBUG "%s: Master mode not yet supported.\n",
-                      ieee->dev->name);
+               netdev_dbg(ieee->dev, "Master mode not yet supported.\n");
                return 0;
 /*
   hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr_4addr *)
@@ -261,9 +260,9 @@ ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
 
            if (ieee->iw_mode == IW_MODE_MASTER) {
                if (type != WLAN_FC_TYPE_MGMT && type != WLAN_FC_TYPE_CTRL) {
-                       printk(KERN_DEBUG "%s: unknown management frame "
+                       netdev_dbg(skb->dev, "unknown management frame "
                               "(type=0x%02x, stype=0x%02x) dropped\n",
-                              skb->dev->name, type, stype);
+                              type, stype);
                        return -1;
                }
 
@@ -271,8 +270,8 @@ ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
                return 0;
        }
 
-       printk(KERN_DEBUG "%s: hostap_rx_frame_mgmt: management frame "
-              "received in non-Host AP mode\n", skb->dev->name);
+       netdev_dbg(skb->dev, "hostap_rx_frame_mgmt: management frame "
+              "received in non-Host AP mode\n");
        return -1;
        #endif
 }
@@ -349,9 +348,9 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb,
        if (ieee->tkip_countermeasures &&
            strcmp(crypt->ops->name, "TKIP") == 0) {
                if (net_ratelimit()) {
-                       printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
+                       netdev_dbg(ieee->dev, "TKIP countermeasures: dropped "
                               "received packet from %pM\n",
-                              ieee->dev->name, hdr->addr2);
+                              hdr->addr2);
                }
                return -1;
        }
@@ -397,9 +396,9 @@ ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee, struct sk_buff *s
        res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
        atomic_dec(&crypt->refcnt);
        if (res < 0) {
-               printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
+               netdev_dbg(ieee->dev, "MSDU decryption/MIC verification failed"
                       " (SA=%pM keyidx=%d)\n",
-                      ieee->dev->name, hdr->addr2, keyidx);
+                      hdr->addr2, keyidx);
                return -1;
        }
 
@@ -749,7 +748,8 @@ static void RxReorderIndicatePacket(struct ieee80211_device *ieee,
        kfree(prxbIndicateArray);
 }
 
-static u8 parse_subframe(struct sk_buff *skb,
+static u8 parse_subframe(struct ieee80211_device *ieee,
+                        struct sk_buff *skb,
                         struct ieee80211_rx_stats *rx_stats,
                         struct ieee80211_rxb *rxb, u8 *src, u8 *dst)
 {
@@ -810,11 +810,11 @@ static u8 parse_subframe(struct sk_buff *skb,
                        nSubframe_Length = (nSubframe_Length >> 8) + (nSubframe_Length << 8);
 
                        if (skb->len < (ETHERNET_HEADER_SIZE + nSubframe_Length)) {
-                               printk("%s: A-MSDU parse error!! pRfd->nTotalSubframe : %d\n",\
-                                               __func__, rxb->nr_subframes);
-                               printk("%s: A-MSDU parse error!! Subframe Length: %d\n", __func__, nSubframe_Length);
-                               printk("nRemain_Length is %d and nSubframe_Length is : %d\n", skb->len, nSubframe_Length);
-                               printk("The Packet SeqNum is %d\n", SeqNum);
+                               netdev_dbg(ieee->dev, "A-MSDU parse error!! pRfd->nTotalSubframe : %d\n",
+                                          rxb->nr_subframes);
+                               netdev_dbg(ieee->dev, "A-MSDU parse error!! Subframe Length: %d\n", nSubframe_Length);
+                               netdev_dbg(ieee->dev, "nRemain_Length is %d and nSubframe_Length is : %d\n", skb->len, nSubframe_Length);
+                               netdev_dbg(ieee->dev, "The Packet SeqNum is %d\n", SeqNum);
                                return 0;
                        }
 
@@ -904,8 +904,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
        stats = &ieee->stats;
 
        if (skb->len < 10) {
-               printk(KERN_INFO "%s: SKB length < 10\n",
-                      dev->name);
+               netdev_info(dev, "SKB length < 10\n");
                goto rx_dropped;
        }
 
@@ -919,7 +918,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 
        if (HTCCheck(ieee, skb->data)) {
                if (net_ratelimit())
-                       printk("find HTCControl\n");
+                       netdev_warn(dev, "find HTCControl\n");
                hdrlen += 4;
                rx_stats->bContainHTC = true;
        }
@@ -1113,7 +1112,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 
        if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
            (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0) {
-               printk("decrypt frame error\n");
+               netdev_dbg(ieee->dev, "decrypt frame error\n");
                goto rx_dropped;
        }
 
@@ -1141,9 +1140,8 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
                        flen -= hdrlen;
 
                if (frag_skb->tail + flen > frag_skb->end) {
-                       printk(KERN_WARNING "%s: host decrypted and "
-                              "reassembled frame did not fit skb\n",
-                              dev->name);
+                       netdev_warn(dev, "host decrypted and "
+                              "reassembled frame did not fit skb\n");
                        ieee80211_frag_cache_invalidate(ieee, hdr);
                        goto rx_dropped;
                }
@@ -1178,7 +1176,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
         * encrypted/authenticated */
        if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
            ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt)) {
-               printk("==>decrypt msdu error\n");
+               netdev_dbg(ieee->dev, "==>decrypt msdu error\n");
                goto rx_dropped;
        }
 
@@ -1250,7 +1248,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
                goto rx_dropped;
        /* to parse amsdu packets */
        /* qos data packets & reserved bit is 1 */
-       if (parse_subframe(skb, rx_stats, rxb, src, dst) == 0) {
+       if (parse_subframe(ieee, skb, rx_stats, rxb, src, dst) == 0) {
                /* only to free rxb, and not submit the packets to upper layer */
                for (i = 0; i < rxb->nr_subframes; i++) {
                        dev_kfree_skb(rxb->subframes[i]);
@@ -1863,7 +1861,7 @@ int ieee80211_parse_info_param(struct ieee80211_device *ieee,
                                info_element->data[0] == 0x00 &&
                                info_element->data[1] == 0x13 &&
                                info_element->data[2] == 0x74)) {
-                               printk("========>%s(): athros AP is exist\n", __func__);
+                               netdev_dbg(ieee->dev, "========> athros AP is exist\n");
                                network->atheros_cap_exist = true;
                        } else
                                network->atheros_cap_exist = false;
@@ -1980,8 +1978,8 @@ int ieee80211_parse_info_param(struct ieee80211_device *ieee,
                        }
                        break;
                case MFIE_TYPE_QOS_PARAMETER:
-                       printk(KERN_ERR
-                              "QoS Error need to parse QOS_PARAMETER IE\n");
+                       netdev_err(ieee->dev,
+                                  "QoS Error need to parse QOS_PARAMETER IE\n");
                        break;
 
                case MFIE_TYPE_COUNTRY:
@@ -2357,14 +2355,14 @@ static inline void ieee80211_process_probe_response(
                        if (IS_COUNTRY_IE_VALID(ieee)) {
                                // Case 1: Country code
                                if (!is_legal_channel(ieee, network->channel)) {
-                                       printk("GetScanInfo(): For Country code, filter probe response at channel(%d).\n", network->channel);
+                                       netdev_warn(ieee->dev, "GetScanInfo(): For Country code, filter probe response at channel(%d).\n", network->channel);
                                        goto out;
                                }
                        } else {
                                // Case 2: No any country code.
                                // Filter over channel ch12~14
                                if (network->channel > 11) {
-                                       printk("GetScanInfo(): For Global Domain, filter probe response at channel(%d).\n", network->channel);
+                                       netdev_warn(ieee->dev, "GetScanInfo(): For Global Domain, filter probe response at channel(%d).\n", network->channel);
                                        goto out;
                                }
                        }
@@ -2372,14 +2370,14 @@ static inline void ieee80211_process_probe_response(
                        if (IS_COUNTRY_IE_VALID(ieee)) {
                                // Case 1: Country code
                                if (!is_legal_channel(ieee, network->channel)) {
-                                       printk("GetScanInfo(): For Country code, filter beacon at channel(%d).\n", network->channel);
+                                       netdev_warn(ieee->dev, "GetScanInfo(): For Country code, filter beacon at channel(%d).\n", network->channel);
                                        goto out;
                                }
                        } else {
                                // Case 2: No any country code.
                                // Filter over channel ch12~14
                                if (network->channel > 14) {
-                                       printk("GetScanInfo(): For Global Domain, filter beacon at channel(%d).\n", network->channel);
+                                       netdev_warn(ieee->dev, "GetScanInfo(): For Global Domain, filter beacon at channel(%d).\n", network->channel);
                                        goto out;
                                }
                        }
index 482382a..89dd1fb 100644 (file)
@@ -60,7 +60,7 @@ double __extendsfdf2(float a)
 #include <linux/seq_file.h>
 /* FIXME: check if 2.6.7 is ok */
 
-#include "dot11d.h"
+#include "ieee80211/dot11d.h"
 /* set here to open your trace code. */
 u32 rt_global_debug_component = COMP_DOWN      |
                                COMP_SEC        |
@@ -3954,18 +3954,11 @@ static u8 rtl819x_query_rxpwrpercentage(s8 antpower)
 
 static u8 rtl819x_evm_dbtopercentage(s8 value)
 {
-       s8 ret_val;
+       s8 ret_val = clamp(-value, 0, 33) * 3;
 
-       ret_val = value;
-
-       if (ret_val >= 0)
-               ret_val = 0;
-       if (ret_val <= -33)
-               ret_val = -33;
-       ret_val = 0 - ret_val;
-       ret_val *= 3;
        if (ret_val == 99)
                ret_val = 100;
+
        return ret_val;
 }
 
index 5822bb7..0118edb 100644 (file)
@@ -23,7 +23,7 @@
 #include "r8192U.h"
 #include "r8192U_hw.h"
 
-#include "dot11d.h"
+#include "ieee80211/dot11d.h"
 #include "r8192U_wx.h"
 
 #define RATE_COUNT 12
index c04d8ec..555e525 100644 (file)
@@ -7,7 +7,7 @@
 #include "r8192U_dm.h"
 #include "r819xU_firmware_img.h"
 
-#include "dot11d.h"
+#include "ieee80211/dot11d.h"
 #include <linux/bitops.h>
 
 static u32 RF_CHANNEL_TABLE_ZEBRA[] = {
index 00ea0be..1167739 100644 (file)
@@ -663,17 +663,11 @@ static u8 evm_db2percentage(s8 value)
        /*
         * -33dB~0dB to 0%~99%
         */
-       s8 ret_val;
+       s8 ret_val = clamp(-value, 0, 33) * 3;
 
-       ret_val = value;
-       if (ret_val >= 0)
-               ret_val = 0;
-       if (ret_val <= -33)
-               ret_val = -33;
-       ret_val = -ret_val;
-       ret_val *= 3;
        if (ret_val == 99)
                ret_val = 100;
+
        return ret_val;
 }
 
index 5e687f6..c642825 100644 (file)
@@ -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));
index beb4002..357802d 100644 (file)
@@ -622,33 +622,3 @@ void ODM_TXPowerTrackingCallback_ThermalMeter(struct adapter *Adapter)
 
        pDM_Odm->RFCalibrateInfo.TXPowercount = 0;
 }
-
-
-
-
-/* 3 ============================================================ */
-/* 3 IQ Calibration */
-/* 3 ============================================================ */
-
-u8 ODM_GetRightChnlPlaceforIQK(u8 chnl)
-{
-       u8 channel_all[ODM_TARGET_CHNL_NUM_2G_5G] = {
-               1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
-               36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
-               60, 62, 64, 100, 102, 104, 106, 108, 110, 112,
-               114, 116, 118, 120, 122, 124, 126, 128, 130, 132,
-               134, 136, 138, 140, 149, 151, 153, 155, 157, 159,
-               161, 163, 165
-       };
-       u8 place = chnl;
-
-
-       if (chnl > 14) {
-               for (place = 14; place < sizeof(channel_all); place++) {
-                       if (channel_all[place] == chnl)
-                               return place-13;
-               }
-       }
-       return 0;
-
-}
index 3d6f68b..643fcf3 100644 (file)
@@ -44,12 +44,4 @@ void ODM_ClearTxPowerTrackingState(PDM_ODM_T pDM_Odm);
 
 void ODM_TXPowerTrackingCallback_ThermalMeter(struct adapter *Adapter);
 
-
-
-#define ODM_TARGET_CHNL_NUM_2G_5G 59
-
-
-u8 ODM_GetRightChnlPlaceforIQK(u8 chnl);
-
-
 #endif /*  #ifndef __HAL_PHY_RF_H__ */
index 1ca9063..85ea535 100644 (file)
@@ -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
@@ -1788,7 +1792,7 @@ void PHY_IQCalibrate_8723B(
        PDM_ODM_T pDM_Odm = &pHalData->odmpriv;
 
        s32 result[4][8];       /* last is final result */
-       u8 i, final_candidate, Indexforchannel;
+       u8 i, final_candidate;
        bool bPathAOK, bPathBOK;
        s32 RegE94, RegE9C, RegEA4, RegEAC, RegEB4, RegEBC, RegEC4, RegECC, RegTmp = 0;
        bool is12simular, is13simular, is23simular;
@@ -1993,17 +1997,14 @@ void PHY_IQCalibrate_8723B(
                        _PHY_PathBFillIQKMatrix8723B(padapter, bPathBOK, result, final_candidate, (RegEC4 == 0));
        }
 
-       Indexforchannel = ODM_GetRightChnlPlaceforIQK(pHalData->CurrentChannel);
-
 /* To Fix BSOD when final_candidate is 0xff */
 /* by sherry 20120321 */
        if (final_candidate < 4) {
                for (i = 0; i < IQK_Matrix_REG_NUM; i++)
-                       pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[Indexforchannel].Value[0][i] = result[final_candidate][i];
-               pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[Indexforchannel].bIQKDone = true;
+                       pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[0].Value[0][i] = result[final_candidate][i];
+               pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[0].bIQKDone = true;
        }
-       /* RT_DISP(FINIT, INIT_IQK, ("\nIQK OK Indexforchannel %d.\n", Indexforchannel)); */
-       ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,  ("\nIQK OK Indexforchannel %d.\n", Indexforchannel));
+       ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,  ("\nIQK OK Indexforchannel %d.\n", 0));
 
        _PHY_SaveADDARegisters8723B(padapter, IQK_BB_REG_92C, pDM_Odm->RFCalibrateInfo.IQK_BB_backup_recover, 9);
 
index 66127f6..de8caa6 100644 (file)
@@ -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)
index 6a934c4..3c9e979 100644 (file)
@@ -1,7 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_RTS5208) := rts5208.o
 
-ccflags-y := -Idrivers/scsi
-
 rts5208-y := rtsx.o rtsx_chip.o rtsx_transport.o rtsx_scsi.o \
        rtsx_card.o general.o sd.o xd.o ms.o spi.o
index fbb42e5..be0053c 100644 (file)
@@ -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 */
index afe43fa..54d9e2f 100644 (file)
@@ -13,5 +13,5 @@ vchiq-objs := \
 obj-$(CONFIG_SND_BCM2835)      += bcm2835-audio/
 obj-$(CONFIG_VIDEO_BCM2835)    += bcm2835-camera/
 
-ccflags-y += -Idrivers/staging/vc04_services -D__VCCOREVER__=0x04000000
+ccflags-y += -D__VCCOREVER__=0x04000000
 
index 826016c..3348518 100644 (file)
@@ -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)
index beb6a00..1ef31a9 100644 (file)
@@ -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",
index 56b1037..ff2b960 100644 (file)
@@ -4,8 +4,8 @@
 #ifndef VCHI_H_
 #define VCHI_H_
 
-#include "interface/vchi/vchi_cfg.h"
-#include "interface/vchi/vchi_common.h"
+#include "vchi_cfg.h"
+#include "vchi_common.h"
 
 /******************************************************************************
  * Global defs
index 0ce3b08..efdd3b1 100644 (file)
@@ -3,7 +3,7 @@
 #include <linux/module.h>
 #include <linux/types.h>
 
-#include "interface/vchi/vchi.h"
+#include "../vchi/vchi.h"
 #include "vchiq.h"
 #include "vchiq_core.h"
 
index fb2855e..d6ca6e5 100644 (file)
@@ -758,7 +758,7 @@ bool RFvWriteWakeProgSyn(struct vnt_private *priv, unsigned char byRFType,
  */
 bool RFbSetPower(struct vnt_private *priv, unsigned int rate, u16 uCH)
 {
-       bool ret = true;
+       bool ret;
        unsigned char byPwr = 0;
        unsigned char byDec = 0;
 
index 4e651b6..f18e059 100644 (file)
@@ -381,8 +381,8 @@ int vnt_vt3184_init(struct vnt_private *priv)
 
        dev_dbg(&priv->usb->dev, "RF Type %d\n", priv->rf_type);
 
-       if ((priv->rf_type == RF_AL2230) ||
-           (priv->rf_type == RF_AL2230S)) {
+       if (priv->rf_type == RF_AL2230 ||
+           priv->rf_type == RF_AL2230S) {
                priv->bb_rx_conf = vnt_vt3184_al2230[10];
                length = sizeof(vnt_vt3184_al2230);
                addr = vnt_vt3184_al2230;
@@ -461,8 +461,8 @@ int vnt_vt3184_init(struct vnt_private *priv)
        if (ret)
                goto end;
 
-       if ((priv->rf_type == RF_VT3226) ||
-           (priv->rf_type == RF_VT3342A0)) {
+       if (priv->rf_type == RF_VT3226 ||
+           priv->rf_type == RF_VT3342A0) {
                ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_MACREG,
                                         MAC_REG_ITRTMSET, 0x23);
                if (ret)
index 50e1c89..fe6c112 100644 (file)
@@ -52,6 +52,8 @@
 #define RATE_AUTO      12
 
 #define MAX_RATE                       12
+#define VNT_B_RATES    (BIT(RATE_1M) | BIT(RATE_2M) |\
+                       BIT(RATE_5M) | BIT(RATE_11M))
 
 /*
  * device specific
@@ -204,6 +206,22 @@ enum {
        CONTEXT_BEACON_PACKET
 };
 
+struct vnt_rx_header {
+       u32 wbk_status;
+       u8 rx_sts;
+       u8 rx_rate;
+       u16 pay_load_len;
+} __packed;
+
+struct vnt_rx_tail {
+       __le64 tsf_time;
+       u8 sq;
+       u8 new_rsr;
+       u8 rssi;
+       u8 rsr;
+       u8 sq_3;
+} __packed;
+
 /* RCB (Receive Control Block) */
 struct vnt_rcb {
        void *priv;
@@ -262,7 +280,6 @@ struct vnt_private {
        struct usb_interface *intf;
 
        u64 tsf_time;
-       u8 rx_rate;
 
        u32 rx_buf_sz;
        int mc_list_count;
index 3b94e80..821aae8 100644 (file)
@@ -29,27 +29,21 @@ int vnt_rx_data(struct vnt_private *priv, struct vnt_rcb *ptr_rcb,
        struct ieee80211_hw *hw = priv->hw;
        struct ieee80211_supported_band *sband;
        struct sk_buff *skb;
-       struct ieee80211_rx_status rx_status = { 0 };
-       struct ieee80211_hdr *hdr;
-       __le16 fc;
-       u8 *rsr, *new_rsr, *rssi;
-       __le64 *tsf_time;
+       struct ieee80211_rx_status *rx_status;
+       struct vnt_rx_header *head;
+       struct vnt_rx_tail *tail;
        u32 frame_size;
-       int ii, r;
-       u8 *rx_rate, *sq, *sq_3;
-       u32 wbk_status;
-       u8 *skb_data;
-       u16 *pay_load_len;
-       u16 pay_load_with_padding;
+       int ii;
+       u16 rx_bitrate, pay_load_with_padding;
        u8 rate_idx = 0;
-       u8 rate[MAX_RATE] = {2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108};
        long rx_dbm;
 
        skb = ptr_rcb->skb;
+       rx_status = IEEE80211_SKB_RXCB(skb);
 
        /* [31:16]RcvByteCount ( not include 4-byte Status ) */
-       wbk_status = *((u32 *)(skb->data));
-       frame_size = wbk_status >> 16;
+       head = (struct vnt_rx_header *)skb->data;
+       frame_size = head->wbk_status >> 16;
        frame_size += 4;
 
        if (bytes_received != frame_size) {
@@ -63,106 +57,66 @@ int vnt_rx_data(struct vnt_private *priv, struct vnt_rcb *ptr_rcb,
                return false;
        }
 
-       skb_data = (u8 *)skb->data;
-
-       rx_rate = skb_data + 5;
-
        /* real Frame Size = USBframe_size -4WbkStatus - 4RxStatus */
        /* -8TSF - 4RSR - 4SQ3 - ?Padding */
 
        /* if SQ3 the range is 24~27, if no SQ3 the range is 20~23 */
 
-       pay_load_len = (u16 *)(skb_data + 6);
-
        /*Fix hardware bug => PLCP_Length error */
-       if (((bytes_received - (*pay_load_len)) > 27) ||
-           ((bytes_received - (*pay_load_len)) < 24) ||
-           (bytes_received < (*pay_load_len))) {
+       if (((bytes_received - head->pay_load_len) > 27) ||
+           ((bytes_received - head->pay_load_len) < 24) ||
+           (bytes_received < head->pay_load_len)) {
                dev_dbg(&priv->usb->dev, "Wrong PLCP Length %x\n",
-                       *pay_load_len);
+                       head->pay_load_len);
                return false;
        }
 
        sband = hw->wiphy->bands[hw->conf.chandef.chan->band];
-
-       for (r = RATE_1M; r < MAX_RATE; r++) {
-               if (*rx_rate == rate[r])
-                       break;
-       }
-
-       priv->rx_rate = r;
+       rx_bitrate = head->rx_rate * 5; /* rx_rate * 5 */
 
        for (ii = 0; ii < sband->n_bitrates; ii++) {
-               if (sband->bitrates[ii].hw_value == r) {
+               if (sband->bitrates[ii].bitrate == rx_bitrate) {
                        rate_idx = ii;
                                break;
                }
        }
 
        if (ii == sband->n_bitrates) {
-               dev_dbg(&priv->usb->dev, "Wrong RxRate %x\n", *rx_rate);
+               dev_dbg(&priv->usb->dev, "Wrong Rx Bit Rate %d\n", rx_bitrate);
                return false;
        }
 
-       pay_load_with_padding = ((*pay_load_len / 4) +
-               ((*pay_load_len % 4) ? 1 : 0)) * 4;
-
-       tsf_time = (__le64 *)(skb_data + 8 + pay_load_with_padding);
-
-       priv->tsf_time = le64_to_cpu(*tsf_time);
+       pay_load_with_padding = ((head->pay_load_len / 4) +
+               ((head->pay_load_len % 4) ? 1 : 0)) * 4;
 
-       if (priv->bb_type == BB_TYPE_11G) {
-               sq_3 = skb_data + 8 + pay_load_with_padding + 12;
-               sq = sq_3;
-       } else {
-               sq = skb_data + 8 + pay_load_with_padding + 8;
-               sq_3 = sq;
-       }
-
-       new_rsr = skb_data + 8 + pay_load_with_padding + 9;
-       rssi = skb_data + 8 + pay_load_with_padding + 10;
+       tail = (struct vnt_rx_tail *)(skb->data +
+                                     sizeof(*head) + pay_load_with_padding);
+       priv->tsf_time = le64_to_cpu(tail->tsf_time);
 
-       rsr = skb_data + 8 + pay_load_with_padding + 11;
-       if (*rsr & (RSR_IVLDTYP | RSR_IVLDLEN))
+       if (tail->rsr & (RSR_IVLDTYP | RSR_IVLDLEN))
                return false;
 
-       frame_size = *pay_load_len;
-
-       vnt_rf_rssi_to_dbm(priv, *rssi, &rx_dbm);
+       vnt_rf_rssi_to_dbm(priv, tail->rssi, &rx_dbm);
 
        priv->bb_pre_ed_rssi = (u8)rx_dbm + 1;
        priv->current_rssi = priv->bb_pre_ed_rssi;
 
-       skb_pull(skb, 8);
-       skb_trim(skb, frame_size);
-
-       rx_status.mactime = priv->tsf_time;
-       rx_status.band = hw->conf.chandef.chan->band;
-       rx_status.signal = rx_dbm;
-       rx_status.flag = 0;
-       rx_status.freq = hw->conf.chandef.chan->center_freq;
+       skb_pull(skb, sizeof(*head));
+       skb_trim(skb, head->pay_load_len);
 
-       if (!(*rsr & RSR_CRCOK))
-               rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
+       rx_status->mactime = priv->tsf_time;
+       rx_status->band = hw->conf.chandef.chan->band;
+       rx_status->signal = rx_dbm;
+       rx_status->flag = 0;
+       rx_status->freq = hw->conf.chandef.chan->center_freq;
 
-       hdr = (struct ieee80211_hdr *)(skb->data);
-       fc = hdr->frame_control;
+       if (!(tail->rsr & RSR_CRCOK))
+               rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
 
-       rx_status.rate_idx = rate_idx;
-
-       if (ieee80211_has_protected(fc)) {
-               if (priv->local_id > REV_ID_VT3253_A1) {
-                       rx_status.flag |= RX_FLAG_DECRYPTED;
-
-                       /* Drop packet */
-                       if (!(*new_rsr & NEWRSR_DECRYPTOK)) {
-                               dev_kfree_skb(skb);
-                               return true;
-                       }
-               }
-       }
+       rx_status->rate_idx = rate_idx;
 
-       memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
+       if (tail->new_rsr & NEWRSR_DECRYPTOK)
+               rx_status->flag |= RX_FLAG_DECRYPTED;
 
        ieee80211_rx_irqsafe(priv->hw, skb);
 
index 60a00af..70358d4 100644 (file)
@@ -30,7 +30,6 @@ int vnt_download_firmware(struct vnt_private *priv)
 {
        struct device *dev = &priv->usb->dev;
        const struct firmware *fw;
-       void *buffer = NULL;
        u16 length;
        int ii;
        int ret = 0;
@@ -44,26 +43,17 @@ int vnt_download_firmware(struct vnt_private *priv)
                goto end;
        }
 
-       buffer = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL);
-       if (!buffer) {
-               ret = -ENOMEM;
-               goto free_fw;
-       }
-
        for (ii = 0; ii < fw->size; ii += FIRMWARE_CHUNK_SIZE) {
                length = min_t(int, fw->size - ii, FIRMWARE_CHUNK_SIZE);
-               memcpy(buffer, fw->data + ii, length);
 
                ret = vnt_control_out(priv, 0, 0x1200 + ii, 0x0000, length,
-                                     buffer);
+                                     fw->data + ii);
                if (ret)
-                       goto free_buffer;
+                       goto free_fw;
 
                dev_dbg(dev, "Download firmware...%d %zu\n", ii, fw->size);
        }
 
-free_buffer:
-       kfree(buffer);
 free_fw:
        release_firmware(fw);
 end:
index f409479..af21586 100644 (file)
@@ -99,9 +99,11 @@ static int vnt_int_report_rate(struct vnt_private *priv, u8 pkt_no, u8 tsr)
 
        info->status.rates[0].count = tx_retry;
 
-       if (!(tsr & (TSR_TMO | TSR_RETRYTMO))) {
+       if (!(tsr & TSR_TMO)) {
                info->status.rates[0].idx = idx;
-               info->flags |= IEEE80211_TX_STAT_ACK;
+
+               if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
+                       info->flags |= IEEE80211_TX_STAT_ACK;
        }
 
        ieee80211_tx_status_irqsafe(priv->hw, context->skb);
index 9cb924c..5e48b3d 100644 (file)
@@ -1015,6 +1015,7 @@ vt6656_probe(struct usb_interface *intf, const struct usb_device_id *id)
        ieee80211_hw_set(priv->hw, RX_INCLUDES_FCS);
        ieee80211_hw_set(priv->hw, REPORTS_TX_ACK_STATUS);
        ieee80211_hw_set(priv->hw, SUPPORTS_PS);
+       ieee80211_hw_set(priv->hw, PS_NULLFUNC_STACK);
 
        priv->hw->max_signal = 100;
 
index f9020a4..29caba7 100644 (file)
@@ -278,11 +278,9 @@ static u16 vnt_rxtx_datahead_g(struct vnt_usb_send_context *tx_context,
                          PK_TYPE_11B, &buf->b);
 
        /* Get Duration and TimeStamp */
-       if (ieee80211_is_pspoll(hdr->frame_control)) {
-               __le16 dur = cpu_to_le16(priv->current_aid | BIT(14) | BIT(15));
-
-               buf->duration_a = dur;
-               buf->duration_b = dur;
+       if (ieee80211_is_nullfunc(hdr->frame_control)) {
+               buf->duration_a = hdr->duration_id;
+               buf->duration_b = hdr->duration_id;
        } else {
                buf->duration_a = vnt_get_duration_le(priv,
                                                tx_context->pkt_type, need_ack);
@@ -371,10 +369,8 @@ static u16 vnt_rxtx_datahead_ab(struct vnt_usb_send_context *tx_context,
                          tx_context->pkt_type, &buf->ab);
 
        /* Get Duration and TimeStampOff */
-       if (ieee80211_is_pspoll(hdr->frame_control)) {
-               __le16 dur = cpu_to_le16(priv->current_aid | BIT(14) | BIT(15));
-
-               buf->duration = dur;
+       if (ieee80211_is_nullfunc(hdr->frame_control)) {
+               buf->duration = hdr->duration_id;
        } else {
                buf->duration = vnt_get_duration_le(priv, tx_context->pkt_type,
                                                    need_ack);
@@ -815,10 +811,14 @@ int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb)
                if (info->band == NL80211_BAND_5GHZ) {
                        pkt_type = PK_TYPE_11A;
                } else {
-                       if (tx_rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
-                               pkt_type = PK_TYPE_11GB;
-                       else
-                               pkt_type = PK_TYPE_11GA;
+                       if (tx_rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
+                               if (priv->basic_rates & VNT_B_RATES)
+                                       pkt_type = PK_TYPE_11GB;
+                               else
+                                       pkt_type = PK_TYPE_11GA;
+                       } else {
+                               pkt_type = PK_TYPE_11A;
+                       }
                }
        } else {
                pkt_type = PK_TYPE_11B;
index d977d47..7bfccc4 100644 (file)
@@ -34,7 +34,7 @@
 #define USB_CTL_WAIT   500 /* ms */
 
 int vnt_control_out(struct vnt_private *priv, u8 request, u16 value,
-                   u16 index, u16 length, u8 *buffer)
+                   u16 index, u16 length, const u8 *buffer)
 {
        int ret = 0;
        u8 *usb_buffer;
index b65d9c0..4e3341b 100644 (file)
@@ -21,7 +21,7 @@
 #define VNT_REG_BLOCK_SIZE     64
 
 int vnt_control_out(struct vnt_private *priv, u8 request, u16 value,
-                   u16 index, u16 length, u8 *buffer);
+                   u16 index, u16 length, const u8 *buffer);
 int vnt_control_in(struct vnt_private *priv, u8 request, u16 value,
                   u16 index, u16 length,  u8 *buffer);
 
index e447722..efcb7c6 100644 (file)
@@ -1,17 +1,60 @@
 This is a list of things that need to be done to get this driver out of the
 staging directory.
 
-  - I have to take a decision about secure link support. I can:
-      - drop completely
-      - keep it in an external patch (my preferred option)
-      - replace call to mbedtls with kernel crypto API (necessitate a
-        bunch of work)
-      - pull mbedtls in kernel (non-realistic)
-
-  - mac80211 interface does not (yet) have expected quality to be placed
-    outside of staging:
-      - Some processings are redundant with mac80211 ones
-      - Many members from wfx_dev/wfx_vif can be retrieved from mac80211
-        structures
-      - Some functions are too complex
-      - ...
+  - All structures defined in hif_api_*.h are intended to sent/received to/from
+    hardware. All their members whould be declared __le32 or __le16.
+    See:
+       https://lore.kernel.org/lkml/20191111202852.GX26530@ZenIV.linux.org.uk
+
+  - Once previous item done, it will be possible to audit the driver with
+    `sparse'. It will probably find tons of problems with big endian
+    architectures.
+
+  - hif_api_*.h whave been imported from firmware code. Some of the structures
+    are never used in driver.
+
+  - Driver try to maintains power save status of the stations. However, this
+    work is already done by mac80211. sta_asleep_mask and pspoll_mask should be
+    dropped.
+
+  - wfx_tx_queues_get() should be reworked. It currently try compute itself the
+    QoS policy. However, firmware already do the job. Firmware would prefer to
+    have a few packets in each queue and be able to choose itself which queue to
+    use.
+
+  - As suggested by Felix, rate control could be improved following this idea:
+        https://lore.kernel.org/lkml/3099559.gv3Q75KnN1@pc-42/
+
+  - When driver is about to loose BSS, it forge its own Null Func request (see
+    wfx_cqm_bssloss_sm()). It should use mechanism provided by mac80211.
+
+  - AP is actually is setup after a call to wfx_bss_info_changed(). Yet,
+    ieee80211_ops provide callback start_ap().
+
+  - The current process for joining a network is incredibly complex. Should be
+    reworked.
+
+  - Monitoring mode is not implemented despite being mandatory by mac80211.
+
+  - "compatible" value are not correct. They should be "vendor,chip". See:
+       https://lore.kernel.org/driverdev-devel/5226570.CMH5hVlZcI@pc-42
+
+  - The "state" field from wfx_vif should be replaced by "vif->type".
+
+  - It seems that wfx_upload_keys() is useless.
+
+  - "event_queue" from wfx_vif seems overkill. These event are rare and they
+     probably could be handled in a simpler fashion.
+
+  - Feature called "secure link" should be either developed (using kernel
+    crypto API) or dropped.
+
+  - In wfx_cmd_send(), "async" allow to send command without waiting the reply.
+    It may help in some situation, but it is not yet used. In add, it may cause
+    some trouble:
+      https://lore.kernel.org/driverdev-devel/alpine.DEB.2.21.1910041317381.2992@hadrien/
+    So, fix it (by replacing the mutex with a semaphore) or drop it.
+
+  - Chip support P2P, but driver does not implement it.
+
+  - Chip support kind of Mesh, but driver does not implement it.
index 2432ba9..983c41d 100644 (file)
@@ -271,8 +271,7 @@ static void bh_work(struct work_struct *work)
 
        if (last_op_is_rx)
                ack_sdio_data(wdev);
-       if (!wdev->hif.tx_buffers_used && !work_pending(work) &&
-           !atomic_read(&wdev->scan_in_progress)) {
+       if (!wdev->hif.tx_buffers_used && !work_pending(work)) {
                device_release(wdev);
                release_chip = true;
        }
index ab0cda1..40bc330 100644 (file)
@@ -107,6 +107,8 @@ static int wfx_spi_copy_to_io(void *priv, unsigned int addr,
 
        cpu_to_le16s(&regaddr);
 
+       // Register address and CONFIG content always use 16bit big endian
+       // ("BADC" order)
        if (bus->need_swab)
                swab16s(&regaddr);
        if (bus->need_swab && addr == WFX_REG_CONFIG)
@@ -183,7 +185,7 @@ static int wfx_spi_probe(struct spi_device *func)
        if (func->bits_per_word != 16 && func->bits_per_word != 8)
                dev_warn(&func->dev, "unusual bits/word value: %d\n",
                         func->bits_per_word);
-       if (func->max_speed_hz > 49000000)
+       if (func->max_speed_hz > 50000000)
                dev_warn(&func->dev, "%dHz is a very high speed\n",
                         func->max_speed_hz);
 
@@ -223,8 +225,7 @@ static int wfx_spi_probe(struct spi_device *func)
        return ret;
 }
 
-/* Disconnect Function to be called by SPI stack when device is disconnected */
-static int wfx_spi_disconnect(struct spi_device *func)
+static int wfx_spi_remove(struct spi_device *func)
 {
        struct wfx_spi_priv *bus = spi_get_drvdata(func);
 
@@ -263,5 +264,5 @@ struct spi_driver wfx_spi_driver = {
        },
        .id_table = wfx_spi_id,
        .probe = wfx_spi_probe,
-       .remove = wfx_spi_disconnect,
+       .remove = wfx_spi_remove,
 };
index e7fcce8..5d19845 100644 (file)
 #include "bh.h"
 #include "sta.h"
 
-static int wfx_handle_pspoll(struct wfx_vif *wvif, struct sk_buff *skb)
-{
-       struct ieee80211_sta *sta;
-       struct ieee80211_pspoll *pspoll = (struct ieee80211_pspoll *)skb->data;
-       int link_id = 0;
-       u32 pspoll_mask = 0;
-       int i;
-
-       if (wvif->state != WFX_STATE_AP)
-               return 1;
-       if (!ether_addr_equal(wvif->vif->addr, pspoll->bssid))
-               return 1;
-
-       rcu_read_lock();
-       sta = ieee80211_find_sta(wvif->vif, pspoll->ta);
-       if (sta)
-               link_id = ((struct wfx_sta_priv *)&sta->drv_priv)->link_id;
-       rcu_read_unlock();
-       if (link_id)
-               pspoll_mask = BIT(link_id);
-       else
-               return 1;
-
-       wvif->pspoll_mask |= pspoll_mask;
-       /* Do not report pspols if data for given link id is queued already. */
-       for (i = 0; i < IEEE80211_NUM_ACS; ++i) {
-               if (wfx_tx_queue_get_num_queued(&wvif->wdev->tx_queue[i],
-                                               pspoll_mask)) {
-                       wfx_bh_request_tx(wvif->wdev);
-                       return 1;
-               }
-       }
-       return 0;
-}
-
-static int wfx_drop_encrypt_data(struct wfx_dev *wdev, struct hif_ind_rx *arg, struct sk_buff *skb)
+static int wfx_drop_encrypt_data(struct wfx_dev *wdev,
+                                const struct hif_ind_rx *arg,
+                                struct sk_buff *skb)
 {
        struct ieee80211_hdr *frame = (struct ieee80211_hdr *) skb->data;
        size_t hdrlen = ieee80211_hdrlen(frame->frame_control);
@@ -98,15 +65,12 @@ static int wfx_drop_encrypt_data(struct wfx_dev *wdev, struct hif_ind_rx *arg, s
 
 }
 
-void wfx_rx_cb(struct wfx_vif *wvif, struct hif_ind_rx *arg,
-              struct sk_buff *skb)
+void wfx_rx_cb(struct wfx_vif *wvif,
+              const struct hif_ind_rx *arg, struct sk_buff *skb)
 {
-       int link_id = arg->rx_flags.peer_sta_id;
        struct ieee80211_rx_status *hdr = IEEE80211_SKB_RXCB(skb);
        struct ieee80211_hdr *frame = (struct ieee80211_hdr *)skb->data;
        struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
-       struct wfx_link_entry *entry = NULL;
-       bool early_data = false;
 
        memset(hdr, 0, sizeof(*hdr));
 
@@ -116,14 +80,6 @@ void wfx_rx_cb(struct wfx_vif *wvif, struct hif_ind_rx *arg,
             ieee80211_is_beacon(frame->frame_control)))
                goto drop;
 
-       if (link_id && link_id <= WFX_MAX_STA_IN_AP_MODE) {
-               entry = &wvif->link_id_db[link_id - 1];
-               entry->timestamp = jiffies;
-               if (entry->status == WFX_LINK_SOFT &&
-                   ieee80211_is_data(frame->frame_control))
-                       early_data = true;
-       }
-
        if (arg->status == HIF_STATUS_MICFAILURE)
                hdr->flag |= RX_FLAG_MMIC_ERROR;
        else if (arg->status)
@@ -134,10 +90,6 @@ void wfx_rx_cb(struct wfx_vif *wvif, struct hif_ind_rx *arg,
                goto drop;
        }
 
-       if (ieee80211_is_pspoll(frame->frame_control))
-               if (wfx_handle_pspoll(wvif, skb))
-                       goto drop;
-
        hdr->band = NL80211_BAND_2GHZ;
        hdr->freq = ieee80211_channel_to_frequency(arg->channel_number,
                                                   hdr->band);
@@ -171,20 +123,6 @@ void wfx_rx_cb(struct wfx_vif *wvif, struct hif_ind_rx *arg,
            !arg->status && wvif->vif &&
            ether_addr_equal(ieee80211_get_SA(frame),
                             wvif->vif->bss_conf.bssid)) {
-               const u8 *tim_ie;
-               u8 *ies = mgmt->u.beacon.variable;
-               size_t ies_len = skb->len - (ies - skb->data);
-
-               tim_ie = cfg80211_find_ie(WLAN_EID_TIM, ies, ies_len);
-               if (tim_ie) {
-                       struct ieee80211_tim_ie *tim = (struct ieee80211_tim_ie *)&tim_ie[2];
-
-                       if (wvif->dtim_period != tim->dtim_period) {
-                               wvif->dtim_period = tim->dtim_period;
-                               schedule_work(&wvif->set_beacon_wakeup_period_work);
-                       }
-               }
-
                /* Disable beacon filter once we're associated... */
                if (wvif->disable_beacon_filter &&
                    (wvif->vif->bss_conf.assoc ||
@@ -193,18 +131,7 @@ void wfx_rx_cb(struct wfx_vif *wvif, struct hif_ind_rx *arg,
                        schedule_work(&wvif->update_filtering_work);
                }
        }
-
-       if (early_data) {
-               spin_lock_bh(&wvif->ps_state_lock);
-               /* Double-check status with lock held */
-               if (entry->status == WFX_LINK_SOFT)
-                       skb_queue_tail(&entry->rx_queue, skb);
-               else
-                       ieee80211_rx_irqsafe(wvif->wdev->hw, skb);
-               spin_unlock_bh(&wvif->ps_state_lock);
-       } else {
-               ieee80211_rx_irqsafe(wvif->wdev->hw, skb);
-       }
+       ieee80211_rx_irqsafe(wvif->wdev->hw, skb);
 
        return;
 
index a50ce35..61c28bf 100644 (file)
@@ -13,7 +13,7 @@
 struct wfx_vif;
 struct sk_buff;
 
-void wfx_rx_cb(struct wfx_vif *wvif, struct hif_ind_rx *arg,
-              struct sk_buff *skb);
+void wfx_rx_cb(struct wfx_vif *wvif,
+              const struct hif_ind_rx *arg, struct sk_buff *skb);
 
 #endif /* WFX_DATA_RX_H */
index b13d734..20f4740 100644 (file)
@@ -17,7 +17,6 @@
 #include "hif_tx_mib.h"
 
 #define WFX_INVALID_RATE_ID    15
-#define WFX_LINK_ID_NO_ASSOC   15
 #define WFX_LINK_ID_GC_TIMEOUT ((unsigned long)(10 * HZ))
 
 static int wfx_get_hw_rate(struct wfx_dev *wdev,
@@ -169,7 +168,8 @@ static int wfx_tx_policy_get(struct wfx_vif *wvif,
        wfx_tx_policy_build(wvif, &wanted, rates);
 
        spin_lock_bh(&cache->lock);
-       if (WARN_ON(list_empty(&cache->free))) {
+       if (list_empty(&cache->free)) {
+               WARN(1, "unable to get a valid Tx policy");
                spin_unlock_bh(&cache->lock);
                return WFX_INVALID_RATE_ID;
        }
@@ -216,38 +216,25 @@ static void wfx_tx_policy_put(struct wfx_vif *wvif, int idx)
 
 static int wfx_tx_policy_upload(struct wfx_vif *wvif)
 {
+       struct tx_policy *policies = wvif->tx_policy_cache.cache;
+       u8 tmp_rates[12];
        int i;
-       struct tx_policy_cache *cache = &wvif->tx_policy_cache;
-       struct hif_mib_set_tx_rate_retry_policy *arg =
-               kzalloc(struct_size(arg,
-                                   tx_rate_retry_policy,
-                                   HIF_MIB_NUM_TX_RATE_RETRY_POLICIES),
-                       GFP_KERNEL);
-       struct hif_mib_tx_rate_retry_policy *dst;
 
-       spin_lock_bh(&cache->lock);
-       /* Upload only modified entries. */
-       for (i = 0; i < HIF_MIB_NUM_TX_RATE_RETRY_POLICIES; ++i) {
-               struct tx_policy *src = &cache->cache[i];
-
-               if (!src->uploaded && memzcmp(src->rates, sizeof(src->rates))) {
-                       dst = arg->tx_rate_retry_policy +
-                               arg->num_tx_rate_policies;
-
-                       dst->policy_index = i;
-                       dst->short_retry_count = 255;
-                       dst->long_retry_count = 255;
-                       dst->first_rate_sel = 1;
-                       dst->terminate = 1;
-                       dst->count_init = 1;
-                       memcpy(&dst->rates, src->rates, sizeof(src->rates));
-                       src->uploaded = true;
-                       arg->num_tx_rate_policies++;
+       do {
+               spin_lock_bh(&wvif->tx_policy_cache.lock);
+               for (i = 0; i < HIF_MIB_NUM_TX_RATE_RETRY_POLICIES; ++i)
+                       if (!policies[i].uploaded &&
+                           memzcmp(policies[i].rates, sizeof(policies[i].rates)))
+                               break;
+               if (i < HIF_MIB_NUM_TX_RATE_RETRY_POLICIES) {
+                       policies[i].uploaded = 1;
+                       memcpy(tmp_rates, policies[i].rates, sizeof(tmp_rates));
+                       spin_unlock_bh(&wvif->tx_policy_cache.lock);
+                       hif_set_tx_rate_retry_policy(wvif, i, tmp_rates);
+               } else {
+                       spin_unlock_bh(&wvif->tx_policy_cache.lock);
                }
-       }
-       spin_unlock_bh(&cache->lock);
-       hif_set_tx_rate_retry_policy(wvif, arg);
-       kfree(arg);
+       } while (i < HIF_MIB_NUM_TX_RATE_RETRY_POLICIES);
        return 0;
 }
 
@@ -277,164 +264,6 @@ void wfx_tx_policy_init(struct wfx_vif *wvif)
                list_add(&cache->cache[i].link, &cache->free);
 }
 
-/* Link ID related functions */
-
-static int wfx_alloc_link_id(struct wfx_vif *wvif, const u8 *mac)
-{
-       int i, ret = 0;
-       unsigned long max_inactivity = 0;
-       unsigned long now = jiffies;
-
-       spin_lock_bh(&wvif->ps_state_lock);
-       for (i = 0; i < WFX_MAX_STA_IN_AP_MODE; ++i) {
-               if (!wvif->link_id_db[i].status) {
-                       ret = i + 1;
-                       break;
-               } else if (wvif->link_id_db[i].status != WFX_LINK_HARD &&
-                          !wvif->wdev->tx_queue_stats.link_map_cache[i + 1]) {
-                       unsigned long inactivity =
-                               now - wvif->link_id_db[i].timestamp;
-
-                       if (inactivity < max_inactivity)
-                               continue;
-                       max_inactivity = inactivity;
-                       ret = i + 1;
-               }
-       }
-
-       if (ret) {
-               struct wfx_link_entry *entry = &wvif->link_id_db[ret - 1];
-
-               entry->status = WFX_LINK_RESERVE;
-               ether_addr_copy(entry->mac, mac);
-               memset(&entry->buffered, 0, WFX_MAX_TID);
-               skb_queue_head_init(&entry->rx_queue);
-               wfx_tx_lock(wvif->wdev);
-
-               if (!schedule_work(&wvif->link_id_work))
-                       wfx_tx_unlock(wvif->wdev);
-       } else {
-               dev_info(wvif->wdev->dev, "no more link-id available\n");
-       }
-       spin_unlock_bh(&wvif->ps_state_lock);
-       return ret;
-}
-
-int wfx_find_link_id(struct wfx_vif *wvif, const u8 *mac)
-{
-       int i, ret = 0;
-
-       spin_lock_bh(&wvif->ps_state_lock);
-       for (i = 0; i < WFX_MAX_STA_IN_AP_MODE; ++i) {
-               if (ether_addr_equal(mac, wvif->link_id_db[i].mac) &&
-                   wvif->link_id_db[i].status) {
-                       wvif->link_id_db[i].timestamp = jiffies;
-                       ret = i + 1;
-                       break;
-               }
-       }
-       spin_unlock_bh(&wvif->ps_state_lock);
-       return ret;
-}
-
-static int wfx_map_link(struct wfx_vif *wvif,
-                       struct wfx_link_entry *link_entry, int sta_id)
-{
-       int ret;
-
-       ret = hif_map_link(wvif, link_entry->mac, 0, sta_id);
-
-       if (ret == 0)
-               /* Save the MAC address currently associated with the peer
-                * for future unmap request
-                */
-               ether_addr_copy(link_entry->old_mac, link_entry->mac);
-
-       return ret;
-}
-
-int wfx_unmap_link(struct wfx_vif *wvif, int sta_id)
-{
-       u8 *mac_addr = NULL;
-
-       if (sta_id)
-               mac_addr = wvif->link_id_db[sta_id - 1].old_mac;
-
-       return hif_map_link(wvif, mac_addr, 1, sta_id);
-}
-
-void wfx_link_id_gc_work(struct work_struct *work)
-{
-       struct wfx_vif *wvif =
-               container_of(work, struct wfx_vif, link_id_gc_work.work);
-       unsigned long now = jiffies;
-       unsigned long next_gc = -1;
-       long ttl;
-       u32 mask;
-       int i;
-
-       if (wvif->state != WFX_STATE_AP)
-               return;
-
-       wfx_tx_lock_flush(wvif->wdev);
-       spin_lock_bh(&wvif->ps_state_lock);
-       for (i = 0; i < WFX_MAX_STA_IN_AP_MODE; ++i) {
-               bool need_reset = false;
-
-               mask = BIT(i + 1);
-               if (wvif->link_id_db[i].status == WFX_LINK_RESERVE ||
-                   (wvif->link_id_db[i].status == WFX_LINK_HARD &&
-                    !(wvif->link_id_map & mask))) {
-                       if (wvif->link_id_map & mask) {
-                               wvif->sta_asleep_mask &= ~mask;
-                               wvif->pspoll_mask &= ~mask;
-                               need_reset = true;
-                       }
-                       wvif->link_id_map |= mask;
-                       if (wvif->link_id_db[i].status != WFX_LINK_HARD)
-                               wvif->link_id_db[i].status = WFX_LINK_SOFT;
-
-                       spin_unlock_bh(&wvif->ps_state_lock);
-                       if (need_reset)
-                               wfx_unmap_link(wvif, i + 1);
-                       wfx_map_link(wvif, &wvif->link_id_db[i], i + 1);
-                       next_gc = min(next_gc, WFX_LINK_ID_GC_TIMEOUT);
-                       spin_lock_bh(&wvif->ps_state_lock);
-               } else if (wvif->link_id_db[i].status == WFX_LINK_SOFT) {
-                       ttl = wvif->link_id_db[i].timestamp - now +
-                                       WFX_LINK_ID_GC_TIMEOUT;
-                       if (ttl <= 0) {
-                               need_reset = true;
-                               wvif->link_id_db[i].status = WFX_LINK_OFF;
-                               wvif->link_id_map &= ~mask;
-                               wvif->sta_asleep_mask &= ~mask;
-                               wvif->pspoll_mask &= ~mask;
-                               spin_unlock_bh(&wvif->ps_state_lock);
-                               wfx_unmap_link(wvif, i + 1);
-                               spin_lock_bh(&wvif->ps_state_lock);
-                       } else {
-                               next_gc = min_t(unsigned long, next_gc, ttl);
-                       }
-               }
-               if (need_reset)
-                       skb_queue_purge(&wvif->link_id_db[i].rx_queue);
-       }
-       spin_unlock_bh(&wvif->ps_state_lock);
-       if (next_gc != -1)
-               schedule_delayed_work(&wvif->link_id_gc_work, next_gc);
-       wfx_tx_unlock(wvif->wdev);
-}
-
-void wfx_link_id_work(struct work_struct *work)
-{
-       struct wfx_vif *wvif =
-               container_of(work, struct wfx_vif, link_id_work);
-
-       wfx_tx_flush(wvif->wdev);
-       wfx_link_id_gc_work(&wvif->link_id_gc_work.work);
-       wfx_tx_unlock(wvif->wdev);
-}
-
 /* Tx implementation */
 
 static bool ieee80211_is_action_back(struct ieee80211_hdr *hdr)
@@ -453,29 +282,21 @@ static void wfx_tx_manage_pm(struct wfx_vif *wvif, struct ieee80211_hdr *hdr,
                             struct ieee80211_sta *sta)
 {
        u32 mask = ~BIT(tx_priv->raw_link_id);
+       struct wfx_sta_priv *sta_priv;
+       int tid = ieee80211_get_tid(hdr);
 
        spin_lock_bh(&wvif->ps_state_lock);
-       if (ieee80211_is_auth(hdr->frame_control)) {
+       if (ieee80211_is_auth(hdr->frame_control))
                wvif->sta_asleep_mask &= mask;
-               wvif->pspoll_mask &= mask;
-       }
-
-       if (tx_priv->link_id == WFX_LINK_ID_AFTER_DTIM &&
-           !wvif->mcast_buffered) {
-               wvif->mcast_buffered = true;
-               if (wvif->sta_asleep_mask)
-                       schedule_work(&wvif->mcast_start_work);
-       }
-
-       if (tx_priv->raw_link_id) {
-               wvif->link_id_db[tx_priv->raw_link_id - 1].timestamp = jiffies;
-               if (tx_priv->tid < WFX_MAX_TID)
-                       wvif->link_id_db[tx_priv->raw_link_id - 1].buffered[tx_priv->tid]++;
-       }
        spin_unlock_bh(&wvif->ps_state_lock);
 
-       if (sta)
-               ieee80211_sta_set_buffered(sta, tx_priv->tid, true);
+       if (sta) {
+               sta_priv = (struct wfx_sta_priv *)&sta->drv_priv;
+               spin_lock_bh(&sta_priv->lock);
+               sta_priv->buffered[tid]++;
+               ieee80211_sta_set_buffered(sta, tid, true);
+               spin_unlock_bh(&sta_priv->lock);
+       }
 }
 
 static u8 wfx_tx_get_raw_link_id(struct wfx_vif *wvif,
@@ -485,7 +306,6 @@ static u8 wfx_tx_get_raw_link_id(struct wfx_vif *wvif,
        struct wfx_sta_priv *sta_priv =
                sta ? (struct wfx_sta_priv *) &sta->drv_priv : NULL;
        const u8 *da = ieee80211_get_DA(hdr);
-       int ret;
 
        if (sta_priv && sta_priv->link_id)
                return sta_priv->link_id;
@@ -493,14 +313,7 @@ static u8 wfx_tx_get_raw_link_id(struct wfx_vif *wvif,
                return 0;
        if (is_multicast_ether_addr(da))
                return 0;
-       ret = wfx_find_link_id(wvif, da);
-       if (!ret)
-               ret = wfx_alloc_link_id(wvif, da);
-       if (!ret) {
-               dev_err(wvif->wdev->dev, "no more link-id available\n");
-               return WFX_LINK_ID_NO_ASSOC;
-       }
-       return ret;
+       return WFX_LINK_ID_NO_ASSOC;
 }
 
 static void wfx_tx_fixup_rates(struct ieee80211_tx_rate *rates)
@@ -597,17 +410,6 @@ static struct hif_ht_tx_parameters wfx_tx_get_tx_parms(struct wfx_dev *wdev, str
        return ret;
 }
 
-static u8 wfx_tx_get_tid(struct ieee80211_hdr *hdr)
-{
-       // FIXME: ieee80211_get_tid(hdr) should be sufficient for all cases.
-       if (!ieee80211_is_data(hdr->frame_control))
-               return WFX_MAX_TID;
-       if (ieee80211_is_data_qos(hdr->frame_control))
-               return ieee80211_get_tid(hdr);
-       else
-               return 0;
-}
-
 static int wfx_tx_get_icv_len(struct ieee80211_key_conf *hw_key)
 {
        int mic_space;
@@ -639,7 +441,6 @@ static int wfx_tx_inner(struct wfx_vif *wvif, struct ieee80211_sta *sta,
        memset(tx_info->rate_driver_data, 0, sizeof(struct wfx_tx_priv));
        // Fill tx_priv
        tx_priv = (struct wfx_tx_priv *)tx_info->rate_driver_data;
-       tx_priv->tid = wfx_tx_get_tid(hdr);
        tx_priv->raw_link_id = wfx_tx_get_raw_link_id(wvif, sta, hdr);
        tx_priv->link_id = tx_priv->raw_link_id;
        if (ieee80211_has_protected(hdr->frame_control))
@@ -668,9 +469,15 @@ static int wfx_tx_inner(struct wfx_vif *wvif, struct ieee80211_sta *sta,
 
        // Fill tx request
        req = (struct hif_req_tx *)hif_msg->body;
-       req->packet_id = queue_id << 16 |
-                        IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl));
+       // packet_id just need to be unique on device. 32bits are more than
+       // necessary for that task, so we tae advantage of it to add some extra
+       // data for debug.
+       req->packet_id = queue_id << 28 |
+                        IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl)) << 16 |
+                        (atomic_add_return(1, &wvif->wdev->packet_id) & 0xFFFF);
        req->data_flags.fc_offset = offset;
+       if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM)
+               req->data_flags.after_dtim = 1;
        req->queue_id.peer_sta_id = tx_priv->raw_link_id;
        // Queue index are inverted between firmware and Linux
        req->queue_id.queue_id = 3 - queue_id;
@@ -680,6 +487,8 @@ static int wfx_tx_inner(struct wfx_vif *wvif, struct ieee80211_sta *sta,
        // Auxiliary operations
        wfx_tx_manage_pm(wvif, hdr, tx_priv, sta);
        wfx_tx_queue_put(wvif->wdev, &wvif->wdev->tx_queue[queue_id], skb);
+       if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM)
+               schedule_work(&wvif->update_tim_work);
        wfx_bh_request_tx(wvif->wdev);
        return 0;
 }
@@ -719,7 +528,7 @@ drop:
        ieee80211_tx_status_irqsafe(wdev->hw, skb);
 }
 
-void wfx_tx_confirm_cb(struct wfx_vif *wvif, struct hif_cnf_tx *arg)
+void wfx_tx_confirm_cb(struct wfx_vif *wvif, const struct hif_cnf_tx *arg)
 {
        int i;
        int tx_count;
@@ -791,14 +600,11 @@ void wfx_tx_confirm_cb(struct wfx_vif *wvif, struct hif_cnf_tx *arg)
                else
                        tx_info->flags |= IEEE80211_TX_STAT_ACK;
        } else if (arg->status == HIF_REQUEUE) {
-               /* "REQUEUE" means "implicit suspend" */
-               struct hif_ind_suspend_resume_tx suspend = {
-                       .suspend_resume_flags.resume = 0,
-                       .suspend_resume_flags.bc_mc_only = 1,
-               };
-
                WARN(!arg->tx_result_flags.requeue, "incoherent status and result_flags");
-               wfx_suspend_resume(wvif, &suspend);
+               if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
+                       wvif->after_dtim_tx_allowed = false; // DTIM period elapsed
+                       schedule_work(&wvif->update_tim_work);
+               }
                tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
        } else {
                if (wvif->bss_loss_state &&
@@ -808,31 +614,25 @@ void wfx_tx_confirm_cb(struct wfx_vif *wvif, struct hif_cnf_tx *arg)
        wfx_pending_remove(wvif->wdev, skb);
 }
 
-static void wfx_notify_buffered_tx(struct wfx_vif *wvif, struct sk_buff *skb,
-                                  struct hif_req_tx *req)
+static void wfx_notify_buffered_tx(struct wfx_vif *wvif, struct sk_buff *skb)
 {
-       struct ieee80211_sta *sta;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-       int tid = wfx_tx_get_tid(hdr);
-       int raw_link_id = req->queue_id.peer_sta_id;
-       u8 *buffered;
-
-       if (raw_link_id && tid < WFX_MAX_TID) {
-               buffered = wvif->link_id_db[raw_link_id - 1].buffered;
-
-               spin_lock_bh(&wvif->ps_state_lock);
-               WARN(!buffered[tid], "inconsistent notification");
-               buffered[tid]--;
-               spin_unlock_bh(&wvif->ps_state_lock);
-
-               if (!buffered[tid]) {
-                       rcu_read_lock();
-                       sta = ieee80211_find_sta(wvif->vif, hdr->addr1);
-                       if (sta)
-                               ieee80211_sta_set_buffered(sta, tid, false);
-                       rcu_read_unlock();
-               }
+       struct ieee80211_sta *sta;
+       struct wfx_sta_priv *sta_priv;
+       int tid = ieee80211_get_tid(hdr);
+
+       rcu_read_lock(); // protect sta
+       sta = ieee80211_find_sta(wvif->vif, hdr->addr1);
+       if (sta) {
+               sta_priv = (struct wfx_sta_priv *)&sta->drv_priv;
+               spin_lock_bh(&sta_priv->lock);
+               WARN(!sta_priv->buffered[tid], "inconsistent notification");
+               sta_priv->buffered[tid]--;
+               if (!sta_priv->buffered[tid])
+                       ieee80211_sta_set_buffered(sta, tid, false);
+               spin_unlock_bh(&sta_priv->lock);
        }
+       rcu_read_unlock();
 }
 
 void wfx_skb_dtor(struct wfx_dev *wdev, struct sk_buff *skb)
@@ -846,7 +646,7 @@ void wfx_skb_dtor(struct wfx_dev *wdev, struct sk_buff *skb)
 
        WARN_ON(!wvif);
        skb_pull(skb, offset);
-       wfx_notify_buffered_tx(wvif, skb, req);
+       wfx_notify_buffered_tx(wvif, skb);
        wfx_tx_policy_put(wvif, req->tx_flags.retry_policy_index);
        ieee80211_tx_status_irqsafe(wdev->hw, skb);
 }
index 0fc388d..04b2147 100644 (file)
 #include "hif_api_cmd.h"
 #include "hif_api_mib.h"
 
-// FIXME: use IEEE80211_NUM_TIDS
-#define WFX_MAX_TID               8
-
 struct wfx_tx_priv;
 struct wfx_dev;
 struct wfx_vif;
 
-enum wfx_link_status {
-       WFX_LINK_OFF,
-       WFX_LINK_RESERVE,
-       WFX_LINK_SOFT,
-       WFX_LINK_HARD,
-};
-
-struct wfx_link_entry {
-       unsigned long           timestamp;
-       enum wfx_link_status    status;
-       u8                      mac[ETH_ALEN];
-       u8                      old_mac[ETH_ALEN];
-       u8                      buffered[WFX_MAX_TID];
-       struct sk_buff_head     rx_queue;
-};
-
 struct tx_policy {
        struct list_head link;
        int usage_count;
@@ -57,7 +38,6 @@ struct wfx_tx_priv {
        struct ieee80211_key_conf *hw_key;
        u8 link_id;
        u8 raw_link_id;
-       u8 tid;
 } __packed;
 
 void wfx_tx_policy_init(struct wfx_vif *wvif);
@@ -65,14 +45,9 @@ void wfx_tx_policy_upload_work(struct work_struct *work);
 
 void wfx_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
            struct sk_buff *skb);
-void wfx_tx_confirm_cb(struct wfx_vif *wvif, struct hif_cnf_tx *arg);
+void wfx_tx_confirm_cb(struct wfx_vif *wvif, const struct hif_cnf_tx *arg);
 void wfx_skb_dtor(struct wfx_dev *wdev, struct sk_buff *skb);
 
-int wfx_unmap_link(struct wfx_vif *wvif, int link_id);
-void wfx_link_id_work(struct work_struct *work);
-void wfx_link_id_gc_work(struct work_struct *work);
-int wfx_find_link_id(struct wfx_vif *wvif, const u8 *mac);
-
 static inline struct wfx_tx_priv *wfx_skb_tx_priv(struct sk_buff *skb)
 {
        struct ieee80211_tx_info *tx_info;
index d17a752..1164aba 100644 (file)
@@ -145,7 +145,7 @@ static int wfx_rx_stats_show(struct seq_file *seq, void *v)
                   st->pwr_clk_freq,
                   st->is_ext_pwr_clk ? "yes" : "no");
        seq_printf(seq,
-                  "N. of frames: %d, PER (x10e4): %d, Throughput: %dKbps/s\n",
+                  "Num. of frames: %d, PER (x10e4): %d, Throughput: %dKbps/s\n",
                   st->nb_rx_frame, st->per_total, st->throughput);
        seq_puts(seq, "       Num. of      PER     RSSI      SNR      CFO\n");
        seq_puts(seq, "        frames  (x10e4)    (dBm)     (dB)    (kHz)\n");
index dbf8bda..9d61082 100644 (file)
@@ -61,7 +61,7 @@
 #define DCA_TIMEOUT  50 // milliseconds
 #define WAKEUP_TIMEOUT 200 // milliseconds
 
-static const char * const fwio_error_strings[] = {
+static const char * const fwio_errors[] = {
        [ERR_INVALID_SEC_TYPE] = "Invalid section type or wrong encryption",
        [ERR_SIG_VERIF_FAILED] = "Signature verification failed",
        [ERR_AES_CTRL_KEY] = "AES control key not initialized",
@@ -220,22 +220,16 @@ static int upload_firmware(struct wfx_dev *wdev, const u8 *data, size_t len)
 
 static void print_boot_status(struct wfx_dev *wdev)
 {
-       u32 val32;
+       u32 reg;
 
-       sram_reg_read(wdev, WFX_STATUS_INFO, &val32);
-       if (val32 == 0x12345678) {
-               dev_info(wdev->dev, "no error reported by secure boot\n");
-       } else {
-               sram_reg_read(wdev, WFX_ERR_INFO, &val32);
-               if (val32 < ARRAY_SIZE(fwio_error_strings) &&
-                   fwio_error_strings[val32])
-                       dev_info(wdev->dev, "secure boot error: %s\n",
-                                fwio_error_strings[val32]);
-               else
-                       dev_info(wdev->dev,
-                                "secure boot error: Unknown (0x%02x)\n",
-                                val32);
-       }
+       sram_reg_read(wdev, WFX_STATUS_INFO, &reg);
+       if (reg == 0x12345678)
+               return;
+       sram_reg_read(wdev, WFX_ERR_INFO, &reg);
+       if (reg < ARRAY_SIZE(fwio_errors) && fwio_errors[reg])
+               dev_info(wdev->dev, "secure boot: %s\n", fwio_errors[reg]);
+       else
+               dev_info(wdev->dev, "secure boot: Error %#02x\n", reg);
 }
 
 static int load_firmware_secure(struct wfx_dev *wdev)
@@ -345,7 +339,7 @@ int wfx_init_device(struct wfx_dev *wdev)
        ktime_t now, start;
        u32 reg;
 
-       reg = CFG_DIRECT_ACCESS_MODE | CFG_CPU_RESET | CFG_WORD_MODE2;
+       reg = CFG_DIRECT_ACCESS_MODE | CFG_CPU_RESET | CFG_BYTE_ORDER_ABCD;
        if (wdev->pdata.use_rising_clk)
                reg |= CFG_CLK_RISE_EDGE;
        ret = config_reg_write(wdev, reg);
index c15831d..5554d6e 100644 (file)
@@ -137,7 +137,7 @@ struct hif_ie_tlv {
 
 struct hif_req_update_ie {
        struct hif_ie_flags ie_flags;
-       u16   num_i_es;
+       u16   num_ies;
        struct hif_ie_tlv ie[];
 } __packed;
 
@@ -180,7 +180,7 @@ struct hif_req_start_scan {
        struct hif_auto_scan_param auto_scan_param;
        u8    num_of_probe_requests;
        u8    probe_delay;
-       u8    num_of_ssi_ds;
+       u8    num_of_ssids;
        u8    num_of_channels;
        u32   min_channel_time;
        u32   max_channel_time;
@@ -188,7 +188,7 @@ struct hif_req_start_scan {
        u8    ssid_and_channel_lists[];
 } __packed;
 
-struct hif_start_scan_req_cstnbssid_body {
+struct hif_req_start_scan_alt {
        u8    band;
        struct hif_scan_type scan_type;
        struct hif_scan_flags scan_flags;
@@ -196,7 +196,7 @@ struct hif_start_scan_req_cstnbssid_body {
        struct hif_auto_scan_param auto_scan_param;
        u8    num_of_probe_requests;
        u8    probe_delay;
-       u8    num_of_ssi_ds;
+       u8    num_of_ssids;
        u8    num_of_channels;
        u32   min_channel_time;
        u32   max_channel_time;
@@ -253,7 +253,8 @@ struct hif_queue {
 struct hif_data_flags {
        u8    more:1;
        u8    fc_offset:3;
-       u8    reserved:4;
+       u8    after_dtim:1;
+       u8    reserved:3;
 } __packed;
 
 struct hif_tx_flags {
@@ -377,17 +378,6 @@ struct hif_cnf_edca_queue_params {
        u32   status;
 } __packed;
 
-enum hif_ap_mode {
-       HIF_MODE_IBSS                              = 0x0,
-       HIF_MODE_BSS                               = 0x1
-};
-
-enum hif_preamble {
-       HIF_PREAMBLE_LONG                          = 0x0,
-       HIF_PREAMBLE_SHORT                         = 0x1,
-       HIF_PREAMBLE_SHORT_LONG12                  = 0x2
-};
-
 struct hif_join_flags {
        u8    reserved1:2;
        u8    force_no_beacon:1;
@@ -396,14 +386,16 @@ struct hif_join_flags {
 } __packed;
 
 struct hif_req_join {
-       u8    mode;
+       u8    infrastructure_bss_mode:1;
+       u8    reserved1:7;
        u8    band;
        u16   channel_number;
        u8    bssid[ETH_ALEN];
        u16   atim_window;
-       u8    preamble_type;
+       u8    short_preamble:1;
+       u8    reserved2:7;
        u8    probe_for_join;
-       u8    reserved;
+       u8    reserved3;
        struct hif_join_flags join_flags;
        u32   ssid_length;
        u8    ssid[HIF_API_SSID_SIZE];
@@ -466,8 +458,9 @@ struct hif_req_start {
        u32   reserved1;
        u32   beacon_interval;
        u8    dtim_period;
-       u8    preamble_type;
-       u8    reserved2;
+       u8    short_preamble:1;
+       u8    reserved2:7;
+       u8    reserved3;
        u8    ssid_length;
        u8    ssid[HIF_API_SSID_SIZE];
        u32   basic_rate_set;
index 94b789c..0c67cd4 100644 (file)
@@ -181,19 +181,13 @@ struct hif_mib_ipv6_addr_data_frame_condition {
        u8    i_pv6_address[HIF_API_IPV6_ADDRESS_SIZE];
 } __packed;
 
-union hif_addr_type {
-       u8 value;
-       struct {
-               u8    type_unicast:1;
-               u8    type_multicast:1;
-               u8    type_broadcast:1;
-               u8    reserved:5;
-       } bits;
-};
+#define HIF_FILTER_UNICAST   0x1
+#define HIF_FILTER_MULTICAST 0x2
+#define HIF_FILTER_BROADCAST 0x4
 
 struct hif_mib_uc_mc_bc_data_frame_condition {
        u8    condition_idx;
-       union hif_addr_type param;
+       u8    allowed_frames;
        u8    reserved[2];
 } __packed;
 
@@ -212,9 +206,11 @@ struct hif_mib_config_data_filter {
 } __packed;
 
 struct hif_mib_set_data_filtering {
-       u8    default_filter;
-       u8    enable;
-       u8    reserved[2];
+       u8    invert_matching:1;
+       u8    reserved1:7;
+       u8    enable:1;
+       u8    reserved2:7;
+       u8    reserved3[2];
 } __packed;
 
 enum hif_arp_ns_frame_treatment {
@@ -395,11 +391,6 @@ struct hif_mib_non_erp_protection {
        u8   reserved2[3];
 } __packed;
 
-enum hif_tx_mode {
-       HIF_TX_MODE_MIXED                        = 0x0,
-       HIF_TX_MODE_GREENFIELD                   = 0x1
-};
-
 enum hif_tmplt {
        HIF_TMPLT_PRBREQ                           = 0x0,
        HIF_TMPLT_BCN                              = 0x1,
@@ -471,9 +462,11 @@ struct hif_mib_set_association_mode {
        u8    mode:1;
        u8    rateset:1;
        u8    spacing:1;
-       u8    reserved:4;
-       u8    preamble_type;
-       u8    mixed_or_greenfield_type;
+       u8    reserved1:4;
+       u8    short_preamble:1;
+       u8    reserved2:7;
+       u8    greenfield:1;
+       u8    reserved3:7;
        u8    mpdu_start_spacing;
        u32   basic_rate_set;
 } __packed;
index 820de21..33c22c5 100644 (file)
@@ -18,8 +18,8 @@
 #include "secure_link.h"
 #include "hif_api_cmd.h"
 
-static int hif_generic_confirm(struct wfx_dev *wdev, struct hif_msg *hif,
-                              void *buf)
+static int hif_generic_confirm(struct wfx_dev *wdev,
+                              const struct hif_msg *hif, const void *buf)
 {
        // All confirm messages start with status
        int status = le32_to_cpu(*((__le32 *) buf));
@@ -59,9 +59,10 @@ static int hif_generic_confirm(struct wfx_dev *wdev, struct hif_msg *hif,
        return status;
 }
 
-static int hif_tx_confirm(struct wfx_dev *wdev, struct hif_msg *hif, void *buf)
+static int hif_tx_confirm(struct wfx_dev *wdev,
+                         const struct hif_msg *hif, const void *buf)
 {
-       struct hif_cnf_tx *body = buf;
+       const struct hif_cnf_tx *body = buf;
        struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface);
 
        WARN_ON(!wvif);
@@ -72,31 +73,27 @@ static int hif_tx_confirm(struct wfx_dev *wdev, struct hif_msg *hif, void *buf)
        return 0;
 }
 
-static int hif_multi_tx_confirm(struct wfx_dev *wdev, struct hif_msg *hif,
-                               void *buf)
+static int hif_multi_tx_confirm(struct wfx_dev *wdev,
+                               const struct hif_msg *hif, const void *buf)
 {
-       struct hif_cnf_multi_transmit *body = buf;
-       struct hif_cnf_tx *buf_loc = (struct hif_cnf_tx *) &body->tx_conf_payload;
+       const struct hif_cnf_multi_transmit *body = buf;
        struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface);
-       int count = body->num_tx_confs;
        int i;
 
-       WARN(count <= 0, "corrupted message");
+       WARN(body->num_tx_confs <= 0, "corrupted message");
        WARN_ON(!wvif);
        if (!wvif)
                return -EFAULT;
 
-       for (i = 0; i < count; ++i) {
-               wfx_tx_confirm_cb(wvif, buf_loc);
-               buf_loc++;
-       }
+       for (i = 0; i < body->num_tx_confs; i++)
+               wfx_tx_confirm_cb(wvif, &body->tx_conf_payload[i]);
        return 0;
 }
 
-static int hif_startup_indication(struct wfx_dev *wdev, struct hif_msg *hif,
-                                 void *buf)
+static int hif_startup_indication(struct wfx_dev *wdev,
+                                 const struct hif_msg *hif, const void *buf)
 {
-       struct hif_ind_startup *body = buf;
+       const struct hif_ind_startup *body = buf;
 
        if (body->status || body->firmware_type > 4) {
                dev_err(wdev->dev, "received invalid startup indication");
@@ -112,8 +109,8 @@ static int hif_startup_indication(struct wfx_dev *wdev, struct hif_msg *hif,
        return 0;
 }
 
-static int hif_wakeup_indication(struct wfx_dev *wdev, struct hif_msg *hif,
-                                void *buf)
+static int hif_wakeup_indication(struct wfx_dev *wdev,
+                                const struct hif_msg *hif, const void *buf)
 {
        if (!wdev->pdata.gpio_wakeup
            || !gpiod_get_value(wdev->pdata.gpio_wakeup)) {
@@ -123,25 +120,27 @@ static int hif_wakeup_indication(struct wfx_dev *wdev, struct hif_msg *hif,
        return 0;
 }
 
-static int hif_keys_indication(struct wfx_dev *wdev, struct hif_msg *hif,
-                              void *buf)
+static int hif_keys_indication(struct wfx_dev *wdev,
+                              const struct hif_msg *hif, const void *buf)
 {
-       struct hif_ind_sl_exchange_pub_keys *body = buf;
+       const struct hif_ind_sl_exchange_pub_keys *body = buf;
+       u8 pubkey[API_NCP_PUB_KEY_SIZE];
 
-       // Compatibility with legacy secure link
-       if (body->status == SL_PUB_KEY_EXCHANGE_STATUS_SUCCESS)
-               body->status = 0;
-       if (body->status)
+       // SL_PUB_KEY_EXCHANGE_STATUS_SUCCESS is used by legacy secure link
+       if (body->status && body->status != SL_PUB_KEY_EXCHANGE_STATUS_SUCCESS)
                dev_warn(wdev->dev, "secure link negociation error\n");
-       wfx_sl_check_pubkey(wdev, body->ncp_pub_key, body->ncp_pub_key_mac);
+       memcpy(pubkey, body->ncp_pub_key, sizeof(pubkey));
+       memreverse(pubkey, sizeof(pubkey));
+       wfx_sl_check_pubkey(wdev, pubkey, body->ncp_pub_key_mac);
        return 0;
 }
 
-static int hif_receive_indication(struct wfx_dev *wdev, struct hif_msg *hif,
-                                 void *buf, struct sk_buff *skb)
+static int hif_receive_indication(struct wfx_dev *wdev,
+                                 const struct hif_msg *hif,
+                                 const void *buf, struct sk_buff *skb)
 {
        struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface);
-       struct hif_ind_rx *body = buf;
+       const struct hif_ind_rx *body = buf;
 
        if (!wvif) {
                dev_warn(wdev->dev, "ignore rx data for non-existent vif %d\n",
@@ -154,11 +153,11 @@ static int hif_receive_indication(struct wfx_dev *wdev, struct hif_msg *hif,
        return 0;
 }
 
-static int hif_event_indication(struct wfx_dev *wdev, struct hif_msg *hif,
-                               void *buf)
+static int hif_event_indication(struct wfx_dev *wdev,
+                               const struct hif_msg *hif, const void *buf)
 {
        struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface);
-       struct hif_ind_event *body = buf;
+       const struct hif_ind_event *body = buf;
        struct wfx_hif_event *event;
        int first;
 
@@ -183,7 +182,8 @@ static int hif_event_indication(struct wfx_dev *wdev, struct hif_msg *hif,
 }
 
 static int hif_pm_mode_complete_indication(struct wfx_dev *wdev,
-                                          struct hif_msg *hif, void *buf)
+                                          const struct hif_msg *hif,
+                                          const void *buf)
 {
        struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface);
 
@@ -194,19 +194,20 @@ static int hif_pm_mode_complete_indication(struct wfx_dev *wdev,
 }
 
 static int hif_scan_complete_indication(struct wfx_dev *wdev,
-                                       struct hif_msg *hif, void *buf)
+                                       const struct hif_msg *hif,
+                                       const void *buf)
 {
        struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface);
-       struct hif_ind_scan_cmpl *body = buf;
 
        WARN_ON(!wvif);
-       wfx_scan_complete_cb(wvif, body);
+       wfx_scan_complete(wvif);
 
        return 0;
 }
 
 static int hif_join_complete_indication(struct wfx_dev *wdev,
-                                       struct hif_msg *hif, void *buf)
+                                       const struct hif_msg *hif,
+                                       const void *buf)
 {
        struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface);
 
@@ -217,21 +218,26 @@ static int hif_join_complete_indication(struct wfx_dev *wdev,
 }
 
 static int hif_suspend_resume_indication(struct wfx_dev *wdev,
-                                        struct hif_msg *hif, void *buf)
+                                        const struct hif_msg *hif,
+                                        const void *buf)
 {
        struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface);
-       struct hif_ind_suspend_resume_tx *body = buf;
+       const struct hif_ind_suspend_resume_tx *body = buf;
 
        WARN_ON(!wvif);
-       wfx_suspend_resume(wvif, body);
+       WARN(!body->suspend_resume_flags.bc_mc_only, "unsupported suspend/resume notification");
+       if (body->suspend_resume_flags.resume)
+               wfx_suspend_resume_mc(wvif, STA_NOTIFY_AWAKE);
+       else
+               wfx_suspend_resume_mc(wvif, STA_NOTIFY_SLEEP);
 
        return 0;
 }
 
-static int hif_error_indication(struct wfx_dev *wdev, struct hif_msg *hif,
-                               void *buf)
+static int hif_error_indication(struct wfx_dev *wdev,
+                               const struct hif_msg *hif, const void *buf)
 {
-       struct hif_ind_error *body = buf;
+       const struct hif_ind_error *body = buf;
        u8 *pRollback = (u8 *) body->data;
        u32 *pStatus = (u32 *) body->data;
 
@@ -268,10 +274,10 @@ static int hif_error_indication(struct wfx_dev *wdev, struct hif_msg *hif,
        return 0;
 }
 
-static int hif_generic_indication(struct wfx_dev *wdev, struct hif_msg *hif,
-                                 void *buf)
+static int hif_generic_indication(struct wfx_dev *wdev,
+                                 const struct hif_msg *hif, const void *buf)
 {
-       struct hif_ind_generic *body = buf;
+       const struct hif_ind_generic *body = buf;
 
        switch (body->indication_type) {
        case HIF_GENERIC_INDICATION_TYPE_RAW:
@@ -299,9 +305,10 @@ static int hif_generic_indication(struct wfx_dev *wdev, struct hif_msg *hif,
 }
 
 static int hif_exception_indication(struct wfx_dev *wdev,
-                                   struct hif_msg *hif, void *buf)
+                                   const struct hif_msg *hif, const void *buf)
 {
        size_t len = hif->len - 4; // drop header
+
        dev_err(wdev->dev, "firmware exception\n");
        print_hex_dump_bytes("Dump: ", DUMP_PREFIX_NONE, buf, len);
        wdev->chip_frozen = 1;
@@ -311,7 +318,8 @@ static int hif_exception_indication(struct wfx_dev *wdev,
 
 static const struct {
        int msg_id;
-       int (*handler)(struct wfx_dev *wdev, struct hif_msg *hif, void *buf);
+       int (*handler)(struct wfx_dev *wdev,
+                      const struct hif_msg *hif, const void *buf);
 } hif_handlers[] = {
        /* Confirmations */
        { HIF_CNF_ID_TX,                   hif_tx_confirm },
@@ -335,7 +343,7 @@ static const struct {
 void wfx_handle_rx(struct wfx_dev *wdev, struct sk_buff *skb)
 {
        int i;
-       struct hif_msg *hif = (struct hif_msg *) skb->data;
+       const struct hif_msg *hif = (const struct hif_msg *)skb->data;
        int hif_id = hif->id;
 
        if (hif_id == HIF_IND_ID_RX) {
@@ -358,7 +366,12 @@ void wfx_handle_rx(struct wfx_dev *wdev, struct sk_buff *skb)
                        goto free;
                }
        }
-       dev_err(wdev->dev, "unsupported HIF ID %02x\n", hif_id);
+       if (hif_id & 0x80)
+               dev_err(wdev->dev, "unsupported HIF indication: ID %02x\n",
+                       hif_id);
+       else
+               dev_err(wdev->dev, "unexpected HIF confirmation: ID %02x\n",
+                       hif_id);
 free:
        dev_kfree_skb(skb);
 }
index cb7cddc..2428363 100644 (file)
@@ -6,7 +6,6 @@
  * Copyright (c) 2017-2019, Silicon Laboratories, Inc.
  * Copyright (c) 2010, ST-Ericsson
  */
-#include <linux/skbuff.h>
 #include <linux/etherdevice.h>
 
 #include "hif_tx.h"
@@ -221,41 +220,59 @@ int hif_write_mib(struct wfx_dev *wdev, int vif_id, u16 mib_id, void *val,
        return ret;
 }
 
-int hif_scan(struct wfx_vif *wvif, const struct wfx_scan_params *arg)
+int hif_scan(struct wfx_vif *wvif, struct cfg80211_scan_request *req,
+            int chan_start_idx, int chan_num)
 {
        int ret, i;
        struct hif_msg *hif;
-       struct hif_ssid_def *ssids;
-       size_t buf_len = sizeof(struct hif_req_start_scan) +
-               arg->scan_req.num_of_channels * sizeof(u8) +
-               arg->scan_req.num_of_ssi_ds * sizeof(struct hif_ssid_def);
-       struct hif_req_start_scan *body = wfx_alloc_hif(buf_len, &hif);
-       u8 *ptr = (u8 *) body + sizeof(*body);
-
-       WARN(arg->scan_req.num_of_channels > HIF_API_MAX_NB_CHANNELS, "invalid params");
-       WARN(arg->scan_req.num_of_ssi_ds > 2, "invalid params");
-       WARN(arg->scan_req.band > 1, "invalid params");
-
-       // FIXME: This API is unnecessary complex, fixing NumOfChannels and
-       // adding a member SsidDef at end of struct hif_req_start_scan would
-       // simplify that a lot.
-       memcpy(body, &arg->scan_req, sizeof(*body));
-       cpu_to_le32s(&body->min_channel_time);
-       cpu_to_le32s(&body->max_channel_time);
-       cpu_to_le32s(&body->tx_power_level);
-       memcpy(ptr, arg->ssids,
-              arg->scan_req.num_of_ssi_ds * sizeof(struct hif_ssid_def));
-       ssids = (struct hif_ssid_def *) ptr;
-       for (i = 0; i < body->num_of_ssi_ds; ++i)
-               cpu_to_le32s(&ssids[i].ssid_length);
-       ptr += arg->scan_req.num_of_ssi_ds * sizeof(struct hif_ssid_def);
-       memcpy(ptr, arg->ch, arg->scan_req.num_of_channels * sizeof(u8));
-       ptr += arg->scan_req.num_of_channels * sizeof(u8);
-       WARN(buf_len != ptr - (u8 *) body, "allocation size mismatch");
+       size_t buf_len =
+               sizeof(struct hif_req_start_scan_alt) + chan_num * sizeof(u8);
+       struct hif_req_start_scan_alt *body = wfx_alloc_hif(buf_len, &hif);
+       int tmo_chan_fg, tmo_chan_bg, tmo;
+
+       WARN(chan_num > HIF_API_MAX_NB_CHANNELS, "invalid params");
+       WARN(req->n_ssids > HIF_API_MAX_NB_SSIDS, "invalid params");
+
+       compiletime_assert(IEEE80211_MAX_SSID_LEN == HIF_API_SSID_SIZE,
+                          "API inconsistency");
+       for (i = 0; i < req->n_ssids; i++) {
+               memcpy(body->ssid_def[i].ssid, req->ssids[i].ssid,
+                      IEEE80211_MAX_SSID_LEN);
+               body->ssid_def[i].ssid_length =
+                       cpu_to_le32(req->ssids[i].ssid_len);
+       }
+       body->num_of_ssids = HIF_API_MAX_NB_SSIDS;
+       // Background scan is always a good idea
+       body->scan_type.type = 1;
+       body->scan_flags.fbg = 1;
+       body->tx_power_level =
+               cpu_to_le32(req->channels[chan_start_idx]->max_power);
+       body->num_of_channels = chan_num;
+       for (i = 0; i < chan_num; i++)
+               body->channel_list[i] =
+                       req->channels[i + chan_start_idx]->hw_value;
+       if (req->no_cck)
+               body->max_transmit_rate = API_RATE_INDEX_G_6MBPS;
+       else
+               body->max_transmit_rate = API_RATE_INDEX_B_1MBPS;
+       if (req->channels[chan_start_idx]->flags & IEEE80211_CHAN_NO_IR) {
+               body->min_channel_time = cpu_to_le32(50);
+               body->max_channel_time = cpu_to_le32(150);
+       } else {
+               body->min_channel_time = cpu_to_le32(10);
+               body->max_channel_time = cpu_to_le32(50);
+               body->num_of_probe_requests = 2;
+               body->probe_delay = 100;
+       }
+       tmo_chan_bg = le32_to_cpu(body->max_channel_time) * USEC_PER_TU;
+       tmo_chan_fg = 512 * USEC_PER_TU + body->probe_delay;
+       tmo_chan_fg *= body->num_of_probe_requests;
+       tmo = chan_num * max(tmo_chan_bg, tmo_chan_fg);
+
        wfx_fill_header(hif, wvif->id, HIF_REQ_ID_START_SCAN, buf_len);
        ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false);
        kfree(hif);
-       return ret;
+       return ret ? ret : usecs_to_jiffies(tmo);
 }
 
 int hif_stop_scan(struct wfx_vif *wvif)
@@ -271,18 +288,29 @@ int hif_stop_scan(struct wfx_vif *wvif)
        return ret;
 }
 
-int hif_join(struct wfx_vif *wvif, const struct hif_req_join *arg)
+int hif_join(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf,
+            const struct ieee80211_channel *channel, const u8 *ssidie)
 {
        int ret;
        struct hif_msg *hif;
        struct hif_req_join *body = wfx_alloc_hif(sizeof(*body), &hif);
 
-       memcpy(body, arg, sizeof(struct hif_req_join));
-       cpu_to_le16s(&body->channel_number);
-       cpu_to_le16s(&body->atim_window);
-       cpu_to_le32s(&body->ssid_length);
-       cpu_to_le32s(&body->beacon_interval);
-       cpu_to_le32s(&body->basic_rate_set);
+       WARN_ON(!conf->basic_rates);
+       body->infrastructure_bss_mode = !conf->ibss_joined;
+       body->short_preamble = conf->use_short_preamble;
+       if (channel && channel->flags & IEEE80211_CHAN_NO_IR)
+               body->probe_for_join = 0;
+       else
+               body->probe_for_join = 1;
+       body->channel_number = cpu_to_le16(channel->hw_value);
+       body->beacon_interval = cpu_to_le32(conf->beacon_int);
+       body->basic_rate_set =
+               cpu_to_le32(wfx_rate_mask_to_hw(wvif->wdev, conf->basic_rates));
+       memcpy(body->bssid, conf->bssid, sizeof(body->bssid));
+       if (!conf->ibss_joined && ssidie) {
+               body->ssid_length = cpu_to_le32(ssidie[1]);
+               memcpy(body->ssid, &ssidie[2], ssidie[1]);
+       }
        wfx_fill_header(hif, wvif->id, HIF_REQ_ID_JOIN, sizeof(*body));
        ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false);
        kfree(hif);
@@ -341,19 +369,28 @@ int hif_remove_key(struct wfx_dev *wdev, int idx)
        return ret;
 }
 
-int hif_set_edca_queue_params(struct wfx_vif *wvif,
-                             const struct hif_req_edca_queue_params *arg)
+int hif_set_edca_queue_params(struct wfx_vif *wvif, u16 queue,
+                             const struct ieee80211_tx_queue_params *arg)
 {
        int ret;
        struct hif_msg *hif;
        struct hif_req_edca_queue_params *body = wfx_alloc_hif(sizeof(*body),
                                                               &hif);
 
-       // NOTE: queues numerotation are not the same between WFx and Linux
-       memcpy(body, arg, sizeof(*body));
-       cpu_to_le16s(&body->cw_min);
-       cpu_to_le16s(&body->cw_max);
-       cpu_to_le16s(&body->tx_op_limit);
+       if (!body)
+               return -ENOMEM;
+
+       WARN_ON(arg->aifs > 255);
+       body->aifsn = arg->aifs;
+       body->cw_min = cpu_to_le16(arg->cw_min);
+       body->cw_max = cpu_to_le16(arg->cw_max);
+       body->tx_op_limit = cpu_to_le16(arg->txop * USEC_PER_TXOP);
+       body->queue_id = 3 - queue;
+       // API 2.0 has changed queue IDs values
+       if (wfx_api_older_than(wvif->wdev, 2, 0) && queue == IEEE80211_AC_BE)
+               body->queue_id = HIF_QUEUE_ID_BACKGROUND;
+       if (wfx_api_older_than(wvif->wdev, 2, 0) && queue == IEEE80211_AC_BK)
+               body->queue_id = HIF_QUEUE_ID_BESTEFFORT;
        wfx_fill_header(hif, wvif->id, HIF_REQ_ID_EDCA_QUEUE_PARAMS,
                        sizeof(*body));
        ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false);
@@ -361,43 +398,57 @@ int hif_set_edca_queue_params(struct wfx_vif *wvif,
        return ret;
 }
 
-int hif_set_pm(struct wfx_vif *wvif, const struct hif_req_set_pm_mode *arg)
+int hif_set_pm(struct wfx_vif *wvif, bool ps, int dynamic_ps_timeout)
 {
        int ret;
        struct hif_msg *hif;
        struct hif_req_set_pm_mode *body = wfx_alloc_hif(sizeof(*body), &hif);
 
-       memcpy(body, arg, sizeof(*body));
+       if (!body)
+               return -ENOMEM;
+
+       if (ps) {
+               body->pm_mode.enter_psm = 1;
+               // Firmware does not support more than 128ms
+               body->fast_psm_idle_period = min(dynamic_ps_timeout * 2, 255);
+               if (body->fast_psm_idle_period)
+                       body->pm_mode.fast_psm = 1;
+       }
        wfx_fill_header(hif, wvif->id, HIF_REQ_ID_SET_PM_MODE, sizeof(*body));
        ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false);
        kfree(hif);
        return ret;
 }
 
-int hif_start(struct wfx_vif *wvif, const struct hif_req_start *arg)
+int hif_start(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf,
+             const struct ieee80211_channel *channel)
 {
        int ret;
        struct hif_msg *hif;
        struct hif_req_start *body = wfx_alloc_hif(sizeof(*body), &hif);
 
-       memcpy(body, arg, sizeof(*body));
-       cpu_to_le16s(&body->channel_number);
-       cpu_to_le32s(&body->beacon_interval);
-       cpu_to_le32s(&body->basic_rate_set);
+       body->dtim_period = conf->dtim_period,
+       body->short_preamble = conf->use_short_preamble,
+       body->channel_number = cpu_to_le16(channel->hw_value),
+       body->beacon_interval = cpu_to_le32(conf->beacon_int);
+       body->basic_rate_set =
+               cpu_to_le32(wfx_rate_mask_to_hw(wvif->wdev, conf->basic_rates));
+       body->ssid_length = conf->ssid_len;
+       memcpy(body->ssid, conf->ssid, conf->ssid_len);
        wfx_fill_header(hif, wvif->id, HIF_REQ_ID_START, sizeof(*body));
        ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false);
        kfree(hif);
        return ret;
 }
 
-int hif_beacon_transmit(struct wfx_vif *wvif, bool enable_beaconing)
+int hif_beacon_transmit(struct wfx_vif *wvif, bool enable)
 {
        int ret;
        struct hif_msg *hif;
        struct hif_req_beacon_transmit *body = wfx_alloc_hif(sizeof(*body),
                                                             &hif);
 
-       body->enable_beaconing = enable_beaconing ? 1 : 0;
+       body->enable_beaconing = enable ? 1 : 0;
        wfx_fill_header(hif, wvif->id, HIF_REQ_ID_BEACON_TRANSMIT,
                        sizeof(*body));
        ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false);
@@ -421,16 +472,15 @@ int hif_map_link(struct wfx_vif *wvif, u8 *mac_addr, int flags, int sta_id)
        return ret;
 }
 
-int hif_update_ie(struct wfx_vif *wvif, const struct hif_ie_flags *target_frame,
-                 const u8 *ies, size_t ies_len)
+int hif_update_ie_beacon(struct wfx_vif *wvif, const u8 *ies, size_t ies_len)
 {
        int ret;
        struct hif_msg *hif;
        int buf_len = sizeof(struct hif_req_update_ie) + ies_len;
        struct hif_req_update_ie *body = wfx_alloc_hif(buf_len, &hif);
 
-       memcpy(&body->ie_flags, target_frame, sizeof(struct hif_ie_flags));
-       body->num_i_es = cpu_to_le16(1);
+       body->ie_flags.beacon = 1;
+       body->num_ies = cpu_to_le16(1);
        memcpy(body->ie, ies, ies_len);
        wfx_fill_header(hif, wvif->id, HIF_REQ_ID_UPDATE_IE, buf_len);
        ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false);
index f61ae7b..20977e4 100644 (file)
 
 #include "hif_api_cmd.h"
 
+struct ieee80211_channel;
+struct ieee80211_bss_conf;
+struct ieee80211_tx_queue_params;
+struct cfg80211_scan_request;
 struct wfx_dev;
 struct wfx_vif;
 
-struct wfx_scan_params {
-       struct hif_req_start_scan scan_req;
-       struct hif_ssid_def *ssids;
-       u8 *ch;
-};
-
 struct wfx_hif_cmd {
        struct mutex      lock;
        struct mutex      key_renew_lock;
@@ -44,21 +42,23 @@ int hif_read_mib(struct wfx_dev *wdev, int vif_id, u16 mib_id,
                 void *buf, size_t buf_size);
 int hif_write_mib(struct wfx_dev *wdev, int vif_id, u16 mib_id,
                  void *buf, size_t buf_size);
-int hif_scan(struct wfx_vif *wvif, const struct wfx_scan_params *arg);
+int hif_scan(struct wfx_vif *wvif, struct cfg80211_scan_request *req80211,
+            int chan_start, int chan_num);
 int hif_stop_scan(struct wfx_vif *wvif);
-int hif_join(struct wfx_vif *wvif, const struct hif_req_join *arg);
-int hif_set_pm(struct wfx_vif *wvif, const struct hif_req_set_pm_mode *arg);
+int hif_join(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf,
+            const struct ieee80211_channel *channel, const u8 *ssidie);
+int hif_set_pm(struct wfx_vif *wvif, bool ps, int dynamic_ps_timeout);
 int hif_set_bss_params(struct wfx_vif *wvif,
                       const struct hif_req_set_bss_params *arg);
 int hif_add_key(struct wfx_dev *wdev, const struct hif_req_add_key *arg);
 int hif_remove_key(struct wfx_dev *wdev, int idx);
-int hif_set_edca_queue_params(struct wfx_vif *wvif,
-                             const struct hif_req_edca_queue_params *arg);
-int hif_start(struct wfx_vif *wvif, const struct hif_req_start *arg);
+int hif_set_edca_queue_params(struct wfx_vif *wvif, u16 queue,
+                             const struct ieee80211_tx_queue_params *arg);
+int hif_start(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf,
+             const struct ieee80211_channel *channel);
 int hif_beacon_transmit(struct wfx_vif *wvif, bool enable);
 int hif_map_link(struct wfx_vif *wvif, u8 *mac_addr, int flags, int sta_id);
-int hif_update_ie(struct wfx_vif *wvif, const struct hif_ie_flags *target_frame,
-                 const u8 *ies, size_t ies_len);
+int hif_update_ie_beacon(struct wfx_vif *wvif, const u8 *ies, size_t ies_len);
 int hif_sl_set_mac_key(struct wfx_dev *wdev, const u8 *slk_key,
                       int destination);
 int hif_sl_config(struct wfx_dev *wdev, const unsigned long *bitmap);
index 9be7488..bf3769c 100644 (file)
 #include "hif_tx.h"
 #include "hif_api_mib.h"
 
-static inline int hif_set_output_power(struct wfx_vif *wvif, int power_level)
+static inline int hif_set_output_power(struct wfx_vif *wvif, int val)
 {
-       __le32 val = cpu_to_le32(power_level);
+       struct hif_mib_current_tx_power_level arg = {
+               .power_level = cpu_to_le32(val * 10),
+       };
 
        return hif_write_mib(wvif->wdev, wvif->id,
                             HIF_MIB_ID_CURRENT_TX_POWER_LEVEL,
-                            &val, sizeof(val));
+                            &arg, sizeof(arg));
 }
 
 static inline int hif_set_beacon_wakeup_period(struct wfx_vif *wvif,
@@ -42,10 +44,25 @@ static inline int hif_set_beacon_wakeup_period(struct wfx_vif *wvif,
 }
 
 static inline int hif_set_rcpi_rssi_threshold(struct wfx_vif *wvif,
-                                             struct hif_mib_rcpi_rssi_threshold *arg)
+                                             int rssi_thold, int rssi_hyst)
 {
+       struct hif_mib_rcpi_rssi_threshold arg = {
+               .rolling_average_count = 8,
+               .detection = 1,
+       };
+
+       if (!rssi_thold && !rssi_hyst) {
+               arg.upperthresh = 1;
+               arg.lowerthresh = 1;
+       } else {
+               arg.upper_threshold = rssi_thold + rssi_hyst;
+               arg.upper_threshold = (arg.upper_threshold + 110) * 2;
+               arg.lower_threshold = rssi_thold;
+               arg.lower_threshold = (arg.lower_threshold + 110) * 2;
+       }
+
        return hif_write_mib(wvif->wdev, wvif->id,
-                            HIF_MIB_ID_RCPI_RSSI_THRESHOLD, arg, sizeof(*arg));
+                            HIF_MIB_ID_RCPI_RSSI_THRESHOLD, &arg, sizeof(arg));
 }
 
 static inline int hif_get_counters_table(struct wfx_dev *wdev,
@@ -130,8 +147,17 @@ static inline int hif_set_operational_mode(struct wfx_dev *wdev,
 }
 
 static inline int hif_set_template_frame(struct wfx_vif *wvif,
-                                        struct hif_mib_template_frame *arg)
+                                        struct sk_buff *skb,
+                                        u8 frame_type, int init_rate)
 {
+       struct hif_mib_template_frame *arg;
+
+       skb_push(skb, 4);
+       arg = (struct hif_mib_template_frame *)skb->data;
+       skb_pull(skb, 4);
+       arg->init_rate = init_rate;
+       arg->frame_type = frame_type;
+       arg->frame_length = cpu_to_le16(skb->len);
        return hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_TEMPLATE_FRAME,
                             arg, sizeof(*arg));
 }
@@ -165,50 +191,105 @@ static inline int hif_set_block_ack_policy(struct wfx_vif *wvif,
 }
 
 static inline int hif_set_association_mode(struct wfx_vif *wvif,
-                                          struct hif_mib_set_association_mode *arg)
+                                          struct ieee80211_bss_conf *info,
+                                          struct ieee80211_sta_ht_cap *ht_cap)
 {
+       int basic_rates = wfx_rate_mask_to_hw(wvif->wdev, info->basic_rates);
+       struct hif_mib_set_association_mode val = {
+               .preambtype_use = 1,
+               .mode = 1,
+               .rateset = 1,
+               .spacing = 1,
+               .short_preamble = info->use_short_preamble,
+               .basic_rate_set = cpu_to_le32(basic_rates)
+       };
+
+       // FIXME: it is strange to not retrieve all information from bss_info
+       if (ht_cap && ht_cap->ht_supported) {
+               val.mpdu_start_spacing = ht_cap->ampdu_density;
+               if (!(info->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT))
+                       val.greenfield = !!(ht_cap->cap & IEEE80211_HT_CAP_GRN_FLD);
+       }
+
        return hif_write_mib(wvif->wdev, wvif->id,
-                            HIF_MIB_ID_SET_ASSOCIATION_MODE, arg, sizeof(*arg));
+                            HIF_MIB_ID_SET_ASSOCIATION_MODE, &val, sizeof(val));
 }
 
 static inline int hif_set_tx_rate_retry_policy(struct wfx_vif *wvif,
-                                              struct hif_mib_set_tx_rate_retry_policy *arg)
+                                              int policy_index, uint8_t *rates)
 {
-       size_t size = struct_size(arg, tx_rate_retry_policy,
-                                 arg->num_tx_rate_policies);
+       struct hif_mib_set_tx_rate_retry_policy *arg;
+       size_t size = struct_size(arg, tx_rate_retry_policy, 1);
+       int ret;
 
-       return hif_write_mib(wvif->wdev, wvif->id,
-                            HIF_MIB_ID_SET_TX_RATE_RETRY_POLICY, arg, size);
+       arg = kzalloc(size, GFP_KERNEL);
+       arg->num_tx_rate_policies = 1;
+       arg->tx_rate_retry_policy[0].policy_index = policy_index;
+       arg->tx_rate_retry_policy[0].short_retry_count = 255;
+       arg->tx_rate_retry_policy[0].long_retry_count = 255;
+       arg->tx_rate_retry_policy[0].first_rate_sel = 1;
+       arg->tx_rate_retry_policy[0].terminate = 1;
+       arg->tx_rate_retry_policy[0].count_init = 1;
+       memcpy(&arg->tx_rate_retry_policy[0].rates, rates,
+              sizeof(arg->tx_rate_retry_policy[0].rates));
+       ret = hif_write_mib(wvif->wdev, wvif->id,
+                           HIF_MIB_ID_SET_TX_RATE_RETRY_POLICY, arg, size);
+       kfree(arg);
+       return ret;
 }
 
 static inline int hif_set_mac_addr_condition(struct wfx_vif *wvif,
-                                            struct hif_mib_mac_addr_data_frame_condition *arg)
+                                            int idx, const u8 *mac_addr)
 {
+       struct hif_mib_mac_addr_data_frame_condition val = {
+               .condition_idx = idx,
+               .address_type = HIF_MAC_ADDR_A1,
+       };
+
+       ether_addr_copy(val.mac_address, mac_addr);
        return hif_write_mib(wvif->wdev, wvif->id,
                             HIF_MIB_ID_MAC_ADDR_DATAFRAME_CONDITION,
-                            arg, sizeof(*arg));
+                            &val, sizeof(val));
 }
 
 static inline int hif_set_uc_mc_bc_condition(struct wfx_vif *wvif,
-                                            struct hif_mib_uc_mc_bc_data_frame_condition *arg)
+                                            int idx, u8 allowed_frames)
 {
+       struct hif_mib_uc_mc_bc_data_frame_condition val = {
+               .condition_idx = idx,
+               .allowed_frames = allowed_frames,
+       };
+
        return hif_write_mib(wvif->wdev, wvif->id,
                             HIF_MIB_ID_UC_MC_BC_DATAFRAME_CONDITION,
-                            arg, sizeof(*arg));
+                            &val, sizeof(val));
 }
 
-static inline int hif_set_config_data_filter(struct wfx_vif *wvif,
-                                            struct hif_mib_config_data_filter *arg)
+static inline int hif_set_config_data_filter(struct wfx_vif *wvif, bool enable,
+                                            int idx, int mac_filters,
+                                            int frames_types_filters)
 {
+       struct hif_mib_config_data_filter val = {
+               .enable = enable,
+               .filter_idx = idx,
+               .mac_cond = mac_filters,
+               .uc_mc_bc_cond = frames_types_filters,
+       };
+
        return hif_write_mib(wvif->wdev, wvif->id,
-                            HIF_MIB_ID_CONFIG_DATA_FILTER, arg, sizeof(*arg));
+                            HIF_MIB_ID_CONFIG_DATA_FILTER, &val, sizeof(val));
 }
 
 static inline int hif_set_data_filtering(struct wfx_vif *wvif,
-                                        struct hif_mib_set_data_filtering *arg)
+                                        bool enable, bool invert)
 {
+       struct hif_mib_set_data_filtering val = {
+               .enable = enable,
+               .invert_matching = invert,
+       };
+
        return hif_write_mib(wvif->wdev, wvif->id,
-                            HIF_MIB_ID_SET_DATA_FILTERING, arg, sizeof(*arg));
+                            HIF_MIB_ID_SET_DATA_FILTERING, &val, sizeof(val));
 }
 
 static inline int hif_keep_alive_period(struct wfx_vif *wvif, int period)
@@ -221,34 +302,56 @@ static inline int hif_keep_alive_period(struct wfx_vif *wvif, int period)
                             &arg, sizeof(arg));
 };
 
-static inline int hif_set_arp_ipv4_filter(struct wfx_vif *wvif,
-                                         struct hif_mib_arp_ip_addr_table *fp)
+static inline int hif_set_arp_ipv4_filter(struct wfx_vif *wvif, int idx,
+                                         __be32 *addr)
 {
+       struct hif_mib_arp_ip_addr_table arg = {
+               .condition_idx = idx,
+               .arp_enable = HIF_ARP_NS_FILTERING_DISABLE,
+       };
+
+       if (addr) {
+               // Caution: type of addr is __be32
+               memcpy(arg.ipv4_address, addr, sizeof(arg.ipv4_address));
+               arg.arp_enable = HIF_ARP_NS_FILTERING_ENABLE;
+       }
        return hif_write_mib(wvif->wdev, wvif->id,
                             HIF_MIB_ID_ARP_IP_ADDRESSES_TABLE,
-                            fp, sizeof(*fp));
+                            &arg, sizeof(arg));
 }
 
-static inline int hif_use_multi_tx_conf(struct wfx_dev *wdev,
-                                       bool enabled)
+static inline int hif_use_multi_tx_conf(struct wfx_dev *wdev, bool enable)
 {
-       __le32 arg = enabled ? cpu_to_le32(1) : 0;
+       struct hif_mib_gl_set_multi_msg arg = {
+               .enable_multi_tx_conf = enable,
+       };
 
        return hif_write_mib(wdev, -1, HIF_MIB_ID_GL_SET_MULTI_MSG,
                             &arg, sizeof(arg));
 }
 
-static inline int hif_set_uapsd_info(struct wfx_vif *wvif,
-                                    struct hif_mib_set_uapsd_information *arg)
+static inline int hif_set_uapsd_info(struct wfx_vif *wvif, unsigned long val)
 {
+       struct hif_mib_set_uapsd_information arg = { };
+
+       if (val & BIT(IEEE80211_AC_VO))
+               arg.trig_voice = 1;
+       if (val & BIT(IEEE80211_AC_VI))
+               arg.trig_video = 1;
+       if (val & BIT(IEEE80211_AC_BE))
+               arg.trig_be = 1;
+       if (val & BIT(IEEE80211_AC_BK))
+               arg.trig_bckgrnd = 1;
        return hif_write_mib(wvif->wdev, wvif->id,
                             HIF_MIB_ID_SET_UAPSD_INFORMATION,
-                            arg, sizeof(*arg));
+                            &arg, sizeof(arg));
 }
 
 static inline int hif_erp_use_protection(struct wfx_vif *wvif, bool enable)
 {
-       __le32 arg = enable ? cpu_to_le32(1) : 0;
+       struct hif_mib_non_erp_protection arg = {
+               .use_cts_to_self = enable,
+       };
 
        return hif_write_mib(wvif->wdev, wvif->id,
                             HIF_MIB_ID_NON_ERP_PROTECTION, &arg, sizeof(arg));
@@ -256,16 +359,18 @@ static inline int hif_erp_use_protection(struct wfx_vif *wvif, bool enable)
 
 static inline int hif_slot_time(struct wfx_vif *wvif, int val)
 {
-       __le32 arg = cpu_to_le32(val);
+       struct hif_mib_slot_time arg = {
+               .slot_time = cpu_to_le32(val),
+       };
 
        return hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_SLOT_TIME,
                             &arg, sizeof(arg));
 }
 
-static inline int hif_dual_cts_protection(struct wfx_vif *wvif, bool val)
+static inline int hif_dual_cts_protection(struct wfx_vif *wvif, bool enable)
 {
        struct hif_mib_set_ht_protection arg = {
-               .dual_cts_prot = val,
+               .dual_cts_prot = enable,
        };
 
        return hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_SET_HT_PROTECTION,
@@ -274,7 +379,9 @@ static inline int hif_dual_cts_protection(struct wfx_vif *wvif, bool val)
 
 static inline int hif_wep_default_key_id(struct wfx_vif *wvif, int val)
 {
-       __le32 arg = cpu_to_le32(val);
+       struct hif_mib_wep_default_key_id arg = {
+               .wep_default_key_id = val,
+       };
 
        return hif_write_mib(wvif->wdev, wvif->id,
                             HIF_MIB_ID_DOT11_WEP_DEFAULT_KEY_ID,
@@ -283,7 +390,9 @@ static inline int hif_wep_default_key_id(struct wfx_vif *wvif, int val)
 
 static inline int hif_rts_threshold(struct wfx_vif *wvif, int val)
 {
-       __le32 arg = cpu_to_le32(val > 0 ? val : 0xFFFF);
+       struct hif_mib_dot11_rts_threshold arg = {
+               .threshold = cpu_to_le32(val >= 0 ? val : 0xFFFF),
+       };
 
        return hif_write_mib(wvif->wdev, wvif->id,
                             HIF_MIB_ID_DOT11_RTS_THRESHOLD, &arg, sizeof(arg));
index b2c1a66..4b6ef06 100644 (file)
@@ -37,16 +37,11 @@ int ahb_reg_write(struct wfx_dev *wdev, u32 addr, u32 val);
 #define CFG_ERR_HOST_NO_IN_QUEUE   0x00000040
 #define CFG_ERR_HOST_CRC_MISS      0x00000080 // only with SDIO
 #define CFG_SPI_IGNORE_CS          0x00000080 // only with SPI
-/* Bytes ordering (only writable in SPI): */
-#define CFG_WORD_MODE_MASK         0x00000300
-/*
- * B1,B0,B3,B2 (In SPI, register address and
- * CONFIG data always use this mode)
- */
-#define     CFG_WORD_MODE0         0x00000000
-#define     CFG_WORD_MODE1         0x00000100 //   B3,B2,B1,B0
-#define     CFG_WORD_MODE2         0x00000200 //   B0,B1,B2,B3 (SDIO)
-#define CFG_DIRECT_ACCESS_MODE     0x00000400 // Direct or queue access mode
+#define CFG_BYTE_ORDER_MASK        0x00000300 // only writable with SPI
+#define     CFG_BYTE_ORDER_BADC    0x00000000
+#define     CFG_BYTE_ORDER_DCBA    0x00000100
+#define     CFG_BYTE_ORDER_ABCD    0x00000200 // SDIO always use this value
+#define CFG_DIRECT_ACCESS_MODE     0x00000400
 #define CFG_PREFETCH_AHB           0x00000800
 #define CFG_DISABLE_CPU_CLK        0x00001000
 #define CFG_PREFETCH_SRAM          0x00002000
index 3b47b6c..84adad6 100644 (file)
@@ -131,10 +131,11 @@ static const struct ieee80211_ops wfx_ops = {
        .stop                   = wfx_stop,
        .add_interface          = wfx_add_interface,
        .remove_interface       = wfx_remove_interface,
-       .config                 = wfx_config,
+       .config                 = wfx_config,
        .tx                     = wfx_tx,
        .conf_tx                = wfx_conf_tx,
        .hw_scan                = wfx_hw_scan,
+       .cancel_hw_scan         = wfx_cancel_hw_scan,
        .sta_add                = wfx_sta_add,
        .sta_remove             = wfx_sta_remove,
        .sta_notify             = wfx_sta_notify,
@@ -182,7 +183,7 @@ struct gpio_desc *wfx_get_gpio(struct device *dev, int override,
        } else {
                ret = devm_gpiod_get(dev, label, GPIOD_OUT_LOW);
        }
-       if (IS_ERR(ret) || !ret) {
+       if (IS_ERR_OR_NULL(ret)) {
                if (!ret || PTR_ERR(ret) == -ENOENT)
                        dev_warn(dev, "gpio %s is not defined\n", label);
                else
@@ -297,6 +298,11 @@ struct wfx_dev *wfx_init_common(struct device *dev,
        hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
                                     BIT(NL80211_IFTYPE_ADHOC) |
                                     BIT(NL80211_IFTYPE_AP);
+       hw->wiphy->probe_resp_offload = NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
+                                       NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
+                                       NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P |
+                                       NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U;
+       hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
        hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
        hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
        hw->wiphy->max_ap_assoc_sta = WFX_MAX_STA_IN_AP_MODE;
index 680fed3..0bcc61f 100644 (file)
@@ -31,8 +31,6 @@ void wfx_tx_flush(struct wfx_dev *wdev)
 {
        int ret;
 
-       WARN(!atomic_read(&wdev->tx_lock), "tx_lock is not locked");
-
        // Do not wait for any reply if chip is frozen
        if (wdev->chip_frozen)
                return;
@@ -177,11 +175,9 @@ void wfx_tx_queues_deinit(struct wfx_dev *wdev)
        wfx_tx_queues_clear(wdev);
 }
 
-size_t wfx_tx_queue_get_num_queued(struct wfx_queue *queue,
-                                  u32 link_id_map)
+int wfx_tx_queue_get_num_queued(struct wfx_queue *queue, u32 link_id_map)
 {
-       size_t ret;
-       int i, bit;
+       int ret, i;
 
        if (!link_id_map)
                return 0;
@@ -191,11 +187,9 @@ size_t wfx_tx_queue_get_num_queued(struct wfx_queue *queue,
                ret = skb_queue_len(&queue->queue);
        } else {
                ret = 0;
-               for (i = 0, bit = 1; i < ARRAY_SIZE(queue->link_map_cache);
-                    ++i, bit <<= 1) {
-                       if (link_id_map & bit)
+               for (i = 0; i < ARRAY_SIZE(queue->link_map_cache); i++)
+                       if (link_id_map & BIT(i))
                                ret += queue->link_map_cache[i];
-               }
        }
        spin_unlock_bh(&queue->queue.lock);
        return ret;
@@ -237,7 +231,6 @@ static struct sk_buff *wfx_tx_queue_get(struct wfx_dev *wdev,
                        break;
                }
        }
-       WARN_ON(!skb);
        if (skb) {
                tx_priv = wfx_skb_tx_priv(skb);
                tx_priv->xmit_timestamp = ktime_get();
@@ -362,80 +355,38 @@ bool wfx_tx_queues_is_empty(struct wfx_dev *wdev)
 static bool hif_handle_tx_data(struct wfx_vif *wvif, struct sk_buff *skb,
                               struct wfx_queue *queue)
 {
-       bool handled = false;
-       struct wfx_tx_priv *tx_priv = wfx_skb_tx_priv(skb);
        struct hif_req_tx *req = wfx_skb_txreq(skb);
-       struct ieee80211_hdr *frame = (struct ieee80211_hdr *) (req->frame + req->data_flags.fc_offset);
-
-       enum {
-               do_probe,
-               do_drop,
-               do_wep,
-               do_tx,
-       } action = do_tx;
-
-       switch (wvif->vif->type) {
-       case NL80211_IFTYPE_STATION:
-               if (wvif->state < WFX_STATE_PRE_STA)
-                       action = do_drop;
-               break;
-       case NL80211_IFTYPE_AP:
-               if (!wvif->state) {
-                       action = do_drop;
-               } else if (!(BIT(tx_priv->raw_link_id) &
-                            (BIT(0) | wvif->link_id_map))) {
-                       dev_warn(wvif->wdev->dev, "a frame with expired link-id is dropped\n");
-                       action = do_drop;
-               }
-               break;
-       case NL80211_IFTYPE_ADHOC:
-               if (wvif->state != WFX_STATE_IBSS)
-                       action = do_drop;
-               break;
-       case NL80211_IFTYPE_MONITOR:
-       default:
-               action = do_drop;
-               break;
-       }
-
-       if (action == do_tx) {
-               if (ieee80211_is_nullfunc(frame->frame_control)) {
-                       mutex_lock(&wvif->bss_loss_lock);
-                       if (wvif->bss_loss_state) {
-                               wvif->bss_loss_confirm_id = req->packet_id;
-                               req->queue_id.queue_id = HIF_QUEUE_ID_VOICE;
-                       }
-                       mutex_unlock(&wvif->bss_loss_lock);
-               } else if (ieee80211_has_protected(frame->frame_control) &&
-                          tx_priv->hw_key &&
-                          tx_priv->hw_key->keyidx != wvif->wep_default_key_id &&
-                          (tx_priv->hw_key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
-                           tx_priv->hw_key->cipher == WLAN_CIPHER_SUITE_WEP104)) {
-                       action = do_wep;
+       struct ieee80211_key_conf *hw_key = wfx_skb_tx_priv(skb)->hw_key;
+       struct ieee80211_hdr *frame =
+               (struct ieee80211_hdr *)(req->frame + req->data_flags.fc_offset);
+
+       // FIXME: mac80211 is smart enough to handle BSS loss. Driver should not
+       // try to do anything about that.
+       if (ieee80211_is_nullfunc(frame->frame_control)) {
+               mutex_lock(&wvif->bss_loss_lock);
+               if (wvif->bss_loss_state) {
+                       wvif->bss_loss_confirm_id = req->packet_id;
+                       req->queue_id.queue_id = HIF_QUEUE_ID_VOICE;
                }
+               mutex_unlock(&wvif->bss_loss_lock);
        }
 
-       switch (action) {
-       case do_drop:
-               wfx_pending_remove(wvif->wdev, skb);
-               handled = true;
-               break;
-       case do_wep:
+       // FIXME: identify the exact scenario matched by this condition. Does it
+       // happen yet?
+       if (ieee80211_has_protected(frame->frame_control) &&
+           hw_key && hw_key->keyidx != wvif->wep_default_key_id &&
+           (hw_key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
+            hw_key->cipher == WLAN_CIPHER_SUITE_WEP104)) {
                wfx_tx_lock(wvif->wdev);
                WARN_ON(wvif->wep_pending_skb);
-               wvif->wep_default_key_id = tx_priv->hw_key->keyidx;
+               wvif->wep_default_key_id = hw_key->keyidx;
                wvif->wep_pending_skb = skb;
                if (!schedule_work(&wvif->wep_key_work))
                        wfx_tx_unlock(wvif->wdev);
-               handled = true;
-               break;
-       case do_tx:
-               break;
-       default:
-               /* Do nothing */
-               break;
+               return true;
+       } else {
+               return false;
        }
-       return handled;
 }
 
 static int wfx_get_prio_queue(struct wfx_vif *wvif,
@@ -443,7 +394,7 @@ static int wfx_get_prio_queue(struct wfx_vif *wvif,
 {
        static const int urgent = BIT(WFX_LINK_ID_AFTER_DTIM) |
                BIT(WFX_LINK_ID_UAPSD);
-       struct hif_req_edca_queue_params *edca;
+       const struct ieee80211_tx_queue_params *edca;
        unsigned int score, best = -1;
        int winner = -1;
        int i;
@@ -452,13 +403,13 @@ static int wfx_get_prio_queue(struct wfx_vif *wvif,
        for (i = 0; i < IEEE80211_NUM_ACS; ++i) {
                int queued;
 
-               edca = &wvif->edca.params[i];
+               edca = &wvif->edca_params[i];
                queued = wfx_tx_queue_get_num_queued(&wvif->wdev->tx_queue[i],
                                tx_allowed_mask);
                if (!queued)
                        continue;
                *total += queued;
-               score = ((edca->aifsn + edca->cw_min) << 16) +
+               score = ((edca->aifs + edca->cw_min) << 16) +
                        ((edca->cw_max - edca->cw_min) *
                         (get_random_int() & 0xFFFF));
                if (score < best && (winner < 0 || i != 3)) {
@@ -480,94 +431,100 @@ static int wfx_get_prio_queue(struct wfx_vif *wvif,
 
 static int wfx_tx_queue_mask_get(struct wfx_vif *wvif,
                                     struct wfx_queue **queue_p,
-                                    u32 *tx_allowed_mask_p,
-                                    bool *more)
+                                    u32 *tx_allowed_mask_p)
 {
        int idx;
        u32 tx_allowed_mask;
        int total = 0;
 
-       /* Search for a queue with multicast frames buffered */
-       if (wvif->mcast_tx) {
-               tx_allowed_mask = BIT(WFX_LINK_ID_AFTER_DTIM);
-               idx = wfx_get_prio_queue(wvif, tx_allowed_mask, &total);
-               if (idx >= 0) {
-                       *more = total > 1;
-                       goto found;
-               }
-       }
-
        /* Search for unicast traffic */
        tx_allowed_mask = ~wvif->sta_asleep_mask;
        tx_allowed_mask |= BIT(WFX_LINK_ID_UAPSD);
-       if (wvif->sta_asleep_mask) {
-               tx_allowed_mask |= wvif->pspoll_mask;
+       if (wvif->sta_asleep_mask)
                tx_allowed_mask &= ~BIT(WFX_LINK_ID_AFTER_DTIM);
-       } else {
+       else
                tx_allowed_mask |= BIT(WFX_LINK_ID_AFTER_DTIM);
-       }
        idx = wfx_get_prio_queue(wvif, tx_allowed_mask, &total);
        if (idx < 0)
                return -ENOENT;
 
-found:
        *queue_p = &wvif->wdev->tx_queue[idx];
        *tx_allowed_mask_p = tx_allowed_mask;
        return 0;
 }
 
+struct hif_msg *wfx_tx_queues_get_after_dtim(struct wfx_vif *wvif)
+{
+       struct wfx_dev *wdev = wvif->wdev;
+       struct ieee80211_tx_info *tx_info;
+       struct hif_msg *hif;
+       struct sk_buff *skb;
+       int i;
+
+       for (i = 0; i < IEEE80211_NUM_ACS; ++i) {
+               skb_queue_walk(&wdev->tx_queue[i].queue, skb) {
+                       tx_info = IEEE80211_SKB_CB(skb);
+                       hif = (struct hif_msg *)skb->data;
+                       if ((tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) &&
+                           (hif->interface == wvif->id))
+                               return (struct hif_msg *)skb->data;
+               }
+       }
+       return NULL;
+}
+
 struct hif_msg *wfx_tx_queues_get(struct wfx_dev *wdev)
 {
        struct sk_buff *skb;
        struct hif_msg *hif = NULL;
-       struct hif_req_tx *req = NULL;
        struct wfx_queue *queue = NULL;
        struct wfx_queue *vif_queue = NULL;
        u32 tx_allowed_mask = 0;
        u32 vif_tx_allowed_mask = 0;
        const struct wfx_tx_priv *tx_priv = NULL;
        struct wfx_vif *wvif;
-       /* More is used only for broadcasts. */
-       bool more = false;
-       bool vif_more = false;
        int not_found;
        int burst;
+       int i;
+
+       if (atomic_read(&wdev->tx_lock))
+               return NULL;
+
+       wvif = NULL;
+       while ((wvif = wvif_iterate(wdev, wvif)) != NULL) {
+               if (wvif->after_dtim_tx_allowed) {
+                       for (i = 0; i < IEEE80211_NUM_ACS; ++i) {
+                               skb = wfx_tx_queue_get(wvif->wdev,
+                                                      &wdev->tx_queue[i],
+                                                      BIT(WFX_LINK_ID_AFTER_DTIM));
+                               if (skb) {
+                                       hif = (struct hif_msg *)skb->data;
+                                       // Cannot happen since only one vif can
+                                       // be AP at time
+                                       WARN_ON(wvif->id != hif->interface);
+                                       return hif;
+                               }
+                       }
+                       // No more multicast to sent
+                       wvif->after_dtim_tx_allowed = false;
+                       schedule_work(&wvif->update_tim_work);
+               }
+       }
 
        for (;;) {
                int ret = -ENOENT;
                int queue_num;
-               struct ieee80211_hdr *hdr;
-
-               if (atomic_read(&wdev->tx_lock))
-                       return NULL;
 
                wvif = NULL;
                while ((wvif = wvif_iterate(wdev, wvif)) != NULL) {
                        spin_lock_bh(&wvif->ps_state_lock);
 
                        not_found = wfx_tx_queue_mask_get(wvif, &vif_queue,
-                                                         &vif_tx_allowed_mask,
-                                                         &vif_more);
-
-                       if (wvif->mcast_buffered && (not_found || !vif_more) &&
-                                       (wvif->mcast_tx ||
-                                        !wvif->sta_asleep_mask)) {
-                               wvif->mcast_buffered = false;
-                               if (wvif->mcast_tx) {
-                                       wvif->mcast_tx = false;
-                                       schedule_work(&wvif->mcast_stop_work);
-                               }
-                       }
+                                                         &vif_tx_allowed_mask);
 
                        spin_unlock_bh(&wvif->ps_state_lock);
 
-                       if (vif_more) {
-                               more = true;
-                               tx_allowed_mask = vif_tx_allowed_mask;
-                               queue = vif_queue;
-                               ret = 0;
-                               break;
-                       } else if (!not_found) {
+                       if (!not_found) {
                                if (queue && queue != vif_queue)
                                        dev_info(wdev->dev, "vifs disagree about queue priority\n");
                                tx_allowed_mask |= vif_tx_allowed_mask;
@@ -592,11 +549,9 @@ struct hif_msg *wfx_tx_queues_get(struct wfx_dev *wdev)
                if (hif_handle_tx_data(wvif, skb, queue))
                        continue;  /* Handled by WSM */
 
-               wvif->pspoll_mask &= ~BIT(tx_priv->raw_link_id);
-
                /* allow bursting if txop is set */
-               if (wvif->edca.params[queue_num].tx_op_limit)
-                       burst = (int)wfx_tx_queue_get_num_queued(queue, tx_allowed_mask) + 1;
+               if (wvif->edca_params[queue_num].txop)
+                       burst = wfx_tx_queue_get_num_queued(queue, tx_allowed_mask) + 1;
                else
                        burst = 1;
 
@@ -606,15 +561,6 @@ struct hif_msg *wfx_tx_queues_get(struct wfx_dev *wdev)
                else
                        wdev->tx_burst_idx = -1;
 
-               /* more buffered multicast/broadcast frames
-                *  ==> set MoreData flag in IEEE 802.11 header
-                *  to inform PS STAs
-                */
-               if (more) {
-                       req = (struct hif_req_tx *) hif->body;
-                       hdr = (struct ieee80211_hdr *) (req->frame + req->data_flags.fc_offset);
-                       hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
-               }
                return hif;
        }
 }
index 21566e4..90bb060 100644 (file)
 #include "hif_api_cmd.h"
 
 #define WFX_MAX_STA_IN_AP_MODE    14
-#define WFX_LINK_ID_AFTER_DTIM    (WFX_MAX_STA_IN_AP_MODE + 1)
-#define WFX_LINK_ID_UAPSD         (WFX_MAX_STA_IN_AP_MODE + 2)
-#define WFX_LINK_ID_MAX           (WFX_MAX_STA_IN_AP_MODE + 3)
+#define WFX_LINK_ID_NO_ASSOC      15
+#define WFX_LINK_ID_AFTER_DTIM    (WFX_LINK_ID_NO_ASSOC + 1)
+#define WFX_LINK_ID_UAPSD         (WFX_LINK_ID_NO_ASSOC + 2)
+#define WFX_LINK_ID_MAX           (WFX_LINK_ID_NO_ASSOC + 3)
 
 struct wfx_dev;
 struct wfx_vif;
@@ -46,10 +47,11 @@ void wfx_tx_queues_clear(struct wfx_dev *wdev);
 bool wfx_tx_queues_is_empty(struct wfx_dev *wdev);
 void wfx_tx_queues_wait_empty_vif(struct wfx_vif *wvif);
 struct hif_msg *wfx_tx_queues_get(struct wfx_dev *wdev);
+struct hif_msg *wfx_tx_queues_get_after_dtim(struct wfx_vif *wvif);
 
 void wfx_tx_queue_put(struct wfx_dev *wdev, struct wfx_queue *queue,
                      struct sk_buff *skb);
-size_t wfx_tx_queue_get_num_queued(struct wfx_queue *queue, u32 link_id_map);
+int wfx_tx_queue_get_num_queued(struct wfx_queue *queue, u32 link_id_map);
 
 struct sk_buff *wfx_pending_get(struct wfx_dev *wdev, u32 packet_id);
 int wfx_pending_remove(struct wfx_dev *wdev, struct sk_buff *skb);
index 35fcf91..6e1e500 100644 (file)
@@ -16,279 +16,118 @@ static void __ieee80211_scan_completed_compat(struct ieee80211_hw *hw,
                                              bool aborted)
 {
        struct cfg80211_scan_info info = {
-               .aborted = aborted ? 1 : 0,
+               .aborted = aborted,
        };
 
        ieee80211_scan_completed(hw, &info);
 }
 
-static void wfx_scan_restart_delayed(struct wfx_vif *wvif)
+static int update_probe_tmpl(struct wfx_vif *wvif,
+                            struct cfg80211_scan_request *req)
 {
-       if (wvif->delayed_unjoin) {
-               wvif->delayed_unjoin = false;
-               if (!schedule_work(&wvif->unjoin_work))
-                       wfx_tx_unlock(wvif->wdev);
-       } else if (wvif->delayed_link_loss) {
-               wvif->delayed_link_loss = 0;
-               wfx_cqm_bssloss_sm(wvif, 1, 0, 0);
-       }
-}
-
-static int wfx_scan_start(struct wfx_vif *wvif, struct wfx_scan_params *scan)
-{
-       int ret;
-       int tmo = 500;
-
-       if (wvif->state == WFX_STATE_PRE_STA)
-               return -EBUSY;
-
-       tmo += scan->scan_req.num_of_channels *
-              ((20 * (scan->scan_req.max_channel_time)) + 10);
-       atomic_set(&wvif->scan.in_progress, 1);
-       atomic_set(&wvif->wdev->scan_in_progress, 1);
-
-       schedule_delayed_work(&wvif->scan.timeout, msecs_to_jiffies(tmo));
-       ret = hif_scan(wvif, scan);
-       if (ret) {
-               wfx_scan_failed_cb(wvif);
-               atomic_set(&wvif->scan.in_progress, 0);
-               atomic_set(&wvif->wdev->scan_in_progress, 0);
-               cancel_delayed_work_sync(&wvif->scan.timeout);
-               wfx_scan_restart_delayed(wvif);
-       }
-       return ret;
-}
-
-int wfx_hw_scan(struct ieee80211_hw *hw,
-                  struct ieee80211_vif *vif,
-                  struct ieee80211_scan_request *hw_req)
-{
-       struct wfx_dev *wdev = hw->priv;
-       struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv;
-       struct cfg80211_scan_request *req = &hw_req->req;
        struct sk_buff *skb;
-       int i, ret;
-       struct hif_mib_template_frame *p;
-
-       if (!wvif)
-               return -EINVAL;
-
-       if (wvif->state == WFX_STATE_AP)
-               return -EOPNOTSUPP;
-
-       if (req->n_ssids == 1 && !req->ssids[0].ssid_len)
-               req->n_ssids = 0;
 
-       if (req->n_ssids > HIF_API_MAX_NB_SSIDS)
-               return -EINVAL;
-
-       skb = ieee80211_probereq_get(hw, wvif->vif->addr, NULL, 0, req->ie_len);
+       skb = ieee80211_probereq_get(wvif->wdev->hw, wvif->vif->addr,
+                                    NULL, 0, req->ie_len);
        if (!skb)
                return -ENOMEM;
 
-       if (req->ie_len)
-               memcpy(skb_put(skb, req->ie_len), req->ie, req->ie_len);
-
-       mutex_lock(&wdev->conf_mutex);
-
-       p = (struct hif_mib_template_frame *)skb_push(skb, 4);
-       p->frame_type = HIF_TMPLT_PRBREQ;
-       p->frame_length = cpu_to_le16(skb->len - 4);
-       ret = hif_set_template_frame(wvif, p);
-       skb_pull(skb, 4);
-
-       if (!ret)
-               /* Host want to be the probe responder. */
-               ret = wfx_fwd_probe_req(wvif, true);
-       if (ret) {
-               mutex_unlock(&wdev->conf_mutex);
-               dev_kfree_skb(skb);
-               return ret;
-       }
-
-       wfx_tx_lock_flush(wdev);
-
-       WARN(wvif->scan.req, "unexpected concurrent scan");
-       wvif->scan.req = req;
-       wvif->scan.n_ssids = 0;
-       wvif->scan.status = 0;
-       wvif->scan.begin = &req->channels[0];
-       wvif->scan.curr = wvif->scan.begin;
-       wvif->scan.end = &req->channels[req->n_channels];
-       wvif->scan.output_power = wdev->output_power;
-
-       for (i = 0; i < req->n_ssids; ++i) {
-               struct hif_ssid_def *dst = &wvif->scan.ssids[wvif->scan.n_ssids];
-
-               memcpy(&dst->ssid[0], req->ssids[i].ssid, sizeof(dst->ssid));
-               dst->ssid_length = req->ssids[i].ssid_len;
-               ++wvif->scan.n_ssids;
-       }
-
-       mutex_unlock(&wdev->conf_mutex);
-
-       if (skb)
-               dev_kfree_skb(skb);
-       schedule_work(&wvif->scan.work);
+       skb_put_data(skb, req->ie, req->ie_len);
+       hif_set_template_frame(wvif, skb, HIF_TMPLT_PRBREQ, 0);
+       dev_kfree_skb(skb);
        return 0;
 }
 
-void wfx_scan_work(struct work_struct *work)
+static int send_scan_req(struct wfx_vif *wvif,
+                        struct cfg80211_scan_request *req, int start_idx)
 {
-       struct wfx_vif *wvif = container_of(work, struct wfx_vif, scan.work);
-       struct ieee80211_channel **it;
-       struct wfx_scan_params scan = {
-               .scan_req.scan_type.type = 0,    /* Foreground */
-       };
-       struct ieee80211_channel *first;
-       bool first_run = (wvif->scan.begin == wvif->scan.curr &&
-                         wvif->scan.begin != wvif->scan.end);
-       int i;
-
-       down(&wvif->scan.lock);
-       mutex_lock(&wvif->wdev->conf_mutex);
-
-       if (first_run) {
-               if (wvif->state == WFX_STATE_STA &&
-                   !(wvif->powersave_mode.pm_mode.enter_psm)) {
-                       struct hif_req_set_pm_mode pm = wvif->powersave_mode;
-
-                       pm.pm_mode.enter_psm = 1;
-                       wfx_set_pm(wvif, &pm);
-               }
-       }
-
-       if (!wvif->scan.req || wvif->scan.curr == wvif->scan.end) {
-               if (wvif->scan.output_power != wvif->wdev->output_power)
-                       hif_set_output_power(wvif,
-                                            wvif->wdev->output_power * 10);
-
-               if (wvif->scan.status < 0)
-                       dev_warn(wvif->wdev->dev, "scan failed\n");
-               else if (wvif->scan.req)
-                       dev_dbg(wvif->wdev->dev, "scan completed\n");
-               else
-                       dev_dbg(wvif->wdev->dev, "scan canceled\n");
-
-               wvif->scan.req = NULL;
-               wfx_scan_restart_delayed(wvif);
-               wfx_tx_unlock(wvif->wdev);
-               mutex_unlock(&wvif->wdev->conf_mutex);
-               __ieee80211_scan_completed_compat(wvif->wdev->hw,
-                                                 wvif->scan.status ? 1 : 0);
-               up(&wvif->scan.lock);
-               if (wvif->state == WFX_STATE_STA &&
-                   !(wvif->powersave_mode.pm_mode.enter_psm))
-                       wfx_set_pm(wvif, &wvif->powersave_mode);
-               return;
-       }
-       first = *wvif->scan.curr;
-
-       for (it = wvif->scan.curr + 1, i = 1;
-            it != wvif->scan.end && i < HIF_API_MAX_NB_CHANNELS;
-            ++it, ++i) {
-               if ((*it)->band != first->band)
-                       break;
-               if (((*it)->flags ^ first->flags) &
-                               IEEE80211_CHAN_NO_IR)
+       int i, ret, timeout;
+       struct ieee80211_channel *ch_start, *ch_cur;
+
+       for (i = start_idx; i < req->n_channels; i++) {
+               ch_start = req->channels[start_idx];
+               ch_cur = req->channels[i];
+               WARN(ch_cur->band != NL80211_BAND_2GHZ, "band not supported");
+               if (ch_cur->max_power != ch_start->max_power)
                        break;
-               if (!(first->flags & IEEE80211_CHAN_NO_IR) &&
-                   (*it)->max_power != first->max_power)
+               if ((ch_cur->flags ^ ch_start->flags) & IEEE80211_CHAN_NO_IR)
                        break;
        }
-       scan.scan_req.band = first->band;
-
-       if (wvif->scan.req->no_cck)
-               scan.scan_req.max_transmit_rate = API_RATE_INDEX_G_6MBPS;
-       else
-               scan.scan_req.max_transmit_rate = API_RATE_INDEX_B_1MBPS;
-       scan.scan_req.num_of_probe_requests =
-               (first->flags & IEEE80211_CHAN_NO_IR) ? 0 : 2;
-       scan.scan_req.num_of_ssi_ds = wvif->scan.n_ssids;
-       scan.ssids = &wvif->scan.ssids[0];
-       scan.scan_req.num_of_channels = it - wvif->scan.curr;
-       scan.scan_req.probe_delay = 100;
-       // FIXME: Check if FW can do active scan while joined.
-       if (wvif->state == WFX_STATE_STA) {
-               scan.scan_req.scan_type.type = 1;
-               scan.scan_req.scan_flags.fbg = 1;
+       wfx_tx_lock_flush(wvif->wdev);
+       wvif->scan_abort = false;
+       reinit_completion(&wvif->scan_complete);
+       timeout = hif_scan(wvif, req, start_idx, i - start_idx);
+       if (timeout < 0)
+               return timeout;
+       ret = wait_for_completion_timeout(&wvif->scan_complete, timeout);
+       if (req->channels[start_idx]->max_power != wvif->vif->bss_conf.txpower)
+               hif_set_output_power(wvif, wvif->vif->bss_conf.txpower);
+       wfx_tx_unlock(wvif->wdev);
+       if (!ret) {
+               dev_notice(wvif->wdev->dev, "scan timeout\n");
+               hif_stop_scan(wvif);
+               return -ETIMEDOUT;
        }
-
-       scan.ch = kcalloc(scan.scan_req.num_of_channels,
-                         sizeof(u8), GFP_KERNEL);
-
-       if (!scan.ch) {
-               wvif->scan.status = -ENOMEM;
-               goto fail;
+       if (wvif->scan_abort) {
+               dev_notice(wvif->wdev->dev, "scan abort\n");
+               return -ECONNABORTED;
        }
-       for (i = 0; i < scan.scan_req.num_of_channels; ++i)
-               scan.ch[i] = wvif->scan.curr[i]->hw_value;
+       return i - start_idx;
+}
 
-       if (wvif->scan.curr[0]->flags & IEEE80211_CHAN_NO_IR) {
-               scan.scan_req.min_channel_time = 50;
-               scan.scan_req.max_channel_time = 150;
-       } else {
-               scan.scan_req.min_channel_time = 10;
-               scan.scan_req.max_channel_time = 50;
-       }
-       if (!(first->flags & IEEE80211_CHAN_NO_IR) &&
-           wvif->scan.output_power != first->max_power) {
-               wvif->scan.output_power = first->max_power;
-               hif_set_output_power(wvif, wvif->scan.output_power * 10);
-       }
-       wvif->scan.status = wfx_scan_start(wvif, &scan);
-       kfree(scan.ch);
-       if (wvif->scan.status)
-               goto fail;
-       wvif->scan.curr = it;
-       mutex_unlock(&wvif->wdev->conf_mutex);
-       return;
+/*
+ * It is not really necessary to run scan request asynchronously. However,
+ * there is a bug in "iw scan" when ieee80211_scan_completed() is called before
+ * wfx_hw_scan() return
+ */
+void wfx_hw_scan_work(struct work_struct *work)
+{
+       struct wfx_vif *wvif = container_of(work, struct wfx_vif, scan_work);
+       struct ieee80211_scan_request *hw_req = wvif->scan_req;
+       int chan_cur, ret;
 
-fail:
-       wvif->scan.curr = wvif->scan.end;
+       mutex_lock(&wvif->scan_lock);
+       mutex_lock(&wvif->wdev->conf_mutex);
+       update_probe_tmpl(wvif, &hw_req->req);
+       wfx_fwd_probe_req(wvif, true);
+       chan_cur = 0;
+       do {
+               ret = send_scan_req(wvif, &hw_req->req, chan_cur);
+               if (ret > 0)
+                       chan_cur += ret;
+       } while (ret > 0 && chan_cur < hw_req->req.n_channels);
        mutex_unlock(&wvif->wdev->conf_mutex);
-       up(&wvif->scan.lock);
-       schedule_work(&wvif->scan.work);
+       mutex_unlock(&wvif->scan_lock);
+       __ieee80211_scan_completed_compat(wvif->wdev->hw, ret < 0);
 }
 
-static void wfx_scan_complete(struct wfx_vif *wvif)
+int wfx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+               struct ieee80211_scan_request *hw_req)
 {
-       up(&wvif->scan.lock);
-       atomic_set(&wvif->wdev->scan_in_progress, 0);
+       struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv;
 
-       wfx_scan_work(&wvif->scan.work);
-}
+       WARN_ON(hw_req->req.n_channels > HIF_API_MAX_NB_CHANNELS);
 
-void wfx_scan_failed_cb(struct wfx_vif *wvif)
-{
-       if (cancel_delayed_work_sync(&wvif->scan.timeout) > 0) {
-               wvif->scan.status = -EIO;
-               schedule_work(&wvif->scan.timeout.work);
-       }
+       if (vif->type == NL80211_IFTYPE_AP)
+               return -EOPNOTSUPP;
+
+       if (wvif->state == WFX_STATE_PRE_STA)
+               return -EBUSY;
+
+       wvif->scan_req = hw_req;
+       schedule_work(&wvif->scan_work);
+       return 0;
 }
 
-void wfx_scan_complete_cb(struct wfx_vif *wvif, struct hif_ind_scan_cmpl *arg)
+void wfx_cancel_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 {
-       if (cancel_delayed_work_sync(&wvif->scan.timeout) > 0) {
-               wvif->scan.status = 1;
-               schedule_work(&wvif->scan.timeout.work);
-       }
+       struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv;
+
+       wvif->scan_abort = true;
+       hif_stop_scan(wvif);
 }
 
-void wfx_scan_timeout(struct work_struct *work)
+void wfx_scan_complete(struct wfx_vif *wvif)
 {
-       struct wfx_vif *wvif = container_of(work, struct wfx_vif,
-                                           scan.timeout.work);
-
-       if (atomic_xchg(&wvif->scan.in_progress, 0)) {
-               if (wvif->scan.status > 0) {
-                       wvif->scan.status = 0;
-               } else if (!wvif->scan.status) {
-                       dev_warn(wvif->wdev->dev, "timeout waiting for scan complete notification\n");
-                       wvif->scan.status = -ETIMEDOUT;
-                       wvif->scan.curr = wvif->scan.end;
-                       hif_stop_scan(wvif);
-               }
-               wfx_scan_complete(wvif);
-       }
+       complete(&wvif->scan_complete);
 }
index b4ddd07..2eb786c 100644 (file)
@@ -8,35 +8,15 @@
 #ifndef WFX_SCAN_H
 #define WFX_SCAN_H
 
-#include <linux/semaphore.h>
-#include <linux/workqueue.h>
 #include <net/mac80211.h>
 
-#include "hif_api_cmd.h"
-
 struct wfx_dev;
 struct wfx_vif;
 
-struct wfx_scan {
-       struct semaphore lock;
-       struct work_struct work;
-       struct delayed_work timeout;
-       struct cfg80211_scan_request *req;
-       struct ieee80211_channel **begin;
-       struct ieee80211_channel **curr;
-       struct ieee80211_channel **end;
-       struct hif_ssid_def ssids[HIF_API_MAX_NB_SSIDS];
-       int output_power;
-       int n_ssids;
-       int status;
-       atomic_t in_progress;
-};
-
+void wfx_hw_scan_work(struct work_struct *work);
 int wfx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                struct ieee80211_scan_request *req);
-void wfx_scan_work(struct work_struct *work);
-void wfx_scan_timeout(struct work_struct *work);
-void wfx_scan_complete_cb(struct wfx_vif *wvif, struct hif_ind_scan_cmpl *arg);
-void wfx_scan_failed_cb(struct wfx_vif *wvif);
+void wfx_cancel_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
+void wfx_scan_complete(struct wfx_vif *wvif);
 
 #endif /* WFX_SCAN_H */
index 666b26e..c3d055b 100644 (file)
@@ -25,14 +25,16 @@ static inline int wfx_sl_decode(struct wfx_dev *wdev, struct hif_sl_msg *m)
        return -EIO;
 }
 
-static inline int wfx_sl_encode(struct wfx_dev *wdev, struct hif_msg *input,
+static inline int wfx_sl_encode(struct wfx_dev *wdev,
+                               const struct hif_msg *input,
                                struct hif_sl_msg *output)
 {
        return -EIO;
 }
 
-static inline int wfx_sl_check_pubkey(struct wfx_dev *wdev, u8 *ncp_pubkey,
-                                     u8 *ncp_pubmac)
+static inline int wfx_sl_check_pubkey(struct wfx_dev *wdev,
+                                     const u8 *ncp_pubkey,
+                                     const u8 *ncp_pubmac)
 {
        return -EIO;
 }
index 471dd15..03d0f22 100644 (file)
 #include "hif_tx.h"
 #include "hif_tx_mib.h"
 
-#define TXOP_UNIT 32
 #define HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES 2
 
-static u32 wfx_rate_mask_to_hw(struct wfx_dev *wdev, u32 rates)
+u32 wfx_rate_mask_to_hw(struct wfx_dev *wdev, u32 rates)
 {
        int i;
        u32 ret = 0;
@@ -64,13 +63,8 @@ void wfx_cqm_bssloss_sm(struct wfx_vif *wvif, int init, int good, int bad)
        int tx = 0;
 
        mutex_lock(&wvif->bss_loss_lock);
-       wvif->delayed_link_loss = 0;
        cancel_work_sync(&wvif->bss_params_work);
 
-       /* If we have a pending unjoin */
-       if (wvif->delayed_unjoin)
-               goto end;
-
        if (init) {
                schedule_delayed_work(&wvif->bss_loss_work, HZ);
                wvif->bss_loss_state = 0;
@@ -94,62 +88,30 @@ void wfx_cqm_bssloss_sm(struct wfx_vif *wvif, int init, int good, int bad)
        // FIXME: call ieee80211_beacon_loss/ieee80211_connection_loss instead
        if (tx) {
                struct sk_buff *skb;
+               struct ieee80211_hdr *hdr;
+               struct ieee80211_tx_control control = { };
 
                wvif->bss_loss_state++;
 
                skb = ieee80211_nullfunc_get(wvif->wdev->hw, wvif->vif, false);
                if (!skb)
                        goto end;
+               hdr = (struct ieee80211_hdr *)skb->data;
                memset(IEEE80211_SKB_CB(skb), 0,
                       sizeof(*IEEE80211_SKB_CB(skb)));
                IEEE80211_SKB_CB(skb)->control.vif = wvif->vif;
                IEEE80211_SKB_CB(skb)->driver_rates[0].idx = 0;
                IEEE80211_SKB_CB(skb)->driver_rates[0].count = 1;
                IEEE80211_SKB_CB(skb)->driver_rates[1].idx = -1;
-               wfx_tx(wvif->wdev->hw, NULL, skb);
+               rcu_read_lock(); // protect control.sta
+               control.sta = ieee80211_find_sta(wvif->vif, hdr->addr1);
+               wfx_tx(wvif->wdev->hw, &control, skb);
+               rcu_read_unlock();
        }
 end:
        mutex_unlock(&wvif->bss_loss_lock);
 }
 
-static int wfx_set_uapsd_param(struct wfx_vif *wvif,
-                          const struct wfx_edca_params *arg)
-{
-       /* Here's the mapping AC [queue, bit]
-        *  VO [0,3], VI [1, 2], BE [2, 1], BK [3, 0]
-        */
-
-       if (arg->uapsd_enable[IEEE80211_AC_VO])
-               wvif->uapsd_info.trig_voice = 1;
-       else
-               wvif->uapsd_info.trig_voice = 0;
-
-       if (arg->uapsd_enable[IEEE80211_AC_VI])
-               wvif->uapsd_info.trig_video = 1;
-       else
-               wvif->uapsd_info.trig_video = 0;
-
-       if (arg->uapsd_enable[IEEE80211_AC_BE])
-               wvif->uapsd_info.trig_be = 1;
-       else
-               wvif->uapsd_info.trig_be = 0;
-
-       if (arg->uapsd_enable[IEEE80211_AC_BK])
-               wvif->uapsd_info.trig_bckgrnd = 1;
-       else
-               wvif->uapsd_info.trig_bckgrnd = 0;
-
-       /* Currently pseudo U-APSD operation is not supported, so setting
-        * MinAutoTriggerInterval, MaxAutoTriggerInterval and
-        * AutoTriggerStep to 0
-        */
-       wvif->uapsd_info.min_auto_trigger_interval = 0;
-       wvif->uapsd_info.max_auto_trigger_interval = 0;
-       wvif->uapsd_info.auto_trigger_step = 0;
-
-       return hif_set_uapsd_info(wvif, &wvif->uapsd_info);
-}
-
 int wfx_fwd_probe_req(struct wfx_vif *wvif, bool enable)
 {
        wvif->fwd_probe_req = enable;
@@ -160,63 +122,31 @@ int wfx_fwd_probe_req(struct wfx_vif *wvif, bool enable)
 static int wfx_set_mcast_filter(struct wfx_vif *wvif,
                                    struct wfx_grp_addr_table *fp)
 {
-       int i, ret;
-       struct hif_mib_config_data_filter config = { };
-       struct hif_mib_set_data_filtering filter_data = { };
-       struct hif_mib_mac_addr_data_frame_condition filter_addr_val = { };
-       struct hif_mib_uc_mc_bc_data_frame_condition filter_addr_type = { };
+       int i;
 
        // Temporary workaround for filters
-       return hif_set_data_filtering(wvif, &filter_data);
-
-       if (!fp->enable) {
-               filter_data.enable = 0;
-               return hif_set_data_filtering(wvif, &filter_data);
-       }
-
-       // A1 Address match on list
-       for (i = 0; i < fp->num_addresses; i++) {
-               filter_addr_val.condition_idx = i;
-               filter_addr_val.address_type = HIF_MAC_ADDR_A1;
-               ether_addr_copy(filter_addr_val.mac_address,
-                               fp->address_list[i]);
-               ret = hif_set_mac_addr_condition(wvif,
-                                                &filter_addr_val);
-               if (ret)
-                       return ret;
-               config.mac_cond |= 1 << i;
-       }
-
-       // Accept unicast and broadcast
-       filter_addr_type.condition_idx = 0;
-       filter_addr_type.param.bits.type_unicast = 1;
-       filter_addr_type.param.bits.type_broadcast = 1;
-       ret = hif_set_uc_mc_bc_condition(wvif, &filter_addr_type);
-       if (ret)
-               return ret;
+       return hif_set_data_filtering(wvif, false, true);
 
-       config.uc_mc_bc_cond = 1;
-       config.filter_idx = 0; // TODO #define MULTICAST_FILTERING 0
-       config.enable = 1;
-       ret = hif_set_config_data_filter(wvif, &config);
-       if (ret)
-               return ret;
+       if (!fp->enable)
+               return hif_set_data_filtering(wvif, false, true);
 
-       // discard all data frames except match filter
-       filter_data.enable = 1;
-       filter_data.default_filter = 1; // discard all
-       ret = hif_set_data_filtering(wvif, &filter_data);
+       for (i = 0; i < fp->num_addresses; i++)
+               hif_set_mac_addr_condition(wvif, i, fp->address_list[i]);
+       hif_set_uc_mc_bc_condition(wvif, 0,
+                                  HIF_FILTER_UNICAST | HIF_FILTER_BROADCAST);
+       hif_set_config_data_filter(wvif, true, 0, BIT(1),
+                                  BIT(fp->num_addresses) - 1);
+       hif_set_data_filtering(wvif, true, true);
 
-       return ret;
+       return 0;
 }
 
 void wfx_update_filtering(struct wfx_vif *wvif)
 {
        int ret;
-       bool is_sta = wvif->vif && NL80211_IFTYPE_STATION == wvif->vif->type;
-       bool filter_bssid = wvif->filter_bssid;
-       bool fwd_probe_req = wvif->fwd_probe_req;
-       struct hif_mib_bcn_filter_enable bf_ctrl;
+       int bf_enable;
+       int bf_count;
+       int n_filter_ies;
        struct hif_ie_table_entry filter_ies[] = {
                {
                        .ie_id        = WLAN_EID_VENDOR_SPECIFIC,
@@ -236,33 +166,29 @@ void wfx_update_filtering(struct wfx_vif *wvif)
                        .has_appeared = 1,
                }
        };
-       int n_filter_ies;
 
        if (wvif->state == WFX_STATE_PASSIVE)
                return;
 
        if (wvif->disable_beacon_filter) {
-               bf_ctrl.enable = 0;
-               bf_ctrl.bcn_count = 1;
+               bf_enable = 0;
+               bf_count = 1;
                n_filter_ies = 0;
-       } else if (!is_sta) {
-               bf_ctrl.enable = HIF_BEACON_FILTER_ENABLE |
-                                HIF_BEACON_FILTER_AUTO_ERP;
-               bf_ctrl.bcn_count = 0;
+       } else if (wvif->vif->type != NL80211_IFTYPE_STATION) {
+               bf_enable = HIF_BEACON_FILTER_ENABLE | HIF_BEACON_FILTER_AUTO_ERP;
+               bf_count = 0;
                n_filter_ies = 2;
        } else {
-               bf_ctrl.enable = HIF_BEACON_FILTER_ENABLE;
-               bf_ctrl.bcn_count = 0;
+               bf_enable = HIF_BEACON_FILTER_ENABLE;
+               bf_count = 0;
                n_filter_ies = 3;
        }
 
-       ret = hif_set_rx_filter(wvif, filter_bssid, fwd_probe_req);
+       ret = hif_set_rx_filter(wvif, wvif->filter_bssid, wvif->fwd_probe_req);
        if (!ret)
-               ret = hif_set_beacon_filter_table(wvif, n_filter_ies,
-                                                 filter_ies);
+               ret = hif_set_beacon_filter_table(wvif, n_filter_ies, filter_ies);
        if (!ret)
-               ret = hif_beacon_filter_control(wvif, bf_ctrl.enable,
-                                               bf_ctrl.bcn_count);
+               ret = hif_beacon_filter_control(wvif, bf_enable, bf_count);
        if (!ret)
                ret = wfx_set_mcast_filter(wvif, &wvif->mcast_filter);
        if (ret)
@@ -316,90 +242,71 @@ void wfx_configure_filter(struct ieee80211_hw *hw,
        *total_flags &= FIF_OTHER_BSS | FIF_FCSFAIL | FIF_PROBE_REQ;
 
        while ((wvif = wvif_iterate(wdev, wvif)) != NULL) {
-               down(&wvif->scan.lock);
+               mutex_lock(&wvif->scan_lock);
                wvif->filter_bssid = (*total_flags &
                                      (FIF_OTHER_BSS | FIF_PROBE_REQ)) ? 0 : 1;
                wvif->disable_beacon_filter = !(*total_flags & FIF_PROBE_REQ);
                wfx_fwd_probe_req(wvif, true);
                wfx_update_filtering(wvif);
-               up(&wvif->scan.lock);
+               mutex_unlock(&wvif->scan_lock);
        }
 }
 
-int wfx_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-                  u16 queue, const struct ieee80211_tx_queue_params *params)
+static int wfx_update_pm(struct wfx_vif *wvif)
 {
-       struct wfx_dev *wdev = hw->priv;
-       struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv;
-       int ret = 0;
-       /* To prevent re-applying PM request OID again and again*/
-       u16 old_uapsd_flags, new_uapsd_flags;
-       struct hif_req_edca_queue_params *edca;
-
-       mutex_lock(&wdev->conf_mutex);
+       struct ieee80211_conf *conf = &wvif->wdev->hw->conf;
+       bool ps = conf->flags & IEEE80211_CONF_PS;
+       int ps_timeout = conf->dynamic_ps_timeout;
+       struct ieee80211_channel *chan0 = NULL, *chan1 = NULL;
 
-       if (queue < hw->queues) {
-               old_uapsd_flags = *((u16 *) &wvif->uapsd_info);
-               edca = &wvif->edca.params[queue];
-
-               wvif->edca.uapsd_enable[queue] = params->uapsd;
-               edca->aifsn = params->aifs;
-               edca->cw_min = params->cw_min;
-               edca->cw_max = params->cw_max;
-               edca->tx_op_limit = params->txop * TXOP_UNIT;
-               edca->allowed_medium_time = 0;
-               ret = hif_set_edca_queue_params(wvif, edca);
-               if (ret) {
-                       ret = -EINVAL;
-                       goto out;
-               }
-
-               if (wvif->vif->type == NL80211_IFTYPE_STATION) {
-                       ret = wfx_set_uapsd_param(wvif, &wvif->edca);
-                       new_uapsd_flags = *((u16 *) &wvif->uapsd_info);
-                       if (!ret && wvif->setbssparams_done &&
-                           wvif->state == WFX_STATE_STA &&
-                           old_uapsd_flags != new_uapsd_flags)
-                               ret = wfx_set_pm(wvif, &wvif->powersave_mode);
-               }
-       } else {
-               ret = -EINVAL;
+       WARN_ON(conf->dynamic_ps_timeout < 0);
+       if (wvif->state != WFX_STATE_STA || !wvif->bss_params.aid)
+               return 0;
+       if (!ps)
+               ps_timeout = 0;
+       if (wvif->uapsd_mask)
+               ps_timeout = 0;
+
+       // Kernel disable powersave when an AP is in use. In contrary, it is
+       // absolutely necessary to enable legacy powersave for WF200 if channels
+       // are differents.
+       if (wdev_to_wvif(wvif->wdev, 0))
+               chan0 = wdev_to_wvif(wvif->wdev, 0)->vif->bss_conf.chandef.chan;
+       if (wdev_to_wvif(wvif->wdev, 1))
+               chan1 = wdev_to_wvif(wvif->wdev, 1)->vif->bss_conf.chandef.chan;
+       if (chan0 && chan1 && chan0->hw_value != chan1->hw_value &&
+           wvif->vif->type != NL80211_IFTYPE_AP) {
+               ps = true;
+               ps_timeout = 0;
        }
 
-out:
-       mutex_unlock(&wdev->conf_mutex);
-       return ret;
+       if (!wait_for_completion_timeout(&wvif->set_pm_mode_complete,
+                                        TU_TO_JIFFIES(512)))
+               dev_warn(wvif->wdev->dev,
+                        "timeout while waiting of set_pm_mode_complete\n");
+       return hif_set_pm(wvif, ps, ps_timeout);
 }
 
-int wfx_set_pm(struct wfx_vif *wvif, const struct hif_req_set_pm_mode *arg)
+int wfx_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+                  u16 queue, const struct ieee80211_tx_queue_params *params)
 {
-       struct hif_req_set_pm_mode pm = *arg;
-       u16 uapsd_flags;
-       int ret;
-
-       if (wvif->state != WFX_STATE_STA || !wvif->bss_params.aid)
-               return 0;
-
-       memcpy(&uapsd_flags, &wvif->uapsd_info, sizeof(uapsd_flags));
+       struct wfx_dev *wdev = hw->priv;
+       struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv;
+       int old_uapsd = wvif->uapsd_mask;
+       int ret = 0;
 
-       if (uapsd_flags != 0)
-               pm.pm_mode.fast_psm = 0;
+       WARN_ON(queue >= hw->queues);
 
-       // Kernel disable PowerSave when multiple vifs are in use. In contrary,
-       // it is absolutly necessary to enable PowerSave for WF200
-       if (wvif_count(wvif->wdev) > 1) {
-               pm.pm_mode.enter_psm = 1;
-               pm.pm_mode.fast_psm = 0;
+       mutex_lock(&wdev->conf_mutex);
+       assign_bit(queue, &wvif->uapsd_mask, params->uapsd);
+       memcpy(&wvif->edca_params[queue], params, sizeof(*params));
+       hif_set_edca_queue_params(wvif, queue, params);
+       if (wvif->vif->type == NL80211_IFTYPE_STATION &&
+           old_uapsd != wvif->uapsd_mask) {
+               hif_set_uapsd_info(wvif, wvif->uapsd_mask);
+               wfx_update_pm(wvif);
        }
-
-       if (!wait_for_completion_timeout(&wvif->set_pm_mode_complete,
-                                        msecs_to_jiffies(300)))
-               dev_warn(wvif->wdev->dev,
-                        "timeout while waiting of set_pm_mode_complete\n");
-       ret = hif_set_pm(wvif, &pm);
-       // FIXME: why ?
-       if (-ETIMEDOUT == wvif->scan.status)
-               wvif->scan.status = 1;
+       mutex_unlock(&wdev->conf_mutex);
        return ret;
 }
 
@@ -413,56 +320,27 @@ int wfx_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
        return 0;
 }
 
-/* If successful, LOCKS the TX queue! */
 static int __wfx_flush(struct wfx_dev *wdev, bool drop)
 {
-       int ret;
-
        for (;;) {
-               if (drop) {
+               if (drop)
                        wfx_tx_queues_clear(wdev);
-               } else {
-                       ret = wait_event_timeout(
-                               wdev->tx_queue_stats.wait_link_id_empty,
-                               wfx_tx_queues_is_empty(wdev),
-                               2 * HZ);
-               }
-
-               if (!drop && ret <= 0) {
-                       ret = -ETIMEDOUT;
-                       break;
-               }
-               ret = 0;
-
-               wfx_tx_lock_flush(wdev);
-               if (!wfx_tx_queues_is_empty(wdev)) {
-                       /* Highly unlikely: WSM requeued frames. */
-                       wfx_tx_unlock(wdev);
-                       continue;
-               }
-               break;
+               if (wait_event_timeout(wdev->tx_queue_stats.wait_link_id_empty,
+                                      wfx_tx_queues_is_empty(wdev),
+                                      2 * HZ) <= 0)
+                       return -ETIMEDOUT;
+               wfx_tx_flush(wdev);
+               if (wfx_tx_queues_is_empty(wdev))
+                       return 0;
+               dev_warn(wdev->dev, "frames queued while flushing tx queues");
        }
-       return ret;
 }
 
 void wfx_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                  u32 queues, bool drop)
 {
-       struct wfx_dev *wdev = hw->priv;
-       struct wfx_vif *wvif;
-
-       if (vif) {
-               wvif = (struct wfx_vif *) vif->drv_priv;
-               if (wvif->vif->type == NL80211_IFTYPE_MONITOR)
-                       drop = true;
-               if (wvif->vif->type == NL80211_IFTYPE_AP &&
-                   !wvif->enable_beacon)
-                       drop = true;
-       }
-
-       // FIXME: only flush requested vif
-       if (!__wfx_flush(wdev, drop))
-               wfx_tx_unlock(wdev);
+       // FIXME: only flush requested vif and queues
+       __wfx_flush(hw->priv, drop);
 }
 
 /* WSM callbacks */
@@ -476,7 +354,7 @@ static void wfx_event_report_rssi(struct wfx_vif *wvif, u8 raw_rcpi_rssi)
        int cqm_evt;
 
        rcpi_rssi = raw_rcpi_rssi / 2 - 110;
-       if (rcpi_rssi <= wvif->cqm_rssi_thold)
+       if (rcpi_rssi <= wvif->vif->bss_conf.cqm_rssi_thold)
                cqm_evt = NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW;
        else
                cqm_evt = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH;
@@ -499,18 +377,9 @@ static void wfx_event_handler_work(struct work_struct *work)
                switch (event->evt.event_id) {
                case HIF_EVENT_IND_BSSLOST:
                        cancel_work_sync(&wvif->unjoin_work);
-                       if (!down_trylock(&wvif->scan.lock)) {
-                               wfx_cqm_bssloss_sm(wvif, 1, 0, 0);
-                               up(&wvif->scan.lock);
-                       } else {
-                               /* Scan is in progress. Delay reporting.
-                                * Scan complete will trigger bss_loss_work
-                                */
-                               wvif->delayed_link_loss = 1;
-                               /* Also start a watchdog. */
-                               schedule_delayed_work(&wvif->bss_loss_work,
-                                                     5 * HZ);
-                       }
+                       mutex_lock(&wvif->scan_lock);
+                       wfx_cqm_bssloss_sm(wvif, 1, 0, 0);
+                       mutex_unlock(&wvif->scan_lock);
                        break;
                case HIF_EVENT_IND_BSSREGAINED:
                        wfx_cqm_bssloss_sm(wvif, 0, 0, 0);
@@ -554,30 +423,10 @@ static void wfx_bss_params_work(struct work_struct *work)
        mutex_unlock(&wvif->wdev->conf_mutex);
 }
 
-static void wfx_set_beacon_wakeup_period_work(struct work_struct *work)
-{
-       struct wfx_vif *wvif = container_of(work, struct wfx_vif,
-                                           set_beacon_wakeup_period_work);
-
-       hif_set_beacon_wakeup_period(wvif, wvif->dtim_period,
-                                    wvif->dtim_period);
-}
-
 static void wfx_do_unjoin(struct wfx_vif *wvif)
 {
        mutex_lock(&wvif->wdev->conf_mutex);
 
-       if (atomic_read(&wvif->scan.in_progress)) {
-               if (wvif->delayed_unjoin)
-                       dev_dbg(wvif->wdev->dev,
-                               "delayed unjoin is already scheduled\n");
-               else
-                       wvif->delayed_unjoin = true;
-               goto done;
-       }
-
-       wvif->delayed_link_loss = false;
-
        if (!wvif->state)
                goto done;
 
@@ -585,7 +434,6 @@ static void wfx_do_unjoin(struct wfx_vif *wvif)
                goto done;
 
        cancel_work_sync(&wvif->update_filtering_work);
-       cancel_work_sync(&wvif->set_beacon_wakeup_period_work);
        wvif->state = WFX_STATE_PASSIVE;
 
        /* Unjoin is a reset. */
@@ -593,8 +441,6 @@ static void wfx_do_unjoin(struct wfx_vif *wvif)
        hif_keep_alive_period(wvif, 0);
        hif_reset(wvif, false);
        wfx_tx_policy_init(wvif);
-       hif_set_output_power(wvif, wvif->wdev->output_power * 10);
-       wvif->dtim_period = 0;
        hif_set_macaddr(wvif, wvif->vif->addr);
        wfx_free_event_queue(wvif);
        cancel_work_sync(&wvif->event_handler_work);
@@ -606,8 +452,6 @@ static void wfx_do_unjoin(struct wfx_vif *wvif)
        wvif->disable_beacon_filter = false;
        wfx_update_filtering(wvif);
        memset(&wvif->bss_params, 0, sizeof(wvif->bss_params));
-       wvif->setbssparams_done = false;
-       memset(&wvif->ht_info, 0, sizeof(wvif->ht_info));
 
 done:
        mutex_unlock(&wvif->wdev->conf_mutex);
@@ -644,33 +488,21 @@ static void wfx_set_mfp(struct wfx_vif *wvif,
        hif_set_mfp(wvif, mfpc, mfpr);
 }
 
-/* MUST be called with tx_lock held!  It will be unlocked for us. */
 static void wfx_do_join(struct wfx_vif *wvif)
 {
-       const u8 *bssid;
+       int ret;
+       const u8 *ssidie;
        struct ieee80211_bss_conf *conf = &wvif->vif->bss_conf;
        struct cfg80211_bss *bss = NULL;
-       struct hif_req_join join = {
-               .mode = conf->ibss_joined ? HIF_MODE_IBSS : HIF_MODE_BSS,
-               .preamble_type = conf->use_short_preamble ? HIF_PREAMBLE_SHORT : HIF_PREAMBLE_LONG,
-               .probe_for_join = 1,
-               .atim_window = 0,
-               .basic_rate_set = wfx_rate_mask_to_hw(wvif->wdev,
-                                                     conf->basic_rates),
-       };
 
-       if (wvif->channel->flags & IEEE80211_CHAN_NO_IR)
-               join.probe_for_join = 0;
+       wfx_tx_lock_flush(wvif->wdev);
 
        if (wvif->state)
                wfx_do_unjoin(wvif);
 
-       bssid = wvif->vif->bss_conf.bssid;
-
        bss = cfg80211_get_bss(wvif->wdev->hw->wiphy, wvif->channel,
-                              bssid, NULL, 0,
+                              conf->bssid, NULL, 0,
                               IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY);
-
        if (!bss && !conf->ibss_joined) {
                wfx_tx_unlock(wvif->wdev);
                return;
@@ -678,41 +510,15 @@ static void wfx_do_join(struct wfx_vif *wvif)
 
        mutex_lock(&wvif->wdev->conf_mutex);
 
-       /* Under the conf lock: check scan status and
-        * bail out if it is in progress.
-        */
-       if (atomic_read(&wvif->scan.in_progress)) {
-               wfx_tx_unlock(wvif->wdev);
-               goto done_put;
-       }
-
-       /* Sanity check basic rates */
-       if (!join.basic_rate_set)
-               join.basic_rate_set = 7;
-
        /* Sanity check beacon interval */
        if (!wvif->beacon_int)
                wvif->beacon_int = 1;
 
-       join.beacon_interval = wvif->beacon_int;
-
-       // DTIM period will be set on first Beacon
-       wvif->dtim_period = 0;
-
-       join.channel_number = wvif->channel->hw_value;
-       memcpy(join.bssid, bssid, sizeof(join.bssid));
-
-       if (!conf->ibss_joined) {
-               const u8 *ssidie;
-
-               rcu_read_lock();
+       rcu_read_lock();
+       if (!conf->ibss_joined)
                ssidie = ieee80211_bss_get_ie(bss, WLAN_EID_SSID);
-               if (ssidie) {
-                       join.ssid_length = ssidie[1];
-                       memcpy(join.ssid, &ssidie[2], join.ssid_length);
-               }
-               rcu_read_unlock();
-       }
+       else
+               ssidie = NULL;
 
        wfx_tx_flush(wvif->wdev);
 
@@ -723,7 +529,9 @@ static void wfx_do_join(struct wfx_vif *wvif)
 
        /* Perform actual join */
        wvif->wdev->tx_burst_idx = -1;
-       if (hif_join(wvif, &join)) {
+       ret = hif_join(wvif, conf, wvif->channel, ssidie);
+       rcu_read_unlock();
+       if (ret) {
                ieee80211_connection_loss(wvif->vif);
                wvif->join_complete_status = -1;
                /* Tx lock still held, unjoin will clear it. */
@@ -749,7 +557,6 @@ static void wfx_do_join(struct wfx_vif *wvif)
        }
        wfx_update_filtering(wvif);
 
-done_put:
        mutex_unlock(&wvif->wdev->conf_mutex);
        if (bss)
                cfg80211_put_bss(wvif->wdev->hw->wiphy, bss);
@@ -766,30 +573,26 @@ static void wfx_unjoin_work(struct work_struct *work)
 int wfx_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                struct ieee80211_sta *sta)
 {
-       struct wfx_dev *wdev = hw->priv;
        struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv;
        struct wfx_sta_priv *sta_priv = (struct wfx_sta_priv *) &sta->drv_priv;
-       struct wfx_link_entry *entry;
-       struct sk_buff *skb;
-
-       if (wvif->vif->type != NL80211_IFTYPE_AP)
-               return 0;
 
+       spin_lock_init(&sta_priv->lock);
        sta_priv->vif_id = wvif->id;
-       sta_priv->link_id = wfx_find_link_id(wvif, sta->addr);
-       if (!sta_priv->link_id) {
-               dev_warn(wdev->dev, "mo more link-id available\n");
-               return -ENOENT;
-       }
 
-       entry = &wvif->link_id_db[sta_priv->link_id - 1];
+       // FIXME: in station mode, the current API interprets new link-id as a
+       // tdls peer.
+       if (vif->type == NL80211_IFTYPE_STATION)
+               return 0;
+       sta_priv->link_id = ffz(wvif->link_id_map);
+       wvif->link_id_map |= BIT(sta_priv->link_id);
+       WARN_ON(!sta_priv->link_id);
+       WARN_ON(sta_priv->link_id >= WFX_MAX_STA_IN_AP_MODE);
+       hif_map_link(wvif, sta->addr, 0, sta_priv->link_id);
+
        spin_lock_bh(&wvif->ps_state_lock);
        if ((sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK) ==
                                        IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
                wvif->sta_asleep_mask |= BIT(sta_priv->link_id);
-       entry->status = WFX_LINK_HARD;
-       while ((skb = skb_dequeue(&entry->rx_queue)))
-               ieee80211_rx_irqsafe(wdev->hw, skb);
        spin_unlock_bh(&wvif->ps_state_lock);
        return 0;
 }
@@ -797,225 +600,116 @@ int wfx_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 int wfx_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                   struct ieee80211_sta *sta)
 {
-       struct wfx_dev *wdev = hw->priv;
        struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv;
        struct wfx_sta_priv *sta_priv = (struct wfx_sta_priv *) &sta->drv_priv;
-       struct wfx_link_entry *entry;
+       int i;
 
-       if (wvif->vif->type != NL80211_IFTYPE_AP || !sta_priv->link_id)
+       for (i = 0; i < ARRAY_SIZE(sta_priv->buffered); i++)
+               WARN(sta_priv->buffered[i], "release station while Tx is in progress");
+       // FIXME: see note in wfx_sta_add()
+       if (vif->type == NL80211_IFTYPE_STATION)
                return 0;
-
-       entry = &wvif->link_id_db[sta_priv->link_id - 1];
-       spin_lock_bh(&wvif->ps_state_lock);
-       entry->status = WFX_LINK_RESERVE;
-       entry->timestamp = jiffies;
-       wfx_tx_lock(wdev);
-       if (!schedule_work(&wvif->link_id_work))
-               wfx_tx_unlock(wdev);
-       spin_unlock_bh(&wvif->ps_state_lock);
-       flush_work(&wvif->link_id_work);
+       // FIXME add a mutex?
+       hif_map_link(wvif, sta->addr, 1, sta_priv->link_id);
+       wvif->link_id_map &= ~BIT(sta_priv->link_id);
        return 0;
 }
 
-static void wfx_set_cts_work(struct work_struct *work)
-{
-       struct wfx_vif *wvif = container_of(work, struct wfx_vif, set_cts_work);
-       u8 erp_ie[3] = { WLAN_EID_ERP_INFO, 1, 0 };
-       struct hif_ie_flags target_frame = {
-               .beacon = 1,
-       };
-
-       mutex_lock(&wvif->wdev->conf_mutex);
-       erp_ie[2] = wvif->erp_info;
-       mutex_unlock(&wvif->wdev->conf_mutex);
-
-       hif_erp_use_protection(wvif, erp_ie[2] & WLAN_ERP_USE_PROTECTION);
-
-       if (wvif->vif->type != NL80211_IFTYPE_STATION)
-               hif_update_ie(wvif, &target_frame, erp_ie, sizeof(erp_ie));
-}
-
 static int wfx_start_ap(struct wfx_vif *wvif)
 {
        int ret;
-       struct ieee80211_bss_conf *conf = &wvif->vif->bss_conf;
-       struct hif_req_start start = {
-               .channel_number = wvif->channel->hw_value,
-               .beacon_interval = conf->beacon_int,
-               .dtim_period = conf->dtim_period,
-               .preamble_type = conf->use_short_preamble ? HIF_PREAMBLE_SHORT : HIF_PREAMBLE_LONG,
-               .basic_rate_set = wfx_rate_mask_to_hw(wvif->wdev,
-                                                     conf->basic_rates),
-       };
-
-       memset(start.ssid, 0, sizeof(start.ssid));
-       if (!conf->hidden_ssid) {
-               start.ssid_length = conf->ssid_len;
-               memcpy(start.ssid, conf->ssid, start.ssid_length);
-       }
-
-       wvif->beacon_int = conf->beacon_int;
-       wvif->dtim_period = conf->dtim_period;
-
-       memset(&wvif->link_id_db, 0, sizeof(wvif->link_id_db));
 
+       wvif->beacon_int = wvif->vif->bss_conf.beacon_int;
        wvif->wdev->tx_burst_idx = -1;
-       ret = hif_start(wvif, &start);
-       if (!ret)
-               ret = wfx_upload_keys(wvif);
-       if (!ret) {
-               if (wvif_count(wvif->wdev) <= 1)
-                       hif_set_block_ack_policy(wvif, 0xFF, 0xFF);
-               wvif->state = WFX_STATE_AP;
-               wfx_update_filtering(wvif);
-       }
-       return ret;
+       ret = hif_start(wvif, &wvif->vif->bss_conf, wvif->channel);
+       if (ret)
+               return ret;
+       ret = wfx_upload_keys(wvif);
+       if (ret)
+               return ret;
+       if (wvif_count(wvif->wdev) <= 1)
+               hif_set_block_ack_policy(wvif, 0xFF, 0xFF);
+       wvif->state = WFX_STATE_AP;
+       wfx_update_filtering(wvif);
+       return 0;
 }
 
 static int wfx_update_beaconing(struct wfx_vif *wvif)
 {
-       struct ieee80211_bss_conf *conf = &wvif->vif->bss_conf;
-
-       if (wvif->vif->type == NL80211_IFTYPE_AP) {
-               /* TODO: check if changed channel, band */
-               if (wvif->state != WFX_STATE_AP ||
-                   wvif->beacon_int != conf->beacon_int) {
-                       wfx_tx_lock_flush(wvif->wdev);
-                       if (wvif->state != WFX_STATE_PASSIVE) {
-                               hif_reset(wvif, false);
-                               wfx_tx_policy_init(wvif);
-                       }
-                       wvif->state = WFX_STATE_PASSIVE;
-                       wfx_start_ap(wvif);
-                       wfx_tx_unlock(wvif->wdev);
-               } else {
-               }
-       }
+       if (wvif->vif->type != NL80211_IFTYPE_AP)
+               return 0;
+       if (wvif->state == WFX_STATE_AP &&
+           wvif->beacon_int == wvif->vif->bss_conf.beacon_int)
+               return 0;
+       wfx_tx_lock_flush(wvif->wdev);
+       hif_reset(wvif, false);
+       wfx_tx_policy_init(wvif);
+       wvif->state = WFX_STATE_PASSIVE;
+       wfx_start_ap(wvif);
+       wfx_tx_unlock(wvif->wdev);
        return 0;
 }
 
-static int wfx_upload_beacon(struct wfx_vif *wvif)
+static int wfx_upload_ap_templates(struct wfx_vif *wvif)
 {
-       int ret = 0;
-       struct sk_buff *skb = NULL;
-       struct ieee80211_mgmt *mgmt;
-       struct hif_mib_template_frame *p;
+       struct sk_buff *skb;
 
        if (wvif->vif->type == NL80211_IFTYPE_STATION ||
            wvif->vif->type == NL80211_IFTYPE_MONITOR ||
            wvif->vif->type == NL80211_IFTYPE_UNSPECIFIED)
-               goto done;
+               return 0;
 
        skb = ieee80211_beacon_get(wvif->wdev->hw, wvif->vif);
-
        if (!skb)
                return -ENOMEM;
-
-       p = (struct hif_mib_template_frame *) skb_push(skb, 4);
-       p->frame_type = HIF_TMPLT_BCN;
-       p->init_rate = API_RATE_INDEX_B_1MBPS; /* 1Mbps DSSS */
-       p->frame_length = cpu_to_le16(skb->len - 4);
-
-       ret = hif_set_template_frame(wvif, p);
-
-       skb_pull(skb, 4);
-
-       if (ret)
-               goto done;
-       /* TODO: Distill probe resp; remove TIM and any other beacon-specific
-        * IEs
-        */
-       mgmt = (void *)skb->data;
-       mgmt->frame_control =
-               cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
-
-       p->frame_type = HIF_TMPLT_PRBRES;
-
-       ret = hif_set_template_frame(wvif, p);
-       wfx_fwd_probe_req(wvif, false);
-
-done:
+       hif_set_template_frame(wvif, skb, HIF_TMPLT_BCN,
+                              API_RATE_INDEX_B_1MBPS);
        dev_kfree_skb(skb);
-       return ret;
-}
-
-static int wfx_is_ht(const struct wfx_ht_info *ht_info)
-{
-       return ht_info->channel_type != NL80211_CHAN_NO_HT;
-}
-
-static int wfx_ht_greenfield(const struct wfx_ht_info *ht_info)
-{
-       return wfx_is_ht(ht_info) &&
-               (ht_info->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) &&
-               !(ht_info->operation_mode &
-                 IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
-}
 
-static int wfx_ht_ampdu_density(const struct wfx_ht_info *ht_info)
-{
-       if (!wfx_is_ht(ht_info))
-               return 0;
-       return ht_info->ht_cap.ampdu_density;
+       skb = ieee80211_proberesp_get(wvif->wdev->hw, wvif->vif);
+       if (!skb)
+               return -ENOMEM;
+       hif_set_template_frame(wvif, skb, HIF_TMPLT_PRBRES,
+                              API_RATE_INDEX_B_1MBPS);
+       dev_kfree_skb(skb);
+       return 0;
 }
 
 static void wfx_join_finalize(struct wfx_vif *wvif,
                              struct ieee80211_bss_conf *info)
 {
        struct ieee80211_sta *sta = NULL;
-       struct hif_mib_set_association_mode association_mode = { };
 
-       if (info->dtim_period)
-               wvif->dtim_period = info->dtim_period;
        wvif->beacon_int = info->beacon_int;
-
-       rcu_read_lock();
+       rcu_read_lock(); // protect sta
        if (info->bssid && !info->ibss_joined)
                sta = ieee80211_find_sta(wvif->vif, info->bssid);
-       if (sta) {
-               wvif->ht_info.ht_cap = sta->ht_cap;
+       if (sta)
                wvif->bss_params.operational_rate_set =
                        wfx_rate_mask_to_hw(wvif->wdev, sta->supp_rates[wvif->channel->band]);
-               wvif->ht_info.operation_mode = info->ht_operation_mode;
-       } else {
-               memset(&wvif->ht_info, 0, sizeof(wvif->ht_info));
+       else
                wvif->bss_params.operational_rate_set = -1;
-       }
-       rcu_read_unlock();
-
-       /* Non Greenfield stations present */
-       if (wvif->ht_info.operation_mode &
-           IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT)
+       if (sta &&
+           info->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT)
                hif_dual_cts_protection(wvif, true);
        else
                hif_dual_cts_protection(wvif, false);
 
-       association_mode.preambtype_use = 1;
-       association_mode.mode = 1;
-       association_mode.rateset = 1;
-       association_mode.spacing = 1;
-       association_mode.preamble_type = info->use_short_preamble ? HIF_PREAMBLE_SHORT : HIF_PREAMBLE_LONG;
-       association_mode.basic_rate_set = cpu_to_le32(wfx_rate_mask_to_hw(wvif->wdev, info->basic_rates));
-       association_mode.mixed_or_greenfield_type = wfx_ht_greenfield(&wvif->ht_info);
-       association_mode.mpdu_start_spacing = wfx_ht_ampdu_density(&wvif->ht_info);
-
        wfx_cqm_bssloss_sm(wvif, 0, 0, 0);
        cancel_work_sync(&wvif->unjoin_work);
 
        wvif->bss_params.beacon_lost_count = 20;
        wvif->bss_params.aid = info->aid;
 
-       if (wvif->dtim_period < 1)
-               wvif->dtim_period = 1;
-
-       hif_set_association_mode(wvif, &association_mode);
+       hif_set_association_mode(wvif, info, sta ? &sta->ht_cap : NULL);
+       rcu_read_unlock();
 
        if (!info->ibss_joined) {
                hif_keep_alive_period(wvif, 30 /* sec */);
                hif_set_bss_params(wvif, &wvif->bss_params);
-               wvif->setbssparams_done = true;
-               wfx_set_beacon_wakeup_period_work(&wvif->set_beacon_wakeup_period_work);
-               wfx_set_pm(wvif, &wvif->powersave_mode);
+               hif_set_beacon_wakeup_period(wvif, info->dtim_period,
+                                            info->dtim_period);
+               wfx_update_pm(wvif);
        }
 }
 
@@ -1028,48 +722,40 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw,
        struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv;
        bool do_join = false;
        int i;
-       int nb_arp_addr;
 
        mutex_lock(&wdev->conf_mutex);
 
        /* TODO: BSS_CHANGED_QOS */
        if (changed & BSS_CHANGED_ARP_FILTER) {
-               struct hif_mib_arp_ip_addr_table filter = { };
-
-               nb_arp_addr = info->arp_addr_cnt;
-               if (nb_arp_addr <= 0 || nb_arp_addr > HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES)
-                       nb_arp_addr = 0;
-
                for (i = 0; i < HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES; i++) {
-                       filter.condition_idx = i;
-                       if (i < nb_arp_addr) {
-                               // Caution: type of arp_addr_list[i] is __be32
-                               memcpy(filter.ipv4_address,
-                                      &info->arp_addr_list[i],
-                                      sizeof(filter.ipv4_address));
-                               filter.arp_enable = HIF_ARP_NS_FILTERING_ENABLE;
-                       } else {
-                               filter.arp_enable = HIF_ARP_NS_FILTERING_DISABLE;
-                       }
-                       hif_set_arp_ipv4_filter(wvif, &filter);
+                       __be32 *arp_addr = &info->arp_addr_list[i];
+
+                       if (info->arp_addr_cnt > HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES)
+                               arp_addr = NULL;
+                       if (i >= info->arp_addr_cnt)
+                               arp_addr = NULL;
+                       hif_set_arp_ipv4_filter(wvif, i, arp_addr);
                }
        }
 
-       if (changed &
-           (BSS_CHANGED_BEACON | BSS_CHANGED_AP_PROBE_RESP |
-            BSS_CHANGED_BSSID | BSS_CHANGED_SSID | BSS_CHANGED_IBSS)) {
+       if (changed & BSS_CHANGED_BEACON ||
+           changed & BSS_CHANGED_AP_PROBE_RESP ||
+           changed & BSS_CHANGED_BSSID ||
+           changed & BSS_CHANGED_SSID ||
+           changed & BSS_CHANGED_IBSS) {
                wvif->beacon_int = info->beacon_int;
                wfx_update_beaconing(wvif);
-               wfx_upload_beacon(wvif);
+               wfx_upload_ap_templates(wvif);
+               wfx_fwd_probe_req(wvif, false);
        }
 
        if (changed & BSS_CHANGED_BEACON_ENABLED &&
-           wvif->state != WFX_STATE_IBSS) {
-               if (wvif->enable_beacon != info->enable_beacon) {
-                       hif_beacon_transmit(wvif, info->enable_beacon);
-                       wvif->enable_beacon = info->enable_beacon;
-               }
-       }
+           wvif->state != WFX_STATE_IBSS)
+               hif_beacon_transmit(wvif, info->enable_beacon);
+
+       if (changed & BSS_CHANGED_BEACON_INFO)
+               hif_set_beacon_wakeup_period(wvif, info->dtim_period,
+                                            info->dtim_period);
 
        /* assoc/disassoc, or maybe AID changed */
        if (changed & BSS_CHANGED_ASSOC) {
@@ -1095,10 +781,11 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw,
                if (changed & BSS_CHANGED_BSSID)
                        do_join = true;
 
-               if (changed &
-                   (BSS_CHANGED_ASSOC | BSS_CHANGED_BSSID |
-                    BSS_CHANGED_IBSS | BSS_CHANGED_BASIC_RATES |
-                    BSS_CHANGED_HT)) {
+               if (changed & BSS_CHANGED_ASSOC ||
+                   changed & BSS_CHANGED_BSSID ||
+                   changed & BSS_CHANGED_IBSS ||
+                   changed & BSS_CHANGED_BASIC_RATES ||
+                   changed & BSS_CHANGED_HT) {
                        if (info->assoc) {
                                if (wvif->state < WFX_STATE_PRE_STA) {
                                        ieee80211_connection_loss(vif);
@@ -1119,106 +806,50 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw,
                }
        }
 
-       /* ERP Protection */
-       if (changed & (BSS_CHANGED_ASSOC |
-                      BSS_CHANGED_ERP_CTS_PROT |
-                      BSS_CHANGED_ERP_PREAMBLE)) {
-               u32 prev_erp_info = wvif->erp_info;
+       if (changed & BSS_CHANGED_ASSOC ||
+           changed & BSS_CHANGED_ERP_CTS_PROT ||
+           changed & BSS_CHANGED_ERP_PREAMBLE) {
+               u8 erp_ie[3] = { WLAN_EID_ERP_INFO, 1, 0 };
 
+               hif_erp_use_protection(wvif, info->use_cts_prot);
                if (info->use_cts_prot)
-                       wvif->erp_info |= WLAN_ERP_USE_PROTECTION;
-               else if (!(prev_erp_info & WLAN_ERP_NON_ERP_PRESENT))
-                       wvif->erp_info &= ~WLAN_ERP_USE_PROTECTION;
-
+                       erp_ie[2] |= WLAN_ERP_USE_PROTECTION;
                if (info->use_short_preamble)
-                       wvif->erp_info |= WLAN_ERP_BARKER_PREAMBLE;
-               else
-                       wvif->erp_info &= ~WLAN_ERP_BARKER_PREAMBLE;
-
-               if (prev_erp_info != wvif->erp_info)
-                       schedule_work(&wvif->set_cts_work);
+                       erp_ie[2] |= WLAN_ERP_BARKER_PREAMBLE;
+               if (wvif->vif->type != NL80211_IFTYPE_STATION)
+                       hif_update_ie_beacon(wvif, erp_ie, sizeof(erp_ie));
        }
 
-       if (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_ERP_SLOT))
+       if (changed & BSS_CHANGED_ASSOC || changed & BSS_CHANGED_ERP_SLOT)
                hif_slot_time(wvif, info->use_short_slot ? 9 : 20);
 
-       if (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_CQM)) {
-               struct hif_mib_rcpi_rssi_threshold th = {
-                       .rolling_average_count = 8,
-                       .detection = 1,
-               };
-
-               wvif->cqm_rssi_thold = info->cqm_rssi_thold;
-
-               if (!info->cqm_rssi_thold && !info->cqm_rssi_hyst) {
-                       th.upperthresh = 1;
-                       th.lowerthresh = 1;
-               } else {
-                       /* FIXME It's not a correct way of setting threshold.
-                        * Upper and lower must be set equal here and adjusted
-                        * in callback. However current implementation is much
-                        * more reliable and stable.
-                        */
-                       /* RSSI: signed Q8.0, RCPI: unsigned Q7.1
-                        * RSSI = RCPI / 2 - 110
-                        */
-                       th.upper_threshold = info->cqm_rssi_thold + info->cqm_rssi_hyst;
-                       th.upper_threshold = (th.upper_threshold + 110) * 2;
-                       th.lower_threshold = info->cqm_rssi_thold;
-                       th.lower_threshold = (th.lower_threshold + 110) * 2;
-               }
-               hif_set_rcpi_rssi_threshold(wvif, &th);
-       }
+       if (changed & BSS_CHANGED_ASSOC || changed & BSS_CHANGED_CQM)
+               hif_set_rcpi_rssi_threshold(wvif, info->cqm_rssi_thold,
+                                           info->cqm_rssi_hyst);
+
+       if (changed & BSS_CHANGED_TXPOWER)
+               hif_set_output_power(wvif, info->txpower);
+
+       if (changed & BSS_CHANGED_PS)
+               wfx_update_pm(wvif);
 
-       if (changed & BSS_CHANGED_TXPOWER &&
-           info->txpower != wdev->output_power) {
-               wdev->output_power = info->txpower;
-               hif_set_output_power(wvif, wdev->output_power * 10);
-       }
        mutex_unlock(&wdev->conf_mutex);
 
-       if (do_join) {
-               wfx_tx_lock_flush(wdev);
-               wfx_do_join(wvif); /* Will unlock it for us */
-       }
+       if (do_join)
+               wfx_do_join(wvif);
 }
 
-static void wfx_ps_notify(struct wfx_vif *wvif, enum sta_notify_cmd notify_cmd,
-                         int link_id)
+static void wfx_ps_notify_sta(struct wfx_vif *wvif,
+                             enum sta_notify_cmd notify_cmd, int link_id)
 {
-       u32 bit, prev;
-
        spin_lock_bh(&wvif->ps_state_lock);
-       /* Zero link id means "for all link IDs" */
-       if (link_id) {
-               bit = BIT(link_id);
-       } else if (notify_cmd != STA_NOTIFY_AWAKE) {
-               dev_warn(wvif->wdev->dev, "unsupported notify command\n");
-               bit = 0;
-       } else {
-               bit = wvif->link_id_map;
-       }
-       prev = wvif->sta_asleep_mask & bit;
-
-       switch (notify_cmd) {
-       case STA_NOTIFY_SLEEP:
-               if (!prev) {
-                       if (wvif->mcast_buffered && !wvif->sta_asleep_mask)
-                               schedule_work(&wvif->mcast_start_work);
-                       wvif->sta_asleep_mask |= bit;
-               }
-               break;
-       case STA_NOTIFY_AWAKE:
-               if (prev) {
-                       wvif->sta_asleep_mask &= ~bit;
-                       wvif->pspoll_mask &= ~bit;
-                       if (link_id && !wvif->sta_asleep_mask)
-                               schedule_work(&wvif->mcast_stop_work);
-                       wfx_bh_request_tx(wvif->wdev);
-               }
-               break;
-       }
+       if (notify_cmd == STA_NOTIFY_SLEEP)
+               wvif->sta_asleep_mask |= BIT(link_id);
+       else // notify_cmd == STA_NOTIFY_AWAKE
+               wvif->sta_asleep_mask &= ~BIT(link_id);
        spin_unlock_bh(&wvif->ps_state_lock);
+       if (notify_cmd == STA_NOTIFY_AWAKE)
+               wfx_bh_request_tx(wvif->wdev);
 }
 
 void wfx_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
@@ -1227,23 +858,19 @@ void wfx_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
        struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv;
        struct wfx_sta_priv *sta_priv = (struct wfx_sta_priv *) &sta->drv_priv;
 
-       wfx_ps_notify(wvif, notify_cmd, sta_priv->link_id);
+       wfx_ps_notify_sta(wvif, notify_cmd, sta_priv->link_id);
 }
 
-static int wfx_set_tim_impl(struct wfx_vif *wvif, bool aid0_bit_set)
+static int wfx_update_tim(struct wfx_vif *wvif)
 {
        struct sk_buff *skb;
-       struct hif_ie_flags target_frame = {
-               .beacon = 1,
-       };
        u16 tim_offset, tim_length;
        u8 *tim_ptr;
 
        skb = ieee80211_beacon_get_tim(wvif->wdev->hw, wvif->vif,
                                       &tim_offset, &tim_length);
        if (!skb) {
-               if (!__wfx_flush(wvif->wdev, true))
-                       wfx_tx_unlock(wvif->wdev);
+               __wfx_flush(wvif->wdev, true);
                return -ENOENT;
        }
        tim_ptr = skb->data + tim_offset;
@@ -1255,23 +882,23 @@ static int wfx_set_tim_impl(struct wfx_vif *wvif, bool aid0_bit_set)
                tim_ptr[2] = 0;
 
                /* Set/reset aid0 bit */
-               if (aid0_bit_set)
+               if (wfx_tx_queues_get_after_dtim(wvif))
                        tim_ptr[4] |= 1;
                else
                        tim_ptr[4] &= ~1;
        }
 
-       hif_update_ie(wvif, &target_frame, tim_ptr, tim_length);
+       hif_update_ie_beacon(wvif, tim_ptr, tim_length);
        dev_kfree_skb(skb);
 
        return 0;
 }
 
-static void wfx_set_tim_work(struct work_struct *work)
+static void wfx_update_tim_work(struct work_struct *work)
 {
-       struct wfx_vif *wvif = container_of(work, struct wfx_vif, set_tim_work);
+       struct wfx_vif *wvif = container_of(work, struct wfx_vif, update_tim_work);
 
-       wfx_set_tim_impl(wvif, wvif->aid0_bit_set);
+       wfx_update_tim(wvif);
 }
 
 int wfx_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set)
@@ -1280,50 +907,16 @@ int wfx_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set)
        struct wfx_sta_priv *sta_dev = (struct wfx_sta_priv *) &sta->drv_priv;
        struct wfx_vif *wvif = wdev_to_wvif(wdev, sta_dev->vif_id);
 
-       schedule_work(&wvif->set_tim_work);
+       schedule_work(&wvif->update_tim_work);
        return 0;
 }
 
-static void wfx_mcast_start_work(struct work_struct *work)
+void wfx_suspend_resume_mc(struct wfx_vif *wvif, enum sta_notify_cmd notify_cmd)
 {
-       struct wfx_vif *wvif = container_of(work, struct wfx_vif,
-                                           mcast_start_work);
-       long tmo = wvif->dtim_period * TU_TO_JIFFIES(wvif->beacon_int + 20);
-
-       cancel_work_sync(&wvif->mcast_stop_work);
-       if (!wvif->aid0_bit_set) {
-               wfx_tx_lock_flush(wvif->wdev);
-               wfx_set_tim_impl(wvif, true);
-               wvif->aid0_bit_set = true;
-               mod_timer(&wvif->mcast_timeout, jiffies + tmo);
-               wfx_tx_unlock(wvif->wdev);
-       }
-}
-
-static void wfx_mcast_stop_work(struct work_struct *work)
-{
-       struct wfx_vif *wvif = container_of(work, struct wfx_vif,
-                                           mcast_stop_work);
-
-       if (wvif->aid0_bit_set) {
-               del_timer_sync(&wvif->mcast_timeout);
-               wfx_tx_lock_flush(wvif->wdev);
-               wvif->aid0_bit_set = false;
-               wfx_set_tim_impl(wvif, false);
-               wfx_tx_unlock(wvif->wdev);
-       }
-}
-
-static void wfx_mcast_timeout(struct timer_list *t)
-{
-       struct wfx_vif *wvif = from_timer(wvif, t, mcast_timeout);
-
-       dev_warn(wvif->wdev->dev, "multicast delivery timeout\n");
-       spin_lock_bh(&wvif->ps_state_lock);
-       wvif->mcast_tx = wvif->aid0_bit_set && wvif->mcast_buffered;
-       if (wvif->mcast_tx)
-               wfx_bh_request_tx(wvif->wdev);
-       spin_unlock_bh(&wvif->ps_state_lock);
+       WARN(!wfx_tx_queues_get_after_dtim(wvif), "incorrect sequence");
+       WARN(wvif->after_dtim_tx_allowed, "incorrect sequence");
+       wvif->after_dtim_tx_allowed = true;
+       wfx_bh_request_tx(wvif->wdev);
 }
 
 int wfx_ampdu_action(struct ieee80211_hw *hw,
@@ -1341,35 +934,6 @@ int wfx_ampdu_action(struct ieee80211_hw *hw,
        return -ENOTSUPP;
 }
 
-void wfx_suspend_resume(struct wfx_vif *wvif,
-                       struct hif_ind_suspend_resume_tx *arg)
-{
-       if (arg->suspend_resume_flags.bc_mc_only) {
-               bool cancel_tmo = false;
-
-               spin_lock_bh(&wvif->ps_state_lock);
-               if (!arg->suspend_resume_flags.resume)
-                       wvif->mcast_tx = false;
-               else
-                       wvif->mcast_tx = wvif->aid0_bit_set &&
-                                        wvif->mcast_buffered;
-               if (wvif->mcast_tx) {
-                       cancel_tmo = true;
-                       wfx_bh_request_tx(wvif->wdev);
-               }
-               spin_unlock_bh(&wvif->ps_state_lock);
-               if (cancel_tmo)
-                       del_timer_sync(&wvif->mcast_timeout);
-       } else if (arg->suspend_resume_flags.resume) {
-               // FIXME: should change each station status independently
-               wfx_ps_notify(wvif, STA_NOTIFY_AWAKE, 0);
-               wfx_bh_request_tx(wvif->wdev);
-       } else {
-               // FIXME: should change each station status independently
-               wfx_ps_notify(wvif, STA_NOTIFY_SLEEP, 0);
-       }
-}
-
 int wfx_add_chanctx(struct ieee80211_hw *hw,
                    struct ieee80211_chanctx_conf *conf)
 {
@@ -1395,7 +959,6 @@ int wfx_assign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 
        WARN(wvif->channel, "channel overwrite");
        wvif->channel = ch;
-       wvif->ht_info.channel_type = cfg80211_get_chandef_type(&conf->def);
 
        return 0;
 }
@@ -1413,97 +976,14 @@ void wfx_unassign_vif_chanctx(struct ieee80211_hw *hw,
 
 int wfx_config(struct ieee80211_hw *hw, u32 changed)
 {
-       int ret = 0;
-       struct wfx_dev *wdev = hw->priv;
-       struct ieee80211_conf *conf = &hw->conf;
-       struct wfx_vif *wvif;
-
-       // FIXME: Interface id should not been hardcoded
-       wvif = wdev_to_wvif(wdev, 0);
-       if (!wvif) {
-               WARN(1, "interface 0 does not exist anymore");
-               return 0;
-       }
-
-       down(&wvif->scan.lock);
-       mutex_lock(&wdev->conf_mutex);
-       if (changed & IEEE80211_CONF_CHANGE_POWER) {
-               wdev->output_power = conf->power_level;
-               hif_set_output_power(wvif, wdev->output_power * 10);
-       }
-
-       if (changed & IEEE80211_CONF_CHANGE_PS) {
-               wvif = NULL;
-               while ((wvif = wvif_iterate(wdev, wvif)) != NULL) {
-                       memset(&wvif->powersave_mode, 0,
-                              sizeof(wvif->powersave_mode));
-                       if (conf->flags & IEEE80211_CONF_PS) {
-                               wvif->powersave_mode.pm_mode.enter_psm = 1;
-                               if (conf->dynamic_ps_timeout > 0) {
-                                       wvif->powersave_mode.pm_mode.fast_psm = 1;
-                                       /*
-                                        * Firmware does not support more than
-                                        * 128ms
-                                        */
-                                       wvif->powersave_mode.fast_psm_idle_period =
-                                               min(conf->dynamic_ps_timeout *
-                                                   2, 255);
-                               }
-                       }
-                       if (wvif->state == WFX_STATE_STA && wvif->bss_params.aid)
-                               wfx_set_pm(wvif, &wvif->powersave_mode);
-               }
-               wvif = wdev_to_wvif(wdev, 0);
-       }
-
-       mutex_unlock(&wdev->conf_mutex);
-       up(&wvif->scan.lock);
-       return ret;
+       return 0;
 }
 
 int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 {
-       int i;
+       int i, ret = 0;
        struct wfx_dev *wdev = hw->priv;
        struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv;
-       // FIXME: parameters are set by kernel juste after interface_add.
-       // Keep struct hif_req_edca_queue_params blank?
-       struct hif_req_edca_queue_params default_edca_params[] = {
-               [IEEE80211_AC_VO] = {
-                       .queue_id = HIF_QUEUE_ID_VOICE,
-                       .aifsn = 2,
-                       .cw_min = 3,
-                       .cw_max = 7,
-                       .tx_op_limit = TXOP_UNIT * 47,
-               },
-               [IEEE80211_AC_VI] = {
-                       .queue_id = HIF_QUEUE_ID_VIDEO,
-                       .aifsn = 2,
-                       .cw_min = 7,
-                       .cw_max = 15,
-                       .tx_op_limit = TXOP_UNIT * 94,
-               },
-               [IEEE80211_AC_BE] = {
-                       .queue_id = HIF_QUEUE_ID_BESTEFFORT,
-                       .aifsn = 3,
-                       .cw_min = 15,
-                       .cw_max = 1023,
-                       .tx_op_limit = TXOP_UNIT * 0,
-               },
-               [IEEE80211_AC_BK] = {
-                       .queue_id = HIF_QUEUE_ID_BACKGROUND,
-                       .aifsn = 7,
-                       .cw_min = 15,
-                       .cw_max = 1023,
-                       .tx_op_limit = TXOP_UNIT * 0,
-               },
-       };
-
-       BUILD_BUG_ON(ARRAY_SIZE(default_edca_params) != ARRAY_SIZE(wvif->edca.params));
-       if (wfx_api_older_than(wdev, 2, 0)) {
-               default_edca_params[IEEE80211_AC_BE].queue_id = HIF_QUEUE_ID_BACKGROUND;
-               default_edca_params[IEEE80211_AC_BK].queue_id = HIF_QUEUE_ID_BESTEFFORT;
-       }
 
        vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
                             IEEE80211_VIF_SUPPORTS_UAPSD |
@@ -1536,51 +1016,37 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
        wvif->vif = vif;
        wvif->wdev = wdev;
 
-       INIT_WORK(&wvif->link_id_work, wfx_link_id_work);
-       INIT_DELAYED_WORK(&wvif->link_id_gc_work, wfx_link_id_gc_work);
-
+       wvif->link_id_map = 1; // link-id 0 is reserved for multicast
        spin_lock_init(&wvif->ps_state_lock);
-       INIT_WORK(&wvif->set_tim_work, wfx_set_tim_work);
+       INIT_WORK(&wvif->update_tim_work, wfx_update_tim_work);
 
-       INIT_WORK(&wvif->mcast_start_work, wfx_mcast_start_work);
-       INIT_WORK(&wvif->mcast_stop_work, wfx_mcast_stop_work);
-       timer_setup(&wvif->mcast_timeout, wfx_mcast_timeout, 0);
+       memset(&wvif->bss_params, 0, sizeof(wvif->bss_params));
 
-       wvif->setbssparams_done = false;
        mutex_init(&wvif->bss_loss_lock);
        INIT_DELAYED_WORK(&wvif->bss_loss_work, wfx_bss_loss_work);
 
        wvif->wep_default_key_id = -1;
        INIT_WORK(&wvif->wep_key_work, wfx_wep_key_work);
 
-       sema_init(&wvif->scan.lock, 1);
-       INIT_WORK(&wvif->scan.work, wfx_scan_work);
-       INIT_DELAYED_WORK(&wvif->scan.timeout, wfx_scan_timeout);
-
        spin_lock_init(&wvif->event_queue_lock);
        INIT_LIST_HEAD(&wvif->event_queue);
        INIT_WORK(&wvif->event_handler_work, wfx_event_handler_work);
 
        init_completion(&wvif->set_pm_mode_complete);
        complete(&wvif->set_pm_mode_complete);
-       INIT_WORK(&wvif->set_beacon_wakeup_period_work,
-                 wfx_set_beacon_wakeup_period_work);
        INIT_WORK(&wvif->update_filtering_work, wfx_update_filtering_work);
        INIT_WORK(&wvif->bss_params_work, wfx_bss_params_work);
-       INIT_WORK(&wvif->set_cts_work, wfx_set_cts_work);
        INIT_WORK(&wvif->unjoin_work, wfx_unjoin_work);
+       INIT_WORK(&wvif->tx_policy_upload_work, wfx_tx_policy_upload_work);
+
+       mutex_init(&wvif->scan_lock);
+       init_completion(&wvif->scan_complete);
+       INIT_WORK(&wvif->scan_work, wfx_hw_scan_work);
 
        INIT_WORK(&wvif->tx_policy_upload_work, wfx_tx_policy_upload_work);
        mutex_unlock(&wdev->conf_mutex);
 
        hif_set_macaddr(wvif, vif->addr);
-       for (i = 0; i < IEEE80211_NUM_ACS; i++) {
-               memcpy(&wvif->edca.params[i], &default_edca_params[i],
-                      sizeof(default_edca_params[i]));
-               wvif->edca.uapsd_enable[i] = false;
-               hif_set_edca_queue_params(wvif, &wvif->edca.params[i]);
-       }
-       wfx_set_uapsd_param(wvif, &wvif->edca);
 
        wfx_tx_policy_init(wvif);
        wvif = NULL;
@@ -1591,9 +1057,9 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
                else
                        hif_set_block_ack_policy(wvif, 0x00, 0x00);
                // Combo force powersave mode. We can re-enable it now
-               wfx_set_pm(wvif, &wvif->powersave_mode);
+               ret = wfx_update_pm(wvif);
        }
-       return 0;
+       return ret;
 }
 
 void wfx_remove_interface(struct ieee80211_hw *hw,
@@ -1601,15 +1067,11 @@ void wfx_remove_interface(struct ieee80211_hw *hw,
 {
        struct wfx_dev *wdev = hw->priv;
        struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv;
-       int i;
 
-       // If scan is in progress, stop it
-       while (down_trylock(&wvif->scan.lock))
-               schedule();
-       up(&wvif->scan.lock);
        wait_for_completion_timeout(&wvif->set_pm_mode_complete, msecs_to_jiffies(300));
 
        mutex_lock(&wdev->conf_mutex);
+       WARN(wvif->link_id_map != 1, "corrupted state");
        switch (wvif->state) {
        case WFX_STATE_PRE_STA:
        case WFX_STATE_STA:
@@ -1619,19 +1081,7 @@ void wfx_remove_interface(struct ieee80211_hw *hw,
                        wfx_tx_unlock(wdev);
                break;
        case WFX_STATE_AP:
-               for (i = 0; wvif->link_id_map; ++i) {
-                       if (wvif->link_id_map & BIT(i)) {
-                               wfx_unmap_link(wvif, i);
-                               wvif->link_id_map &= ~BIT(i);
-                       }
-               }
-               memset(wvif->link_id_db, 0, sizeof(wvif->link_id_db));
                wvif->sta_asleep_mask = 0;
-               wvif->enable_beacon = false;
-               wvif->mcast_tx = false;
-               wvif->aid0_bit_set = false;
-               wvif->mcast_buffered = false;
-               wvif->pspoll_mask = 0;
                /* reset.link_id = 0; */
                hif_reset(wvif, false);
                break;
@@ -1646,12 +1096,8 @@ void wfx_remove_interface(struct ieee80211_hw *hw,
        /* FIXME: In add to reset MAC address, try to reset interface */
        hif_set_macaddr(wvif, NULL);
 
-       cancel_delayed_work_sync(&wvif->scan.timeout);
-
        wfx_cqm_bssloss_sm(wvif, 0, 0, 0);
        cancel_work_sync(&wvif->unjoin_work);
-       cancel_delayed_work_sync(&wvif->link_id_gc_work);
-       del_timer_sync(&wvif->mcast_timeout);
        wfx_free_event_queue(wvif);
 
        wdev->vif[wvif->id] = NULL;
@@ -1666,7 +1112,7 @@ void wfx_remove_interface(struct ieee80211_hw *hw,
                else
                        hif_set_block_ack_policy(wvif, 0x00, 0x00);
                // Combo force powersave mode. We can re-enable it now
-               wfx_set_pm(wvif, &wvif->powersave_mode);
+               wfx_update_pm(wvif);
        }
 }
 
index 4ccf1b1..cf99a8a 100644 (file)
@@ -23,23 +23,11 @@ enum wfx_state {
        WFX_STATE_AP,
 };
 
-struct wfx_ht_info {
-       struct ieee80211_sta_ht_cap ht_cap;
-       enum nl80211_channel_type channel_type;
-       u16 operation_mode;
-};
-
 struct wfx_hif_event {
        struct list_head link;
        struct hif_ind_event evt;
 };
 
-struct wfx_edca_params {
-       /* NOTE: index is a linux queue id. */
-       struct hif_req_edca_queue_params params[IEEE80211_NUM_ACS];
-       bool uapsd_enable[IEEE80211_NUM_ACS];
-};
-
 struct wfx_grp_addr_table {
        bool enable;
        int num_addresses;
@@ -49,6 +37,9 @@ struct wfx_grp_addr_table {
 struct wfx_sta_priv {
        int link_id;
        int vif_id;
+       u8 buffered[IEEE80211_NUM_TIDS];
+       // Ensure atomicity of "buffered" and calls to ieee80211_sta_set_buffered()
+       spinlock_t lock;
 };
 
 // mac80211 interface
@@ -91,13 +82,12 @@ void wfx_unassign_vif_chanctx(struct ieee80211_hw *hw,
                              struct ieee80211_chanctx_conf *conf);
 
 // WSM Callbacks
-void wfx_suspend_resume(struct wfx_vif *wvif,
-                       struct hif_ind_suspend_resume_tx *arg);
+void wfx_suspend_resume_mc(struct wfx_vif *wvif, enum sta_notify_cmd cmd);
 
 // Other Helpers
 void wfx_cqm_bssloss_sm(struct wfx_vif *wvif, int init, int good, int bad);
 void wfx_update_filtering(struct wfx_vif *wvif);
-int wfx_set_pm(struct wfx_vif *wvif, const struct hif_req_set_pm_mode *arg);
 int wfx_fwd_probe_req(struct wfx_vif *wvif, bool enable);
+u32 wfx_rate_mask_to_hw(struct wfx_dev *wdev, u32 rates);
 
 #endif /* WFX_STA_H */
index 3f6198a..30c6a13 100644 (file)
@@ -153,7 +153,7 @@ hif_mib_list_enum
 #define hif_mib_list hif_mib_list_enum { -1, NULL }
 
 DECLARE_EVENT_CLASS(hif_data,
-       TP_PROTO(struct hif_msg *hif, int tx_fill_level, bool is_recv),
+       TP_PROTO(const struct hif_msg *hif, int tx_fill_level, bool is_recv),
        TP_ARGS(hif, tx_fill_level, is_recv),
        TP_STRUCT__entry(
                __field(int, tx_fill_level)
@@ -203,12 +203,12 @@ DECLARE_EVENT_CLASS(hif_data,
        )
 );
 DEFINE_EVENT(hif_data, hif_send,
-       TP_PROTO(struct hif_msg *hif, int tx_fill_level, bool is_recv),
+       TP_PROTO(const struct hif_msg *hif, int tx_fill_level, bool is_recv),
        TP_ARGS(hif, tx_fill_level, is_recv));
 #define _trace_hif_send(hif, tx_fill_level)\
        trace_hif_send(hif, tx_fill_level, false)
 DEFINE_EVENT(hif_data, hif_recv,
-       TP_PROTO(struct hif_msg *hif, int tx_fill_level, bool is_recv),
+       TP_PROTO(const struct hif_msg *hif, int tx_fill_level, bool is_recv),
        TP_ARGS(hif, tx_fill_level, is_recv));
 #define _trace_hif_recv(hif, tx_fill_level)\
        trace_hif_recv(hif, tx_fill_level, true)
@@ -359,7 +359,8 @@ TRACE_EVENT(bh_stats,
        trace_bh_stats(ind, req, cnf, busy, release)
 
 TRACE_EVENT(tx_stats,
-       TP_PROTO(struct hif_cnf_tx *tx_cnf, struct sk_buff *skb, int delay),
+       TP_PROTO(const struct hif_cnf_tx *tx_cnf, const struct sk_buff *skb,
+                int delay),
        TP_ARGS(tx_cnf, skb, delay),
        TP_STRUCT__entry(
                __field(int, pkt_id)
@@ -375,8 +376,9 @@ TRACE_EVENT(tx_stats,
                // Keep sync with wfx_rates definition in main.c
                static const int hw_rate[] = { 0, 1, 2, 3, 6, 7, 8, 9,
                                               10, 11, 12, 13 };
-               struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-               struct ieee80211_tx_rate *rates = tx_info->driver_rates;
+               const struct ieee80211_tx_info *tx_info =
+                       (const struct ieee80211_tx_info *)skb->cb;
+               const struct ieee80211_tx_rate *rates = tx_info->driver_rates;
                int i;
 
                __entry->pkt_id = tx_cnf->packet_id;
index 781a8c8..8b85bb1 100644 (file)
@@ -26,6 +26,9 @@
 #include "hif_tx.h"
 #include "hif_api_general.h"
 
+#define USEC_PER_TXOP 32 // see struct ieee80211_tx_queue_params
+#define USEC_PER_TU 1024
+
 struct hwbus_ops;
 
 struct wfx_dev {
@@ -51,14 +54,12 @@ struct wfx_dev {
        int                     tx_burst_idx;
        atomic_t                tx_lock;
 
+       atomic_t                packet_id;
        u32                     key_map;
        struct hif_req_add_key  keys[MAX_KEY_ENTRIES];
 
        struct hif_rx_stats     rx_stats;
        struct mutex            rx_stats_lock;
-
-       int                     output_power;
-       atomic_t                scan_in_progress;
 };
 
 struct wfx_vif {
@@ -68,24 +69,15 @@ struct wfx_vif {
        int                     id;
        enum wfx_state          state;
 
-       int                     delayed_link_loss;
        int                     bss_loss_state;
        u32                     bss_loss_confirm_id;
        struct mutex            bss_loss_lock;
        struct delayed_work     bss_loss_work;
 
        u32                     link_id_map;
-       struct wfx_link_entry   link_id_db[WFX_MAX_STA_IN_AP_MODE];
-       struct delayed_work     link_id_gc_work;
-       struct work_struct      link_id_work;
 
-       bool                    aid0_bit_set;
-       bool                    mcast_tx;
-       bool                    mcast_buffered;
+       bool                    after_dtim_tx_allowed;
        struct wfx_grp_addr_table mcast_filter;
-       struct timer_list       mcast_timeout;
-       struct work_struct      mcast_start_work;
-       struct work_struct      mcast_stop_work;
 
        s8                      wep_default_key_id;
        struct sk_buff          *wep_pending_skb;
@@ -95,37 +87,30 @@ struct wfx_vif {
        struct work_struct      tx_policy_upload_work;
 
        u32                     sta_asleep_mask;
-       u32                     pspoll_mask;
        spinlock_t              ps_state_lock;
-       struct work_struct      set_tim_work;
+       struct work_struct      update_tim_work;
 
-       int                     dtim_period;
        int                     beacon_int;
-       bool                    enable_beacon;
-       struct work_struct      set_beacon_wakeup_period_work;
-
        bool                    filter_bssid;
        bool                    fwd_probe_req;
        bool                    disable_beacon_filter;
        struct work_struct      update_filtering_work;
 
-       u32                     erp_info;
-       int                     cqm_rssi_thold;
-       bool                    setbssparams_done;
-       struct wfx_ht_info      ht_info;
-       struct wfx_edca_params  edca;
-       struct hif_mib_set_uapsd_information uapsd_info;
+       unsigned long           uapsd_mask;
+       struct ieee80211_tx_queue_params edca_params[IEEE80211_NUM_ACS];
        struct hif_req_set_bss_params bss_params;
        struct work_struct      bss_params_work;
-       struct work_struct      set_cts_work;
 
        int                     join_complete_status;
-       bool                    delayed_unjoin;
        struct work_struct      unjoin_work;
 
-       struct wfx_scan         scan;
+       /* avoid some operations in parallel with scan */
+       struct mutex            scan_lock;
+       struct work_struct      scan_work;
+       struct completion       scan_complete;
+       bool                    scan_abort;
+       struct ieee80211_scan_request *scan_req;
 
-       struct hif_req_set_pm_mode powersave_mode;
        struct completion       set_pm_mode_complete;
 
        struct list_head        event_queue;
diff --git a/drivers/staging/wilc1000/fw.h b/drivers/staging/wilc1000/fw.h
new file mode 100644 (file)
index 0000000..a76e1de
--- /dev/null
@@ -0,0 +1,119 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
+ * All rights reserved.
+ */
+
+#ifndef WILC_FW_H
+#define WILC_FW_H
+
+#include <linux/ieee80211.h>
+
+#define WILC_MAX_NUM_STA                       9
+#define WILC_MAX_RATES_SUPPORTED               12
+#define WILC_MAX_NUM_PMKIDS                    16
+#define WILC_MAX_NUM_SCANNED_CH                        14
+
+struct wilc_assoc_resp {
+       __le16 capab_info;
+       __le16 status_code;
+       __le16 aid;
+} __packed;
+
+struct wilc_pmkid {
+       u8 bssid[ETH_ALEN];
+       u8 pmkid[WLAN_PMKID_LEN];
+} __packed;
+
+struct wilc_pmkid_attr {
+       u8 numpmkid;
+       struct wilc_pmkid pmkidlist[WILC_MAX_NUM_PMKIDS];
+} __packed;
+
+struct wilc_reg_frame {
+       u8 reg;
+       u8 reg_id;
+       __le16 frame_type;
+} __packed;
+
+struct wilc_drv_handler {
+       __le32 handler;
+       u8 mode;
+} __packed;
+
+struct wilc_wep_key {
+       u8 index;
+       u8 key_len;
+       u8 key[0];
+} __packed;
+
+struct wilc_sta_wpa_ptk {
+       u8 mac_addr[ETH_ALEN];
+       u8 key_len;
+       u8 key[0];
+} __packed;
+
+struct wilc_ap_wpa_ptk {
+       u8 mac_addr[ETH_ALEN];
+       u8 index;
+       u8 key_len;
+       u8 key[0];
+} __packed;
+
+struct wilc_gtk_key {
+       u8 mac_addr[ETH_ALEN];
+       u8 rsc[8];
+       u8 index;
+       u8 key_len;
+       u8 key[0];
+} __packed;
+
+struct wilc_op_mode {
+       __le32 mode;
+} __packed;
+
+struct wilc_noa_opp_enable {
+       u8 ct_window;
+       u8 cnt;
+       __le32 duration;
+       __le32 interval;
+       __le32 start_time;
+} __packed;
+
+struct wilc_noa_opp_disable {
+       u8 cnt;
+       __le32 duration;
+       __le32 interval;
+       __le32 start_time;
+} __packed;
+
+struct wilc_join_bss_param {
+       char ssid[IEEE80211_MAX_SSID_LEN];
+       u8 ssid_terminator;
+       u8 bss_type;
+       u8 ch;
+       __le16 cap_info;
+       u8 sa[ETH_ALEN];
+       u8 bssid[ETH_ALEN];
+       __le16 beacon_period;
+       u8 dtim_period;
+       u8 supp_rates[WILC_MAX_RATES_SUPPORTED + 1];
+       u8 wmm_cap;
+       u8 uapsd_cap;
+       u8 ht_capable;
+       u8 rsn_found;
+       u8 rsn_grp_policy;
+       u8 mode_802_11i;
+       u8 p_suites[3];
+       u8 akm_suites[3];
+       u8 rsn_cap[2];
+       u8 noa_enabled;
+       __le32 tsf_lo;
+       u8 idx;
+       u8 opp_enabled;
+       union {
+               struct wilc_noa_opp_disable opp_dis;
+               struct wilc_noa_opp_enable opp_en;
+       };
+} __packed;
+#endif
index 349e45d..658790b 100644 (file)
@@ -10,7 +10,6 @@
 #define WILC_HIF_CONNECT_TIMEOUT_MS             9500
 
 #define WILC_FALSE_FRMWR_CHANNEL               100
-#define WILC_MAX_RATES_SUPPORTED               12
 
 struct wilc_rcvd_mac_info {
        u8 status;
@@ -27,48 +26,6 @@ struct wilc_del_all_sta {
        u8 mac[WILC_MAX_NUM_STA][ETH_ALEN];
 };
 
-struct wilc_op_mode {
-       __le32 mode;
-};
-
-struct wilc_reg_frame {
-       u8 reg;
-       u8 reg_id;
-       __le16 frame_type;
-} __packed;
-
-struct wilc_drv_handler {
-       __le32 handler;
-       u8 mode;
-} __packed;
-
-struct wilc_wep_key {
-       u8 index;
-       u8 key_len;
-       u8 key[0];
-} __packed;
-
-struct wilc_sta_wpa_ptk {
-       u8 mac_addr[ETH_ALEN];
-       u8 key_len;
-       u8 key[0];
-} __packed;
-
-struct wilc_ap_wpa_ptk {
-       u8 mac_addr[ETH_ALEN];
-       u8 index;
-       u8 key_len;
-       u8 key[0];
-} __packed;
-
-struct wilc_gtk_key {
-       u8 mac_addr[ETH_ALEN];
-       u8 rsc[8];
-       u8 index;
-       u8 key_len;
-       u8 key[0];
-} __packed;
-
 union wilc_message_body {
        struct wilc_rcvd_net_info net_info;
        struct wilc_rcvd_mac_info mac_info;
@@ -86,51 +43,6 @@ struct host_if_msg {
        bool is_sync;
 };
 
-struct wilc_noa_opp_enable {
-       u8 ct_window;
-       u8 cnt;
-       __le32 duration;
-       __le32 interval;
-       __le32 start_time;
-} __packed;
-
-struct wilc_noa_opp_disable {
-       u8 cnt;
-       __le32 duration;
-       __le32 interval;
-       __le32 start_time;
-} __packed;
-
-struct wilc_join_bss_param {
-       char ssid[IEEE80211_MAX_SSID_LEN];
-       u8 ssid_terminator;
-       u8 bss_type;
-       u8 ch;
-       __le16 cap_info;
-       u8 sa[ETH_ALEN];
-       u8 bssid[ETH_ALEN];
-       __le16 beacon_period;
-       u8 dtim_period;
-       u8 supp_rates[WILC_MAX_RATES_SUPPORTED + 1];
-       u8 wmm_cap;
-       u8 uapsd_cap;
-       u8 ht_capable;
-       u8 rsn_found;
-       u8 rsn_grp_policy;
-       u8 mode_802_11i;
-       u8 p_suites[3];
-       u8 akm_suites[3];
-       u8 rsn_cap[2];
-       u8 noa_enabled;
-       __le32 tsf_lo;
-       u8 idx;
-       u8 opp_enabled;
-       union {
-               struct wilc_noa_opp_disable opp_dis;
-               struct wilc_noa_opp_enable opp_en;
-       };
-} __packed;
-
 /* 'msg' should be free by the caller for syc */
 static struct host_if_msg*
 wilc_alloc_work(struct wilc_vif *vif, void (*work_fun)(struct work_struct *),
@@ -640,7 +552,7 @@ static s32 wilc_parse_assoc_resp_info(u8 *buffer, u32 buffer_len,
 {
        u8 *ies;
        u16 ies_len;
-       struct assoc_resp *res = (struct assoc_resp *)buffer;
+       struct wilc_assoc_resp *res = (struct wilc_assoc_resp *)buffer;
 
        ret_conn_info->status = le16_to_cpu(res->status_code);
        if (ret_conn_info->status == WLAN_STATUS_SUCCESS) {
index 22ee6ff..db91791 100644 (file)
@@ -17,14 +17,11 @@ enum {
        WILC_CLIENT_MODE = 0x4
 };
 
-#define WILC_MAX_NUM_STA                       9
-#define WILC_MAX_NUM_SCANNED_CH                        14
 #define WILC_MAX_NUM_PROBED_SSID               10
 
 #define WILC_TX_MIC_KEY_LEN                    8
 #define WILC_RX_MIC_KEY_LEN                    8
 
-#define WILC_MAX_NUM_PMKIDS                    16
 #define WILC_ADD_STA_LENGTH                    40
 #define WILC_NUM_CONCURRENT_IFC                        2
 
@@ -35,12 +32,6 @@ enum {
 
 #define WILC_MAX_ASSOC_RESP_FRAME_SIZE   256
 
-struct assoc_resp {
-       __le16 capab_info;
-       __le16 status_code;
-       __le16 aid;
-} __packed;
-
 struct rf_info {
        u8 link_speed;
        s8 rssi;
@@ -59,16 +50,6 @@ enum host_if_state {
        HOST_IF_FORCE_32BIT             = 0xFFFFFFFF
 };
 
-struct wilc_pmkid {
-       u8 bssid[ETH_ALEN];
-       u8 pmkid[WLAN_PMKID_LEN];
-} __packed;
-
-struct wilc_pmkid_attr {
-       u8 numpmkid;
-       struct wilc_pmkid pmkidlist[WILC_MAX_NUM_PMKIDS];
-} __packed;
-
 struct cfg_param_attr {
        u32 flag;
        u16 short_retry_limit;
index d2c0b0f..fce5bf2 100644 (file)
@@ -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;
                        }
@@ -177,7 +174,7 @@ static int wilc_txq_task(void *vp)
                                }
                                srcu_read_unlock(&wl->srcu, srcu_idx);
                        }
-               } while (ret == -ENOBUFS && !wl->close);
+               } while (ret == WILC_VMM_ENTRY_FULL_RETRY && !wl->close);
        }
        return 0;
 }
@@ -186,7 +183,7 @@ static int wilc_wlan_get_firmware(struct net_device *dev)
 {
        struct wilc_vif *vif = netdev_priv(dev);
        struct wilc *wilc = vif->wilc;
-       int chip_id, ret = 0;
+       int chip_id;
        const struct firmware *wilc_firmware;
        char *firmware;
 
@@ -201,14 +198,11 @@ static int wilc_wlan_get_firmware(struct net_device *dev)
 
        if (request_firmware(&wilc_firmware, firmware, wilc->dev) != 0) {
                netdev_err(dev, "%s - firmware not available\n", firmware);
-               ret = -1;
-               goto fail;
+               return -EINVAL;
        }
        wilc->firmware = wilc_firmware;
 
-fail:
-
-       return ret;
+       return 0;
 }
 
 static int wilc_start_firmware(struct net_device *dev)
@@ -218,7 +212,7 @@ static int wilc_start_firmware(struct net_device *dev)
        int ret = 0;
 
        ret = wilc_wlan_start(wilc);
-       if (ret < 0)
+       if (ret)
                return ret;
 
        if (!wait_for_completion_timeout(&wilc->sync_event,
@@ -241,7 +235,7 @@ static int wilc1000_firmware_download(struct net_device *dev)
 
        ret = wilc_wlan_firmware_download(wilc, wilc->firmware->data,
                                          wilc->firmware->size);
-       if (ret < 0)
+       if (ret)
                return ret;
 
        release_firmware(wilc->firmware);
@@ -420,7 +414,7 @@ static int wilc_init_fw_config(struct net_device *dev, struct wilc_vif *vif)
        return 0;
 
 fail:
-       return -1;
+       return -EINVAL;
 }
 
 static void wlan_deinitialize_threads(struct net_device *dev)
@@ -500,14 +494,12 @@ static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif)
                wl->close = 0;
 
                ret = wilc_wlan_init(dev);
-               if (ret < 0)
-                       return -EIO;
+               if (ret)
+                       return ret;
 
                ret = wlan_initialize_threads(dev);
-               if (ret < 0) {
-                       ret = -EIO;
+               if (ret)
                        goto fail_wilc_wlan;
-               }
 
                if (wl->gpio_irq && init_irq(dev)) {
                        ret = -EIO;
@@ -521,22 +513,17 @@ static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif)
                        goto fail_irq_init;
                }
 
-               if (wilc_wlan_get_firmware(dev)) {
-                       ret = -EIO;
+               ret = wilc_wlan_get_firmware(dev);
+               if (ret)
                        goto fail_irq_enable;
-               }
 
                ret = wilc1000_firmware_download(dev);
-               if (ret < 0) {
-                       ret = -EIO;
+               if (ret)
                        goto fail_irq_enable;
-               }
 
                ret = wilc_start_firmware(dev);
-               if (ret < 0) {
-                       ret = -EIO;
+               if (ret)
                        goto fail_irq_enable;
-               }
 
                if (wilc_wlan_cfg_get(vif, 1, WID_FIRMWARE_VERSION, 1, 0)) {
                        int size;
@@ -548,11 +535,10 @@ static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif)
                        firmware_ver[size] = '\0';
                        netdev_dbg(dev, "Firmware Ver = %s\n", firmware_ver);
                }
-               ret = wilc_init_fw_config(dev, vif);
 
-               if (ret < 0) {
+               ret = wilc_init_fw_config(dev, vif);
+               if (ret) {
                        netdev_err(dev, "Failed to configure firmware\n");
-                       ret = -EIO;
                        goto fail_fw_start;
                }
                wl->initialized = true;
@@ -603,11 +589,11 @@ static int wilc_mac_open(struct net_device *ndev)
        netdev_dbg(ndev, "MAC OPEN[%p]\n", ndev);
 
        ret = wilc_init_host_int(ndev);
-       if (ret < 0)
+       if (ret)
                return ret;
 
        ret = wilc_wlan_initialize(ndev, vif);
-       if (ret < 0) {
+       if (ret) {
                wilc_deinit_host_int(ndev);
                return ret;
        }
@@ -840,7 +826,7 @@ static const struct net_device_ops wilc_netdev_ops = {
 void wilc_netdev_cleanup(struct wilc *wilc)
 {
        struct wilc_vif *vif;
-       int srcu_idx;
+       int srcu_idx, ifc_cnt = 0;
 
        if (!wilc)
                return;
@@ -861,7 +847,7 @@ void wilc_netdev_cleanup(struct wilc *wilc)
        flush_workqueue(wilc->hif_workqueue);
        destroy_workqueue(wilc->hif_workqueue);
 
-       do {
+       while (ifc_cnt < WILC_NUM_CONCURRENT_IFC) {
                mutex_lock(&wilc->vif_mutex);
                if (wilc->vif_num <= 0) {
                        mutex_unlock(&wilc->vif_mutex);
@@ -874,7 +860,8 @@ void wilc_netdev_cleanup(struct wilc *wilc)
                wilc->vif_num--;
                mutex_unlock(&wilc->vif_mutex);
                synchronize_srcu(&wilc->srcu);
-       } while (1);
+               ifc_cnt++;
+       }
 
        wilc_wlan_cfg_deinit(wilc);
        wlan_deinit_locks(wilc);
index cd8f0d7..d5f7a60 100644 (file)
@@ -21,7 +21,6 @@
 #define FLOW_CONTROL_LOWER_THRESHOLD           128
 #define FLOW_CONTROL_UPPER_THRESHOLD           256
 
-#define WILC_MAX_NUM_PMKIDS                    16
 #define PMKID_FOUND                            1
 #define NUM_STA_ASSOCIATED                     8
 
index 319e039..ca99335 100644 (file)
@@ -273,7 +273,7 @@ static int wilc_sdio_set_func0_csa_address(struct wilc *wilc, u32 adr)
        ret = wilc_sdio_cmd52(wilc, &cmd);
        if (ret) {
                dev_err(&func->dev, "Failed cmd52, set 0x10c data...\n");
-               goto fail;
+               return ret;
        }
 
        cmd.address = 0x10d;
@@ -281,7 +281,7 @@ static int wilc_sdio_set_func0_csa_address(struct wilc *wilc, u32 adr)
        ret = wilc_sdio_cmd52(wilc, &cmd);
        if (ret) {
                dev_err(&func->dev, "Failed cmd52, set 0x10d data...\n");
-               goto fail;
+               return ret;
        }
 
        cmd.address = 0x10e;
@@ -289,11 +289,9 @@ static int wilc_sdio_set_func0_csa_address(struct wilc *wilc, u32 adr)
        ret = wilc_sdio_cmd52(wilc, &cmd);
        if (ret) {
                dev_err(&func->dev, "Failed cmd52, set 0x10e data...\n");
-               goto fail;
+               return ret;
        }
 
-       return 1;
-fail:
        return 0;
 }
 
@@ -311,7 +309,7 @@ static int wilc_sdio_set_func0_block_size(struct wilc *wilc, u32 block_size)
        ret = wilc_sdio_cmd52(wilc, &cmd);
        if (ret) {
                dev_err(&func->dev, "Failed cmd52, set 0x10 data...\n");
-               goto fail;
+               return ret;
        }
 
        cmd.address = 0x11;
@@ -319,11 +317,9 @@ static int wilc_sdio_set_func0_block_size(struct wilc *wilc, u32 block_size)
        ret = wilc_sdio_cmd52(wilc, &cmd);
        if (ret) {
                dev_err(&func->dev, "Failed cmd52, set 0x11 data...\n");
-               goto fail;
+               return ret;
        }
 
-       return 1;
-fail:
        return 0;
 }
 
@@ -347,18 +343,16 @@ static int wilc_sdio_set_func1_block_size(struct wilc *wilc, u32 block_size)
        ret = wilc_sdio_cmd52(wilc, &cmd);
        if (ret) {
                dev_err(&func->dev, "Failed cmd52, set 0x110 data...\n");
-               goto fail;
+               return ret;
        }
        cmd.address = 0x111;
        cmd.data = (u8)(block_size >> 8);
        ret = wilc_sdio_cmd52(wilc, &cmd);
        if (ret) {
                dev_err(&func->dev, "Failed cmd52, set 0x111 data...\n");
-               goto fail;
+               return ret;
        }
 
-       return 1;
-fail:
        return 0;
 }
 
@@ -384,19 +378,18 @@ static int wilc_sdio_write_reg(struct wilc *wilc, u32 addr, u32 data)
                cmd.address = addr;
                cmd.data = data;
                ret = wilc_sdio_cmd52(wilc, &cmd);
-               if (ret) {
+               if (ret)
                        dev_err(&func->dev,
                                "Failed cmd 52, read reg (%08x) ...\n", addr);
-                       goto fail;
-               }
        } else {
                struct sdio_cmd53 cmd;
 
                /**
                 *      set the AHB address
                 **/
-               if (!wilc_sdio_set_func0_csa_address(wilc, addr))
-                       goto fail;
+               ret = wilc_sdio_set_func0_csa_address(wilc, addr);
+               if (ret)
+                       return ret;
 
                cmd.read_write = 1;
                cmd.function = 0;
@@ -407,18 +400,12 @@ static int wilc_sdio_write_reg(struct wilc *wilc, u32 addr, u32 data)
                cmd.buffer = (u8 *)&data;
                cmd.block_size = sdio_priv->block_size;
                ret = wilc_sdio_cmd53(wilc, &cmd);
-               if (ret) {
+               if (ret)
                        dev_err(&func->dev,
                                "Failed cmd53, write reg (%08x)...\n", addr);
-                       goto fail;
-               }
        }
 
-       return 1;
-
-fail:
-
-       return 0;
+       return ret;
 }
 
 static int wilc_sdio_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
@@ -470,14 +457,15 @@ static int wilc_sdio_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
                cmd.buffer = buf;
                cmd.block_size = block_size;
                if (addr > 0) {
-                       if (!wilc_sdio_set_func0_csa_address(wilc, addr))
-                               goto fail;
+                       ret = wilc_sdio_set_func0_csa_address(wilc, addr);
+                       if (ret)
+                               return ret;
                }
                ret = wilc_sdio_cmd53(wilc, &cmd);
                if (ret) {
                        dev_err(&func->dev,
                                "Failed cmd53 [%x], block send...\n", addr);
-                       goto fail;
+                       return ret;
                }
                if (addr > 0)
                        addr += nblk * block_size;
@@ -493,21 +481,18 @@ static int wilc_sdio_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
                cmd.block_size = block_size;
 
                if (addr > 0) {
-                       if (!wilc_sdio_set_func0_csa_address(wilc, addr))
-                               goto fail;
+                       ret = wilc_sdio_set_func0_csa_address(wilc, addr);
+                       if (ret)
+                               return ret;
                }
                ret = wilc_sdio_cmd53(wilc, &cmd);
                if (ret) {
                        dev_err(&func->dev,
                                "Failed cmd53 [%x], bytes send...\n", addr);
-                       goto fail;
+                       return ret;
                }
        }
 
-       return 1;
-
-fail:
-
        return 0;
 }
 
@@ -528,14 +513,15 @@ static int wilc_sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data)
                if (ret) {
                        dev_err(&func->dev,
                                "Failed cmd 52, read reg (%08x) ...\n", addr);
-                       goto fail;
+                       return ret;
                }
                *data = cmd.data;
        } else {
                struct sdio_cmd53 cmd;
 
-               if (!wilc_sdio_set_func0_csa_address(wilc, addr))
-                       goto fail;
+               ret = wilc_sdio_set_func0_csa_address(wilc, addr);
+               if (ret)
+                       return ret;
 
                cmd.read_write = 0;
                cmd.function = 0;
@@ -550,16 +536,11 @@ static int wilc_sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data)
                if (ret) {
                        dev_err(&func->dev,
                                "Failed cmd53, read reg (%08x)...\n", addr);
-                       goto fail;
+                       return ret;
                }
        }
 
        le32_to_cpus(data);
-
-       return 1;
-
-fail:
-
        return 0;
 }
 
@@ -612,14 +593,15 @@ static int wilc_sdio_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
                cmd.buffer = buf;
                cmd.block_size = block_size;
                if (addr > 0) {
-                       if (!wilc_sdio_set_func0_csa_address(wilc, addr))
-                               goto fail;
+                       ret = wilc_sdio_set_func0_csa_address(wilc, addr);
+                       if (ret)
+                               return ret;
                }
                ret = wilc_sdio_cmd53(wilc, &cmd);
                if (ret) {
                        dev_err(&func->dev,
                                "Failed cmd53 [%x], block read...\n", addr);
-                       goto fail;
+                       return ret;
                }
                if (addr > 0)
                        addr += nblk * block_size;
@@ -635,21 +617,18 @@ static int wilc_sdio_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
                cmd.block_size = block_size;
 
                if (addr > 0) {
-                       if (!wilc_sdio_set_func0_csa_address(wilc, addr))
-                               goto fail;
+                       ret = wilc_sdio_set_func0_csa_address(wilc, addr);
+                       if (ret)
+                               return ret;
                }
                ret = wilc_sdio_cmd53(wilc, &cmd);
                if (ret) {
                        dev_err(&func->dev,
                                "Failed cmd53 [%x], bytes read...\n", addr);
-                       goto fail;
+                       return ret;
                }
        }
 
-       return 1;
-
-fail:
-
        return 0;
 }
 
@@ -661,7 +640,7 @@ fail:
 
 static int wilc_sdio_deinit(struct wilc *wilc)
 {
-       return 1;
+       return 0;
 }
 
 static int wilc_sdio_init(struct wilc *wilc, bool resume)
@@ -686,15 +665,16 @@ static int wilc_sdio_init(struct wilc *wilc, bool resume)
        ret = wilc_sdio_cmd52(wilc, &cmd);
        if (ret) {
                dev_err(&func->dev, "Fail cmd 52, enable csa...\n");
-               goto fail;
+               return ret;
        }
 
        /**
         *      function 0 block size
         **/
-       if (!wilc_sdio_set_func0_block_size(wilc, WILC_SDIO_BLOCK_SIZE)) {
+       ret = wilc_sdio_set_func0_block_size(wilc, WILC_SDIO_BLOCK_SIZE);
+       if (ret) {
                dev_err(&func->dev, "Fail cmd 52, set func 0 block size...\n");
-               goto fail;
+               return ret;
        }
        sdio_priv->block_size = WILC_SDIO_BLOCK_SIZE;
 
@@ -710,7 +690,7 @@ static int wilc_sdio_init(struct wilc *wilc, bool resume)
        if (ret) {
                dev_err(&func->dev,
                        "Fail cmd 52, set IOE register...\n");
-               goto fail;
+               return ret;
        }
 
        /**
@@ -727,7 +707,7 @@ static int wilc_sdio_init(struct wilc *wilc, bool resume)
                if (ret) {
                        dev_err(&func->dev,
                                "Fail cmd 52, get IOR register...\n");
-                       goto fail;
+                       return ret;
                }
                if (cmd.data == 0x2)
                        break;
@@ -735,15 +715,16 @@ static int wilc_sdio_init(struct wilc *wilc, bool resume)
 
        if (loop <= 0) {
                dev_err(&func->dev, "Fail func 1 is not ready...\n");
-               goto fail;
+               return -EINVAL;
        }
 
        /**
         *      func 1 is ready, set func 1 block size
         **/
-       if (!wilc_sdio_set_func1_block_size(wilc, WILC_SDIO_BLOCK_SIZE)) {
+       ret = wilc_sdio_set_func1_block_size(wilc, WILC_SDIO_BLOCK_SIZE);
+       if (ret) {
                dev_err(&func->dev, "Fail set func 1 block size...\n");
-               goto fail;
+               return ret;
        }
 
        /**
@@ -757,16 +738,17 @@ static int wilc_sdio_init(struct wilc *wilc, bool resume)
        ret = wilc_sdio_cmd52(wilc, &cmd);
        if (ret) {
                dev_err(&func->dev, "Fail cmd 52, set IEN register...\n");
-               goto fail;
+               return ret;
        }
 
        /**
         *      make sure can read back chip id correctly
         **/
        if (!resume) {
-               if (!wilc_sdio_read_reg(wilc, 0x1000, &chipid)) {
+               ret = wilc_sdio_read_reg(wilc, 0x1000, &chipid);
+               if (ret) {
                        dev_err(&func->dev, "Fail cmd read chip id...\n");
-                       goto fail;
+                       return ret;
                }
                dev_err(&func->dev, "chipid (%08x)\n", chipid);
                if ((chipid & 0xfff) > 0x2a0)
@@ -777,10 +759,6 @@ static int wilc_sdio_init(struct wilc *wilc, bool resume)
                         sdio_priv->has_thrpt_enh3);
        }
 
-       return 1;
-
-fail:
-
        return 0;
 }
 
@@ -806,7 +784,7 @@ static int wilc_sdio_read_size(struct wilc *wilc, u32 *size)
        tmp |= (cmd.data << 8);
 
        *size = tmp;
-       return 1;
+       return 0;
 }
 
 static int wilc_sdio_read_int(struct wilc *wilc, u32 *int_status)
@@ -865,7 +843,7 @@ static int wilc_sdio_read_int(struct wilc *wilc, u32 *int_status)
 
        *int_status = tmp;
 
-       return 1;
+       return 0;
 }
 
 static int wilc_sdio_clear_int_ext(struct wilc *wilc, u32 val)
@@ -909,10 +887,10 @@ static int wilc_sdio_clear_int_ext(struct wilc *wilc, u32 val)
                                dev_err(&func->dev,
                                        "Failed cmd52, set 0xf8 data (%d) ...\n",
                                        __LINE__);
-                               goto fail;
+                               return ret;
                        }
                }
-               return 1;
+               return 0;
        }
        if (sdio_priv->irq_gpio) {
                /* has_thrpt_enh2 uses register 0xf8 to clear interrupts. */
@@ -926,7 +904,6 @@ static int wilc_sdio_clear_int_ext(struct wilc *wilc, u32 val)
                if (flags) {
                        int i;
 
-                       ret = 1;
                        for (i = 0; i < sdio_priv->nint; i++) {
                                if (flags & 1) {
                                        struct sdio_cmd52 cmd;
@@ -942,15 +919,12 @@ static int wilc_sdio_clear_int_ext(struct wilc *wilc, u32 val)
                                                dev_err(&func->dev,
                                                        "Failed cmd52, set 0xf8 data (%d) ...\n",
                                                        __LINE__);
-                                               goto fail;
+                                               return ret;
                                        }
                                }
-                               if (!ret)
-                                       break;
                                flags >>= 1;
                        }
-                       if (!ret)
-                               goto fail;
+
                        for (i = sdio_priv->nint; i < MAX_NUM_INT; i++) {
                                if (flags & 1)
                                        dev_err(&func->dev,
@@ -985,11 +959,9 @@ static int wilc_sdio_clear_int_ext(struct wilc *wilc, u32 val)
                        dev_err(&func->dev,
                                "Failed cmd52, set 0xf6 data (%d) ...\n",
                                __LINE__);
-                       goto fail;
+                       return ret;
                }
        }
-       return 1;
-fail:
        return 0;
 }
 
@@ -1001,12 +973,12 @@ static int wilc_sdio_sync_ext(struct wilc *wilc, int nint)
 
        if (nint > MAX_NUM_INT) {
                dev_err(&func->dev, "Too many interrupts (%d)...\n", nint);
-               return 0;
+               return -EINVAL;
        }
        if (nint > MAX_NUN_INT_THRPT_ENH2) {
                dev_err(&func->dev,
                        "Cannot support more than 5 interrupts when has_thrpt_enh2=1.\n");
-               return 0;
+               return -EINVAL;
        }
 
        sdio_priv->nint = nint;
@@ -1014,15 +986,15 @@ static int wilc_sdio_sync_ext(struct wilc *wilc, int nint)
        /**
         *      Disable power sequencer
         **/
-       if (!wilc_sdio_read_reg(wilc, WILC_MISC, &reg)) {
+       if (wilc_sdio_read_reg(wilc, WILC_MISC, &reg)) {
                dev_err(&func->dev, "Failed read misc reg...\n");
-               return 0;
+               return -EINVAL;
        }
 
        reg &= ~BIT(8);
-       if (!wilc_sdio_write_reg(wilc, WILC_MISC, reg)) {
+       if (wilc_sdio_write_reg(wilc, WILC_MISC, reg)) {
                dev_err(&func->dev, "Failed write misc reg...\n");
-               return 0;
+               return -EINVAL;
        }
 
        if (sdio_priv->irq_gpio) {
@@ -1033,59 +1005,59 @@ static int wilc_sdio_sync_ext(struct wilc *wilc, int nint)
                 *      interrupt pin mux select
                 **/
                ret = wilc_sdio_read_reg(wilc, WILC_PIN_MUX_0, &reg);
-               if (!ret) {
+               if (ret) {
                        dev_err(&func->dev, "Failed read reg (%08x)...\n",
                                WILC_PIN_MUX_0);
-                       return 0;
+                       return ret;
                }
                reg |= BIT(8);
                ret = wilc_sdio_write_reg(wilc, WILC_PIN_MUX_0, reg);
-               if (!ret) {
+               if (ret) {
                        dev_err(&func->dev, "Failed write reg (%08x)...\n",
                                WILC_PIN_MUX_0);
-                       return 0;
+                       return ret;
                }
 
                /**
                 *      interrupt enable
                 **/
                ret = wilc_sdio_read_reg(wilc, WILC_INTR_ENABLE, &reg);
-               if (!ret) {
+               if (ret) {
                        dev_err(&func->dev, "Failed read reg (%08x)...\n",
                                WILC_INTR_ENABLE);
-                       return 0;
+                       return ret;
                }
 
                for (i = 0; (i < 5) && (nint > 0); i++, nint--)
                        reg |= BIT((27 + i));
                ret = wilc_sdio_write_reg(wilc, WILC_INTR_ENABLE, reg);
-               if (!ret) {
+               if (ret) {
                        dev_err(&func->dev, "Failed write reg (%08x)...\n",
                                WILC_INTR_ENABLE);
-                       return 0;
+                       return ret;
                }
                if (nint) {
                        ret = wilc_sdio_read_reg(wilc, WILC_INTR2_ENABLE, &reg);
-                       if (!ret) {
+                       if (ret) {
                                dev_err(&func->dev,
                                        "Failed read reg (%08x)...\n",
                                        WILC_INTR2_ENABLE);
-                               return 0;
+                               return ret;
                        }
 
                        for (i = 0; (i < 3) && (nint > 0); i++, nint--)
                                reg |= BIT(i);
 
                        ret = wilc_sdio_read_reg(wilc, WILC_INTR2_ENABLE, &reg);
-                       if (!ret) {
+                       if (ret) {
                                dev_err(&func->dev,
                                        "Failed write reg (%08x)...\n",
                                        WILC_INTR2_ENABLE);
-                               return 0;
+                               return ret;
                        }
                }
        }
-       return 1;
+       return 0;
 }
 
 /* Global sdio HIF function table */
index 55f8757..3ffc7b4 100644 (file)
@@ -13,7 +13,6 @@
 struct wilc_spi {
        int crc_off;
        int nint;
-       int has_thrpt_enh;
 };
 
 static const struct wilc_hif_func wilc_hif_spi;
@@ -89,11 +88,6 @@ static u8 crc7(u8 crc, const u8 *buffer, u32 len)
 #define CMD_SINGLE_READ                                0xca
 #define CMD_RESET                              0xcf
 
-#define N_OK                                   1
-#define N_FAIL                                 0
-#define N_RESET                                        -1
-#define N_RETRY                                        -2
-
 #define DATA_PKT_SZ_256                                256
 #define DATA_PKT_SZ_512                                512
 #define DATA_PKT_SZ_1K                         1024
@@ -300,7 +294,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz,
        u32 len2;
        u8 rsp;
        int len = 0;
-       int result = N_OK;
+       int result = 0;
        int retry;
        u8 crc[2];
 
@@ -388,11 +382,11 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz,
                break;
 
        default:
-               result = N_FAIL;
+               result = -EINVAL;
                break;
        }
 
-       if (result != N_OK)
+       if (result)
                return result;
 
        if (!spi_priv->crc_off)
@@ -425,7 +419,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz,
        if (len2 > ARRAY_SIZE(wb)) {
                dev_err(&spi->dev, "spi buffer size too small (%d) (%zu)\n",
                        len2, ARRAY_SIZE(wb));
-               return N_FAIL;
+               return -EINVAL;
        }
        /* zero spi write buffers. */
        for (wix = len; wix < len2; wix++)
@@ -434,7 +428,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz,
 
        if (wilc_spi_tx_rx(wilc, wb, rb, len2)) {
                dev_err(&spi->dev, "Failed cmd write, bus error...\n");
-               return N_FAIL;
+               return -EINVAL;
        }
 
        /*
@@ -449,7 +443,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz,
                dev_err(&spi->dev,
                        "Failed cmd response, cmd (%02x), resp (%02x)\n",
                        cmd, rsp);
-               return N_FAIL;
+               return -EINVAL;
        }
 
        /*
@@ -459,7 +453,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz,
        if (rsp != 0x00) {
                dev_err(&spi->dev, "Failed cmd state response state (%02x)\n",
                        rsp);
-               return N_FAIL;
+               return -EINVAL;
        }
 
        if (cmd == CMD_INTERNAL_READ || cmd == CMD_SINGLE_READ ||
@@ -486,7 +480,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz,
                if (retry <= 0) {
                        dev_err(&spi->dev,
                                "Error, data read response (%02x)\n", rsp);
-                       return N_RESET;
+                       return -EAGAIN;
                }
        }
 
@@ -502,7 +496,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz,
                } else {
                        dev_err(&spi->dev,
                                "buffer overrun when reading data.\n");
-                       return N_FAIL;
+                       return -EINVAL;
                }
 
                if (!spi_priv->crc_off) {
@@ -515,7 +509,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz,
                        } else {
                                dev_err(&spi->dev,
                                        "buffer overrun when reading crc.\n");
-                               return N_FAIL;
+                               return -EINVAL;
                        }
                }
        } else if ((cmd == CMD_DMA_READ) || (cmd == CMD_DMA_EXT_READ)) {
@@ -541,7 +535,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz,
                        if (wilc_spi_rx(wilc, &b[ix], nbytes)) {
                                dev_err(&spi->dev,
                                        "Failed block read, bus err\n");
-                               return N_FAIL;
+                               return -EINVAL;
                        }
 
                        /*
@@ -550,7 +544,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz,
                        if (!spi_priv->crc_off && wilc_spi_rx(wilc, crc, 2)) {
                                dev_err(&spi->dev,
                                        "Failed block crc read, bus err\n");
-                               return N_FAIL;
+                               return -EINVAL;
                        }
 
                        ix += nbytes;
@@ -582,14 +576,14 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz,
                                if (wilc_spi_rx(wilc, &rsp, 1)) {
                                        dev_err(&spi->dev,
                                                "Failed resp read, bus err\n");
-                                       result = N_FAIL;
+                                       result = -EINVAL;
                                        break;
                                }
                                if (((rsp >> 4) & 0xf) == 0xf)
                                        break;
                        } while (retry--);
 
-                       if (result == N_FAIL)
+                       if (result)
                                break;
 
                        /*
@@ -598,7 +592,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz,
                        if (wilc_spi_rx(wilc, &b[ix], nbytes)) {
                                dev_err(&spi->dev,
                                        "Failed block read, bus err\n");
-                               result = N_FAIL;
+                               result = -EINVAL;
                                break;
                        }
 
@@ -608,7 +602,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz,
                        if (!spi_priv->crc_off && wilc_spi_rx(wilc, crc, 2)) {
                                dev_err(&spi->dev,
                                        "Failed block crc read, bus err\n");
-                               result = N_FAIL;
+                               result = -EINVAL;
                                break;
                        }
 
@@ -624,7 +618,7 @@ static int spi_data_write(struct wilc *wilc, u8 *b, u32 sz)
        struct spi_device *spi = to_spi_device(wilc->dev);
        struct wilc_spi *spi_priv = wilc->bus_data;
        int ix, nbytes;
-       int result = 1;
+       int result = 0;
        u8 cmd, order, crc[2] = {0};
 
        /*
@@ -652,7 +646,7 @@ static int spi_data_write(struct wilc *wilc, u8 *b, u32 sz)
                if (wilc_spi_tx(wilc, &cmd, 1)) {
                        dev_err(&spi->dev,
                                "Failed data block cmd write, bus error...\n");
-                       result = N_FAIL;
+                       result = -EINVAL;
                        break;
                }
 
@@ -662,7 +656,7 @@ static int spi_data_write(struct wilc *wilc, u8 *b, u32 sz)
                if (wilc_spi_tx(wilc, &b[ix], nbytes)) {
                        dev_err(&spi->dev,
                                "Failed data block write, bus error...\n");
-                       result = N_FAIL;
+                       result = -EINVAL;
                        break;
                }
 
@@ -672,7 +666,7 @@ static int spi_data_write(struct wilc *wilc, u8 *b, u32 sz)
                if (!spi_priv->crc_off) {
                        if (wilc_spi_tx(wilc, crc, 2)) {
                                dev_err(&spi->dev, "Failed data block crc write, bus error...\n");
-                               result = N_FAIL;
+                               result = -EINVAL;
                                break;
                        }
                }
@@ -701,7 +695,7 @@ static int spi_internal_write(struct wilc *wilc, u32 adr, u32 dat)
        cpu_to_le32s(&dat);
        result = spi_cmd_complete(wilc, CMD_INTERNAL_WRITE, adr, (u8 *)&dat, 4,
                                  0);
-       if (result != N_OK)
+       if (result)
                dev_err(&spi->dev, "Failed internal write cmd...\n");
 
        return result;
@@ -714,14 +708,14 @@ static int spi_internal_read(struct wilc *wilc, u32 adr, u32 *data)
 
        result = spi_cmd_complete(wilc, CMD_INTERNAL_READ, adr, (u8 *)data, 4,
                                  0);
-       if (result != N_OK) {
+       if (result) {
                dev_err(&spi->dev, "Failed internal read cmd...\n");
-               return 0;
+               return result;
        }
 
        le32_to_cpus(data);
 
-       return 1;
+       return result;
 }
 
 /********************************************
@@ -733,7 +727,7 @@ static int spi_internal_read(struct wilc *wilc, u32 adr, u32 *data)
 static int wilc_spi_write_reg(struct wilc *wilc, u32 addr, u32 data)
 {
        struct spi_device *spi = to_spi_device(wilc->dev);
-       int result = N_OK;
+       int result;
        u8 cmd = CMD_SINGLE_WRITE;
        u8 clockless = 0;
 
@@ -745,7 +739,7 @@ static int wilc_spi_write_reg(struct wilc *wilc, u32 addr, u32 data)
        }
 
        result = spi_cmd_complete(wilc, cmd, addr, (u8 *)&data, 4, clockless);
-       if (result != N_OK)
+       if (result)
                dev_err(&spi->dev, "Failed cmd, write reg (%08x)...\n", addr);
 
        return result;
@@ -760,29 +754,29 @@ static int wilc_spi_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
         * has to be greated than 4
         */
        if (size <= 4)
-               return 0;
+               return -EINVAL;
 
        result = spi_cmd_complete(wilc, CMD_DMA_EXT_WRITE, addr, NULL, size, 0);
-       if (result != N_OK) {
+       if (result) {
                dev_err(&spi->dev,
                        "Failed cmd, write block (%08x)...\n", addr);
-               return 0;
+               return result;
        }
 
        /*
         * Data
         */
        result = spi_data_write(wilc, buf, size);
-       if (result != N_OK)
+       if (result)
                dev_err(&spi->dev, "Failed block data write...\n");
 
-       return 1;
+       return result;
 }
 
 static int wilc_spi_read_reg(struct wilc *wilc, u32 addr, u32 *data)
 {
        struct spi_device *spi = to_spi_device(wilc->dev);
-       int result = N_OK;
+       int result;
        u8 cmd = CMD_SINGLE_READ;
        u8 clockless = 0;
 
@@ -793,14 +787,14 @@ static int wilc_spi_read_reg(struct wilc *wilc, u32 addr, u32 *data)
        }
 
        result = spi_cmd_complete(wilc, cmd, addr, (u8 *)data, 4, clockless);
-       if (result != N_OK) {
+       if (result) {
                dev_err(&spi->dev, "Failed cmd, read reg (%08x)...\n", addr);
-               return 0;
+               return result;
        }
 
        le32_to_cpus(data);
 
-       return 1;
+       return 0;
 }
 
 static int wilc_spi_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
@@ -809,15 +803,13 @@ static int wilc_spi_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
        int result;
 
        if (size <= 4)
-               return 0;
+               return -EINVAL;
 
        result = spi_cmd_complete(wilc, CMD_DMA_EXT_READ, addr, buf, size, 0);
-       if (result != N_OK) {
+       if (result)
                dev_err(&spi->dev, "Failed cmd, read block (%08x)...\n", addr);
-               return 0;
-       }
 
-       return 1;
+       return result;
 }
 
 /********************************************
@@ -831,7 +823,7 @@ static int wilc_spi_deinit(struct wilc *wilc)
        /*
         * TODO:
         */
-       return 1;
+       return 0;
 }
 
 static int wilc_spi_init(struct wilc *wilc, bool resume)
@@ -841,13 +833,14 @@ static int wilc_spi_init(struct wilc *wilc, bool resume)
        u32 reg;
        u32 chipid;
        static int isinit;
+       int ret;
 
        if (isinit) {
-               if (!wilc_spi_read_reg(wilc, 0x1000, &chipid)) {
+               ret = wilc_spi_read_reg(wilc, 0x1000, &chipid);
+               if (ret)
                        dev_err(&spi->dev, "Fail cmd read chip id...\n");
-                       return 0;
-               }
-               return 1;
+
+               return ret;
        }
 
        /*
@@ -859,7 +852,8 @@ static int wilc_spi_init(struct wilc *wilc, bool resume)
         * way to reset
         */
        /* the SPI to it's initial value. */
-       if (!spi_internal_read(wilc, WILC_SPI_PROTOCOL_OFFSET, &reg)) {
+       ret = spi_internal_read(wilc, WILC_SPI_PROTOCOL_OFFSET, &reg);
+       if (ret) {
                /*
                 * Read failed. Try with CRC off. This might happen when module
                 * is removed but chip isn't reset
@@ -867,24 +861,26 @@ static int wilc_spi_init(struct wilc *wilc, bool resume)
                spi_priv->crc_off = 1;
                dev_err(&spi->dev,
                        "Failed read with CRC on, retrying with CRC off\n");
-               if (!spi_internal_read(wilc, WILC_SPI_PROTOCOL_OFFSET, &reg)) {
+               ret = spi_internal_read(wilc, WILC_SPI_PROTOCOL_OFFSET, &reg);
+               if (ret) {
                        /*
                         * Read failed with both CRC on and off,
                         * something went bad
                         */
                        dev_err(&spi->dev, "Failed internal read protocol\n");
-                       return 0;
+                       return ret;
                }
        }
        if (spi_priv->crc_off == 0) {
                reg &= ~0xc; /* disable crc checking */
                reg &= ~0x70;
                reg |= (0x5 << 4);
-               if (!spi_internal_write(wilc, WILC_SPI_PROTOCOL_OFFSET, reg)) {
+               ret = spi_internal_write(wilc, WILC_SPI_PROTOCOL_OFFSET, reg);
+               if (ret) {
                        dev_err(&spi->dev,
                                "[wilc spi %d]: Failed internal write reg\n",
                                __LINE__);
-                       return 0;
+                       return ret;
                }
                spi_priv->crc_off = 1;
        }
@@ -892,168 +888,35 @@ static int wilc_spi_init(struct wilc *wilc, bool resume)
        /*
         * make sure can read back chip id correctly
         */
-       if (!wilc_spi_read_reg(wilc, 0x1000, &chipid)) {
+       ret = wilc_spi_read_reg(wilc, 0x1000, &chipid);
+       if (ret) {
                dev_err(&spi->dev, "Fail cmd read chip id...\n");
-               return 0;
+               return ret;
        }
 
-       spi_priv->has_thrpt_enh = 1;
-
        isinit = 1;
 
-       return 1;
+       return 0;
 }
 
 static int wilc_spi_read_size(struct wilc *wilc, u32 *size)
 {
-       struct spi_device *spi = to_spi_device(wilc->dev);
-       struct wilc_spi *spi_priv = wilc->bus_data;
        int ret;
 
-       if (spi_priv->has_thrpt_enh) {
-               ret = spi_internal_read(wilc, 0xe840 - WILC_SPI_REG_BASE,
-                                       size);
-               *size = *size  & IRQ_DMA_WD_CNT_MASK;
-       } else {
-               u32 tmp;
-               u32 byte_cnt;
-
-               ret = wilc_spi_read_reg(wilc, WILC_VMM_TO_HOST_SIZE,
-                                       &byte_cnt);
-               if (!ret) {
-                       dev_err(&spi->dev,
-                               "Failed read WILC_VMM_TO_HOST_SIZE ...\n");
-                       return ret;
-               }
-               tmp = (byte_cnt >> 2) & IRQ_DMA_WD_CNT_MASK;
-               *size = tmp;
-       }
+       ret = spi_internal_read(wilc, 0xe840 - WILC_SPI_REG_BASE, size);
+       *size = *size & IRQ_DMA_WD_CNT_MASK;
 
        return ret;
 }
 
 static int wilc_spi_read_int(struct wilc *wilc, u32 *int_status)
 {
-       struct spi_device *spi = to_spi_device(wilc->dev);
-       struct wilc_spi *spi_priv = wilc->bus_data;
-       int ret;
-       u32 tmp;
-       u32 byte_cnt;
-       bool unexpected_irq;
-       int j;
-       u32 unknown_mask;
-       u32 irq_flags;
-       int k = IRG_FLAGS_OFFSET + 5;
-
-       if (spi_priv->has_thrpt_enh)
-               return spi_internal_read(wilc, 0xe840 - WILC_SPI_REG_BASE,
-                                        int_status);
-       ret = wilc_spi_read_reg(wilc, WILC_VMM_TO_HOST_SIZE, &byte_cnt);
-       if (!ret) {
-               dev_err(&spi->dev,
-                       "Failed read WILC_VMM_TO_HOST_SIZE ...\n");
-               return ret;
-       }
-       tmp = (byte_cnt >> 2) & IRQ_DMA_WD_CNT_MASK;
-
-       j = 0;
-       do {
-               wilc_spi_read_reg(wilc, 0x1a90, &irq_flags);
-               tmp |= ((irq_flags >> 27) << IRG_FLAGS_OFFSET);
-
-               if (spi_priv->nint > 5) {
-                       wilc_spi_read_reg(wilc, 0x1a94, &irq_flags);
-                       tmp |= (((irq_flags >> 0) & 0x7) << k);
-               }
-
-               unknown_mask = ~((1ul << spi_priv->nint) - 1);
-
-               unexpected_irq = (tmp >> IRG_FLAGS_OFFSET) & unknown_mask;
-               if (unexpected_irq) {
-                       dev_err(&spi->dev,
-                               "Unexpected interrupt(2):j=%d,tmp=%x,mask=%x\n",
-                               j, tmp, unknown_mask);
-               }
-
-               j++;
-       } while (unexpected_irq);
-
-       *int_status = tmp;
-
-       return ret;
+       return spi_internal_read(wilc, 0xe840 - WILC_SPI_REG_BASE, int_status);
 }
 
 static int wilc_spi_clear_int_ext(struct wilc *wilc, u32 val)
 {
-       struct spi_device *spi = to_spi_device(wilc->dev);
-       struct wilc_spi *spi_priv = wilc->bus_data;
-       int ret;
-       u32 flags;
-       u32 tbl_ctl;
-
-       if (spi_priv->has_thrpt_enh) {
-               return spi_internal_write(wilc, 0xe844 - WILC_SPI_REG_BASE,
-                                         val);
-       }
-
-       flags = val & (BIT(MAX_NUM_INT) - 1);
-       if (flags) {
-               int i;
-
-               ret = 1;
-               for (i = 0; i < spi_priv->nint; i++) {
-                       /*
-                        * No matter what you write 1 or 0,
-                        * it will clear interrupt.
-                        */
-                       if (flags & 1)
-                               ret = wilc_spi_write_reg(wilc,
-                                                        0x10c8 + i * 4, 1);
-                       if (!ret)
-                               break;
-                       flags >>= 1;
-               }
-               if (!ret) {
-                       dev_err(&spi->dev,
-                               "Failed wilc_spi_write_reg, set reg %x ...\n",
-                               0x10c8 + i * 4);
-                       return ret;
-               }
-               for (i = spi_priv->nint; i < MAX_NUM_INT; i++) {
-                       if (flags & 1)
-                               dev_err(&spi->dev,
-                                       "Unexpected interrupt cleared %d...\n",
-                                       i);
-                       flags >>= 1;
-               }
-       }
-
-       tbl_ctl = 0;
-       /* select VMM table 0 */
-       if (val & SEL_VMM_TBL0)
-               tbl_ctl |= BIT(0);
-       /* select VMM table 1 */
-       if (val & SEL_VMM_TBL1)
-               tbl_ctl |= BIT(1);
-
-       ret = wilc_spi_write_reg(wilc, WILC_VMM_TBL_CTL, tbl_ctl);
-       if (!ret) {
-               dev_err(&spi->dev, "fail write reg vmm_tbl_ctl...\n");
-               return ret;
-       }
-
-       if (val & EN_VMM) {
-               /*
-                * enable vmm transfer.
-                */
-               ret = wilc_spi_write_reg(wilc, WILC_VMM_CORE_CTL, 1);
-               if (!ret) {
-                       dev_err(&spi->dev, "fail write reg vmm_core_ctl...\n");
-                       return ret;
-               }
-       }
-
-       return ret;
+       return spi_internal_write(wilc, 0xe844 - WILC_SPI_REG_BASE, val);
 }
 
 static int wilc_spi_sync_ext(struct wilc *wilc, int nint)
@@ -1065,7 +928,7 @@ static int wilc_spi_sync_ext(struct wilc *wilc, int nint)
 
        if (nint > MAX_NUM_INT) {
                dev_err(&spi->dev, "Too many interrupts (%d)...\n", nint);
-               return 0;
+               return -EINVAL;
        }
 
        spi_priv->nint = nint;
@@ -1074,58 +937,58 @@ static int wilc_spi_sync_ext(struct wilc *wilc, int nint)
         * interrupt pin mux select
         */
        ret = wilc_spi_read_reg(wilc, WILC_PIN_MUX_0, &reg);
-       if (!ret) {
+       if (ret) {
                dev_err(&spi->dev, "Failed read reg (%08x)...\n",
                        WILC_PIN_MUX_0);
-               return 0;
+               return ret;
        }
        reg |= BIT(8);
        ret = wilc_spi_write_reg(wilc, WILC_PIN_MUX_0, reg);
-       if (!ret) {
+       if (ret) {
                dev_err(&spi->dev, "Failed write reg (%08x)...\n",
                        WILC_PIN_MUX_0);
-               return 0;
+               return ret;
        }
 
        /*
         * interrupt enable
         */
        ret = wilc_spi_read_reg(wilc, WILC_INTR_ENABLE, &reg);
-       if (!ret) {
+       if (ret) {
                dev_err(&spi->dev, "Failed read reg (%08x)...\n",
                        WILC_INTR_ENABLE);
-               return 0;
+               return ret;
        }
 
        for (i = 0; (i < 5) && (nint > 0); i++, nint--)
                reg |= (BIT((27 + i)));
 
        ret = wilc_spi_write_reg(wilc, WILC_INTR_ENABLE, reg);
-       if (!ret) {
+       if (ret) {
                dev_err(&spi->dev, "Failed write reg (%08x)...\n",
                        WILC_INTR_ENABLE);
-               return 0;
+               return ret;
        }
        if (nint) {
                ret = wilc_spi_read_reg(wilc, WILC_INTR2_ENABLE, &reg);
-               if (!ret) {
+               if (ret) {
                        dev_err(&spi->dev, "Failed read reg (%08x)...\n",
                                WILC_INTR2_ENABLE);
-                       return 0;
+                       return ret;
                }
 
                for (i = 0; (i < 3) && (nint > 0); i++, nint--)
                        reg |= BIT(i);
 
                ret = wilc_spi_read_reg(wilc, WILC_INTR2_ENABLE, &reg);
-               if (!ret) {
+               if (ret) {
                        dev_err(&spi->dev, "Failed write reg (%08x)...\n",
                                WILC_INTR2_ENABLE);
-                       return 0;
+                       return ret;
                }
        }
 
-       return 1;
+       return 0;
 }
 
 /* Global spi HIF function table */
index d3de761..601e4d1 100644 (file)
@@ -489,50 +489,44 @@ int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count)
        struct wilc_vif *vif;
 
        if (wilc->quit)
-               goto out;
+               goto out_update_cnt;
 
        mutex_lock(&wilc->txq_add_to_head_cs);
        tqe = wilc_wlan_txq_get_first(wilc);
        if (!tqe)
-               goto out;
+               goto out_unlock;
        dev = tqe->vif->ndev;
        wilc_wlan_txq_filter_dup_tcp_ack(dev);
        i = 0;
        sum = 0;
-       do {
-               if (tqe && (i < (WILC_VMM_TBL_SIZE - 1))) {
-                       if (tqe->type == WILC_CFG_PKT)
-                               vmm_sz = ETH_CONFIG_PKT_HDR_OFFSET;
-
-                       else if (tqe->type == WILC_NET_PKT)
-                               vmm_sz = ETH_ETHERNET_HDR_OFFSET;
-
-                       else
-                               vmm_sz = HOST_HDR_OFFSET;
+       while (tqe && (i < (WILC_VMM_TBL_SIZE - 1))) {
+               if (tqe->type == WILC_CFG_PKT)
+                       vmm_sz = ETH_CONFIG_PKT_HDR_OFFSET;
+               else if (tqe->type == WILC_NET_PKT)
+                       vmm_sz = ETH_ETHERNET_HDR_OFFSET;
+               else
+                       vmm_sz = HOST_HDR_OFFSET;
 
-                       vmm_sz += tqe->buffer_size;
+               vmm_sz += tqe->buffer_size;
 
-                       if (vmm_sz & 0x3)
-                               vmm_sz = (vmm_sz + 4) & ~0x3;
+               if (vmm_sz & 0x3)
+                       vmm_sz = (vmm_sz + 4) & ~0x3;
 
-                       if ((sum + vmm_sz) > WILC_TX_BUFF_SIZE)
-                               break;
+               if ((sum + vmm_sz) > WILC_TX_BUFF_SIZE)
+                       break;
 
-                       vmm_table[i] = vmm_sz / 4;
-                       if (tqe->type == WILC_CFG_PKT)
-                               vmm_table[i] |= BIT(10);
-                       cpu_to_le32s(&vmm_table[i]);
+               vmm_table[i] = vmm_sz / 4;
+               if (tqe->type == WILC_CFG_PKT)
+                       vmm_table[i] |= BIT(10);
+               cpu_to_le32s(&vmm_table[i]);
 
-                       i++;
-                       sum += vmm_sz;
-                       tqe = wilc_wlan_txq_get_next(wilc, tqe);
-               } else {
-                       break;
-               }
-       } while (1);
+               i++;
+               sum += vmm_sz;
+               tqe = wilc_wlan_txq_get_next(wilc, tqe);
+       }
 
        if (i == 0)
-               goto out;
+               goto out_unlock;
        vmm_table[i] = 0x0;
 
        acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
@@ -540,7 +534,7 @@ int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count)
        func = wilc->hif_func;
        do {
                ret = func->hif_read_reg(wilc, WILC_HOST_TX_CTRL, &reg);
-               if (!ret)
+               if (ret)
                        break;
 
                if ((reg & 0x1) == 0)
@@ -554,7 +548,7 @@ int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count)
                }
        } while (!wilc->quit);
 
-       if (!ret)
+       if (ret)
                goto out_release_bus;
 
        timeout = 200;
@@ -563,16 +557,16 @@ int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count)
                                         WILC_VMM_TBL_RX_SHADOW_BASE,
                                         (u8 *)vmm_table,
                                         ((i + 1) * 4));
-               if (!ret)
+               if (ret)
                        break;
 
                ret = func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0x2);
-               if (!ret)
+               if (ret)
                        break;
 
                do {
                        ret = func->hif_read_reg(wilc, WILC_HOST_VMM_CTL, &reg);
-                       if (!ret)
+                       if (ret)
                                break;
                        if ((reg >> 2) & 0x1) {
                                entries = ((reg >> 3) & 0x3f);
@@ -585,27 +579,27 @@ int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count)
                        break;
                }
 
-               if (!ret)
+               if (ret)
                        break;
 
                if (entries == 0) {
                        ret = func->hif_read_reg(wilc, WILC_HOST_TX_CTRL, &reg);
-                       if (!ret)
+                       if (ret)
                                break;
                        reg &= ~BIT(0);
                        ret = func->hif_write_reg(wilc, WILC_HOST_TX_CTRL, reg);
-                       if (!ret)
-                               break;
-                       break;
                }
-               break;
-       } while (1);
+       } while (0);
 
-       if (!ret)
+       if (ret)
                goto out_release_bus;
 
        if (entries == 0) {
-               ret = -ENOBUFS;
+               /*
+                * No VMM space available in firmware so retry to transmit
+                * the packet from tx queue.
+                */
+               ret = WILC_VMM_ENTRY_FULL_RETRY;
                goto out_release_bus;
        }
 
@@ -664,7 +658,7 @@ int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count)
        acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
 
        ret = func->hif_clear_int_ext(wilc, ENABLE_TX_VMM);
-       if (!ret)
+       if (ret)
                goto out_release_bus;
 
        ret = func->hif_block_tx_ext(wilc, 0, txb, offset);
@@ -672,9 +666,10 @@ int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count)
 out_release_bus:
        release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
 
-out:
+out_unlock:
        mutex_unlock(&wilc->txq_add_to_head_cs);
 
+out_update_cnt:
        *txq_count = wilc->txq_entries;
        return ret;
 }
@@ -725,9 +720,7 @@ static void wilc_wlan_handle_rx_buff(struct wilc *wilc, u8 *buffer, int size)
                        }
                }
                offset += tp_len;
-               if (offset >= size)
-                       break;
-       } while (1);
+       } while (offset < size);
 }
 
 static void wilc_wlan_handle_rxq(struct wilc *wilc)
@@ -736,11 +729,7 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc)
        u8 *buffer;
        struct rxq_entry_t *rqe;
 
-       do {
-               if (wilc->quit) {
-                       complete(&wilc->cfg_event);
-                       break;
-               }
+       while (!wilc->quit) {
                rqe = wilc_wlan_rxq_remove(wilc);
                if (!rqe)
                        break;
@@ -750,7 +739,9 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc)
                wilc_wlan_handle_rx_buff(wilc, buffer, size);
 
                kfree(rqe);
-       } while (1);
+       }
+       if (wilc->quit)
+               complete(&wilc->cfg_event);
 }
 
 static void wilc_unknown_isr_ext(struct wilc *wilc)
@@ -785,7 +776,7 @@ static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status)
 
        wilc->hif_func->hif_clear_int_ext(wilc, DATA_INT_CLR | ENABLE_RX_VMM);
        ret = wilc->hif_func->hif_block_rx_ext(wilc, 0, buffer, size);
-       if (!ret)
+       if (ret)
                return;
 
        offset += size;
@@ -846,7 +837,7 @@ int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer,
                        memcpy(dma_buffer, &buffer[offset], size2);
                        ret = wilc->hif_func->hif_block_tx(wilc, addr,
                                                           dma_buffer, size2);
-                       if (!ret)
+                       if (ret)
                                break;
 
                        addr += size2;
@@ -855,17 +846,15 @@ int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer,
                }
                release_bus(wilc, WILC_BUS_RELEASE_ONLY);
 
-               if (!ret) {
-                       ret = -EIO;
+               if (ret)
                        goto fail;
-               }
        } while (offset < buffer_size);
 
 fail:
 
        kfree(dma_buffer);
 
-       return (ret < 0) ? ret : 0;
+       return ret;
 }
 
 int wilc_wlan_start(struct wilc *wilc)
@@ -882,49 +871,26 @@ int wilc_wlan_start(struct wilc *wilc)
        }
        acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
        ret = wilc->hif_func->hif_write_reg(wilc, WILC_VMM_CORE_CFG, reg);
-       if (!ret) {
+       if (ret) {
                release_bus(wilc, WILC_BUS_RELEASE_ONLY);
-               return -EIO;
+               return ret;
        }
        reg = 0;
        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) {
+       if (ret) {
                release_bus(wilc, WILC_BUS_RELEASE_ONLY);
-               return -EIO;
+               return ret;
        }
 
        wilc->hif_func->hif_sync_ext(wilc, NUM_INT_EXT);
 
        ret = wilc->hif_func->hif_read_reg(wilc, 0x1000, &chipid);
-       if (!ret) {
+       if (ret) {
                release_bus(wilc, WILC_BUS_RELEASE_ONLY);
-               return -EIO;
+               return ret;
        }
 
        wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
@@ -939,7 +905,7 @@ int wilc_wlan_start(struct wilc *wilc)
        wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
        release_bus(wilc, WILC_BUS_RELEASE_ONLY);
 
-       return (ret < 0) ? ret : 0;
+       return ret;
 }
 
 int wilc_wlan_stop(struct wilc *wilc, struct wilc_vif *vif)
@@ -950,33 +916,33 @@ int wilc_wlan_stop(struct wilc *wilc, struct wilc_vif *vif)
        acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
 
        ret = wilc->hif_func->hif_read_reg(wilc, WILC_GP_REG_0, &reg);
-       if (!ret) {
+       if (ret) {
                netdev_err(vif->ndev, "Error while reading reg\n");
                release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
-               return -EIO;
+               return ret;
        }
 
        ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_0,
                                        (reg | WILC_ABORT_REQ_BIT));
-       if (!ret) {
+       if (ret) {
                netdev_err(vif->ndev, "Error while writing reg\n");
                release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
-               return -EIO;
+               return ret;
        }
 
        ret = wilc->hif_func->hif_read_reg(wilc, WILC_FW_HOST_COMM, &reg);
-       if (!ret) {
+       if (ret) {
                netdev_err(vif->ndev, "Error while reading reg\n");
                release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
-               return -EIO;
+               return ret;
        }
        reg = BIT(0);
 
        ret = wilc->hif_func->hif_write_reg(wilc, WILC_FW_HOST_COMM, reg);
-       if (!ret) {
+       if (ret) {
                netdev_err(vif->ndev, "Error while writing reg\n");
                release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
-               return -EIO;
+               return ret;
        }
 
        release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
@@ -992,21 +958,14 @@ void wilc_wlan_cleanup(struct net_device *dev)
        struct wilc *wilc = vif->wilc;
 
        wilc->quit = 1;
-       do {
-               tqe = wilc_wlan_txq_remove_from_head(dev);
-               if (!tqe)
-                       break;
+       while ((tqe = wilc_wlan_txq_remove_from_head(dev))) {
                if (tqe->tx_complete_func)
                        tqe->tx_complete_func(tqe->priv, 0);
                kfree(tqe);
-       } while (1);
+       }
 
-       do {
-               rqe = wilc_wlan_rxq_remove(wilc);
-               if (!rqe)
-                       break;
+       while ((rqe = wilc_wlan_rxq_remove(wilc)))
                kfree(rqe);
-       } while (1);
 
        kfree(wilc->rx_buffer);
        wilc->rx_buffer = NULL;
@@ -1156,10 +1115,11 @@ int wilc_send_config_pkt(struct wilc_vif *vif, u8 mode, struct wid *wids,
        return ret;
 }
 
-static u32 init_chip(struct net_device *dev)
+static int init_chip(struct net_device *dev)
 {
        u32 chipid;
-       u32 reg, ret = 0;
+       u32 reg;
+       int ret = 0;
        struct wilc_vif *vif = netdev_priv(dev);
        struct wilc *wilc = vif->wilc;
 
@@ -1169,18 +1129,18 @@ static u32 init_chip(struct net_device *dev)
 
        if ((chipid & 0xfff) != 0xa0) {
                ret = wilc->hif_func->hif_read_reg(wilc, 0x1118, &reg);
-               if (!ret) {
+               if (ret) {
                        netdev_err(dev, "fail read reg 0x1118\n");
                        goto release;
                }
                reg |= BIT(0);
                ret = wilc->hif_func->hif_write_reg(wilc, 0x1118, reg);
-               if (!ret) {
+               if (ret) {
                        netdev_err(dev, "fail write reg 0x1118\n");
                        goto release;
                }
                ret = wilc->hif_func->hif_write_reg(wilc, 0xc0000, 0x71);
-               if (!ret) {
+               if (ret) {
                        netdev_err(dev, "fail write reg 0xc0000\n");
                        goto release;
                }
@@ -1230,7 +1190,7 @@ int wilc_wlan_init(struct net_device *dev)
 
        wilc->quit = 0;
 
-       if (!wilc->hif_func->hif_init(wilc, false)) {
+       if (wilc->hif_func->hif_init(wilc, false)) {
                ret = -EIO;
                goto fail;
        }
@@ -1251,12 +1211,12 @@ int wilc_wlan_init(struct net_device *dev)
                goto fail;
        }
 
-       if (!init_chip(dev)) {
+       if (init_chip(dev)) {
                ret = -EIO;
                goto fail;
        }
 
-       return 1;
+       return 0;
 
 fail:
 
index 1f6957c..8c46342 100644 (file)
 #define IS_MANAGMEMENT_CALLBACK        0x080
 #define IS_MGMT_STATUS_SUCCES  0x040
 
+#define WILC_WID_TYPE          GENMASK(15, 12)
+#define WILC_VMM_ENTRY_FULL_RETRY      1
 /********************************************
  *
  *      Tx/Rx Queue Structure
index 6f6b286..fe2a7ed 100644 (file)
@@ -4,6 +4,7 @@
  * All rights reserved.
  */
 
+#include <linux/bitfield.h>
 #include "wlan_if.h"
 #include "wlan.h"
 #include "wlan_cfg.h"
@@ -132,75 +133,54 @@ 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;
        u32 len = 0, i = 0;
+       struct wilc_cfg *cfg = &wl->cfg;
 
        while (size > 0) {
                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)
-                                       break;
-
-                               if (wl->cfg.b[i].id == wid) {
-                                       wl->cfg.b[i].val = info[4];
-                                       break;
-                               }
+                       while (cfg->b[i].id != WID_NIL && cfg->b[i].id != wid)
                                i++;
-                       } while (1);
+
+                       if (cfg->b[i].id == wid)
+                               cfg->b[i].val = info[4];
+
                        len = 3;
                        break;
 
                case WID_SHORT:
-                       do {
-                               struct wilc_cfg_hword *hw = &wl->cfg.hw[i];
+                       while (cfg->hw[i].id != WID_NIL && cfg->hw[i].id != wid)
+                               i++;
 
-                               if (hw->id == WID_NIL)
-                                       break;
+                       if (cfg->hw[i].id == wid)
+                               cfg->hw[i].val = get_unaligned_le16(&info[4]);
 
-                               if (hw->id == wid) {
-                                       hw->val = get_unaligned_le16(&info[4]);
-                                       break;
-                               }
-                               i++;
-                       } while (1);
                        len = 4;
                        break;
 
                case WID_INT:
-                       do {
-                               struct wilc_cfg_word *w = &wl->cfg.w[i];
+                       while (cfg->w[i].id != WID_NIL && cfg->w[i].id != wid)
+                               i++;
 
-                               if (w->id == WID_NIL)
-                                       break;
+                       if (cfg->w[i].id == wid)
+                               cfg->w[i].val = get_unaligned_le32(&info[4]);
 
-                               if (w->id == wid) {
-                                       w->val = get_unaligned_le32(&info[4]);
-                                       break;
-                               }
-                               i++;
-                       } while (1);
                        len = 6;
                        break;
 
                case WID_STR:
-                       do {
-                               if (wl->cfg.s[i].id == WID_NIL)
-                                       break;
-
-                               if (wl->cfg.s[i].id == wid) {
-                                       memcpy(wl->cfg.s[i].str, &info[2],
-                                              (info[2] + 2));
-                                       break;
-                               }
+                       while (cfg->s[i].id != WID_NIL && cfg->s[i].id != wid)
                                i++;
-                       } while (1);
+
+                       if (cfg->s[i].id == wid)
+                               memcpy(cfg->s[i].str, &info[2], info[2] + 2);
+
                        len = 2 + info[2];
                        break;
 
@@ -223,16 +203,12 @@ static void wilc_wlan_parse_info_frame(struct wilc *wl, u8 *info)
        if (len == 1 && wid == WID_STATUS) {
                int i = 0;
 
-               do {
-                       if (wl->cfg.b[i].id == WID_NIL)
-                               break;
-
-                       if (wl->cfg.b[i].id == wid) {
-                               wl->cfg.b[i].val = info[3];
-                               break;
-                       }
+               while (wl->cfg.b[i].id != WID_NIL &&
+                      wl->cfg.b[i].id != wid)
                        i++;
-               } while (1);
+
+               if (wl->cfg.b[i].id == wid)
+                       wl->cfg.b[i].val = info[3];
        }
 }
 
@@ -244,7 +220,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,65 +266,47 @@ 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;
+       struct wilc_cfg *cfg = &wl->cfg;
 
        i = 0;
        if (type == CFG_BYTE_CMD) {
-               do {
-                       if (wl->cfg.b[i].id == WID_NIL)
-                               break;
-
-                       if (wl->cfg.b[i].id == wid) {
-                               memcpy(buffer, &wl->cfg.b[i].val, 1);
-                               ret = 1;
-                               break;
-                       }
+               while (cfg->b[i].id != WID_NIL && cfg->b[i].id != wid)
                        i++;
-               } while (1);
+
+               if (cfg->b[i].id == wid) {
+                       memcpy(buffer, &cfg->b[i].val, 1);
+                       ret = 1;
+               }
        } else if (type == CFG_HWORD_CMD) {
-               do {
-                       if (wl->cfg.hw[i].id == WID_NIL)
-                               break;
-
-                       if (wl->cfg.hw[i].id == wid) {
-                               memcpy(buffer, &wl->cfg.hw[i].val, 2);
-                               ret = 2;
-                               break;
-                       }
+               while (cfg->hw[i].id != WID_NIL && cfg->hw[i].id != wid)
                        i++;
-               } while (1);
+
+               if (cfg->hw[i].id == wid) {
+                       memcpy(buffer, &cfg->hw[i].val, 2);
+                       ret = 2;
+               }
        } else if (type == CFG_WORD_CMD) {
-               do {
-                       if (wl->cfg.w[i].id == WID_NIL)
-                               break;
-
-                       if (wl->cfg.w[i].id == wid) {
-                               memcpy(buffer, &wl->cfg.w[i].val, 4);
-                               ret = 4;
-                               break;
-                       }
+               while (cfg->w[i].id != WID_NIL && cfg->w[i].id != wid)
                        i++;
-               } while (1);
-       } else if (type == CFG_STR_CMD) {
-               do {
-                       u32 id = wl->cfg.s[i].id;
 
-                       if (id == WID_NIL)
-                               break;
+               if (cfg->w[i].id == wid) {
+                       memcpy(buffer, &cfg->w[i].val, 4);
+                       ret = 4;
+               }
+       } else if (type == CFG_STR_CMD) {
+               while (cfg->s[i].id != WID_NIL && cfg->s[i].id != wid)
+                       i++;
 
-                       if (id == wid) {
-                               u16 size = get_unaligned_le16(wl->cfg.s[i].str);
+               if (cfg->s[i].id == wid) {
+                       u16 size = get_unaligned_le16(cfg->s[i].str);
 
-                               if (buffer_size >= size) {
-                                       memcpy(buffer, &wl->cfg.s[i].str[2],
-                                              size);
-                                       ret = size;
-                               }
-                               break;
+                       if (buffer_size >= size) {
+                               memcpy(buffer, &cfg->s[i].str[2], size);
+                               ret = size;
                        }
-                       i++;
-               } while (1);
+               }
        }
        return ret;
 }
index 7c7ee66..f85fd57 100644 (file)
@@ -8,6 +8,7 @@
 #define WILC_WLAN_IF_H
 
 #include <linux/netdevice.h>
+#include "fw.h"
 
 /********************************************
  *
index 7350fe5..a8860d2 100644 (file)
@@ -959,7 +959,7 @@ int prism2mgmt_flashdl_state(struct wlandevice *wlandev, void *msgp)
                }
        }
 
-       return 0;
+       return result;
 }
 
 /*----------------------------------------------------------------
diff --git a/include/linux/b1pcmcia.h b/include/linux/b1pcmcia.h
deleted file mode 100644 (file)
index 12a867c..0000000
+++ /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_ */
index 8c3c78b..ea0ecb7 100644 (file)
@@ -7,8 +7,11 @@
 #ifndef __IIO_KXCJK_1013_H__
 #define __IIO_KXCJK_1013_H__
 
+#include <linux/iio/iio.h>
+
 struct kxcjk_1013_platform_data {
        bool active_high_intr;
+       struct iio_mount_matrix orientation;
 };
 
 #endif
index 8a4e25a..5a127c0 100644 (file)
@@ -40,6 +40,7 @@ struct iio_dev;
  * @read_mask: Mask for the communications register having the read bit set.
  * @data_reg: Address of the data register, if 0 the default address of 0x3 will
  *   be used.
+ * @irq_flags: flags for the interrupt used by the triggered buffer
  */
 struct ad_sigma_delta_info {
        int (*set_channel)(struct ad_sigma_delta *, unsigned int channel);
@@ -49,6 +50,7 @@ struct ad_sigma_delta_info {
        unsigned int addr_shift;
        unsigned int read_mask;
        unsigned int data_reg;
+       unsigned long irq_flags;
 };
 
 /**
index d1171db..a4d2d80 100644 (file)
@@ -18,7 +18,7 @@ struct iio_buffer;
 /**
  * struct iio_buffer_access_funcs - access functions for buffers.
  * @store_to:          actually store stuff to the buffer
- * @read_first_n:      try to get a specified number of bytes (must exist)
+ * @read:              try to get a specified number of bytes (must exist)
  * @data_available:    indicates how much data is available for reading from
  *                     the buffer.
  * @request_update:    if a parameter change has been marked, update underlying
@@ -45,9 +45,7 @@ struct iio_buffer;
  **/
 struct iio_buffer_access_funcs {
        int (*store_to)(struct iio_buffer *buffer, const void *data);
-       int (*read_first_n)(struct iio_buffer *buffer,
-                           size_t n,
-                           char __user *buf);
+       int (*read)(struct iio_buffer *buffer, size_t n, char __user *buf);
        size_t (*data_available)(struct iio_buffer *buffer);
 
        int (*request_update)(struct iio_buffer *buffer);
index 686be53..33e9399 100644 (file)
@@ -315,16 +315,6 @@ ssize_t st_sensors_sysfs_sampling_frequency_avail(struct device *dev,
 ssize_t st_sensors_sysfs_scale_avail(struct device *dev,
                                struct device_attribute *attr, char *buf);
 
-#ifdef CONFIG_OF
-void st_sensors_of_name_probe(struct device *dev,
-                             const struct of_device_id *match,
-                             char *name, int len);
-#else
-static inline void st_sensors_of_name_probe(struct device *dev,
-                                           const struct of_device_id *match,
-                                           char *name, int len)
-{
-}
-#endif
+void st_sensors_dev_name_probe(struct device *dev, char *name, int len);
 
 #endif /* ST_SENSORS_H */
index 01e424e..5f15cf0 100644 (file)
 
 #include <linux/i2c.h>
 #include <linux/iio/common/st_sensors.h>
-#include <linux/of.h>
 
 int st_sensors_i2c_configure(struct iio_dev *indio_dev,
                             struct i2c_client *client);
 
-#ifdef CONFIG_ACPI
-int st_sensors_match_acpi_device(struct device *dev);
-#else
-static inline int st_sensors_match_acpi_device(struct device *dev)
-{
-       return -ENODEV;
-}
-#endif
-
 #endif /* ST_SENSORS_I2C_H */
index ce9490b..de45cf2 100644 (file)
  * @r2_user_settings:  User defined settings for ADF4350/1 REGISTER_2.
  * @r3_user_settings:  User defined settings for ADF4350/1 REGISTER_3.
  * @r4_user_settings:  User defined settings for ADF4350/1 REGISTER_4.
- * @gpio_lock_detect:  Optional, if set with a valid GPIO number,
- *                     pll lock state is tested upon read.
- *                     If not used - set to -1.
  */
 
 struct adf4350_platform_data {
@@ -121,7 +118,6 @@ struct adf4350_platform_data {
        unsigned                r2_user_settings;
        unsigned                r3_user_settings;
        unsigned                r4_user_settings;
-       int                     gpio_lock_detect;
 };
 
 #endif /* IIO_PLL_ADF4350_H_ */
index 92aae14..d2fcf45 100644 (file)
 struct adis;
 struct adis_burst;
 
+/**
+ * struct adis_timeouts - ADIS chip variant timeouts
+ * @reset_ms - Wait time after rst pin goes inactive
+ * @sw_reset_ms - Wait time after sw reset command
+ * @self_test_ms - Wait time after self test command
+ */
+struct adis_timeout {
+       u16 reset_ms;
+       u16 sw_reset_ms;
+       u16 self_test_ms;
+};
 /**
  * struct adis_data - ADIS chip variant specific data
  * @read_delay: SPI delay for read operations in us
@@ -32,6 +43,7 @@ struct adis_burst;
  * @diag_stat_reg: Register address of the DIAG_STAT register
  * @status_error_msgs: Array of error messgaes
  * @status_error_mask:
+ * @timeouts: Chip specific delays
  */
 struct adis_data {
        unsigned int read_delay;
@@ -44,7 +56,7 @@ struct adis_data {
 
        unsigned int self_test_mask;
        bool self_test_no_autoclear;
-       unsigned int startup_delay;
+       const struct adis_timeout *timeouts;
 
        const char * const *status_error_msgs;
        unsigned int status_error_mask;
@@ -61,7 +73,7 @@ struct adis {
        const struct adis_data  *data;
        struct adis_burst       *burst;
 
-       struct mutex            txrx_lock;
+       struct mutex            state_lock;
        struct spi_message      msg;
        struct spi_transfer     *xfer;
        unsigned int            current_page;
@@ -73,13 +85,142 @@ struct adis {
 
 int adis_init(struct adis *adis, struct iio_dev *indio_dev,
        struct spi_device *spi, const struct adis_data *data);
-int adis_reset(struct adis *adis);
+int __adis_reset(struct adis *adis);
+
+/**
+ * adis_reset() - Reset the device
+ * @adis: The adis device
+ *
+ * Returns 0 on success, a negative error code otherwise
+ */
+static inline int adis_reset(struct adis *adis)
+{
+       int ret;
+
+       mutex_lock(&adis->state_lock);
+       ret = __adis_reset(adis);
+       mutex_unlock(&adis->state_lock);
+
+       return ret;
+}
 
-int adis_write_reg(struct adis *adis, unsigned int reg,
+int __adis_write_reg(struct adis *adis, unsigned int reg,
        unsigned int val, unsigned int size);
-int adis_read_reg(struct adis *adis, unsigned int reg,
+int __adis_read_reg(struct adis *adis, unsigned int reg,
        unsigned int *val, unsigned int size);
 
+/**
+ * __adis_write_reg_8() - Write single byte to a register (unlocked)
+ * @adis: The adis device
+ * @reg: The address of the register to be written
+ * @value: The value to write
+ */
+static inline int __adis_write_reg_8(struct adis *adis, unsigned int reg,
+       uint8_t val)
+{
+       return __adis_write_reg(adis, reg, val, 1);
+}
+
+/**
+ * __adis_write_reg_16() - Write 2 bytes to a pair of registers (unlocked)
+ * @adis: The adis device
+ * @reg: The address of the lower of the two registers
+ * @value: Value to be written
+ */
+static inline int __adis_write_reg_16(struct adis *adis, unsigned int reg,
+       uint16_t val)
+{
+       return __adis_write_reg(adis, reg, val, 2);
+}
+
+/**
+ * __adis_write_reg_32() - write 4 bytes to four registers (unlocked)
+ * @adis: The adis device
+ * @reg: The address of the lower of the four register
+ * @value: Value to be written
+ */
+static inline int __adis_write_reg_32(struct adis *adis, unsigned int reg,
+       uint32_t val)
+{
+       return __adis_write_reg(adis, reg, val, 4);
+}
+
+/**
+ * __adis_read_reg_16() - read 2 bytes from a 16-bit register (unlocked)
+ * @adis: The adis device
+ * @reg: The address of the lower of the two registers
+ * @val: The value read back from the device
+ */
+static inline int __adis_read_reg_16(struct adis *adis, unsigned int reg,
+       uint16_t *val)
+{
+       unsigned int tmp;
+       int ret;
+
+       ret = __adis_read_reg(adis, reg, &tmp, 2);
+       if (ret == 0)
+               *val = tmp;
+
+       return ret;
+}
+
+/**
+ * __adis_read_reg_32() - read 4 bytes from a 32-bit register (unlocked)
+ * @adis: The adis device
+ * @reg: The address of the lower of the two registers
+ * @val: The value read back from the device
+ */
+static inline int __adis_read_reg_32(struct adis *adis, unsigned int reg,
+       uint32_t *val)
+{
+       unsigned int tmp;
+       int ret;
+
+       ret = __adis_read_reg(adis, reg, &tmp, 4);
+       if (ret == 0)
+               *val = tmp;
+
+       return ret;
+}
+
+/**
+ * adis_write_reg() - write N bytes to register
+ * @adis: The adis device
+ * @reg: The address of the lower of the two registers
+ * @value: The value to write to device (up to 4 bytes)
+ * @size: The size of the @value (in bytes)
+ */
+static inline int adis_write_reg(struct adis *adis, unsigned int reg,
+       unsigned int val, unsigned int size)
+{
+       int ret;
+
+       mutex_lock(&adis->state_lock);
+       ret = __adis_write_reg(adis, reg, val, size);
+       mutex_unlock(&adis->state_lock);
+
+       return ret;
+}
+
+/**
+ * adis_read_reg() - read N bytes from register
+ * @adis: The adis device
+ * @reg: The address of the lower of the two registers
+ * @val: The value read back from the device
+ * @size: The size of the @val buffer
+ */
+static int adis_read_reg(struct adis *adis, unsigned int reg,
+       unsigned int *val, unsigned int size)
+{
+       int ret;
+
+       mutex_lock(&adis->state_lock);
+       ret = __adis_read_reg(adis, reg, val, size);
+       mutex_unlock(&adis->state_lock);
+
+       return ret;
+}
+
 /**
  * adis_write_reg_8() - Write single byte to a register
  * @adis: The adis device
@@ -155,7 +296,18 @@ static inline int adis_read_reg_32(struct adis *adis, unsigned int reg,
 }
 
 int adis_enable_irq(struct adis *adis, bool enable);
-int adis_check_status(struct adis *adis);
+int __adis_check_status(struct adis *adis);
+
+static inline int adis_check_status(struct adis *adis)
+{
+       int ret;
+
+       mutex_lock(&adis->state_lock);
+       ret = __adis_check_status(adis);
+       mutex_unlock(&adis->state_lock);
+
+       return ret;
+}
 
 int adis_initial_startup(struct adis *adis);
 
diff --git a/include/linux/iio/magnetometer/ak8975.h b/include/linux/iio/magnetometer/ak8975.h
deleted file mode 100644 (file)
index ac9366f..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __IIO_MAGNETOMETER_AK8975_H__
-#define __IIO_MAGNETOMETER_AK8975_H__
-
-#include <linux/iio/iio.h>
-
-/**
- * struct ak8975_platform_data - AK8975 magnetometer driver platform data
- * @eoc_gpio:    data ready event gpio
- * @orientation: mounting matrix relative to main hardware
- */
-struct ak8975_platform_data {
-       int                     eoc_gpio;
-       struct iio_mount_matrix orientation;
-};
-
-#endif
index fa824e1..e6fd364 100644 (file)
@@ -25,6 +25,7 @@ enum iio_event_info {
 #define IIO_VAL_INT_MULTIPLE 5
 #define IIO_VAL_FRACTIONAL 10
 #define IIO_VAL_FRACTIONAL_LOG2 11
+#define IIO_VAL_CHAR 12
 
 enum iio_available_type {
        IIO_AVAIL_LIST,
@@ -57,6 +58,7 @@ enum iio_chan_info_enum {
        IIO_CHAN_INFO_DEBOUNCE_TIME,
        IIO_CHAN_INFO_CALIBEMISSIVITY,
        IIO_CHAN_INFO_OVERSAMPLING_RATIO,
+       IIO_CHAN_INFO_THERMOCOUPLE_TYPE,
 };
 
 #endif /* _IIO_TYPES_H_ */
index d75e1ad..12be09b 100644 (file)
@@ -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__ */
index 44bd604..953fd50 100644 (file)
@@ -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__ */
index 075fab5..94ba42b 100644 (file)
 #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__ */
index 7de6c16..f065256 100644 (file)
@@ -40,14 +40,11 @@ enum ad7266_mode {
  * @range: Reference voltage range the device is configured for
  * @mode: Sample mode the device is configured for
  * @fixed_addr: Whether the address pins are hard-wired
- * @addr_gpios: GPIOs used for controlling the address pins, only used if
- *             fixed_addr is set to false.
  */
 struct ad7266_platform_data {
        enum ad7266_range range;
        enum ad7266_mode mode;
        bool fixed_addr;
-       unsigned int addr_gpios[3];
 };
 
 #endif
diff --git a/include/linux/platform_data/ads1015.h b/include/linux/platform_data/ads1015.h
deleted file mode 100644 (file)
index 4cc9ffc..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Platform Data for ADS1015 12-bit 4-input ADC
- * (C) Copyright 2010
- * Dirk Eibach, Guntermann & Drunck GmbH <eibach@gdsys.de>
- */
-
-#ifndef LINUX_ADS1015_H
-#define LINUX_ADS1015_H
-
-#define ADS1015_CHANNELS 8
-
-struct ads1015_channel_data {
-       bool enabled;
-       unsigned int pga;
-       unsigned int data_rate;
-};
-
-struct ads1015_platform_data {
-       struct ads1015_channel_data channel_data[ADS1015_CHANNELS];
-};
-
-#endif /* LINUX_ADS1015_H */
diff --git a/include/uapi/linux/b1lli.h b/include/uapi/linux/b1lli.h
deleted file mode 100644 (file)
index 4ae6ac9..0000000
+++ /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 (file)
index 279551a..0000000
+++ /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 (file)
index 99f77c5..0000000
+++ /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 */ 
-
-
-
-